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

Proposed by Daniel van Vugt
Status: Merged
Merged at revision: 3006
Proposed branch: lp:~vanvugt/compiz-core/fix-925293.2
Merge into: lp:compiz-core
Diff against target: 133 lines (+28/-31)
3 files modified
src/event.cpp (+22/-29)
src/privatescreen.h (+1/-1)
src/screen.cpp (+5/-1)
To merge this branch: bzr merge lp:~vanvugt/compiz-core/fix-925293.2
Reviewer Review Type Date Requested Status
Sam Spilsbury Approve
Review via email: mp+93544@code.launchpad.net

This proposal supersedes a proposal from 2012-02-17.

Description of the change

Improved the fix for LP: #925293 (add tap support):
  * Add correct tap detection for non-modifier-only key combinations.
  * Avoid getting "stuck" with modifiers apparently locked down.
  * Ungrab the keyboard on key releases, not presses.
  * ReplayKeyboard of release events as well as presses (previously only
    presses, which could cause release events to queue up and block the
    server).

My test case which previously caused modifiers to get "stuck" now works. The test case was "Add correct tap detection for non-modifier-only key combinations", which caused the modifiers-stuck problem in previous revisions.

To post a comment you must log in.
Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

> XAllowEvents (priv->dpy, ReplayKeyboard, event->xkey.time);

Do we need to do that if an action event was handled ? I would think that AsyncKeyboard makes more sense here.

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

62 - if (priv->grabs.empty ()

You should also change tapGrab to false whenever a plugin takes a grab too.

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Both good points. Though I haven't tested AsyncKeyboard where you say...

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

actionEventHandled ? AsyncKeyboard : ReplayKeyboard

This is what I did when I fixed it locally.

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Yes, I understand what you meant thanks. Now testing changes...

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Looks great, thanks!

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-02-15 11:21:07 +0000
3+++ src/event.cpp 2012-02-17 09:23:17 +0000
4@@ -136,32 +136,24 @@
5 CompAction::State state,
6 CompOption::Vector &arguments)
7 {
8- possibleTap = action;
9- modTapGrab = false;
10-
11 if (state == CompAction::StateInitKey &&
12 grabs.empty () &&
13- action->key ().modifiers () &&
14- action->key ().keycode () == 0)
15+ !action->terminate ().empty ())
16 {
17- /*
18- * So you're trying to detect taps on a modifier key?
19- * You will need to grab the keyboard SYNCHRONOUSLY.
20- * This is so that later if the user presses another key with
21- * this modifier, we will be able to ReplayKeyboard with
22- * XAllowEvents. Otherwise that modifier+other_key event would
23- * be absorbed and lost.
24- */
25- XGrabKeyboard (dpy, grabWindow, True,
26- GrabModeAsync, GrabModeSync, CurrentTime);
27- XAllowEvents (dpy, SyncKeyboard, CurrentTime);
28- modTapGrab = true;
29+ possibleTap = action;
30+ int err = XGrabKeyboard (dpy, grabWindow, True,
31+ GrabModeAsync, GrabModeSync, CurrentTime);
32+ if (err == GrabSuccess)
33+ {
34+ XAllowEvents (dpy, SyncKeyboard, CurrentTime);
35+ tapGrab = true;
36+ }
37 }
38
39- if (action->initiate ().empty ())
40+ if (action->initiate ().empty () && !action->terminate ().empty ())
41 {
42- /* Default Initiate implementation for plugins that only provide
43- a Terminate callback (as you might want if responding to taps) */
44+ /* Default Initiate implementation for plugins that only
45+ provide a Terminate callback */
46 if (state & CompAction::StateInitKey)
47 action->setState (action->state () | CompAction::StateTermKey);
48 }
49@@ -180,8 +172,6 @@
50 {
51 state |= CompAction::StateTermTapped;
52 possibleTap = NULL;
53- if (modTapGrab)
54- XUngrabKeyboard (dpy, CurrentTime);
55 }
56
57 if (!action->terminate ().empty () &&
58@@ -1086,14 +1076,17 @@
59 actionEventHandled = true;
60 }
61
62- if (priv->grabs.empty () && event->type == KeyPress)
63- {
64- if (priv->modTapGrab)
65- {
66- XAllowEvents (priv->dpy, ReplayKeyboard, event->xkey.time);
67- priv->modTapGrab = false;
68- }
69+ if (priv->tapGrab &&
70+ (event->type == KeyPress || event->type == KeyRelease))
71+ {
72+ int mode = actionEventHandled ? AsyncKeyboard : ReplayKeyboard;
73+ XAllowEvents (priv->dpy, mode, event->xkey.time);
74+ }
75+
76+ if (priv->grabs.empty () && event->type == KeyRelease)
77+ {
78 XUngrabKeyboard (priv->dpy, event->xkey.time);
79+ priv->tapGrab = false;
80 }
81
82 if (actionEventHandled)
83
84=== modified file 'src/privatescreen.h'
85--- src/privatescreen.h 2012-02-16 01:11:23 +0000
86+++ src/privatescreen.h 2012-02-17 09:23:17 +0000
87@@ -541,7 +541,7 @@
88 Window xdndWindow;
89
90 void *possibleTap;
91- bool modTapGrab;
92+ bool tapGrab;
93
94 bool initialized;
95 };
96
97=== modified file 'src/screen.cpp'
98--- src/screen.cpp 2012-02-16 01:11:23 +0000
99+++ src/screen.cpp 2012-02-17 09:23:17 +0000
100@@ -2942,6 +2942,8 @@
101 XUngrabPointer (priv->dpy, CurrentTime);
102 return NULL;
103 }
104+ else
105+ priv->tapGrab = false;
106 }
107 else
108 return NULL;
109@@ -3004,6 +3006,7 @@
110
111 XUngrabPointer (priv->dpy, CurrentTime);
112 XUngrabKeyboard (priv->dpy, CurrentTime);
113+ priv->tapGrab = false;
114 }
115 }
116
117@@ -3580,6 +3583,7 @@
118
119 XUngrabPointer (priv->dpy, CurrentTime);
120 XUngrabKeyboard (priv->dpy, CurrentTime);
121+ priv->tapGrab = false;
122
123 XSendEvent (priv->dpy, priv->root, false,
124 StructureNotifyMask, &ev);
125@@ -4985,7 +4989,7 @@
126 edgeWindow (None),
127 xdndWindow (None),
128 possibleTap (NULL),
129- modTapGrab (false),
130+ tapGrab (false),
131 initialized (false)
132 {
133 TimeoutHandler *dTimeoutHandler = new TimeoutHandler ();

Subscribers

People subscribed via source and target branches