summarylogtreecommitdiffstats
path: root/freedesktop-bug-865.patch
blob: cd4d644ad668cf7c44e824c96d840326b324e8c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
--- xorg-server-1.14.0/xkb/xkbActions.c.orig	2013-02-08 20:50:40.000000000 +0400
+++ xorg-server-1.14.0/xkb/xkbActions.c	2013-03-18 22:00:20.113844672 +0400
@@ -339,23 +339,82 @@
     return 1;
 }
 
+static int xkbSwitchGroupOnRelease(void)
+{
+    /* TODO: user configuring */
+    return TRUE;
+}
+
+static void xkbUpdateLockedGroup(XkbSrvInfoPtr xkbi, XkbAction* pAction)
+{
+    XkbGroupAction ga = pAction->group;
+    if (ga.flags&XkbSA_GroupAbsolute)
+	xkbi->state.locked_group= XkbSAGroup(&ga);
+    else xkbi->state.locked_group+= XkbSAGroup(&ga);
+}
+
+static XkbFilterPtr _XkbNextFreeFilter(XkbSrvInfoPtr xkbi);
+
 static int
-_XkbFilterLockState(XkbSrvInfoPtr xkbi,
+_XkbFilterLockGroup(	XkbSrvInfoPtr	xkbi,
                     XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
 {
-    if (pAction && (pAction->type == XkbSA_LockGroup)) {
-        if (pAction->group.flags & XkbSA_GroupAbsolute)
-            xkbi->state.locked_group = XkbSAGroup(&pAction->group);
-        else
-            xkbi->state.locked_group += XkbSAGroup(&pAction->group);
-        return 1;
+
+    int sendEvent = 1;
+
+    if (!xkbSwitchGroupOnRelease()) {
+	xkbUpdateLockedGroup(xkbi, pAction);
+	return sendEvent;
+    }
+    
+    /* Delay switch till button release */
+    if (filter->keycode==0) {		/* initial press */
+	filter->keycode = keycode;
+	filter->active = 1;
+	filter->filterOthers = 0; /* for what? */
+	filter->filter = _XkbFilterLockGroup;
+
+	/* filter->priv = 0; */
+	filter->upAction = *pAction;
+
+	/* Ok, now we need to simulate the action which would go if this action didn't block it.
+	   XkbSA_SetMods is the one: it is to set modifier' flag up. */
+	{
+	    XkbStateRec	fake_state = xkbi->state;
+	    XkbAction act;
+
+	    fake_state.mods = 0;
+	    act = XkbGetKeyAction(xkbi, &fake_state, keycode);
+
+	    /* KLUDGE: XkbSA_SetMods only? */
+	    if (act.type == XkbSA_SetMods) { 
+		XkbFilterPtr filter = _XkbNextFreeFilter(xkbi);
+		sendEvent = _XkbFilterSetState(xkbi,filter,keycode,&act);
+	    }
+	}
+     }
+    else {
+  	/* do nothing if some button else is pressed */
+	if (!pAction)
+	    xkbUpdateLockedGroup(xkbi, &filter->upAction);
+	filter->active = 0;
     }
+
+    return sendEvent;
+}
+
+static int
+_XkbFilterLockMods(	XkbSrvInfoPtr	xkbi,
+			XkbFilterPtr	filter,
+			unsigned	keycode,
+			XkbAction *	pAction)
+{
     if (filter->keycode == 0) { /* initial press */
         filter->keycode = keycode;
         filter->active = 1;
         filter->filterOthers = 0;
         filter->priv = xkbi->state.locked_mods & pAction->mods.mask;
-        filter->filter = _XkbFilterLockState;
+        filter->filter = _XkbFilterLockMods;
         filter->upAction = *pAction;
         if (!(filter->upAction.mods.flags & XkbSA_LockNoLock))
             xkbi->state.locked_mods |= pAction->mods.mask;
@@ -1174,9 +1233,12 @@
                 sendEvent = _XkbFilterLatchState(xkbi, filter, key, &act);
                 break;
             case XkbSA_LockMods:
+				filter = _XkbNextFreeFilter(xkbi);
+				sendEvent=_XkbFilterLockMods(xkbi,filter,key,&act);
+				break;
             case XkbSA_LockGroup:
                 filter = _XkbNextFreeFilter(xkbi);
-                sendEvent = _XkbFilterLockState(xkbi, filter, key, &act);
+                sendEvent=_XkbFilterLockGroup(xkbi,filter,key,&act);
                 break;
             case XkbSA_ISOLock:
                 filter = _XkbNextFreeFilter(xkbi);