Xpra: Ticket #602: some altgr keys are not honoured with win32 client and non-us layouts

ie: with 'fr' layout and a Linux client, I get the correct keys:

but with a win32 client, I get:

typical azerty layout



Sat, 14 Jun 2014 14:11:40 GMT - Antoine Martin: attachment set

typical azerty layout


Sat, 14 Jun 2014 14:12:36 GMT - Antoine Martin: owner, status, description changed


Sun, 15 Jun 2014 08:20:47 GMT - Antoine Martin:

win32 client

(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:


Linux Client

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

xev

Despite the buggy quirks which will need fixing, the xev looks OK:

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"

Sun, 15 Jun 2014 12:17:30 GMT - Antoine Martin:

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).


Wed, 18 Jun 2014 10:53:21 GMT - Antoine Martin: status changed; resolution set

Backport in r6829, released in 0.13.6


Sat, 23 Jan 2021 05:00:34 GMT - migration script:

this ticket has been moved to: https://github.com/Xpra-org/xpra/issues/602