Commit | Line | Data |
---|---|---|
7217e0ca ML |
1 | diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c |
2 | index c473df1..0ac2c71 100644 | |
3 | --- a/xkb/xkbActions.c | |
4 | +++ b/xkb/xkbActions.c | |
5 | @@ -341,22 +341,83 @@ _XkbFilterLatchState(XkbSrvInfoPtr xkbi, | |
6 | } | |
7 | ||
8 | static int | |
9 | -_XkbFilterLockState(XkbSrvInfoPtr xkbi, | |
10 | +xkbSwitchGroupOnRelease(void) | |
11 | +{ | |
12 | + /* TODO: user configuring */ | |
13 | + return TRUE; | |
14 | +} | |
15 | + | |
16 | +static void | |
17 | +xkbUpdateLockedGroup(XkbSrvInfoPtr xkbi, XkbAction *pAction) | |
18 | +{ | |
19 | + XkbGroupAction ga = pAction->group; | |
20 | + | |
21 | + if (ga.flags & XkbSA_GroupAbsolute) | |
22 | + xkbi->state.locked_group = XkbSAGroup(&ga); | |
23 | + else | |
24 | + xkbi->state.locked_group += XkbSAGroup(&ga); | |
25 | +} | |
26 | + | |
27 | +static XkbFilterPtr _XkbNextFreeFilter(XkbSrvInfoPtr xkbi); | |
28 | + | |
29 | +static int | |
30 | +_XkbFilterLockGroup(XkbSrvInfoPtr xkbi, | |
31 | XkbFilterPtr filter, unsigned keycode, XkbAction *pAction) | |
32 | { | |
33 | - if (pAction && (pAction->type == XkbSA_LockGroup)) { | |
34 | - if (pAction->group.flags & XkbSA_GroupAbsolute) | |
35 | - xkbi->state.locked_group = XkbSAGroup(&pAction->group); | |
36 | - else | |
37 | - xkbi->state.locked_group += XkbSAGroup(&pAction->group); | |
38 | - return 1; | |
39 | + int sendEvent = 1; | |
40 | + | |
41 | + if (!xkbSwitchGroupOnRelease()) { | |
42 | + xkbUpdateLockedGroup(xkbi, pAction); | |
43 | + return sendEvent; | |
44 | } | |
45 | + | |
46 | + /* Delay switch till button release */ | |
47 | + if (filter->keycode == 0) { /* initial press */ | |
48 | + filter->keycode = keycode; | |
49 | + filter->active = 1; | |
50 | + filter->filterOthers = 0; /* for what? */ | |
51 | + filter->filter = _XkbFilterLockGroup; | |
52 | + | |
53 | + /* filter->priv = 0; */ | |
54 | + filter->upAction = *pAction; | |
55 | + | |
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. */ | |
58 | + { | |
59 | + XkbStateRec fake_state = xkbi->state; | |
60 | + XkbAction act; | |
61 | + | |
62 | + fake_state.mods = 0; | |
63 | + act = XkbGetKeyAction(xkbi, &fake_state, keycode); | |
64 | + | |
65 | + /* KLUDGE: XkbSA_SetMods only? */ | |
66 | + if (act.type == XkbSA_SetMods) { | |
67 | + XkbFilterPtr filter = _XkbNextFreeFilter(xkbi); | |
68 | + | |
69 | + sendEvent = _XkbFilterSetState(xkbi, filter, keycode, &act); | |
70 | + } | |
71 | + } | |
72 | + } | |
73 | + else { | |
74 | + /* do nothing if some button else is pressed */ | |
75 | + if (!pAction) | |
76 | + xkbUpdateLockedGroup(xkbi, &filter->upAction); | |
77 | + filter->active = 0; | |
78 | + } | |
79 | + | |
80 | + return sendEvent; | |
81 | +} | |
82 | + | |
83 | +static int | |
84 | +_XkbFilterLockMods(XkbSrvInfoPtr xkbi, | |
85 | + XkbFilterPtr filter, unsigned keycode, XkbAction *pAction) | |
86 | +{ | |
87 | if (filter->keycode == 0) { /* initial press */ | |
88 | filter->keycode = keycode; | |
89 | filter->active = 1; | |
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); | |
99 | break; | |
100 | case XkbSA_LockMods: | |
101 | + filter = _XkbNextFreeFilter(xkbi); | |
102 | + sendEvent = _XkbFilterLockMods(xkbi, filter, key, &act); | |
103 | + break; | |
104 | case XkbSA_LockGroup: | |
105 | filter = _XkbNextFreeFilter(xkbi); | |
106 | - sendEvent = _XkbFilterLockState(xkbi, filter, key, &act); | |
107 | + sendEvent = _XkbFilterLockGroup(xkbi, filter, key, &act); | |
108 | break; | |
109 | case XkbSA_ISOLock: | |
110 | filter = _XkbNextFreeFilter(xkbi); |