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.
*/
@ -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;
}
if(xev->type == KeyPress)
switch(k) {
case XK_Control_L:
if(xev->type == KeyPress)
case XK_Control_R:
kcodecontrol = ke->keycode;
c |= ControlMask;
else
c &= ~ControlMask;
goto kbutton;
modp = 1;
break;
case XK_Alt_L:
case XK_Alt_R:
kcodealt = ke->keycode;
// fall through
case XK_Shift_L:
if(xev->type == KeyPress)
case XK_Shift_R:
kcodeshift = ke->keycode;
c |= Mod1Mask;
else
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)