diff options
| author | Xiao-Yong Jin <xjin@anl.gov> | 2019-04-11 19:43:11 -0500 |
|---|---|---|
| committer | Dan Cross <crossd@gmail.com> | 2022-07-26 12:13:13 -0400 |
| commit | 85bfd19a7beb628f24b051d23e6c94ecc6e4babc (patch) | |
| tree | 1e29202da06a072edf0382a41306095fc594d30a /src/cmd/devdraw/x11-screen.c | |
| parent | 07b24459ea4f06f7e86b7c4557eea5b451354575 (diff) | |
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 (limited to 'src/cmd/devdraw/x11-screen.c')
| -rw-r--r-- | src/cmd/devdraw/x11-screen.c | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/src/cmd/devdraw/x11-screen.c b/src/cmd/devdraw/x11-screen.c index 0bbc25d6..9490ab8f 100644 --- 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) |