Merge lp:~vanvugt/compiz-core/fix-953089.2 into lp:compiz-core

Proposed by Daniel van Vugt
Status: Merged
Merged at revision: 3066
Proposed branch: lp:~vanvugt/compiz-core/fix-953089.2
Merge into: lp:compiz-core
Diff against target: 121 lines (+35/-19)
3 files modified
src/event.cpp (+31/-18)
src/privatescreen.h (+2/-0)
src/screen.cpp (+2/-1)
To merge this branch: bzr merge lp:~vanvugt/compiz-core/fix-953089.2
Reviewer Review Type Date Requested Status
Sam Spilsbury Approve
Review via email: mp+98833@code.launchpad.net

Description of the change

Don't rely on the value of "grabbed" to tell you if the root window is
presently accepting key events (meaning there are no external active grabs).
There are some edge cases where grabbed is false but root is still accepting
key events, so when that happened compiz would ignore its own key shortcuts
(LP: #953089)

This was a regression caused by the fix for LP: #806255. The fix for that
bug has now been redesigned to avoid causing LP: #953089.

To post a comment you must log in.
Revision history for this message
Sam Spilsbury (smspillaz) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/event.cpp'
2--- src/event.cpp 2012-03-21 03:54:56 +0000
3+++ src/event.cpp 2012-03-22 12:48:23 +0000
4@@ -143,24 +143,7 @@
5
6 if (state == CompAction::StateInitKey && grabsEmpty ())
7 {
8- if (grabbed)
9- {
10- possibleTap = action;
11- }
12- else
13- {
14- /*
15- * If we received this keypress event and weren't grabbed then
16- * the event doesn't belong to us. More likely belongs to
17- * a different client's grab so ignore it. (LP: #806255)
18- * The reason why we might receive such keypress events while
19- * other clients have grabs is because of the XKB extension that
20- * we're using. It sends you events even if they're not yours...
21- * http://www.x.org/releases/current/doc/libX11/specs/XKB/xkblib.html
22- */
23- possibleTap = NULL;
24- return false;
25- }
26+ possibleTap = action;
27 }
28
29 if (!action->initiate ().empty ())
30@@ -680,6 +663,8 @@
31
32 switch (event->type) {
33 case ButtonPress:
34+ lastKeyCode = 0;
35+
36 /* We need to determine if we clicked on a parent frame
37 * window, if so, pass the appropriate child window as
38 * "window" and the frame as "event_window"
39@@ -715,6 +700,8 @@
40 }
41 break;
42 case ButtonRelease:
43+ lastKeyCode = 0;
44+
45 o[0].value ().set ((int) event->xbutton.window);
46 o[1].value ().set ((int) event->xbutton.window);
47 o[2].value ().set ((int) event->xbutton.state);
48@@ -736,6 +723,8 @@
49 }
50 break;
51 case KeyPress:
52+ lastKeyCode = event->xkey.keycode;
53+
54 o[0].value ().set ((int) event->xkey.window);
55 o[1].value ().set ((int) activeWindow);
56 o[2].value ().set ((int) event->xkey.state);
57@@ -758,6 +747,8 @@
58 }
59 break;
60 case KeyRelease:
61+ lastKeyCode = event->xkey.keycode;
62+
63 o[0].value ().set ((int) event->xkey.window);
64 o[1].value ().set ((int) activeWindow);
65 o[2].value ().set ((int) event->xkey.state);
66@@ -959,6 +950,28 @@
67 {
68 XkbStateNotifyEvent *stateEvent = (XkbStateNotifyEvent *) event;
69
70+ /*
71+ * You will reach this point when modifier keys or mouse
72+ * buttons change state (are pressed or released). However the
73+ * XKB extension does not honour active grabs held by other
74+ * clients and will send us these XkbStateNotify events even
75+ * when we shouldn't receive them at all (LP: #806255).
76+ * [http://www.x.org/releases/current/doc/libX11/specs/XKB/xkblib.html]
77+ *
78+ * So we need a sanity check. The sanity check is to only
79+ * accept XkbStateNotify's which were preceded by a matching
80+ * KeyPress or KeyRelease event, or which occurred during a
81+ * compiz active grab. Then we can be sure the keyboard is not
82+ * actively grabbed by another client and that compiz can
83+ * safely respond to this event.
84+ *
85+ * The only cleaner fix for LP: #806255 I can think of would
86+ * be to remove XkbStateNotify support completely from compiz.
87+ * But that would be a huge change, in core and some plugins.
88+ */
89+ if (grabsEmpty() && stateEvent->keycode != lastKeyCode)
90+ break;
91+
92 o[0].value ().set ((int) activeWindow);
93 o[1].value ().set ((int) activeWindow);
94 o[2].value ().set ((int) stateEvent->mods);
95
96=== modified file 'src/privatescreen.h'
97--- src/privatescreen.h 2012-03-12 14:30:28 +0000
98+++ src/privatescreen.h 2012-03-22 12:48:23 +0000
99@@ -989,6 +989,8 @@
100 CompTimer edgeDelayTimer;
101 CompDelayedEdgeSettings edgeDelaySettings;
102 Window xdndWindow;
103+
104+ int lastKeyCode;
105 };
106
107 class CompManager
108
109=== modified file 'src/screen.cpp'
110--- src/screen.cpp 2012-03-15 06:01:46 +0000
111+++ src/screen.cpp 2012-03-22 12:48:23 +0000
112@@ -5124,7 +5124,8 @@
113 initialized (false),
114 edgeWindow (None),
115 edgeDelayTimer (),
116- xdndWindow (None)
117+ xdndWindow (None),
118+ lastKeyCode (0)
119 {
120 pingTimer.setCallback (
121 boost::bind (&PrivateScreen::handlePingTimeout, this));

Subscribers

People subscribed via source and target branches