Merge lp:~vanvugt/compiz-core/fix-alt-bugs into lp:compiz-core

Proposed by Daniel van Vugt
Status: Merged
Approved by: Alan Griffiths
Approved revision: 3046
Merged at revision: 3046
Proposed branch: lp:~vanvugt/compiz-core/fix-alt-bugs
Merge into: lp:compiz-core
Diff against target: 160 lines (+36/-15)
4 files modified
metadata/core.xml.in (+7/-0)
src/event.cpp (+25/-6)
src/privatescreen.h (+1/-2)
src/screen.cpp (+3/-7)
To merge this branch: bzr merge lp:~vanvugt/compiz-core/fix-alt-bugs
Reviewer Review Type Date Requested Status
Alan Griffiths Approve
Review via email: mp+96314@code.launchpad.net

Description of the change

Don't keep an active keyboard grab the whole time a shortcut key is held
down. Doing so was causing multiple bugs with Unity 5, which binds to
the Alt key. Instead use some simple heurisitics to decide if a key has
been "tapped" or not. (LP: #943194) (LP: #943851) (LP: #945373)

Yes, it is a compromise to go back to detecting taps based on timing.
However it is the only existing solution to all of these bugs related to
the Alt key.

To post a comment you must log in.
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Looks sane, seems to work (not entirely sure about reproducing 943194, but it doesn't seems worse.)

review: Approve
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'metadata/core.xml.in'
2--- metadata/core.xml.in 2010-06-12 07:43:36 +0000
3+++ metadata/core.xml.in 2012-03-07 10:06:17 +0000
4@@ -31,6 +31,13 @@
5 <min>0</min>
6 <max>10000</max>
7 </option>
8+ <option name="tap_time" type="int">
9+ <_short>Key Tap Time</_short>
10+ <_long>Maximim amount of time (milliseconds) a key may be held down and still be reported as a "tap".</_long>
11+ <default>150</default>
12+ <min>0</min>
13+ <max>10000</max>
14+ </option>
15 <option name="ping_delay" type="int">
16 <_short>Ping Delay</_short>
17 <_long>Interval between ping messages</_long>
18
19=== modified file 'src/event.cpp'
20--- src/event.cpp 2012-03-06 11:05:05 +0000
21+++ src/event.cpp 2012-03-07 10:06:17 +0000
22@@ -143,13 +143,20 @@
23
24 if (state == CompAction::StateInitKey && grabs.empty ())
25 {
26- possibleTap = action;
27+ int pressTime = arguments[7].value ().i ();
28 int err = XGrabKeyboard (dpy, grabWindow, True,
29- GrabModeAsync, GrabModeSync, arguments[7].value ().i ());
30+ GrabModeAsync, GrabModeAsync, pressTime);
31+ /*
32+ * We don't actually need this active grab for anything other than
33+ * to test if it fails (AlreadyGrabbed). So we know if some other
34+ * app has an active grab like a virtual machine or lock screen.
35+ * (LP: #806255)
36+ */
37 if (err == GrabSuccess)
38 {
39- XAllowEvents (dpy, SyncKeyboard, CurrentTime);
40- tapGrab = true;
41+ XUngrabKeyboard (dpy, pressTime);
42+ possibleTap = action;
43+ tapStart = pressTime;
44 }
45 else
46 {
47@@ -183,7 +190,10 @@
48 {
49 if (action == possibleTap)
50 {
51- state |= CompAction::StateTermTapped;
52+ int releaseTime = arguments[7].value ().i ();
53+ int tapDuration = releaseTime - tapStart;
54+ if (tapDuration < optionGetTapTime ())
55+ state |= CompAction::StateTermTapped;
56 possibleTap = NULL;
57 }
58
59@@ -964,6 +974,8 @@
60 o[3].value ().set ((int) xkbEvent->time);
61 o[4].reset ();
62 o[5].reset ();
63+ o[6].reset ();
64+ o[7].value ().set ((int) xkbEvent->time);
65
66 if (stateEvent->event_type == KeyPress)
67 possibleTap = NULL;
68@@ -1076,7 +1088,6 @@
69 if (priv->grabs.empty () && event->type == KeyPress)
70 {
71 XUngrabKeyboard (priv->dpy, event->xkey.time);
72- priv->tapGrab = false;
73 }
74 }
75
76@@ -1905,6 +1916,14 @@
77 break;
78 case FocusIn:
79 {
80+ /* When a menu etc gets a grab, it's safe to say we're not tapping
81+ any key right now. e.g. Detecting taps of "Alt" and cancelling
82+ when a menu is opened */
83+ if (event->xfocus.mode == NotifyGrab &&
84+ event->xfocus.window != priv->root &&
85+ event->xfocus.window != priv->grabWindow)
86+ priv->possibleTap = NULL;
87+
88 if (!XGetWindowAttributes (priv->dpy, event->xfocus.window, &wa))
89 priv->setDefaultWindowAttributes (&wa);
90
91
92=== modified file 'src/privatescreen.h'
93--- src/privatescreen.h 2012-03-05 09:04:16 +0000
94+++ src/privatescreen.h 2012-03-07 10:06:17 +0000
95@@ -559,6 +559,7 @@
96 CompOption::Value plugin;
97 bool dirtyPluginList;
98 void *possibleTap;
99+ Time tapStart;
100 };
101
102 class EventManager :
103@@ -607,8 +608,6 @@
104
105 CompIcon *defaultIcon;
106
107- bool tapGrab;
108-
109 private:
110 virtual bool initDisplay (const char *name);
111 };
112
113=== modified file 'src/screen.cpp'
114--- src/screen.cpp 2012-03-05 09:04:16 +0000
115+++ src/screen.cpp 2012-03-07 10:06:17 +0000
116@@ -2950,8 +2950,6 @@
117 XUngrabPointer (priv->dpy, CurrentTime);
118 return NULL;
119 }
120- else
121- priv->tapGrab = false;
122 }
123 else
124 return NULL;
125@@ -3014,7 +3012,6 @@
126
127 XUngrabPointer (priv->dpy, CurrentTime);
128 XUngrabKeyboard (priv->dpy, CurrentTime);
129- priv->tapGrab = false;
130 }
131 }
132
133@@ -3591,7 +3588,6 @@
134
135 XUngrabPointer (priv->dpy, CurrentTime);
136 XUngrabKeyboard (priv->dpy, CurrentTime);
137- priv->tapGrab = false;
138
139 XSendEvent (priv->dpy, priv->root, false,
140 StructureNotifyMask, &ev);
141@@ -5033,7 +5029,8 @@
142 CoreOptions (false),
143 plugin (),
144 dirtyPluginList (true),
145- possibleTap (NULL)
146+ possibleTap (NULL),
147+ tapStart (0)
148 {
149 }
150
151@@ -5049,8 +5046,7 @@
152 edgeDelayTimer (),
153 desktopWindowCount (0),
154 mapNum (1),
155- defaultIcon (0),
156- tapGrab (false)
157+ defaultIcon (0)
158 {
159 ValueHolder::SetDefault (static_cast<ValueHolder *> (this));
160 TimeoutHandler *dTimeoutHandler = new TimeoutHandler ();

Subscribers

People subscribed via source and target branches