commit 85bfd19a7beb628f24b051d23e6c94ecc6e4babc from: Xiao-Yong Jin via: Dan Cross date: Tue Jul 26 16:13:13 2022 UTC devdraw/x11: fix modifier key handling for some XkbOptions Certain XkbOptions in X11 would change keysyms for modifier keys between the key press and key release. For example, under the XkbOptions "grp:shifts_toggle", though shift keys remain Shift_L/R when pressed, they become ISO_Group_Next/Prev when released. This behavior makes devdraw unable to detect the release event correctly and as a result mouse button 1 click always interpreted as button 3 event after a shift key is used. commit - 07b24459ea4f06f7e86b7c4557eea5b451354575 commit + 85bfd19a7beb628f24b051d23e6c94ecc6e4babc blob - 0bbc25d693ef1a5cc262759ffe0db8b183f2f099 blob + 9490ab8f2324fe037d6f28cb87f61e4995815aec --- src/cmd/devdraw/x11-screen.c +++ src/cmd/devdraw/x11-screen.c @@ -311,6 +311,8 @@ xloop(void) } } } + +static int kcodecontrol, kcodealt, kcodeshift; /* * Handle an incoming X event. @@ -319,12 +321,15 @@ static void runxevent(XEvent *xev) { int c; + int modp; KeySym k; static Mouse m; XButtonEvent *be; XKeyEvent *ke; Xwin *w; + modp = 0; + #ifdef SHOWEVENT static int first = 1; if(first){ @@ -424,20 +429,34 @@ runxevent(XEvent *xev) break; } - switch(k) { - case XK_Control_L: - if(xev->type == KeyPress) + if(xev->type == KeyPress) + switch(k) { + case XK_Control_L: + case XK_Control_R: + kcodecontrol = ke->keycode; c |= ControlMask; - else - c &= ~ControlMask; - goto kbutton; - case XK_Alt_L: - case XK_Shift_L: - if(xev->type == KeyPress) - c |= Mod1Mask; - else + modp = 1; + break; + case XK_Alt_L: + case XK_Alt_R: + kcodealt = ke->keycode; + // fall through + case XK_Shift_L: + case XK_Shift_R: + kcodeshift = ke->keycode; + c |= Mod1Mask; + modp = 1; + } + else { + if(ke->keycode == kcodecontrol){ + c &= ~ControlMask; + modp = 1; + } else if(ke->keycode == kcodealt || ke->keycode == kcodeshift){ c &= ~Mod1Mask; - kbutton: + modp = 1; + } + } + if(modp){ _x.kstate = c; if(m.buttons || _x.kbuttons) { _x.altdown = 0; // used alt @@ -447,8 +466,8 @@ runxevent(XEvent *xev) if(c & Mod1Mask) _x.kbuttons |= 4; gfx_mousetrack(w->client, m.xy.x, m.xy.y, m.buttons|_x.kbuttons, m.msec); - break; } + modp = 0; } if(xev->type != KeyPress)