Bug 577187 - Xvnc emulating CapsLock with Shift breaks shortcuts' grabs logic in applications/toolkit
Summary: Xvnc emulating CapsLock with Shift breaks shortcuts' grabs logic in applicati...
Keywords:
Status: CLOSED WONTFIX
Alias: None
Product: Red Hat Enterprise Linux 5
Classification: Red Hat
Component: vnc
Version: 5.4
Hardware: All
OS: Linux
medium
medium
Target Milestone: rc
: ---
Assignee: Adam Tkac
QA Contact: qe-baseos-daemons
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2010-03-26 12:17 UTC by Olivier Fourdan
Modified: 2018-10-27 12:11 UTC (History)
3 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2010-05-10 13:26:42 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
Reproducer program (1.50 KB, text/plain)
2010-03-26 12:18 UTC, Olivier Fourdan
no flags Details
XEvents from a local X11 connection (5.35 KB, text/plain)
2010-03-26 12:20 UTC, Olivier Fourdan
no flags Details
XEvents from a VNC connection (5.31 KB, text/plain)
2010-03-26 12:21 UTC, Olivier Fourdan
no flags Details

Description Olivier Fourdan 2010-03-26 12:17:45 UTC
Description of problem:

This bug is a follow-up on bug #492529 regarding key accelerators in OpenMotif.

The problem is that in X11R6 CapsLock is seen as a modifier, so the state on a KeyPress event with CapsLock enabled is different from the state without.

The solution is to grab the key with both states, CapsLock on and off (the same goes for other modifiers like NumLock or ScrollLock).

This solution works fine except when using VNC. Within VNC, enabling CapsLock defeats the key accelerators.

The reason for this is that VNC emulates CapsLock with Shift, so the accelerator wil lnot work with CapsLock enabled in VNC.

Another problem is that some applications (for example NEdit) will have different meaning with or without shift (for example, in NEdit, Ctrl+v is "paste" whereas Ctrl+Shift+v is "paste column").

Version-Release number of selected component (if applicable):

vnc-server-4.1.2-14.el5_3.1

How reproducible:

Always

Steps to Reproduce:
1. Make sure the latest openmotif-2.3.1-2.el5_4.1 from RHBA-2010-0132 or later is installed

2. Save and build the attached "accel.c" file

  $ cc -o accel accel.c -L/usr/lib -lXm -lXt -lX11

3. Run the program locally

  $ ./accel

4. Enable CapLock

5. Press Ctrl+w, notice the window closes as expected

6. Redo step 3. 4. and 5. via VNC
  
Actual results:

In VNC the window does not close

Expected results:

The window closes as expected even in VNC

Additional info:

Attaching 2 xev captures, one from locally, the other one via VNC.

Locally, when CapsLock is enabled, the state field of the event reports the modifier:

  KeyPress event, serial 31, synthetic NO, window 0x4200001,
      root 0x10a, subw 0x0, time 13172032, (698,1049), root:(1582,1199),
      state 0x12, keycode 38 (keysym 0x41, A), same_screen YES,
      XLookupString gives 1 bytes: (41) "A"
      XmbLookupString gives 1 bytes: (41) "A"
      XFilterEvent returns: False

  KeyRelease event, serial 31, synthetic NO, window 0x4200001,
      root 0x10a, subw 0x0, time 13172168, (698,1049), root:(1582,1199),
      state 0x12, keycode 38 (keysym 0x41, A), same_screen YES,
      XLookupString gives 1 bytes: (41) "A"
      XFilterEvent returns: False

Note the state field in the KeyPress event is 0x12, this is expected because NumLock and CapsLock as enabled during the test.

Now the same test in VNC gives:

  KeyPress event, serial 29, synthetic NO, window 0x1c00001,
      root 0x3a, subw 0x0, time 2583228944, (443,730), root:(447,752),
      state 0x0, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
      XLookupString gives 0 bytes: 
      XmbLookupString gives 0 bytes: 
      XFilterEvent returns: False

  KeyPress event, serial 29, synthetic NO, window 0x1c00001,
      root 0x3a, subw 0x0, time 2583228944, (443,730), root:(447,752),
      state 0x1, keycode 38 (keysym 0x41, A), same_screen YES,
      XLookupString gives 1 bytes: (41) "A"
      XmbLookupString gives 1 bytes: (41) "A"
      XFilterEvent returns: False

  KeyRelease event, serial 29, synthetic NO, window 0x1c00001,
      root 0x3a, subw 0x0, time 2583228944, (443,730), root:(447,752),
      state 0x1, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
      XLookupString gives 0 bytes: 
      XFilterEvent returns: False

  KeyRelease event, serial 29, synthetic NO, window 0x1c00001,
      root 0x3a, subw 0x0, time 2583229036, (443,730), root:(447,752),
      state 0x0, keycode 38 (keysym 0x61, a), same_screen YES,
      XLookupString gives 1 bytes: (61) "a"
      XFilterEvent returns: False

Note that there additional KeyPress for Shift_L (which was not pressed intentionally) and the state field is now 0x1, ie CapsLock is not reported, instead it's emulated by a fake Shift.

This behaviour /might/ be intentional in vncserver because this is what the documentation for the RFB protocols specifies in paragraph 6.4 "CLIENT TO SERVER MESSAGES":

    http://www.realvnc.com/docs/rfbproto.pdf

    ...
    The difference between upper and lower case keysyms is significant. This is
    unlike some of the keyboard processing in the X Window System which treats
    them as the same. For example, a server receiving an uppercase ’A’ keysym
    without any shift presses should interpret it as an uppercase ’A’. Again
    this may involve an internal “fake” shift press.
    ...

    ...
    Servers should ignore “lock” keysyms such as CapsLock and NumLock where
    possible. Instead they should interpret each character-based keysym
    according to its case.
    ... 

Unfortunately, this is causing troubles for applications and toolkit which deal with modifiers in their accelerators.

Some other VNC server, like "x11vnc" do implement a workaround for this problem:

    http://linux.die.net/man/1/x11vnc

    ...
    -capslock
  
    When in -modtweak (the default) or -xkb mode, if a keysym in the range A-Z
    comes in check the X server to see if the Caps_Lock is set. If it is do not
    artificially press Shift to generate the keysym. This will enable the
    CapsLock key to behave correctly in some circumstances: namely *both* the
    VNC viewer machine and the x11vnc X server are in the CapsLock on state. If
    one side has CapsLock on and the other off and the keyboard is not behaving
    as you think it should you should correct the CapsLock states (hint:
    pressing CapsLock inside and outside of the viewer can help toggle them
    both to the correct state). However, for best results do not use this
    option, but rather *only* enable CapsLock on the VNC viewer side (i.e. by
    pressing CapsLock outside of the viewer window, also -skip_lockkeys below).
    Also try -nomodtweak for a possible workaround.
    ...

Unfortunately, vncserver we have in Red Hat Enterprise Linux do not have such an option.

Comment 1 Olivier Fourdan 2010-03-26 12:18:29 UTC
Created attachment 402826 [details]
Reproducer program

Comment 2 Olivier Fourdan 2010-03-26 12:20:00 UTC
Created attachment 402827 [details]
XEvents from a local X11 connection

Test is:

 - Press 2x "a" without shift nor CapsLock
 - Press 2x "a" with Shift_L pressed, but no CapsLock
 - Press 2x "a" with CApsLock but no Shift.

Comment 3 Olivier Fourdan 2010-03-26 12:21:13 UTC
Created attachment 402828 [details]
XEvents from a VNC connection

Same test, via VNC this time:

 - Press 2x "a" without shift nor CapsLock
 - Press 2x "a" with Shift_L pressed, but no CapsLock
 - Press 2x "a" with CApsLock but no Shift.

Comment 4 Adam Tkac 2010-03-26 13:45:45 UTC
Issues like this are very tricky due RFB protocol shortages as you wrote in original comment. VNC server receives only X11 keysym so it has no idea if client pressed CapsLock + key or simply Shift + key.

This scenario can be solved via new option which will control how to handle "upper" keysyms inside server (fake shift + key or fake CapsLock + key). If I understand correctly Xvnc server will raise fake CapsLock press instead of Shift press when run with -capslock option, won't it?

Comment 5 Olivier Fourdan 2010-03-26 14:01:39 UTC
If I understand correctly how x11vnc works with the "-capslock" option, it will report the CapsLock modifier only if it has received the Capslock KeyPress event before.

A side effect of this approach is that CapsLock has to be pressed when the focus is on the vncviewer window otherwise the x11vnc server is not aware that the CapsLock has changed.

If you press CapsLock while input focus is on some other window, then the -capslock option in x11vnc will also be defeated.

A "all-or-nothing" option might not be appropriate, because at times we do want to receive Shift+key and not just key with CapslLock modifier "on", otherwise the apps that rely on Shift+key as a shortcut (such as NEdit) will not work anymore, I think that's the reason why x11vnc tries to track the CapsLock key events and decide whether or not to report the modifier accordingly (or so I think, but I could be wrong, I have not checked x11vnc source code yet).

Comment 6 Adam Tkac 2010-03-30 13:18:40 UTC
(In reply to comment #5)
> If I understand correctly how x11vnc works with the "-capslock" option, it will
> report the CapsLock modifier only if it has received the Capslock KeyPress
> event before.
> 
> A side effect of this approach is that CapsLock has to be pressed when the
> focus is on the vncviewer window otherwise the x11vnc server is not aware that
> the CapsLock has changed.
> 
> If you press CapsLock while input focus is on some other window, then the
> -capslock option in x11vnc will also be defeated.

I don't like this approach much but, unfortunately, I don't know better solution. I will discuss this issue in upstream - if we will do something with this or rather close this as wontfix.

Comment 10 Adam Tkac 2010-05-10 13:26:42 UTC
After discussion in upstream (http://www.mail-archive.com/tigervnc-devel@lists.sourceforge.net/msg00577.html) this bug won't be fixed due shortages in the RFB protocol. There is no "right" way how to fix the problem.


Note You need to log in before you can comment on or make changes to this bug.