Merge lp:~aacid/unity-2d/kill_keyboardmodifiersmonitor into lp:unity-2d
- kill_keyboardmodifiersmonitor
- Merge into trunk
Proposed by
Albert Astals Cid
Status: | Merged |
---|---|
Approved by: | Gerry Boland |
Approved revision: | 1075 |
Merged at revision: | 1072 |
Proposed branch: | lp:~aacid/unity-2d/kill_keyboardmodifiersmonitor |
Merge into: | lp:unity-2d |
Diff against target: |
600 lines (+136/-252) 9 files modified
libunity-2d-private/src/CMakeLists.txt (+0/-1) libunity-2d-private/src/keyboardmodifiersmonitor.cpp (+0/-162) libunity-2d-private/src/keyboardmodifiersmonitor.h (+0/-69) libunity-2d-private/src/keymonitor.cpp (+83/-3) libunity-2d-private/src/keymonitor.h (+13/-3) libunity-2d-private/tests/CMakeLists.txt (+3/-1) libunity-2d-private/tests/keymonitortest.cpp (+31/-6) panel/applets/appname/appnameapplet.cpp (+3/-3) shell/app/shellmanager.cpp (+3/-4) |
To merge this branch: | bzr merge lp:~aacid/unity-2d/kill_keyboardmodifiersmonitor |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Gerry Boland (community) | Approve | ||
Review via email: mp+102646@code.launchpad.net |
This proposal supersedes a proposal from 2012-04-18.
Commit message
[lib] Kill keyboardmodifie
This helps to prevent wrong HUD triggers on ultrafast alt+key presses
Description of the change
Kill keyboardmodifie
Integrate its functionality in keymonitor, helps preventing wrong HUD triggers on ultrafast alt+key presses
UNBLOCK
To post a comment you must log in.
Revision history for this message
Albert Astals Cid (aacid) wrote : Posted in a previous version of this proposal | # |
Revision history for this message
Albert Astals Cid (aacid) wrote : | # |
Branch dependency on lp:~aacid/unity-2d/fast_alt_left_press_fail_test removed as per Gerry's request
Revision history for this message
Gerry Boland (gerboland) wrote : | # |
Works well, I notice a improvement in the tap detection so I get even fewer false HUD appearances. Approved!
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'libunity-2d-private/src/CMakeLists.txt' | |||
2 | --- libunity-2d-private/src/CMakeLists.txt 2012-04-02 14:03:32 +0000 | |||
3 | +++ libunity-2d-private/src/CMakeLists.txt 2012-04-19 08:51:21 +0000 | |||
4 | @@ -9,7 +9,6 @@ | |||
5 | 9 | gconnector.cpp | 9 | gconnector.cpp |
6 | 10 | gimageutils.cpp | 10 | gimageutils.cpp |
7 | 11 | gnomesessionclient.cpp | 11 | gnomesessionclient.cpp |
8 | 12 | keyboardmodifiersmonitor.cpp | ||
9 | 13 | hotmodifier.cpp | 12 | hotmodifier.cpp |
10 | 14 | hotkeymonitor.cpp | 13 | hotkeymonitor.cpp |
11 | 15 | hotkey.cpp | 14 | hotkey.cpp |
12 | 16 | 15 | ||
13 | === removed file 'libunity-2d-private/src/keyboardmodifiersmonitor.cpp' | |||
14 | --- libunity-2d-private/src/keyboardmodifiersmonitor.cpp 2012-02-15 14:45:17 +0000 | |||
15 | +++ libunity-2d-private/src/keyboardmodifiersmonitor.cpp 1970-01-01 00:00:00 +0000 | |||
16 | @@ -1,162 +0,0 @@ | |||
17 | 1 | /* | ||
18 | 2 | * This file is part of unity-2d | ||
19 | 3 | * | ||
20 | 4 | * Copyright 2011 Canonical Ltd. | ||
21 | 5 | * | ||
22 | 6 | * Authors: | ||
23 | 7 | * - Aurélien Gâteau <aurelien.gateau@canonical.com> | ||
24 | 8 | * | ||
25 | 9 | * This program is free software; you can redistribute it and/or modify | ||
26 | 10 | * it under the terms of the GNU General Public License as published by | ||
27 | 11 | * the Free Software Foundation; version 3. | ||
28 | 12 | * | ||
29 | 13 | * This program is distributed in the hope that it will be useful, | ||
30 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
31 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
32 | 16 | * GNU General Public License for more details. | ||
33 | 17 | * | ||
34 | 18 | * You should have received a copy of the GNU General Public License | ||
35 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
36 | 20 | */ | ||
37 | 21 | |||
38 | 22 | // Self | ||
39 | 23 | #include "keyboardmodifiersmonitor.h" | ||
40 | 24 | |||
41 | 25 | // Local | ||
42 | 26 | #include <hotmodifier.h> | ||
43 | 27 | #include <debug_p.h> | ||
44 | 28 | |||
45 | 29 | // Qt | ||
46 | 30 | #include <QX11Info> | ||
47 | 31 | |||
48 | 32 | // X11 | ||
49 | 33 | #include <X11/Xlib.h> | ||
50 | 34 | #include <X11/XKBlib.h> | ||
51 | 35 | #include <X11/extensions/XKB.h> | ||
52 | 36 | |||
53 | 37 | static int sXkbBaseEventType = 0; | ||
54 | 38 | |||
55 | 39 | static void setupXkb() | ||
56 | 40 | { | ||
57 | 41 | int opcode, error; | ||
58 | 42 | XkbQueryExtension(QX11Info::display(), &opcode, &sXkbBaseEventType, &error, NULL, NULL); | ||
59 | 43 | XkbSelectEvents(QX11Info::display(), XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask); | ||
60 | 44 | } | ||
61 | 45 | |||
62 | 46 | struct KeyboardModifiersMonitorPrivate | ||
63 | 47 | { | ||
64 | 48 | KeyboardModifiersMonitorPrivate() | ||
65 | 49 | : m_modifiers(0) | ||
66 | 50 | {} | ||
67 | 51 | |||
68 | 52 | int m_modifiers; | ||
69 | 53 | }; | ||
70 | 54 | |||
71 | 55 | KeyboardModifiersMonitor::KeyboardModifiersMonitor(QObject *parent) | ||
72 | 56 | : QObject(parent) | ||
73 | 57 | , d(new KeyboardModifiersMonitorPrivate) | ||
74 | 58 | { | ||
75 | 59 | if (sXkbBaseEventType == 0) { | ||
76 | 60 | setupXkb(); | ||
77 | 61 | } | ||
78 | 62 | |||
79 | 63 | Unity2dApplication* application = Unity2dApplication::instance(); | ||
80 | 64 | if (application == NULL) { | ||
81 | 65 | /* This can happen for example when using qmlviewer to run the launcher */ | ||
82 | 66 | UQ_WARNING << "The application is not an Unity2dApplication." | ||
83 | 67 | "Modifiers will not be monitored."; | ||
84 | 68 | } else { | ||
85 | 69 | application->installX11EventFilter(this); | ||
86 | 70 | } | ||
87 | 71 | } | ||
88 | 72 | |||
89 | 73 | KeyboardModifiersMonitor::~KeyboardModifiersMonitor() | ||
90 | 74 | { | ||
91 | 75 | delete d; | ||
92 | 76 | } | ||
93 | 77 | |||
94 | 78 | KeyboardModifiersMonitor* KeyboardModifiersMonitor::instance() | ||
95 | 79 | { | ||
96 | 80 | static KeyboardModifiersMonitor* monitor = new KeyboardModifiersMonitor(); | ||
97 | 81 | return monitor; | ||
98 | 82 | } | ||
99 | 83 | |||
100 | 84 | bool KeyboardModifiersMonitor::x11EventFilter(XEvent* event) | ||
101 | 85 | { | ||
102 | 86 | if (event->type == sXkbBaseEventType + XkbEventCode) { | ||
103 | 87 | XkbEvent *xkbEvent = (XkbEvent*)event; | ||
104 | 88 | if (xkbEvent->any.xkb_type == XkbStateNotify) { | ||
105 | 89 | d->m_modifiers = xkbEvent->state.mods; | ||
106 | 90 | Qt::KeyboardModifiers modifiers = keyboardModifiers(); | ||
107 | 91 | keyboardModifiersChanged(modifiers); | ||
108 | 92 | |||
109 | 93 | Q_FOREACH(HotModifier* hotModifier, m_hotModifiers) { | ||
110 | 94 | if (hotModifier->modifiers() & m_disabledModifiers) { | ||
111 | 95 | /* If any of the modifiers have been disabled, the | ||
112 | 96 | * hotModifier cannot be triggered */ | ||
113 | 97 | continue; | ||
114 | 98 | } | ||
115 | 99 | hotModifier->onModifiersChanged(modifiers); | ||
116 | 100 | } | ||
117 | 101 | } | ||
118 | 102 | } | ||
119 | 103 | return false; | ||
120 | 104 | } | ||
121 | 105 | |||
122 | 106 | Qt::KeyboardModifiers KeyboardModifiersMonitor::keyboardModifiers() const | ||
123 | 107 | { | ||
124 | 108 | Qt::KeyboardModifiers value = 0; | ||
125 | 109 | if (d->m_modifiers & ShiftMask) { | ||
126 | 110 | value |= Qt::ShiftModifier; | ||
127 | 111 | } | ||
128 | 112 | if (d->m_modifiers & ControlMask) { | ||
129 | 113 | value |= Qt::ControlModifier; | ||
130 | 114 | } | ||
131 | 115 | if (d->m_modifiers & Mod1Mask) { | ||
132 | 116 | value |= Qt::AltModifier; | ||
133 | 117 | } | ||
134 | 118 | if (d->m_modifiers & Mod4Mask) { | ||
135 | 119 | value |= Qt::MetaModifier; | ||
136 | 120 | } | ||
137 | 121 | return value; | ||
138 | 122 | } | ||
139 | 123 | |||
140 | 124 | HotModifier* | ||
141 | 125 | KeyboardModifiersMonitor::getHotModifierFor(Qt::KeyboardModifiers modifiers) | ||
142 | 126 | { | ||
143 | 127 | Q_FOREACH(HotModifier* hotModifier, m_hotModifiers) { | ||
144 | 128 | if (hotModifier->modifiers() == modifiers) { | ||
145 | 129 | return hotModifier; | ||
146 | 130 | } | ||
147 | 131 | } | ||
148 | 132 | |||
149 | 133 | HotModifier *hotModifier = new HotModifier(modifiers, this); | ||
150 | 134 | m_hotModifiers.append(hotModifier); | ||
151 | 135 | return hotModifier; | ||
152 | 136 | } | ||
153 | 137 | |||
154 | 138 | void | ||
155 | 139 | KeyboardModifiersMonitor::disableModifiers(Qt::KeyboardModifiers modifiers) | ||
156 | 140 | { | ||
157 | 141 | m_disabledModifiers |= modifiers; | ||
158 | 142 | Q_FOREACH(HotModifier* hotModifier, m_hotModifiers) { | ||
159 | 143 | if (hotModifier->modifiers() & m_disabledModifiers) { | ||
160 | 144 | hotModifier->disable(); | ||
161 | 145 | } | ||
162 | 146 | } | ||
163 | 147 | } | ||
164 | 148 | |||
165 | 149 | void | ||
166 | 150 | KeyboardModifiersMonitor::enableModifiers(Qt::KeyboardModifiers modifiers) | ||
167 | 151 | { | ||
168 | 152 | Qt::KeyboardModifiers previouslyDisabled = m_disabledModifiers; | ||
169 | 153 | m_disabledModifiers &= ~modifiers; | ||
170 | 154 | Q_FOREACH(HotModifier* hotModifier, m_hotModifiers) { | ||
171 | 155 | if (hotModifier->modifiers() & previouslyDisabled | ||
172 | 156 | && !hotModifier->modifiers() & m_disabledModifiers) { | ||
173 | 157 | hotModifier->onModifiersChanged(keyboardModifiers()); | ||
174 | 158 | } | ||
175 | 159 | } | ||
176 | 160 | } | ||
177 | 161 | |||
178 | 162 | #include "keyboardmodifiersmonitor.moc" | ||
179 | 163 | 0 | ||
180 | === removed file 'libunity-2d-private/src/keyboardmodifiersmonitor.h' | |||
181 | --- libunity-2d-private/src/keyboardmodifiersmonitor.h 2012-02-15 14:45:17 +0000 | |||
182 | +++ libunity-2d-private/src/keyboardmodifiersmonitor.h 1970-01-01 00:00:00 +0000 | |||
183 | @@ -1,69 +0,0 @@ | |||
184 | 1 | /* | ||
185 | 2 | * This file is part of unity-2d | ||
186 | 3 | * | ||
187 | 4 | * Copyright 2011 Canonical Ltd. | ||
188 | 5 | * | ||
189 | 6 | * Authors: | ||
190 | 7 | * - Aurélien Gâteau <aurelien.gateau@canonical.com> | ||
191 | 8 | * | ||
192 | 9 | * This program is free software; you can redistribute it and/or modify | ||
193 | 10 | * it under the terms of the GNU General Public License as published by | ||
194 | 11 | * the Free Software Foundation; version 3. | ||
195 | 12 | * | ||
196 | 13 | * This program is distributed in the hope that it will be useful, | ||
197 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
198 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
199 | 16 | * GNU General Public License for more details. | ||
200 | 17 | * | ||
201 | 18 | * You should have received a copy of the GNU General Public License | ||
202 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
203 | 20 | */ | ||
204 | 21 | |||
205 | 22 | #ifndef KEYBOARDMODIFIERMONITOR_H | ||
206 | 23 | #define KEYBOARDMODIFIERMONITOR_H | ||
207 | 24 | |||
208 | 25 | // Local | ||
209 | 26 | #include <unity2dapplication.h> | ||
210 | 27 | |||
211 | 28 | class HotModifier; | ||
212 | 29 | |||
213 | 30 | struct KeyboardModifiersMonitorPrivate; | ||
214 | 31 | |||
215 | 32 | /** | ||
216 | 33 | * This class monitor keyboard modifiers. It is able to track changes even if | ||
217 | 34 | * the active window does not belong to the application. | ||
218 | 35 | * | ||
219 | 36 | * You *must* use Unity2dApplication to be able to use this class. | ||
220 | 37 | * | ||
221 | 38 | * In most case you don't need your own instance: use the one returned by | ||
222 | 39 | * instance() instead. | ||
223 | 40 | */ | ||
224 | 41 | class KeyboardModifiersMonitor : public QObject, protected AbstractX11EventFilter | ||
225 | 42 | { | ||
226 | 43 | Q_OBJECT | ||
227 | 44 | public: | ||
228 | 45 | KeyboardModifiersMonitor(QObject *parent = 0); | ||
229 | 46 | ~KeyboardModifiersMonitor(); | ||
230 | 47 | |||
231 | 48 | Qt::KeyboardModifiers keyboardModifiers() const; | ||
232 | 49 | |||
233 | 50 | HotModifier* getHotModifierFor(Qt::KeyboardModifiers modifiers); | ||
234 | 51 | |||
235 | 52 | void disableModifiers(Qt::KeyboardModifiers modifiers); | ||
236 | 53 | void enableModifiers(Qt::KeyboardModifiers modifiers); | ||
237 | 54 | |||
238 | 55 | static KeyboardModifiersMonitor* instance(); | ||
239 | 56 | |||
240 | 57 | Q_SIGNALS: | ||
241 | 58 | void keyboardModifiersChanged(Qt::KeyboardModifiers); | ||
242 | 59 | |||
243 | 60 | protected: | ||
244 | 61 | bool x11EventFilter(XEvent*); | ||
245 | 62 | |||
246 | 63 | private: | ||
247 | 64 | KeyboardModifiersMonitorPrivate* const d; | ||
248 | 65 | QList<HotModifier*> m_hotModifiers; | ||
249 | 66 | Qt::KeyboardModifiers m_disabledModifiers; | ||
250 | 67 | }; | ||
251 | 68 | |||
252 | 69 | #endif /* KEYBOARDMODIFIERMONITOR_H */ | ||
253 | 70 | 0 | ||
254 | === modified file 'libunity-2d-private/src/keymonitor.cpp' | |||
255 | --- libunity-2d-private/src/keymonitor.cpp 2012-04-10 16:05:39 +0000 | |||
256 | +++ libunity-2d-private/src/keymonitor.cpp 2012-04-19 08:51:21 +0000 | |||
257 | @@ -27,20 +27,23 @@ | |||
258 | 27 | // X11 | 27 | // X11 |
259 | 28 | #include <X11/Xlib.h> | 28 | #include <X11/Xlib.h> |
260 | 29 | #include <X11/keysym.h> | 29 | #include <X11/keysym.h> |
261 | 30 | #include <X11/XKBlib.h> | ||
262 | 30 | 31 | ||
263 | 31 | // Local | 32 | // Local |
264 | 32 | #include <debug_p.h> | 33 | #include <debug_p.h> |
265 | 34 | #include <hotmodifier.h> | ||
266 | 33 | 35 | ||
267 | 34 | #define INVALID_EVENT_TYPE -1 | 36 | #define INVALID_EVENT_TYPE -1 |
268 | 35 | 37 | ||
269 | 36 | static int key_press_type = INVALID_EVENT_TYPE; | 38 | static int key_press_type = INVALID_EVENT_TYPE; |
270 | 37 | static int notify_type = INVALID_EVENT_TYPE; | 39 | static int notify_type = INVALID_EVENT_TYPE; |
272 | 38 | 40 | static int sXkbBaseEventType = 0; | |
273 | 39 | 41 | ||
274 | 40 | KeyMonitor::KeyMonitor(QObject* parent) | 42 | KeyMonitor::KeyMonitor(QObject* parent) |
276 | 41 | : QObject(parent) | 43 | : QObject(parent), |
277 | 44 | m_modifiers(Qt::NoModifier) | ||
278 | 42 | { | 45 | { |
280 | 43 | if (this->registerEvents()) { | 46 | if (registerEvents()) { |
281 | 44 | getModifiers(); | 47 | getModifiers(); |
282 | 45 | } | 48 | } |
283 | 46 | } | 49 | } |
284 | @@ -57,6 +60,45 @@ | |||
285 | 57 | return monitor; | 60 | return monitor; |
286 | 58 | } | 61 | } |
287 | 59 | 62 | ||
288 | 63 | Qt::KeyboardModifiers KeyMonitor::keyboardModifiers() const | ||
289 | 64 | { | ||
290 | 65 | return m_modifiers; | ||
291 | 66 | } | ||
292 | 67 | |||
293 | 68 | HotModifier *KeyMonitor::getHotModifierFor(Qt::KeyboardModifiers modifiers) | ||
294 | 69 | { | ||
295 | 70 | Q_FOREACH(HotModifier* hotModifier, m_hotModifiers) { | ||
296 | 71 | if (hotModifier->modifiers() == modifiers) { | ||
297 | 72 | return hotModifier; | ||
298 | 73 | } | ||
299 | 74 | } | ||
300 | 75 | |||
301 | 76 | HotModifier *hotModifier = new HotModifier(modifiers, this); | ||
302 | 77 | m_hotModifiers.append(hotModifier); | ||
303 | 78 | return hotModifier; | ||
304 | 79 | } | ||
305 | 80 | |||
306 | 81 | void KeyMonitor::disableModifiers(Qt::KeyboardModifiers modifiers) | ||
307 | 82 | { | ||
308 | 83 | m_disabledModifiers |= modifiers; | ||
309 | 84 | Q_FOREACH(HotModifier* hotModifier, m_hotModifiers) { | ||
310 | 85 | if (hotModifier->modifiers() & m_disabledModifiers) { | ||
311 | 86 | hotModifier->disable(); | ||
312 | 87 | } | ||
313 | 88 | } | ||
314 | 89 | } | ||
315 | 90 | |||
316 | 91 | void KeyMonitor::enableModifiers(Qt::KeyboardModifiers modifiers) | ||
317 | 92 | { | ||
318 | 93 | Qt::KeyboardModifiers previouslyDisabled = m_disabledModifiers; | ||
319 | 94 | m_disabledModifiers &= ~modifiers; | ||
320 | 95 | Q_FOREACH(HotModifier* hotModifier, m_hotModifiers) { | ||
321 | 96 | if (hotModifier->modifiers() & previouslyDisabled | ||
322 | 97 | && !hotModifier->modifiers() & m_disabledModifiers) { | ||
323 | 98 | hotModifier->onModifiersChanged(keyboardModifiers()); | ||
324 | 99 | } | ||
325 | 100 | } | ||
326 | 101 | } | ||
327 | 60 | 102 | ||
328 | 61 | void KeyMonitor::getModifiers() | 103 | void KeyMonitor::getModifiers() |
329 | 62 | { | 104 | { |
330 | @@ -134,6 +176,10 @@ | |||
331 | 134 | return false; | 176 | return false; |
332 | 135 | } | 177 | } |
333 | 136 | 178 | ||
334 | 179 | int opcode, error; | ||
335 | 180 | XkbQueryExtension(m_display, &opcode, &sXkbBaseEventType, &error, NULL, NULL); | ||
336 | 181 | XkbSelectEvents(m_display, XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask); | ||
337 | 182 | |||
338 | 137 | /* Dispatch XEvents when there is activity on the X11 file descriptor */ | 183 | /* Dispatch XEvents when there is activity on the X11 file descriptor */ |
339 | 138 | x11FileDescriptor = ConnectionNumber(m_display); | 184 | x11FileDescriptor = ConnectionNumber(m_display); |
340 | 139 | QSocketNotifier* socketNotifier = new QSocketNotifier(x11FileDescriptor, QSocketNotifier::Read, this); | 185 | QSocketNotifier* socketNotifier = new QSocketNotifier(x11FileDescriptor, QSocketNotifier::Read, this); |
341 | @@ -142,6 +188,23 @@ | |||
342 | 142 | return true; | 188 | return true; |
343 | 143 | } | 189 | } |
344 | 144 | 190 | ||
345 | 191 | static Qt::KeyboardModifiers qtModifiersFromXcbMods(int xcbModifiers) | ||
346 | 192 | { | ||
347 | 193 | Qt::KeyboardModifiers value = Qt::NoModifier; | ||
348 | 194 | if (xcbModifiers & ShiftMask) { | ||
349 | 195 | value |= Qt::ShiftModifier; | ||
350 | 196 | } | ||
351 | 197 | if (xcbModifiers & ControlMask) { | ||
352 | 198 | value |= Qt::ControlModifier; | ||
353 | 199 | } | ||
354 | 200 | if (xcbModifiers & Mod1Mask) { | ||
355 | 201 | value |= Qt::AltModifier; | ||
356 | 202 | } | ||
357 | 203 | if (xcbModifiers & Mod4Mask) { | ||
358 | 204 | value |= Qt::MetaModifier; | ||
359 | 205 | } | ||
360 | 206 | return value; | ||
361 | 207 | } | ||
362 | 145 | 208 | ||
363 | 146 | void KeyMonitor::x11EventDispatch() | 209 | void KeyMonitor::x11EventDispatch() |
364 | 147 | { | 210 | { |
365 | @@ -158,6 +221,23 @@ | |||
366 | 158 | } | 221 | } |
367 | 159 | else if (event.type == notify_type) { | 222 | else if (event.type == notify_type) { |
368 | 160 | getModifiers(); | 223 | getModifiers(); |
369 | 224 | } else if (event.type == sXkbBaseEventType + XkbEventCode) { | ||
370 | 225 | XkbEvent *xkbEvent = (XkbEvent*)&event; | ||
371 | 226 | if (xkbEvent->any.xkb_type == XkbStateNotify) { | ||
372 | 227 | const Qt::KeyboardModifiers prevMods = m_modifiers; | ||
373 | 228 | m_modifiers = qtModifiersFromXcbMods(xkbEvent->state.mods); | ||
374 | 229 | if (prevMods != m_modifiers) { | ||
375 | 230 | Q_EMIT keyboardModifiersChanged(m_modifiers); | ||
376 | 231 | Q_FOREACH(HotModifier* hotModifier, m_hotModifiers) { | ||
377 | 232 | if (hotModifier->modifiers() & m_disabledModifiers) { | ||
378 | 233 | /* If any of the modifiers have been disabled, the | ||
379 | 234 | * hotModifier cannot be triggered */ | ||
380 | 235 | continue; | ||
381 | 236 | } | ||
382 | 237 | hotModifier->onModifiersChanged(m_modifiers); | ||
383 | 238 | } | ||
384 | 239 | } | ||
385 | 240 | } | ||
386 | 161 | } | 241 | } |
387 | 162 | } | 242 | } |
388 | 163 | } | 243 | } |
389 | 164 | 244 | ||
390 | === modified file 'libunity-2d-private/src/keymonitor.h' | |||
391 | --- libunity-2d-private/src/keymonitor.h 2011-10-28 22:14:18 +0000 | |||
392 | +++ libunity-2d-private/src/keymonitor.h 2012-04-19 08:51:21 +0000 | |||
393 | @@ -28,12 +28,11 @@ | |||
394 | 28 | // X11 | 28 | // X11 |
395 | 29 | #include <X11/extensions/XInput.h> | 29 | #include <X11/extensions/XInput.h> |
396 | 30 | 30 | ||
397 | 31 | class HotModifier; | ||
398 | 32 | |||
399 | 31 | /** | 33 | /** |
400 | 32 | * This class monitors global keypresses. Whenever a non-modifier is pressed, | 34 | * This class monitors global keypresses. Whenever a non-modifier is pressed, |
401 | 33 | * keyPressed() is emitted. | 35 | * keyPressed() is emitted. |
402 | 34 | * | ||
403 | 35 | * In most case you don't need your own instance: use the one returned by | ||
404 | 36 | * instance() instead. | ||
405 | 37 | */ | 36 | */ |
406 | 38 | class KeyMonitor : public QObject | 37 | class KeyMonitor : public QObject |
407 | 39 | { | 38 | { |
408 | @@ -43,8 +42,16 @@ | |||
409 | 43 | static KeyMonitor* instance(); | 42 | static KeyMonitor* instance(); |
410 | 44 | ~KeyMonitor(); | 43 | ~KeyMonitor(); |
411 | 45 | 44 | ||
412 | 45 | Qt::KeyboardModifiers keyboardModifiers() const; | ||
413 | 46 | |||
414 | 47 | HotModifier* getHotModifierFor(Qt::KeyboardModifiers modifiers); | ||
415 | 48 | |||
416 | 49 | void disableModifiers(Qt::KeyboardModifiers modifiers); | ||
417 | 50 | void enableModifiers(Qt::KeyboardModifiers modifiers); | ||
418 | 51 | |||
419 | 46 | Q_SIGNALS: | 52 | Q_SIGNALS: |
420 | 47 | void keyPressed(); | 53 | void keyPressed(); |
421 | 54 | void keyboardModifiersChanged(Qt::KeyboardModifiers); | ||
422 | 48 | 55 | ||
423 | 49 | private: | 56 | private: |
424 | 50 | KeyMonitor(QObject* parent=0); | 57 | KeyMonitor(QObject* parent=0); |
425 | @@ -59,6 +66,9 @@ | |||
426 | 59 | Display *m_display; | 66 | Display *m_display; |
427 | 60 | QVector<XEventClass> m_eventList; | 67 | QVector<XEventClass> m_eventList; |
428 | 61 | QVector<KeyCode> m_modList; | 68 | QVector<KeyCode> m_modList; |
429 | 69 | Qt::KeyboardModifiers m_modifiers; | ||
430 | 70 | QList<HotModifier*> m_hotModifiers; | ||
431 | 71 | Qt::KeyboardModifiers m_disabledModifiers; | ||
432 | 62 | }; | 72 | }; |
433 | 63 | 73 | ||
434 | 64 | #endif // KEYMONITOR_H | 74 | #endif // KEYMONITOR_H |
435 | 65 | 75 | ||
436 | === modified file 'libunity-2d-private/tests/CMakeLists.txt' | |||
437 | --- libunity-2d-private/tests/CMakeLists.txt 2012-04-02 15:15:59 +0000 | |||
438 | +++ libunity-2d-private/tests/CMakeLists.txt 2012-04-19 08:51:21 +0000 | |||
439 | @@ -33,7 +33,7 @@ | |||
440 | 33 | 33 | ||
441 | 34 | libunity_2d_tests( | 34 | libunity_2d_tests( |
442 | 35 | gconnectortest | 35 | gconnectortest |
444 | 36 | keyboardmodifiersmonitortest | 36 | keymonitortest |
445 | 37 | launchermenutest | 37 | launchermenutest |
446 | 38 | listaggregatormodeltest | 38 | listaggregatormodeltest |
447 | 39 | qsortfilterproxymodeltest | 39 | qsortfilterproxymodeltest |
448 | @@ -47,6 +47,8 @@ | |||
449 | 47 | target_link_libraries(pointerbarriertest ${X11_XTest_LIB}) | 47 | target_link_libraries(pointerbarriertest ${X11_XTest_LIB}) |
450 | 48 | 48 | ||
451 | 49 | target_link_libraries(hotkeytest ${X11_XTest_LIB}) | 49 | target_link_libraries(hotkeytest ${X11_XTest_LIB}) |
452 | 50 | |||
453 | 51 | target_link_libraries(keymonitortest ${X11_XTest_LIB}) | ||
454 | 50 | 52 | ||
455 | 51 | # unity2dtrtest - FIXME | 53 | # unity2dtrtest - FIXME |
456 | 52 | #add_test(NAME unity2dtrtest_check | 54 | #add_test(NAME unity2dtrtest_check |
457 | 53 | 55 | ||
458 | === renamed file 'libunity-2d-private/tests/keyboardmodifiersmonitortest.cpp' => 'libunity-2d-private/tests/keymonitortest.cpp' | |||
459 | --- libunity-2d-private/tests/keyboardmodifiersmonitortest.cpp 2011-11-17 20:10:19 +0000 | |||
460 | +++ libunity-2d-private/tests/keymonitortest.cpp 2012-04-19 08:51:21 +0000 | |||
461 | @@ -22,7 +22,8 @@ | |||
462 | 22 | // Local | 22 | // Local |
463 | 23 | #include <unitytestmacro.h> | 23 | #include <unitytestmacro.h> |
464 | 24 | #include <debug_p.h> | 24 | #include <debug_p.h> |
466 | 25 | #include <keyboardmodifiersmonitor.h> | 25 | #include <keymonitor.h> |
467 | 26 | #include <hotmodifier.h> | ||
468 | 26 | 27 | ||
469 | 27 | // Qt | 28 | // Qt |
470 | 28 | #include <QSignalSpy> | 29 | #include <QSignalSpy> |
471 | @@ -33,6 +34,8 @@ | |||
472 | 33 | #include <X11/Xlib.h> | 34 | #include <X11/Xlib.h> |
473 | 34 | #include <X11/XKBlib.h> | 35 | #include <X11/XKBlib.h> |
474 | 35 | #include <X11/extensions/XKB.h> | 36 | #include <X11/extensions/XKB.h> |
475 | 37 | #include <X11/extensions/XTest.h> | ||
476 | 38 | #include <X11/keysym.h> | ||
477 | 36 | 39 | ||
478 | 37 | Q_DECLARE_METATYPE(Qt::KeyboardModifiers) | 40 | Q_DECLARE_METATYPE(Qt::KeyboardModifiers) |
479 | 38 | 41 | ||
480 | @@ -70,23 +73,45 @@ | |||
481 | 70 | { | 73 | { |
482 | 71 | QFETCH(int, x11Mask); | 74 | QFETCH(int, x11Mask); |
483 | 72 | QFETCH(Qt::KeyboardModifiers, qtModifiers); | 75 | QFETCH(Qt::KeyboardModifiers, qtModifiers); |
486 | 73 | KeyboardModifiersMonitor monitor; | 76 | KeyMonitor *monitor = KeyMonitor::instance(); |
487 | 74 | QSignalSpy spy(&monitor, SIGNAL(keyboardModifiersChanged(Qt::KeyboardModifiers))); | 77 | QSignalSpy spy(monitor, SIGNAL(keyboardModifiersChanged(Qt::KeyboardModifiers))); |
488 | 75 | 78 | ||
489 | 76 | setModifierState(x11Mask, true); | 79 | setModifierState(x11Mask, true); |
490 | 77 | QTest::qWait(200); | 80 | QTest::qWait(200); |
492 | 78 | QCOMPARE(monitor.keyboardModifiers(), qtModifiers); | 81 | QCOMPARE(monitor->keyboardModifiers(), qtModifiers); |
493 | 79 | QCOMPARE(spy.count(), 1); | 82 | QCOMPARE(spy.count(), 1); |
494 | 80 | QCOMPARE(spy.takeFirst().at(0).value<Qt::KeyboardModifiers>(), qtModifiers); | 83 | QCOMPARE(spy.takeFirst().at(0).value<Qt::KeyboardModifiers>(), qtModifiers); |
495 | 81 | 84 | ||
496 | 82 | setModifierState(x11Mask, false); | 85 | setModifierState(x11Mask, false); |
497 | 83 | QTest::qWait(200); | 86 | QTest::qWait(200); |
499 | 84 | QCOMPARE(monitor.keyboardModifiers(), 0); | 87 | QCOMPARE(monitor->keyboardModifiers(), 0); |
500 | 85 | QCOMPARE(spy.count(), 1); | 88 | QCOMPARE(spy.count(), 1); |
501 | 86 | QCOMPARE(spy.takeFirst().at(0).value<Qt::KeyboardModifiers>(), 0); | 89 | QCOMPARE(spy.takeFirst().at(0).value<Qt::KeyboardModifiers>(), 0); |
502 | 87 | } | 90 | } |
503 | 91 | |||
504 | 92 | void testFastModifierKeyPress() | ||
505 | 93 | { | ||
506 | 94 | Display *display = XOpenDisplay(0); | ||
507 | 95 | |||
508 | 96 | HotModifier* hm = KeyMonitor::instance()->getHotModifierFor(Qt::AltModifier); | ||
509 | 97 | QSignalSpy spy(hm, SIGNAL(tapped())); | ||
510 | 98 | |||
511 | 99 | XTestGrabControl(display, 1); | ||
512 | 100 | XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Alt_L), 1 /* PRESS */, CurrentTime); | ||
513 | 101 | XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Left), 1 /* PRESS */, CurrentTime); | ||
514 | 102 | XFlush(display); | ||
515 | 103 | |||
516 | 104 | XTestGrabControl(display, 1); | ||
517 | 105 | XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Alt_L), 0 /* RELEASE */, CurrentTime); | ||
518 | 106 | XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Left), 0 /* RELEASE */, CurrentTime); | ||
519 | 107 | XFlush(display); | ||
520 | 108 | |||
521 | 109 | QTest::qWait(200); | ||
522 | 110 | |||
523 | 111 | QCOMPARE(spy.count(), 0); | ||
524 | 112 | } | ||
525 | 88 | }; | 113 | }; |
526 | 89 | 114 | ||
527 | 90 | UAPP_TEST_MAIN(KeyboardModifiersMonitorTest) | 115 | UAPP_TEST_MAIN(KeyboardModifiersMonitorTest) |
528 | 91 | 116 | ||
530 | 92 | #include "keyboardmodifiersmonitortest.moc" | 117 | #include "keymonitortest.moc" |
531 | 93 | 118 | ||
532 | === modified file 'panel/applets/appname/appnameapplet.cpp' | |||
533 | --- panel/applets/appname/appnameapplet.cpp 2012-04-05 09:34:40 +0000 | |||
534 | +++ panel/applets/appname/appnameapplet.cpp 2012-04-19 08:51:21 +0000 | |||
535 | @@ -34,7 +34,7 @@ | |||
536 | 34 | 34 | ||
537 | 35 | // Unity-2d | 35 | // Unity-2d |
538 | 36 | #include <debug_p.h> | 36 | #include <debug_p.h> |
540 | 37 | #include <keyboardmodifiersmonitor.h> | 37 | #include <keymonitor.h> |
541 | 38 | #include <launcherclient.h> | 38 | #include <launcherclient.h> |
542 | 39 | #include <hotkey.h> | 39 | #include <hotkey.h> |
543 | 40 | #include <hotkeymonitor.h> | 40 | #include <hotkeymonitor.h> |
544 | @@ -271,7 +271,7 @@ | |||
545 | 271 | 271 | ||
546 | 272 | void setupKeyboardModifiersMonitor() | 272 | void setupKeyboardModifiersMonitor() |
547 | 273 | { | 273 | { |
549 | 274 | QObject::connect(KeyboardModifiersMonitor::instance(), SIGNAL(keyboardModifiersChanged(Qt::KeyboardModifiers)), | 274 | QObject::connect(KeyMonitor::instance(), SIGNAL(keyboardModifiersChanged(Qt::KeyboardModifiers)), |
550 | 275 | q, SLOT(updateWidgets())); | 275 | q, SLOT(updateWidgets())); |
551 | 276 | } | 276 | } |
552 | 277 | }; | 277 | }; |
553 | @@ -321,7 +321,7 @@ | |||
554 | 321 | bool isUnderMouse = rect().contains(mapFromGlobal(QCursor::pos())); | 321 | bool isUnderMouse = rect().contains(mapFromGlobal(QCursor::pos())); |
555 | 322 | bool isOpened = isOnSameScreen && | 322 | bool isOpened = isOnSameScreen && |
556 | 323 | (isUnderMouse | 323 | (isUnderMouse |
558 | 324 | || KeyboardModifiersMonitor::instance()->keyboardModifiers() == Qt::AltModifier | 324 | || KeyMonitor::instance()->keyboardModifiers() == Qt::AltModifier |
559 | 325 | || d->m_menuBarWidget->isOpened() | 325 | || d->m_menuBarWidget->isOpened() |
560 | 326 | ); | 326 | ); |
561 | 327 | bool showDesktopLabel = !app; | 327 | bool showDesktopLabel = !app; |
562 | 328 | 328 | ||
563 | === modified file 'shell/app/shellmanager.cpp' | |||
564 | --- shell/app/shellmanager.cpp 2012-04-06 15:16:39 +0000 | |||
565 | +++ shell/app/shellmanager.cpp 2012-04-19 08:51:21 +0000 | |||
566 | @@ -31,7 +31,6 @@ | |||
567 | 31 | #include <hotmodifier.h> | 31 | #include <hotmodifier.h> |
568 | 32 | #include <hotkeymonitor.h> | 32 | #include <hotkeymonitor.h> |
569 | 33 | #include <hotkey.h> | 33 | #include <hotkey.h> |
570 | 34 | #include <keyboardmodifiersmonitor.h> | ||
571 | 35 | #include <keymonitor.h> | 34 | #include <keymonitor.h> |
572 | 36 | #include <screeninfo.h> | 35 | #include <screeninfo.h> |
573 | 37 | 36 | ||
574 | @@ -300,7 +299,7 @@ | |||
575 | 300 | updateSuperKeyMonitoring(); | 299 | updateSuperKeyMonitoring(); |
576 | 301 | 300 | ||
577 | 302 | /* Super tap shows the dash, super held shows the launcher hints */ | 301 | /* Super tap shows the dash, super held shows the launcher hints */ |
579 | 303 | d->m_superHotModifier = KeyboardModifiersMonitor::instance()->getHotModifierFor(Qt::MetaModifier); | 302 | d->m_superHotModifier = KeyMonitor::instance()->getHotModifierFor(Qt::MetaModifier); |
580 | 304 | connect(d->m_superHotModifier, SIGNAL(tapped()), SLOT(toggleDashRequested())); | 303 | connect(d->m_superHotModifier, SIGNAL(tapped()), SLOT(toggleDashRequested())); |
581 | 305 | connect(d->m_superHotModifier, SIGNAL(heldChanged(bool)), SIGNAL(superKeyHeldChanged(bool))); | 304 | connect(d->m_superHotModifier, SIGNAL(heldChanged(bool)), SIGNAL(superKeyHeldChanged(bool))); |
582 | 306 | 305 | ||
583 | @@ -514,7 +513,7 @@ | |||
584 | 514 | d->m_hudHotKey = HotkeyMonitor::instance().getHotkeyFor(x11KeyCode, modifiers); | 513 | d->m_hudHotKey = HotkeyMonitor::instance().getHotkeyFor(x11KeyCode, modifiers); |
585 | 515 | connect(d->m_hudHotKey, SIGNAL(pressed()), SLOT(toggleHudRequested())); | 514 | connect(d->m_hudHotKey, SIGNAL(pressed()), SLOT(toggleHudRequested())); |
586 | 516 | } else if (modifiers != Qt::NoModifier) { | 515 | } else if (modifiers != Qt::NoModifier) { |
588 | 517 | d->m_hudHotModifier = KeyboardModifiersMonitor::instance()->getHotModifierFor(modifiers); | 516 | d->m_hudHotModifier = KeyMonitor::instance()->getHotModifierFor(modifiers); |
589 | 518 | connect(d->m_hudHotModifier, SIGNAL(tapped()), SLOT(toggleHudRequested())); | 517 | connect(d->m_hudHotModifier, SIGNAL(tapped()), SLOT(toggleHudRequested())); |
590 | 519 | } | 518 | } |
591 | 520 | } else { | 519 | } else { |
592 | @@ -527,7 +526,7 @@ | |||
593 | 527 | void | 526 | void |
594 | 528 | ShellManager::updateSuperKeyMonitoring() | 527 | ShellManager::updateSuperKeyMonitoring() |
595 | 529 | { | 528 | { |
597 | 530 | KeyboardModifiersMonitor *modifiersMonitor = KeyboardModifiersMonitor::instance(); | 529 | KeyMonitor *modifiersMonitor = KeyMonitor::instance(); |
598 | 531 | HotkeyMonitor& hotkeyMonitor = HotkeyMonitor::instance(); | 530 | HotkeyMonitor& hotkeyMonitor = HotkeyMonitor::instance(); |
599 | 532 | 531 | ||
600 | 533 | QVariant value = launcher2dConfiguration().property("superKeyEnable"); | 532 | QVariant value = launcher2dConfiguration().property("superKeyEnable"); |
I'll try to integrate the test code from https:/ /bugs.launchpad .net/unity- 2d/+bug/ 968840/ comments/ 4 next