Bugzilla – Full Text Bug Listing
|Summary:||detect AltGr on Windows|
|Product:||ThinLinc||Reporter:||Pierre Ossman <firstname.lastname@example.org>|
|Component:||VNC||Assignee:||Pierre Ossman <email@example.com>|
|Status:||CLOSED FIXED||QA Contact:||Bugzilla mail exporter <firstname.lastname@example.org>|
|Version:||trunk||Keywords:||hean01_tester, ossman_tester, relnotes, upstream|
* 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
|Bug Depends on:||7158|
|Bug Blocks:||965, 3523|
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.
Chromium/Chrome has implemented some detection for this: https://bugs.chromium.org/p/chromium/issues/detail?id=25503
(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
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.)
> * 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
(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.
> * Release note should be written Done. > * Switching client layout should directly change Alt/AltGr behaviour It does.
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?
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.
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).