www.cendio.com
Bug 5226 - detect AltGr on Windows
: detect AltGr on Windows
Status: CLOSED FIXED
: ThinLinc
VNC
: trunk
: PC Windows
: P2 Normal
: 4.10.0
Assigned To:
:
:
: 7158
: 965 3523
  Show dependency treegraph
 
Reported: 2014-08-21 13:23 by
Modified: 2018-11-07 11:03 (History)
Acceptance Criteria:
* Pressing AltGr should send _only_ ISO_Level3_Shift to the server * Pressing right Alt (e.g. us layout) should send Alt_R * Pressing Ctrl+AltGr should send Ctrl_* and ISO_Level3_Shift * Release note should be written * Switching client layout should directly change Alt/AltGr behaviour


Attachments


Note

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


Description From cendio 2014-08-21 13:23:15
Windows has this idiotic behaviour of sending a VK_LCONTROL/VK_RMENU
combination when you press AltGr. This wreaks havoc with VNC as we cannot tell
an actual press of the left control key from that fake one, and we don't know
if we should be sending XK_ISO_Level3_Shift of XK_Alt_R.

We have as of yet not figured out a good way to work around this. The window
messages are identical for fake and real presses, as well are the responses
from GetKeyState() and GetAsyncKeyState(). There are currently three known
methods of detecting this scenario:

 1. Check if a VK_LCONTROL is immediately followed by a VK_RMENU on the message
queue. This is however race-y, and Windows doesn't send the fake VK_LCONTROL if
that key is already down anyway.

 2. Keyboard hook. Entirely undocumented, the scan code will have an extra
0x200 or:ed in for the fake control events. Spice relies on this somehow. The
problem is that keyboard hooks are a pain in the ass as they run globally,
asynchronously relative our main message queue, and we don't even know if this
key press will be for us.

 3. Raw input. The fake control events are not seen at this level, so we can
detect the AltGr scenario by seeing if we get a window message for a key that
we did not get a raw input event for. Unfortunately Windows, for brain dead
reasons (and this is also completely undocumented), disables keyboard hooks in
your process if you enable raw input. And since we need keyboard hooks to grab
things like Alt+Tab and the Windows keys, it means we cannot use raw input.
------- Comment #2 From cendio 2018-02-05 15:55:36 -------
Chromium/Chrome has implemented some detection for this:

https://bugs.chromium.org/p/chromium/issues/detail?id=25503
------- Comment #3 From cendio 2018-03-07 17:01:36 -------
(In reply to comment #0)
> 
>  2. Keyboard hook. Entirely undocumented, the scan code will have an extra
> 0x200 or:ed in for the fake control events. Spice relies on this somehow. The
> problem is that keyboard hooks are a pain in the ass as they run globally,
> asynchronously relative our main message queue, and we don't even know if this
> key press will be for us.
> 

gtk-vnc copied this approach:

https://git.gnome.org/browse/gtk-vnc/commit/?id=590c344ad3340dfabb9985c98f418ce2fcae7b44

It also demonstrates how they hook it up with the main window:

 - They use SendMessage() to bounce the keyboard events to the main window

 - They have a global variable that is updated on focus changes to determine if
messages should be bounced or not
------- Comment #4 From cendio 2018-03-08 17:34:28 -------
https://github.com/TigerVNC/tigervnc/pull/608
------- Comment #5 From cendio 2018-09-19 13:29:11 -------
The method implemented upstream is the method used by Chrome. This is a variant
of method 1. with the addition that the system keymap is also examined to see
if it contains the AltGr key or not. This addition avoid the risk of false
detections when they layout doesn't have AltGr, and it makes it reliable to
detect AltGr even when Ctrl is already pressed.

(The method Chrome, and now TigerVNC, uses is that it checks if Ctrl+Alt+<key>
gives a symbol for any value for <key>. If so the layout is assumed to use
AltGr.)
------- Comment #6 From cendio 2018-09-20 08:10:03 -------
> * Pressing AltGr should send _only_ ISO_Level3_Shift to the server
>

Works as expected

> * Pressing right Alt (e.g. us layout) should send Alt_R
>

Selecting english layout on client will send Alt_L instead of
expected Alt_R

> * Pressing Ctrl+AltGr should send Ctrl_* and ISO_Level3_Shift
>

Work as expected
------- Comment #7 From cendio 2018-09-24 10:04:24 -------
(In reply to comment #6)
> > * Pressing right Alt (e.g. us layout) should send Alt_R
> >
> 
> Selecting english layout on client will send Alt_L instead of
> expected Alt_R
> 

We got this because the server had a layout configured that didn't include
Alt_R (Swedish). Instead of mapping a new key the server then picks an
equivalent one, Alt_L in this case. Selecting e.g. us layout gets a Alt_R here.
------- Comment #9 From cendio 2018-09-28 10:35:12 -------
> * Release note should be written

Done.

> * Switching client layout should directly change Alt/AltGr behaviour

It does.
------- Comment #10 From cendio 2018-11-05 17:46:15 -------
Does not work properly with the virtual, touch keyboard on Windows 10:

https://github.com/TigerVNC/tigervnc/issues/760

Doesn't work properly for Chrome or Firefox either, but maybe we can do better?
------- Comment #12 From cendio 2018-11-06 17:22:49 -------
The above commit was for the touch keyboard in its advanced mode. Unfortunately
it is also broken in other was in its standard mode. Added bug 7276 for that.
------- Comment #14 From cendio 2018-11-07 11:03:33 -------
Retested the various AltGr and Alt_R combinations using both a physical
keyboard, and the touch keyboard. Works well now.

Also tested multimedia keys as they also come without a scancode (lack of
scancode is part of the detection for the touch keyboard's AltGr).