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.
This commit is contained in:
Xiao-Yong Jin 2019-04-11 19:43:11 -05:00 committed by Dan Cross
parent 07b24459ea
commit 85bfd19a7b

View file

@ -312,6 +312,8 @@ xloop(void)
} }
} }
static int kcodecontrol, kcodealt, kcodeshift;
/* /*
* Handle an incoming X event. * Handle an incoming X event.
*/ */
@ -319,12 +321,15 @@ static void
runxevent(XEvent *xev) runxevent(XEvent *xev)
{ {
int c; int c;
int modp;
KeySym k; KeySym k;
static Mouse m; static Mouse m;
XButtonEvent *be; XButtonEvent *be;
XKeyEvent *ke; XKeyEvent *ke;
Xwin *w; Xwin *w;
modp = 0;
#ifdef SHOWEVENT #ifdef SHOWEVENT
static int first = 1; static int first = 1;
if(first){ if(first){
@ -424,20 +429,34 @@ runxevent(XEvent *xev)
break; break;
} }
switch(k) { if(xev->type == KeyPress)
case XK_Control_L: switch(k) {
if(xev->type == KeyPress) case XK_Control_L:
case XK_Control_R:
kcodecontrol = ke->keycode;
c |= ControlMask; c |= ControlMask;
else modp = 1;
c &= ~ControlMask; break;
goto kbutton; case XK_Alt_L:
case XK_Alt_L: case XK_Alt_R:
case XK_Shift_L: kcodealt = ke->keycode;
if(xev->type == KeyPress) // fall through
case XK_Shift_L:
case XK_Shift_R:
kcodeshift = ke->keycode;
c |= Mod1Mask; c |= Mod1Mask;
else modp = 1;
}
else {
if(ke->keycode == kcodecontrol){
c &= ~ControlMask;
modp = 1;
} else if(ke->keycode == kcodealt || ke->keycode == kcodeshift){
c &= ~Mod1Mask; c &= ~Mod1Mask;
kbutton: modp = 1;
}
}
if(modp){
_x.kstate = c; _x.kstate = c;
if(m.buttons || _x.kbuttons) { if(m.buttons || _x.kbuttons) {
_x.altdown = 0; // used alt _x.altdown = 0; // used alt
@ -447,8 +466,8 @@ runxevent(XEvent *xev)
if(c & Mod1Mask) if(c & Mod1Mask)
_x.kbuttons |= 4; _x.kbuttons |= 4;
gfx_mousetrack(w->client, m.xy.x, m.xy.y, m.buttons|_x.kbuttons, m.msec); gfx_mousetrack(w->client, m.xy.x, m.xy.y, m.buttons|_x.kbuttons, m.msec);
break;
} }
modp = 0;
} }
if(xev->type != KeyPress) if(xev->type != KeyPress)