Export to GitHub

semicomplete - issue #7

Modifier key not detected


Posted on Jul 30, 2009 by Happy Giraffe

What steps will reproduce the problem? I've mapped my ISO_Level3_Shift button, which is the right Alt button on my keyboard, to be mod5: $ xmodmap xmodmap: up to 3 keys per modifier, (keycodes in parentheses):

shift Shift_L (0x32), Shift_R (0x3e) lock
control Control_L (0x25), Control_L (0x42), Control_R (0x69) mod1 Alt_L (0x40), Meta_L (0xcd) mod2 Num_Lock (0x4d) mod3
mod4 Super_L (0xce), Hyper_L (0xcf) mod5 ISO_Level3_Shift (0x5c), Mode_switch (0xcb)

So that when I press my Alt button on the right, xev sees: KeyPress event, serial 25, synthetic NO, window 0x1e00001, root 0xa5, subw 0x0, time 358194927, (621,436), root:(622,455), state 0x0, 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

So it mentions two keycodes, 108 and 92. Keycode 92 is detected by xdotool as mod5, but the loop in xdo_active_modifiers_to_keycode_list sees it as 108, and so doesn't recognize it as a modifier. This causes a problem for me when I try to port the clearmodifiers feature to mouse buttons, because the modifier key is not detected and is still active, so it sends both the modifier and the button press.

I changed the code:

--- orig/xdotool-20090710/xdo.c 2009-07-10 00:55:14.000000000 -0700 +++ changed/xdotool-20090710/xdo.c 2009-07-30 09:52:08.000000000 -0700 @@ -1151,14 +1151,18 @@ char keymap[32]; /* keycode map: 256 bits */ int keys_size = 10; int keycode = 0; + int realKeycode = 0; + KeySym sym; *nkeys = 0; *keys = malloc(keys_size * sizeof(charcodemap_t));

XQueryKeymap(xdo->xdpy, keymap);

for (keycode = 0; keycode < 256; keycode++) { + sym = XKeycodeToKeysym(xdo->xdpy, keycode, 0); + realKeycode = XKeysymToKeycode(xdo->xdpy, sym); if ((keymap[(keycode / 8)] & (1 << (keycode % 8))) \ - && _xdo_cached_keycode_to_modifier(xdo, keycode)) { + && _xdo_cached_keycode_to_modifier(xdo, realKeycode)) { /* This keycode is active and is a modifier */

   (*keys)[*nkeys].code = keycode;

and that seems to fix it. I don't actually know much about X keycodes and keysyms, so I'm not sure if this is the right way to do this.

Comment #1

Posted on Jan 1, 2010 by Happy Camel

That's funky indeed. Can you add the contents of 'xmodmap -pke' here?

Reading over the functions involved in this doesn't point out anything obvious.

The 'if' statement checks if the keycode (keyboard key) is active and if it's a modifier. the _xdo_cached_keycode_to_modifier() function uses data from data populated using _xdo_query_keycode_to_modifier, which walks data given by XGetModifierMapping.

Either way, it seems like a bug. I'll see if I can reproduce it. If not, I'll give you some test code to help me inspect this more.

Status: New

Labels:
Type-Defect Priority-Medium