xkb: Match key releases with an overlaid press
Testcase:
In ~/.xbindkeysrc:
"xterm &"
XF86LaunchA
In ~/ov.xkb:
xkb_keymap {
xkb_keycodes { include "evdev" };
xkb_types { include "complete" };
xkb_compat { include "complete"
interpret Overlay1_Enable+AnyOfOrNone(all) {
action= SetControls(controls=Overlay1);
};
};
xkb_symbols { include "pc+inet(evdev)+us"
key <INS> { [ Overlay1_Enable ] };
key <AE01> { overlay1 = <AE02> }; // Insert+1 => 2
key <TLDE> { overlay1 = <I128> }; // Insert+~ => XF86LaunchA
};
xkb_geometry { include "pc(pc104)" };
};
Apply this layout: 'xkbcomp ~/ov.xkb $DISPLAY'.
Run "xbindkeys -n -v"
In the exact order:
- press Insert
- press Tilde
- release Insert
- wait
- release Tilde
Keyboard input in the new terminal window(s) would be locked
until another Insert+Tilde .
Reported-by: Mariusz Mazur <mariusz.g.mazur@gmail.com>
Signed-off-by: Mihail Konev <k.mvc@ya.ru>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
29a4f3db60
commit
9d32b71c93
|
|
@ -195,6 +195,8 @@ typedef struct _XkbSrvInfo {
|
||||||
XkbFilterPtr filters;
|
XkbFilterPtr filters;
|
||||||
|
|
||||||
XkbSrvCheckRepeatPtr checkRepeat;
|
XkbSrvCheckRepeatPtr checkRepeat;
|
||||||
|
|
||||||
|
char overlay_perkey_state[256/8]; /* bitfield */
|
||||||
} XkbSrvInfoRec, *XkbSrvInfoPtr;
|
} XkbSrvInfoRec, *XkbSrvInfoPtr;
|
||||||
|
|
||||||
#define XkbSLI_IsDefault (1L<<0)
|
#define XkbSLI_IsDefault (1L<<0)
|
||||||
|
|
|
||||||
|
|
@ -505,6 +505,13 @@ XkbInitControls(DeviceIntPtr pXDev, XkbSrvInfoPtr xkbi)
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Status
|
||||||
|
XkbInitOverlayState(XkbSrvInfoPtr xkbi)
|
||||||
|
{
|
||||||
|
memset(xkbi->overlay_perkey_state, 0, sizeof(xkbi->overlay_perkey_state));
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
InitKeyboardDeviceStructInternal(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
|
InitKeyboardDeviceStructInternal(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
|
||||||
const char *keymap, int keymap_length,
|
const char *keymap, int keymap_length,
|
||||||
|
|
@ -608,6 +615,8 @@ InitKeyboardDeviceStructInternal(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
|
||||||
|
|
||||||
XkbInitIndicatorMap(xkbi);
|
XkbInitIndicatorMap(xkbi);
|
||||||
|
|
||||||
|
XkbInitOverlayState(xkbi);
|
||||||
|
|
||||||
XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &changes,
|
XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &changes,
|
||||||
&check, &cause);
|
&check, &cause);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -121,20 +121,33 @@ XkbProcessKeyboardEvent(DeviceEvent *event, DeviceIntPtr keybd)
|
||||||
case XkbKB_Overlay2:
|
case XkbKB_Overlay2:
|
||||||
{
|
{
|
||||||
unsigned which;
|
unsigned which;
|
||||||
|
unsigned overlay_active_now;
|
||||||
|
unsigned is_keyrelease = (event->type == ET_KeyRelease) ? 1 : 0;
|
||||||
|
/* Remembers whether the key was pressed while overlay was down,
|
||||||
|
* for when overlay is already released, but the key is not. */
|
||||||
|
unsigned key_was_overlaid = 0;
|
||||||
|
|
||||||
if (behavior.type == XkbKB_Overlay1)
|
if (behavior.type == XkbKB_Overlay1)
|
||||||
which = XkbOverlay1Mask;
|
which = XkbOverlay1Mask;
|
||||||
else
|
else
|
||||||
which = XkbOverlay2Mask;
|
which = XkbOverlay2Mask;
|
||||||
if ((xkbi->desc->ctrls->enabled_ctrls & which) == 0)
|
overlay_active_now = (xkbi->desc->ctrls->enabled_ctrls & which) ? 1 : 0;
|
||||||
break;
|
|
||||||
if ((behavior.data >= xkbi->desc->min_key_code) &&
|
if ((unsigned char)key == key) {
|
||||||
(behavior.data <= xkbi->desc->max_key_code)) {
|
key_was_overlaid = BitIsOn(xkbi->overlay_perkey_state, key);
|
||||||
|
if (!is_keyrelease) {
|
||||||
|
if (overlay_active_now)
|
||||||
|
SetBit(xkbi->overlay_perkey_state, key);
|
||||||
|
} else {
|
||||||
|
if (key_was_overlaid)
|
||||||
|
ClearBit(xkbi->overlay_perkey_state, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((overlay_active_now || key_was_overlaid) &&
|
||||||
|
(behavior.data >= xkbi->desc->min_key_code) &&
|
||||||
|
(behavior.data <= xkbi->desc->max_key_code)) {
|
||||||
event->detail.key = behavior.data;
|
event->detail.key = behavior.data;
|
||||||
/* 9/11/94 (ef) -- XXX! need to match release with */
|
|
||||||
/* press even if the state of the */
|
|
||||||
/* corresponding overlay control */
|
|
||||||
/* changes while the key is down */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue