commit 85bfd19a7beb628f24b051d23e6c94ecc6e4babc
parent 07b24459ea4f06f7e86b7c4557eea5b451354575
Author: Xiao-Yong Jin <xjin@anl.gov>
Date: Thu, 11 Apr 2019 19:43:11 -0500
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.
Diffstat:
1 file changed, 31 insertions(+), 12 deletions(-)
diff --git a/src/cmd/devdraw/x11-screen.c b/src/cmd/devdraw/x11-screen.c
@@ -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;
}
- 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)
+ 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;
- 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)