1
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
2
index c473df1..0ac2c71 100644
5
@@ -341,22 +341,83 @@ _XkbFilterLatchState(XkbSrvInfoPtr xkbi,
9
-_XkbFilterLockState(XkbSrvInfoPtr xkbi,
10
+xkbSwitchGroupOnRelease(void)
12
+ /* TODO: user configuring */
17
+xkbUpdateLockedGroup(XkbSrvInfoPtr xkbi, XkbAction *pAction)
19
+ XkbGroupAction ga = pAction->group;
21
+ if (ga.flags & XkbSA_GroupAbsolute)
22
+ xkbi->state.locked_group = XkbSAGroup(&ga);
24
+ xkbi->state.locked_group += XkbSAGroup(&ga);
27
+static XkbFilterPtr _XkbNextFreeFilter(XkbSrvInfoPtr xkbi);
30
+_XkbFilterLockGroup(XkbSrvInfoPtr xkbi,
31
XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
33
- if (pAction && (pAction->type == XkbSA_LockGroup)) {
34
- if (pAction->group.flags & XkbSA_GroupAbsolute)
35
- xkbi->state.locked_group = XkbSAGroup(&pAction->group);
37
- xkbi->state.locked_group += XkbSAGroup(&pAction->group);
41
+ if (!xkbSwitchGroupOnRelease()) {
42
+ xkbUpdateLockedGroup(xkbi, pAction);
46
+ /* Delay switch till button release */
47
+ if (filter->keycode == 0) { /* initial press */
48
+ filter->keycode = keycode;
50
+ filter->filterOthers = 0; /* for what? */
51
+ filter->filter = _XkbFilterLockGroup;
53
+ /* filter->priv = 0; */
54
+ filter->upAction = *pAction;
56
+ /* Ok, now we need to simulate the action which would go if this action didn't block it.
57
+ XkbSA_SetMods is the one: it is to set modifier' flag up. */
59
+ XkbStateRec fake_state = xkbi->state;
62
+ fake_state.mods = 0;
63
+ act = XkbGetKeyAction(xkbi, &fake_state, keycode);
65
+ /* KLUDGE: XkbSA_SetMods only? */
66
+ if (act.type == XkbSA_SetMods) {
67
+ XkbFilterPtr filter = _XkbNextFreeFilter(xkbi);
69
+ sendEvent = _XkbFilterSetState(xkbi, filter, keycode, &act);
74
+ /* do nothing if some button else is pressed */
76
+ xkbUpdateLockedGroup(xkbi, &filter->upAction);
84
+_XkbFilterLockMods(XkbSrvInfoPtr xkbi,
85
+ XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
87
if (filter->keycode == 0) { /* initial press */
88
filter->keycode = keycode;
90
filter->filterOthers = 0;
91
filter->priv = xkbi->state.locked_mods & pAction->mods.mask;
92
- filter->filter = _XkbFilterLockState;
93
+ filter->filter = _XkbFilterLockMods;
94
filter->upAction = *pAction;
95
if (!(filter->upAction.mods.flags & XkbSA_LockNoLock))
96
xkbi->state.locked_mods |= pAction->mods.mask;
97
@@ -1129,9 +1190,12 @@ XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
98
sendEvent = _XkbFilterLatchState(xkbi, filter, key, &act);
101
+ filter = _XkbNextFreeFilter(xkbi);
102
+ sendEvent = _XkbFilterLockMods(xkbi, filter, key, &act);
104
case XkbSA_LockGroup:
105
filter = _XkbNextFreeFilter(xkbi);
106
- sendEvent = _XkbFilterLockState(xkbi, filter, key, &act);
107
+ sendEvent = _XkbFilterLockGroup(xkbi, filter, key, &act);
110
filter = _XkbNextFreeFilter(xkbi);