3 @@ -351,22 +351,83 @@ _XkbFilterLatchState(XkbSrvInfoPtr xkbi,
7 -_XkbFilterLockState(XkbSrvInfoPtr xkbi,
8 +xkbSwitchGroupOnRelease(void)
10 + /* TODO: user configuring */
15 +xkbUpdateLockedGroup(XkbSrvInfoPtr xkbi, XkbAction *pAction)
17 + XkbGroupAction ga = pAction->group;
19 + if (ga.flags & XkbSA_GroupAbsolute)
20 + xkbi->state.locked_group = XkbSAGroup(&ga);
22 + xkbi->state.locked_group += XkbSAGroup(&ga);
25 +static XkbFilterPtr _XkbNextFreeFilter(XkbSrvInfoPtr xkbi);
28 +_XkbFilterLockGroup(XkbSrvInfoPtr xkbi,
29 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
31 - if (pAction && (pAction->type == XkbSA_LockGroup)) {
32 - if (pAction->group.flags & XkbSA_GroupAbsolute)
33 - xkbi->state.locked_group = XkbSAGroup(&pAction->group);
35 - xkbi->state.locked_group += XkbSAGroup(&pAction->group);
39 + if (!xkbSwitchGroupOnRelease()) {
40 + xkbUpdateLockedGroup(xkbi, pAction);
44 + /* Delay switch till button release */
45 + if (filter->keycode == 0) { /* initial press */
46 + filter->keycode = keycode;
48 + filter->filterOthers = 0; /* for what? */
49 + filter->filter = _XkbFilterLockGroup;
51 + /* filter->priv = 0; */
52 + filter->upAction = *pAction;
54 + /* Ok, now we need to simulate the action which would go if this action didn't block it.
55 + XkbSA_SetMods is the one: it is to set modifier' flag up. */
57 + XkbStateRec fake_state = xkbi->state;
60 + fake_state.mods = 0;
61 + act = XkbGetKeyAction(xkbi, &fake_state, keycode);
63 + /* KLUDGE: XkbSA_SetMods only? */
64 + if (act.type == XkbSA_SetMods) {
65 + XkbFilterPtr filter = _XkbNextFreeFilter(xkbi);
67 + sendEvent = _XkbFilterSetState(xkbi, filter, keycode, &act);
72 + /* do nothing if some button else is pressed */
74 + xkbUpdateLockedGroup(xkbi, &filter->upAction);
82 +_XkbFilterLockMods(XkbSrvInfoPtr xkbi,
83 + XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
85 if (filter->keycode == 0) { /* initial press */
86 filter->keycode = keycode;
88 filter->filterOthers = 0;
89 filter->priv = xkbi->state.locked_mods & pAction->mods.mask;
90 - filter->filter = _XkbFilterLockState;
91 + filter->filter = _XkbFilterLockMods;
92 filter->upAction = *pAction;
93 if (!(filter->upAction.mods.flags & XkbSA_LockNoLock))
94 xkbi->state.locked_mods |= pAction->mods.mask;
95 @@ -1185,9 +1246,12 @@ XkbHandleActions(DeviceIntPtr dev, Devic
96 sendEvent = _XkbFilterLatchState(xkbi, filter, key, &act);
99 + filter = _XkbNextFreeFilter(xkbi);
100 + sendEvent = _XkbFilterLockMods(xkbi, filter, key, &act);
102 case XkbSA_LockGroup:
103 filter = _XkbNextFreeFilter(xkbi);
104 - sendEvent = _XkbFilterLockState(xkbi, filter, key, &act);
105 + sendEvent = _XkbFilterLockGroup(xkbi, filter, key, &act);
108 filter = _XkbNextFreeFilter(xkbi);