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:
parent
07b24459ea
commit
85bfd19a7b
1 changed files with 31 additions and 12 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue