ie: with 'fr' layout and a Linux client, I get the correct keys:
AltGr
+ 2
comes up as ~
AltGr
+ 7
comes up as `
but with a win32 client, I get:
AltGr
+ 2
comes up as é
AltGr
+ 7
comes up as è
typical azerty layout
(bear in mind those quirks: AltGr
triggers a spurious Control_L
... mod2
/ NumLock
is missing from modifiers):
send_key_action(1, <GTKKeyEvent object, contents: \ {'modifiers': ['control', 'mod2'], 'group': 0, 'string': '', 'keyname': 'Control_L', \ 'pressed': True, 'keyval': 65507, 'keycode': 17}>) send_key_action(1, <GTKKeyEvent object, contents: \ {'modifiers': ['control', 'mod2'], 'group': 0, 'string': '', 'keyname': 'Control_L', \ 'pressed': False, 'keyval': 65507, 'keycode': 17}>) send_key_action(1, <GTKKeyEvent object, contents: \ {'modifiers': [], 'group': 1, 'string': '', 'keyname': 'Alt_R', \ 'pressed': True, 'keyval': 65514, 'keycode': 165}>) AltGr_modifiers(['mod2'], True) add=['mod5'], clear=['mod1', 'mod2', 'control'] mask_to_names(<flags GDK_MOD2_MASK of type GdkModifierType>) GetKeyState(VK_NUMLOCK)=1, names=[' mod5', 'mod2'] send_key_action(1, <GTKKeyEvent object, contents: \ {'modifiers': ['mod5', 'mod2'], 'group': 1, 'string': '', 'keyname': 'dead_tilde', \ 'pressed': True, 'keyval': 65107, 'keycode': 50}>)
server:
get_keycode(17, Control_L, ('control', 'mod2')) is_native_keymap=False, found using translation: 37 handle keycode pressing 37: key Control_L get_keycode(17, Control_L, ('control', 'mod2')) is_native_keymap=False, found using translation: 37 handle keycode unpressing 37: key Control_L get_keycode(165, Alt_R, ()) is_native_keymap=False, found using translation: 248 make_keymask_match(remove) () modifier mod2 using 77, success: False remove mod2 with keycode 77 did not work - trying to undo it! handle keycode pressing 248: key Alt_R get_keycode(50, dead_tilde, ('mod5', 'mod2')) is_native_keymap=False, found using translation: 103 make_keymask_match(remove) ('mod5', 'mod2') modifier mod1 using 248, success: True make_keymask_match(add) ('mod5', 'mod2') modifier mod5 using 108, success: True handle keycode pressing 103: key dead_tilde
With this modmap:
shift Shift_L (0x32), Shift_R (0x3e), Shift_L (0xde) lock Caps_Lock (0x42) control Control_L (0x25), Control_R (0x69), Control_L (0xe6) mod1 Alt_L (0x40), Meta_R (0x84), Alt_L (0xcc), Meta_L (0xcd), Alt_L (0xf7), Alt_R (0xf8) mod2 Num_Lock (0x4d) mod3 Super_L (0x85), Super_R (0x86), Super_L (0xce) mod4 Hyper_L (0xcf), Hyper_R (0xf9) mod5 ISO_Level3_Shift (0x5c), ISO_Level3_Shift (0x6c), Mode_switch (0xcb)
Problems:
mod2
/ NumLock
using keycode 77
- looks like it should be skipped, as we already do for mouse events
mod5
/ ISO_Level3_Shift
, yet the dead_tilde
key isn't the one that's used
keycode 103 = eacute 2 dead_tilde keycode 108 = ISO_Level3_Shift NoSymbol ISO_Level3_Shift NoSymbol ISO_Level3_Shift ISO_Level3_Shift
which works OK:
send_key_action(1, <GTKKeyEvent object, contents: \ {'modifiers': ['mod2'], 'group': 0, 'string': '', 'keyname': 'ISO_Level3_Shift', \ 'pressed': True, 'keyval': 65027, 'keycode': 108}>) send_key_action(1, <GTKKeyEvent object, contents: \ {'modifiers': ['mod2', 'mod5'], 'group': 0, 'string': '~', 'keyname': 'asciitilde', \ 'pressed': True, 'keyval': 126, 'keycode': 11}>)
server logging:
get_keycode(108, ISO_Level3_Shift, ('mod2',)) native keymap, using unmodified keycode: 108 handle keycode pressing 108: key ISO_Level3_Shift get_keycode(11, asciitilde, ('mod2', 'mod5')) native keymap, using unmodified keycode: 11 handle keycode pressing 11: key asciitilde
The main difference is in the modmap:
shift Shift_L (0x32), Shift_R (0x3e) lock Caps_Lock (0x42) control Control_L (0x25), Control_R (0x69) mod1 Alt_L (0x40), Alt_L (0xcc), Meta_L (0xcd) mod2 Num_Lock (0x4d) mod3 mod4 Super_L (0x85), Super_R (0x86), Super_L (0xce), Hyper_L (0xcf) mod5 ISO_Level3_Shift (0x5c), ISO_Level3_Shift (0x6c), Mode_switch (0xcb)
keycode 11 = eacute 2 eacute 2 asciitilde oneeighth asciitilde keycode 108 = ISO_Level3_Shift NoSymbol ISO_Level3_Shift NoSymbol ISO_Level3_Shift ISO_Level3_Shift
Despite the buggy quirks which will need fixing, the xev looks OK:
KeyPress event, serial 35, synthetic NO, window 0xa00001, root 0x44, subw 0x0, time 22256542, (83,109), root:(87,139), state 0x10, keycode 108 (keysym 0xfe03, ISO_Level3_Shift), same_screen YES, XKeysymToKeycode returns keycode: 92 XLookupString gives 0 bytes: XmbLookupString gives 0 bytes: XFilterEvent returns: False KeyPress event, serial 35, synthetic NO, window 0xa00001, root 0x44, subw 0x0, time 22256542, (83,109), root:(87,139), state 0x90, keycode 103 (keysym 0xe9, eacute), same_screen YES, XKeysymToKeycode returns keycode: 11 XLookupString gives 2 bytes: (c3 a9) "é" XmbLookupString gives 2 bytes: (c3 a9) "é" XFilterEvent returns: False
KeyPress event, serial 63, synthetic NO, window 0xc00001, root 0x44, subw 0x0, time 22515073, (71,54), root:(126,107), state 0x10, keycode 108 (keysym 0xfe03, ISO_Level3_Shift), same_screen YES, XKeysymToKeycode returns keycode: 92 XLookupString gives 0 bytes: XmbLookupString gives 0 bytes: XFilterEvent returns: False KeyPress event, serial 63, synthetic NO, window 0xc00001, root 0x44, subw 0x0, time 22515169, (71,54), root:(126,107), state 0x90, keycode 11 (keysym 0x7e, asciitilde), same_screen YES, XKeysymToKeycode returns keycode: 49 XLookupString gives 1 bytes: (7e) "~" XmbLookupString gives 1 bytes: (7e) "~" XFilterEvent returns: False
Manually changing the keymap does not solve the problem:
xmodmap -e "keycode 103 = eacute 2 eacute 2 asciitilde oneeighth asciitilde"
One can verify that this is the key that gets used with:
xmodmap -e "keycode 103 = asciitilde"
r6806 adds the ability to simulate keys via xpra control, which makes testing keycodes directly so much easier. With this sequence of commands (simulating pressing the numbers 1 to 0 with altgr held):
xpra control :10 key 0x5c press for i in `seq 10 19`; do echo $i; xpra control :10 key $i press; xpra control :10 key $i unpress; done xpra control :10 key 0x5c unpress
I see:
¹~#{[|`\^@
Which is the correct list of characters according to wikipedia: AltGr_key French
Whereas with the win32 client doing the same sequence of keypresses, I see:
¹é#{(|è\^@
Logging the keycodes:
handle keycode pressing 10: key ampersand handle keycode pressing 119: key dead_tilde handle keycode pressing 12: key numbersign handle keycode pressing 13: key braceleft handle keycode pressing 14: key bracketleft handle keycode pressing 15: key bar handle keycode pressing 120: key dead_grave handle keycode pressing 17: key backslash handle keycode pressing 18: key asciicircum handle keycode pressing 19: key at
So the problem comes from the fact that those two keys are mapped to other keycodes. And that's because they have different key names under win32 than they do in the X11 keymap, so we end up assigning a new keycode for them.
r6807 fixes that using the existing client-side key name translation code from #588 (will backport).
Backport in r6829, released in 0.13.6
this ticket has been moved to: https://github.com/Xpra-org/xpra/issues/602