xpra icon
Bug tracker and wiki

Opened 5 years ago

Closed 5 years ago

#602 closed defect (fixed)

some altgr keys are not honoured with win32 client and non-us layouts

Reported by: Antoine Martin Owned by: Antoine Martin
Priority: major Milestone: 0.14
Component: platforms Version: 0.13.x
Keywords: win32 keyboard Cc:

Description (last modified by Antoine Martin)

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

Attachments (1)

800px-KB_France.svg.png (56.1 KB) - added by Antoine Martin 5 years ago.
typical azerty layout

Download all attachments as: .zip

Change History (5)

Changed 5 years ago by Antoine Martin

Attachment: 800px-KB_France.svg.png added

typical azerty layout

comment:1 Changed 5 years ago by Antoine Martin

Description: modified (diff)
Owner: changed from Antoine Martin to Antoine Martin
Status: newassigned

comment:2 Changed 5 years ago by 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:

  • we try and fail to unpress mod2 / NumLock using keycode 77 - looks like it should be skipped, as we already do for mouse events
  • we succeed in pressing 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
    

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:

  • win32 client:
    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
    
  • linux client:
    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"
Last edited 5 years ago by Antoine Martin (previous) (diff)

comment:3 Changed 5 years ago by 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).

Last edited 5 years ago by Antoine Martin (previous) (diff)

comment:4 Changed 5 years ago by Antoine Martin

Resolution: fixed
Status: assignedclosed

Backport in r6829, released in 0.13.6

Note: See TracTickets for help on using tickets.