Merge lp:~uriboni/unity-2d/launcher-keyboard-shortcuts into lp:unity-2d/3.0
- launcher-keyboard-shortcuts
- Merge into natty
Proposed by
Ugo Riboni
Status: | Merged |
---|---|
Merged at revision: | 407 |
Proposed branch: | lp:~uriboni/unity-2d/launcher-keyboard-shortcuts |
Merge into: | lp:unity-2d/3.0 |
Diff against target: |
975 lines (+458/-279) 18 files modified
launcher/LauncherItem.qml (+18/-0) launcher/LauncherList.qml (+15/-0) launcher/app/CMakeLists.txt (+3/-0) launcher/app/launcher.cpp (+3/-1) launcher/app/launcherview.cpp (+83/-1) launcher/app/launcherview.h (+17/-1) launcher/tests/CMakeLists.txt (+1/-0) libunity-2d-private/src/CMakeLists.txt (+2/-0) libunity-2d-private/src/hotkey.cpp (+101/-0) libunity-2d-private/src/hotkey.h (+59/-0) libunity-2d-private/src/hotkeymonitor.cpp (+105/-0) libunity-2d-private/src/hotkeymonitor.h (+50/-0) places/app/CMakeLists.txt (+0/-4) places/app/keymonitor.cpp (+0/-62) places/app/keymonitor.h (+0/-42) places/app/places.cpp (+1/-34) places/app/superkeymonitor.cpp (+0/-79) places/app/superkeymonitor.h (+0/-55) |
To merge this branch: | bzr merge lp:~uriboni/unity-2d/launcher-keyboard-shortcuts |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Florian Boucault | Pending | ||
Review via email: mp+51046@code.launchpad.net |
Commit message
[launcher] Make the first 10 items in the launcher able to be activated via Super+n, and show the launcher when Super is pressed if hidden.
Description of the change
Make the first 10 items in the launcher able to be activated via Super+n, and show the launcher when Super is pressed if hidden.
Please note that this branch has already merged into it the following branches:
lp:~fboucault/unity-2d/more_robust_intellihide and
lp:~fboucault/unity-2d/launcher_four_fingers_drag
To post a comment you must log in.
Revision history for this message
Florian Boucault (fboucault) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'launcher/LauncherItem.qml' |
2 | --- launcher/LauncherItem.qml 2011-02-18 14:02:46 +0000 |
3 | +++ launcher/LauncherItem.qml 2011-02-24 00:23:17 +0000 |
4 | @@ -53,6 +53,9 @@ |
5 | property bool backgroundFromIcon |
6 | property color defaultBackgroundColor: "#333333" |
7 | |
8 | + property alias shortcutVisible: shortcut.visible |
9 | + property alias shortcutText: shortcutText.text |
10 | + |
11 | property int pips: 0 |
12 | property string pipSource: engineBaseUrl + "artwork/launcher_" + |
13 | ((pips <= 1) ? "arrow" : "pip") + "_ltr.png" |
14 | @@ -263,6 +266,21 @@ |
15 | } |
16 | } |
17 | |
18 | + Rectangle { |
19 | + id: shortcut |
20 | + anchors.centerIn: parent |
21 | + color: "#B3000000" // 0.7 opacity on black |
22 | + radius: 2 |
23 | + width: 22 |
24 | + height: 22 |
25 | + |
26 | + Text { |
27 | + id: shortcutText |
28 | + anchors.centerIn: parent |
29 | + color: "white" |
30 | + } |
31 | + } |
32 | + |
33 | Image { |
34 | id: emblemIcon |
35 | anchors.left: parent.left |
36 | |
37 | === modified file 'launcher/LauncherList.qml' |
38 | --- launcher/LauncherList.qml 2011-02-21 10:23:45 +0000 |
39 | +++ launcher/LauncherList.qml 2011-02-24 00:23:17 +0000 |
40 | @@ -31,6 +31,10 @@ |
41 | emblem: (noOverlays && item.emblem) ? "image://icons/" + item.emblem : "" |
42 | emblemVisible: (noOverlays) ? false : item.emblemVisible |
43 | |
44 | + shortcutVisible: item.toString().indexOf("LauncherApplication") == 0 && |
45 | + index <= 9 && launcherView.superKeyPressed |
46 | + shortcutText: index + 1 |
47 | + |
48 | /* Best way I could find to check if the item is an application or the |
49 | workspaces switcher. There may be something cleaner and better. */ |
50 | backgroundFromIcon: item.toString().indexOf("LauncherApplication") == 0 || |
51 | @@ -121,5 +125,16 @@ |
52 | /* Not all items are applications. */ |
53 | ignoreUnknownSignals: true |
54 | } |
55 | + |
56 | + Connections { |
57 | + target: launcherView |
58 | + onKeyboardShortcutPressed: { |
59 | + /* Only applications can be launched by keyboard shortcuts */ |
60 | + if (item.toString().indexOf("LauncherApplication") == 0 && index == itemIndex) { |
61 | + item.menu.hide() |
62 | + item.activate() |
63 | + } |
64 | + } |
65 | + } |
66 | } |
67 | } |
68 | |
69 | === modified file 'launcher/app/CMakeLists.txt' |
70 | --- launcher/app/CMakeLists.txt 2011-02-16 02:21:24 +0000 |
71 | +++ launcher/app/CMakeLists.txt 2011-02-24 00:23:17 +0000 |
72 | @@ -2,6 +2,7 @@ |
73 | pkg_check_modules(GTK REQUIRED gtk+-2.0) |
74 | pkg_check_modules(X11 REQUIRED x11) |
75 | pkg_check_modules(GEIS REQUIRED libutouch-geis) |
76 | +pkg_check_modules(QTGCONF REQUIRED libqtgconf) |
77 | |
78 | # Sources |
79 | set(launcher_SRCS |
80 | @@ -34,6 +35,7 @@ |
81 | ${GTK_INCLUDE_DIRS} |
82 | ${X11_INCLUDE_DIRS} |
83 | ${GEIS_INCLUDE_DIRS} |
84 | + ${QTGCONF_INCLUDE_DIRS} |
85 | ${libunity-2d-private_SOURCE_DIR}/src |
86 | ) |
87 | |
88 | @@ -45,6 +47,7 @@ |
89 | ${GTK_LDFLAGS} |
90 | ${X11_LDFLAGS} |
91 | ${GEIS_LDFLAGS} |
92 | + ${QTGCONF_LDFLAGS} |
93 | unity-2d-private |
94 | ) |
95 | |
96 | |
97 | === modified file 'launcher/app/launcher.cpp' |
98 | --- launcher/app/launcher.cpp 2011-02-22 16:54:40 +0000 |
99 | +++ launcher/app/launcher.cpp 2011-02-24 00:23:17 +0000 |
100 | @@ -29,6 +29,8 @@ |
101 | #include <QDeclarativeContext> |
102 | #include <QDir> |
103 | |
104 | +#include <unity2dapplication.h> |
105 | + |
106 | #include "config.h" |
107 | #include "launcherview.h" |
108 | #include "launchercontrol.h" |
109 | @@ -53,7 +55,7 @@ |
110 | */ |
111 | QApplication::setGraphicsSystem("raster"); |
112 | QApplication::setColorSpec(QApplication::ManyColor); |
113 | - QApplication application(argc, argv); |
114 | + Unity2dApplication application(argc, argv); |
115 | |
116 | GnomeSessionClient client(INSTALL_PREFIX "/share/applications/unity-2d-launcher.desktop"); |
117 | client.connectToSessionManager(); |
118 | |
119 | === modified file 'launcher/app/launcherview.cpp' |
120 | --- launcher/app/launcherview.cpp 2011-02-16 11:11:46 +0000 |
121 | +++ launcher/app/launcherview.cpp 2011-02-24 00:23:17 +0000 |
122 | @@ -35,13 +35,95 @@ |
123 | #include <X11/Xatom.h> |
124 | |
125 | #include "dragdropevent.h" |
126 | +#include <keyboardmodifiersmonitor.h> |
127 | +#include <hotkey.h> |
128 | +#include <hotkeymonitor.h> |
129 | |
130 | LauncherView::LauncherView() : |
131 | QDeclarativeView(), m_resizing(false), m_reserved(false), |
132 | m_dndCurrentLauncherItem(NULL), m_dndCurrentLauncherItemAccepted(false), |
133 | - m_dndAccepted(false) |
134 | + m_dndAccepted(false), m_superKeyPressed(false) |
135 | { |
136 | setAcceptDrops(true); |
137 | + |
138 | + m_enableSuperKey.setKey("/desktop/unity/launcher/super_key_enable"); |
139 | + QObject::connect(&m_enableSuperKey, SIGNAL(valueChanged()), |
140 | + this, SLOT(updateSuperKeyMonitoring())); |
141 | + updateSuperKeyMonitoring(); |
142 | +} |
143 | + |
144 | +void |
145 | +LauncherView::updateSuperKeyMonitoring() |
146 | +{ |
147 | + KeyboardModifiersMonitor *modifiersMonitor = KeyboardModifiersMonitor::instance(); |
148 | + |
149 | + QVariant value = m_enableSuperKey.getValue(); |
150 | + if (!value.isValid() || value.toBool() == true) { |
151 | + QObject::connect(modifiersMonitor, |
152 | + SIGNAL(keyboardModifiersChanged(Qt::KeyboardModifiers)), |
153 | + this, SLOT(setHotkeysForModifiers(Qt::KeyboardModifiers))); |
154 | + setHotkeysForModifiers(modifiersMonitor->keyboardModifiers()); |
155 | + } else { |
156 | + QObject::disconnect(modifiersMonitor, |
157 | + SIGNAL(keyboardModifiersChanged(Qt::KeyboardModifiers)), |
158 | + this, SLOT(setHotkeysForModifiers(Qt::KeyboardModifiers))); |
159 | + m_superKeyPressed = false; |
160 | + Q_EMIT superKeyPressedChanged(false); |
161 | + changeKeyboardShortcutsState(false); |
162 | + } |
163 | +} |
164 | + |
165 | +void |
166 | +LauncherView::setHotkeysForModifiers(Qt::KeyboardModifiers modifiers) |
167 | +{ |
168 | + /* This is the new new state of the Super key (AKA Meta key), while |
169 | + m_superKeyPressed is the previous state of the key at the last modifiers change. */ |
170 | + bool superKeyPressed = modifiers.testFlag(Qt::MetaModifier); |
171 | + |
172 | + if (m_superKeyPressed != superKeyPressed) { |
173 | + m_superKeyPressed = superKeyPressed; |
174 | + Q_EMIT superKeyPressedChanged(m_superKeyPressed); |
175 | + changeKeyboardShortcutsState(m_superKeyPressed); |
176 | + } |
177 | +} |
178 | + |
179 | +void |
180 | +LauncherView::changeKeyboardShortcutsState(bool enabled) |
181 | +{ |
182 | + /* We are going to connect 10 Hotkeys, but to make things simpler on the QML |
183 | + side we want to have only one signal with the number of the item that needs to |
184 | + be activated in response to the hotkey press. |
185 | + So we connect all of them to a single slot where we emit a single signal with |
186 | + an index based on which Hotkey was the sender. */ |
187 | + Qt::Key key = Qt::Key_0; |
188 | + while (key <= Qt::Key_9) { |
189 | + Hotkey *hotkey = HotkeyMonitor::instance().getHotkeyFor(key, Qt::MetaModifier); |
190 | + |
191 | + if (enabled) { |
192 | + QObject::connect(hotkey, SIGNAL(pressed()), this, SLOT(forwardHotkey())); |
193 | + } else { |
194 | + QObject::disconnect(hotkey, SIGNAL(pressed()), this, SLOT(forwardHotkey())); |
195 | + } |
196 | + key = (Qt::Key) (key + 1); |
197 | + } |
198 | +} |
199 | + |
200 | +void |
201 | +LauncherView::forwardHotkey() |
202 | +{ |
203 | + Hotkey *hotkey = qobject_cast<Hotkey*>(sender()); |
204 | + if (hotkey != NULL) { |
205 | + /* Shortcuts from 1 to 9 should activate the items with index |
206 | + from 0 to 8. Shortcut for 0 should activate item with index 10. |
207 | + In other words, the indexes are activated in the same order as |
208 | + the keys appear on a standard keyboard. */ |
209 | + int itemIndex = hotkey->key() - Qt::Key_0; |
210 | + itemIndex = (itemIndex == 0) ? 9 : itemIndex - 1; |
211 | + |
212 | + if (itemIndex >= 0 && itemIndex <= 10) { |
213 | + Q_EMIT keyboardShortcutPressed(itemIndex); |
214 | + } |
215 | + } |
216 | } |
217 | |
218 | QGraphicsObject* |
219 | |
220 | === modified file 'launcher/app/launcherview.h' |
221 | --- launcher/app/launcherview.h 2011-02-16 11:11:46 +0000 |
222 | +++ launcher/app/launcherview.h 2011-02-24 00:23:17 +0000 |
223 | @@ -24,23 +24,36 @@ |
224 | #include <QUrl> |
225 | #include <QList> |
226 | #include <QDragEnterEvent> |
227 | +#include "gconfitem-qml-wrapper.h" |
228 | |
229 | class QGraphicsObject; |
230 | |
231 | class LauncherView : public QDeclarativeView |
232 | { |
233 | Q_OBJECT |
234 | + Q_PROPERTY(bool superKeyPressed READ superKeyPressed |
235 | + NOTIFY superKeyPressedChanged) |
236 | |
237 | public: |
238 | explicit LauncherView(); |
239 | Q_INVOKABLE QList<QVariant> getColorsFromIcon(QUrl source, QSize size) const; |
240 | |
241 | -signals: |
242 | + bool superKeyPressed() const { return m_superKeyPressed; } |
243 | + |
244 | +Q_SIGNALS: |
245 | void desktopFileDropped(QString path); |
246 | void webpageUrlDropped(const QUrl& url); |
247 | + void keyboardShortcutPressed(int itemIndex); |
248 | + void superKeyPressedChanged(bool superKeyPressed); |
249 | + |
250 | +private Q_SLOTS: |
251 | + void setHotkeysForModifiers(Qt::KeyboardModifiers modifiers); |
252 | + void forwardHotkey(); |
253 | + void updateSuperKeyMonitoring(); |
254 | |
255 | private: |
256 | QList<QUrl> getEventUrls(QDropEvent*); |
257 | + void changeKeyboardShortcutsState(bool enabled); |
258 | |
259 | /* Whether the launcher is already being resized */ |
260 | bool m_resizing; |
261 | @@ -63,6 +76,9 @@ |
262 | bool m_dndCurrentLauncherItemAccepted; |
263 | /* Whether the launcher itself handles the current dnd event */ |
264 | bool m_dndAccepted; |
265 | + |
266 | + GConfItemQmlWrapper m_enableSuperKey; |
267 | + bool m_superKeyPressed; |
268 | }; |
269 | |
270 | #endif // LAUNCHERVIEW |
271 | |
272 | === modified file 'launcher/tests/CMakeLists.txt' |
273 | --- launcher/tests/CMakeLists.txt 2011-01-27 16:23:33 +0000 |
274 | +++ launcher/tests/CMakeLists.txt 2011-02-24 00:23:17 +0000 |
275 | @@ -22,6 +22,7 @@ |
276 | ${CMAKE_CURRENT_SOURCE_DIR}/../UnityApplications |
277 | ${CMAKE_CURRENT_BINARY_DIR} |
278 | ${QT_QTTEST_INCLUDE_DIR} |
279 | + ${QTGCONF_INCLUDE_DIRS} |
280 | ) |
281 | |
282 | enable_testing() |
283 | |
284 | === modified file 'libunity-2d-private/src/CMakeLists.txt' |
285 | --- libunity-2d-private/src/CMakeLists.txt 2011-02-11 11:37:55 +0000 |
286 | +++ libunity-2d-private/src/CMakeLists.txt 2011-02-24 00:23:17 +0000 |
287 | @@ -2,6 +2,8 @@ |
288 | set(libunity-2d-private_SRCS |
289 | gnomesessionclient.cpp |
290 | keyboardmodifiersmonitor.cpp |
291 | + hotkeymonitor.cpp |
292 | + hotkey.cpp |
293 | unity2dapplication.cpp |
294 | unity2dpanel.cpp |
295 | mimedata.cpp |
296 | |
297 | === added file 'libunity-2d-private/src/hotkey.cpp' |
298 | --- libunity-2d-private/src/hotkey.cpp 1970-01-01 00:00:00 +0000 |
299 | +++ libunity-2d-private/src/hotkey.cpp 2011-02-24 00:23:17 +0000 |
300 | @@ -0,0 +1,101 @@ |
301 | +/* |
302 | + * Copyright (C) 2011 Canonical, Ltd. |
303 | + * |
304 | + * Authors: |
305 | + * Ugo Riboni <ugo.riboni@canonical.com> |
306 | + * |
307 | + * This program is free software; you can redistribute it and/or modify |
308 | + * it under the terms of the GNU General Public License as published by |
309 | + * the Free Software Foundation; version 3. |
310 | + * |
311 | + * This program is distributed in the hope that it will be useful, |
312 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
313 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
314 | + * GNU General Public License for more details. |
315 | + * |
316 | + * You should have received a copy of the GNU General Public License |
317 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
318 | + */ |
319 | + |
320 | +#include "hotkey.h" |
321 | + |
322 | +#include <QX11Info> |
323 | +#include <QDebug> |
324 | +#include <QKeySequence> |
325 | + |
326 | +#include <X11/Xlib.h> |
327 | +#include <X11/XKBlib.h> |
328 | +#include <X11/extensions/XKB.h> |
329 | + |
330 | +Hotkey::Hotkey(Qt::Key key, Qt::KeyboardModifiers modifiers, QObject *parent) : |
331 | + QObject(parent), m_connections(0), |
332 | + m_key(key), m_modifiers(modifiers), |
333 | + m_x11key(0), m_x11modifiers(0) |
334 | +{ |
335 | + /* Translate the QT modifiers to X11 modifiers */ |
336 | + |
337 | + if (modifiers.testFlag(Qt::ShiftModifier)) { |
338 | + m_x11modifiers |= ShiftMask ; |
339 | + } |
340 | + if (modifiers.testFlag(Qt::ControlModifier)) { |
341 | + m_x11modifiers |= ControlMask ; |
342 | + } |
343 | + if (modifiers.testFlag(Qt::AltModifier)) { |
344 | + m_x11modifiers |= Mod1Mask; |
345 | + } |
346 | + if (modifiers.testFlag(Qt::MetaModifier)) { |
347 | + m_x11modifiers |= Mod4Mask; |
348 | + } |
349 | + |
350 | + /* Translate the QT key to X11 keycode */ |
351 | + |
352 | + /* QKeySequence can be used to translate a Qt::Key in a format that is |
353 | + understood by XStringToKeysym if the sequence is composed only by the key */ |
354 | + QString keyString = QKeySequence(key).toString(); |
355 | + KeySym keysym = XStringToKeysym(keyString.toLatin1().data()); |
356 | + if (keysym == NoSymbol) { |
357 | + qWarning() << "Could not convert" << keyString << "to an x11 keysym"; |
358 | + } else { |
359 | + m_x11key = XKeysymToKeycode(QX11Info::display(), keysym); |
360 | + if (m_x11key == 0) { |
361 | + qWarning() << "Could not get keycode for keysym" << keysym |
362 | + << "(" << keyString << ")"; |
363 | + } |
364 | + } |
365 | +} |
366 | + |
367 | +void |
368 | +Hotkey::connectNotify(const char * signal) |
369 | +{ |
370 | + Q_UNUSED(signal); |
371 | + if (m_connections == 0) { |
372 | + qDebug() << "Grabbing hotkey" << QKeySequence(m_key | m_modifiers).toString(); |
373 | + XGrabKey(QX11Info::display(), m_x11key, m_x11modifiers, |
374 | + QX11Info::appRootWindow(), True, GrabModeAsync, GrabModeAsync); |
375 | + } |
376 | + m_connections++; |
377 | +} |
378 | + |
379 | +void |
380 | +Hotkey::disconnectNotify(const char * signal) |
381 | +{ |
382 | + Q_UNUSED(signal); |
383 | + if (m_connections == 1) { |
384 | + qDebug() << "Ungrabbing hotkey" << QKeySequence(m_key | m_modifiers).toString(); |
385 | + XUngrabKey(QX11Info::display(), m_x11key, m_x11modifiers, |
386 | + QX11Info::appRootWindow()); |
387 | + } |
388 | + m_connections--; |
389 | +} |
390 | + |
391 | +bool |
392 | +Hotkey::processNativeEvent(uint x11Keycode, uint x11Modifiers, bool isPressEvent) |
393 | +{ |
394 | + if (x11Keycode == m_x11key && x11Modifiers == m_x11modifiers) { |
395 | + Q_EMIT (isPressEvent) ? pressed() : released(); |
396 | + return true; |
397 | + } |
398 | + return false; |
399 | +} |
400 | + |
401 | +#include "hotkey.moc" |
402 | |
403 | === added file 'libunity-2d-private/src/hotkey.h' |
404 | --- libunity-2d-private/src/hotkey.h 1970-01-01 00:00:00 +0000 |
405 | +++ libunity-2d-private/src/hotkey.h 2011-02-24 00:23:17 +0000 |
406 | @@ -0,0 +1,59 @@ |
407 | +/* |
408 | + * Copyright (C) 2011 Canonical, Ltd. |
409 | + * |
410 | + * Authors: |
411 | + * Ugo Riboni <ugo.riboni@canonical.com> |
412 | + * |
413 | + * This program is free software; you can redistribute it and/or modify |
414 | + * it under the terms of the GNU General Public License as published by |
415 | + * the Free Software Foundation; version 3. |
416 | + * |
417 | + * This program is distributed in the hope that it will be useful, |
418 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
419 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
420 | + * GNU General Public License for more details. |
421 | + * |
422 | + * You should have received a copy of the GNU General Public License |
423 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
424 | + */ |
425 | + |
426 | +#ifndef Hotkey_H |
427 | +#define Hotkey_H |
428 | + |
429 | +#include <QObject> |
430 | + |
431 | +class Hotkey : public QObject |
432 | +{ |
433 | + friend class HotkeyMonitor; |
434 | + |
435 | + Q_OBJECT |
436 | + Q_PROPERTY(Qt::Key key READ key NOTIFY keyChanged) |
437 | + Q_PROPERTY(Qt::KeyboardModifiers modifiers READ modifiers NOTIFY modifiersChanged) |
438 | + |
439 | +public: |
440 | + Qt::Key key() const { return m_key; } |
441 | + Qt::KeyboardModifiers modifiers() const { return m_modifiers; } |
442 | + |
443 | +Q_SIGNALS: |
444 | + void keyChanged(Qt::Key key); |
445 | + void modifiersChanged(Qt::KeyboardModifiers modifiers); |
446 | + void pressed(); |
447 | + void released(); |
448 | + |
449 | +protected: |
450 | + virtual void connectNotify(const char * signal); |
451 | + virtual void disconnectNotify(const char * signal); |
452 | + |
453 | +private: |
454 | + Hotkey(Qt::Key key, Qt::KeyboardModifiers modifiers, QObject *parent); |
455 | + bool processNativeEvent(uint x11Keycode, uint x11Modifiers, bool isPressEvent); |
456 | + |
457 | +private: |
458 | + uint m_connections; |
459 | + Qt::Key m_key; |
460 | + Qt::KeyboardModifiers m_modifiers; |
461 | + uint m_x11key; |
462 | + uint m_x11modifiers; |
463 | +}; |
464 | + |
465 | +#endif // Hotkey_H |
466 | |
467 | === added file 'libunity-2d-private/src/hotkeymonitor.cpp' |
468 | --- libunity-2d-private/src/hotkeymonitor.cpp 1970-01-01 00:00:00 +0000 |
469 | +++ libunity-2d-private/src/hotkeymonitor.cpp 2011-02-24 00:23:17 +0000 |
470 | @@ -0,0 +1,105 @@ |
471 | +/* |
472 | + * Copyright (C) 2011 Canonical, Ltd. |
473 | + * |
474 | + * Authors: |
475 | + * Ugo Riboni <ugo.riboni@canonical.com> |
476 | + * |
477 | + * This program is free software; you can redistribute it and/or modify |
478 | + * it under the terms of the GNU General Public License as published by |
479 | + * the Free Software Foundation; version 3. |
480 | + * |
481 | + * This program is distributed in the hope that it will be useful, |
482 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
483 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
484 | + * GNU General Public License for more details. |
485 | + * |
486 | + * You should have received a copy of the GNU General Public License |
487 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
488 | + */ |
489 | + |
490 | +#include "hotkeymonitor.h" |
491 | +#include "hotkey.h" |
492 | + |
493 | +#include <QDebug> |
494 | + |
495 | +#include <X11/X.h> |
496 | +#include <X11/Xlib.h> |
497 | +#include <X11/XKBlib.h> |
498 | +#include <X11/extensions/XKB.h> |
499 | + |
500 | +#include <QX11Info> |
501 | +#include <QAbstractEventDispatcher> |
502 | + |
503 | +HotkeyMonitor::HotkeyMonitor(QObject* parent) |
504 | + : QObject(parent) |
505 | +{ |
506 | + int opcode, baseError, baseEvent; |
507 | + if (XkbQueryExtension(QX11Info::display(), &opcode, &baseEvent, |
508 | + &baseError, NULL, NULL) == False) { |
509 | + qWarning() << "Failed to initialize Xkb extension. CapsLock and NumLock" |
510 | + "active will prevent shortcuts from working."; |
511 | + } else { |
512 | + /* With this call we ignore CapsLock and NumLock when grabbing keys. */ |
513 | + XkbSetIgnoreLockMods(QX11Info::display(), XkbUseCoreKbd, |
514 | + Mod2Mask | LockMask, Mod2Mask | LockMask, |
515 | + 0, 0); |
516 | + } |
517 | + |
518 | + QAbstractEventDispatcher::instance()->setEventFilter(HotkeyMonitor::keyEventFilter); |
519 | +} |
520 | + |
521 | +HotkeyMonitor& |
522 | +HotkeyMonitor::instance() |
523 | +{ |
524 | + static HotkeyMonitor monitor; |
525 | + return monitor; |
526 | +} |
527 | + |
528 | +HotkeyMonitor::~HotkeyMonitor() |
529 | +{ |
530 | + qDeleteAll(m_hotkeys); |
531 | +} |
532 | + |
533 | + |
534 | +Hotkey* |
535 | +HotkeyMonitor::getHotkeyFor(Qt::Key key, Qt::KeyboardModifiers modifiers) |
536 | +{ |
537 | + Q_FOREACH(Hotkey* currentHotkey, m_hotkeys) { |
538 | + if (currentHotkey->key() == key && |
539 | + currentHotkey->modifiers() == modifiers) { |
540 | + return currentHotkey; |
541 | + } |
542 | + } |
543 | + |
544 | + Hotkey *hotkey = new Hotkey(key, modifiers, this); |
545 | + m_hotkeys.append(hotkey); |
546 | + return hotkey; |
547 | +} |
548 | + |
549 | +bool |
550 | +HotkeyMonitor::keyEventFilter(void* message) |
551 | +{ |
552 | + XEvent* event = static_cast<XEvent*>(message); |
553 | + if (event->type == KeyRelease || event->type == KeyPress) |
554 | + { |
555 | + XKeyEvent* key = (XKeyEvent*) event; |
556 | + HotkeyMonitor::instance().processKeyEvent(key->keycode, key->state, |
557 | + event->type == KeyPress); |
558 | + } |
559 | + return false; |
560 | +} |
561 | + |
562 | +void |
563 | +HotkeyMonitor::processKeyEvent(uint x11Keycode, uint x11Modifiers, |
564 | + bool isPressEvent) |
565 | +{ |
566 | + Q_FOREACH(Hotkey* hotkey, m_hotkeys) { |
567 | + if (hotkey->processNativeEvent(x11Keycode, x11Modifiers, isPressEvent)) { |
568 | + return; |
569 | + } |
570 | + } |
571 | + qWarning() << "Received x11 key event that wasn't processed by any hotkey:" |
572 | + << x11Keycode << x11Modifiers << ((isPressEvent) ? "Press" : "Release"); |
573 | +} |
574 | + |
575 | +#include "hotkeymonitor.moc" |
576 | |
577 | === added file 'libunity-2d-private/src/hotkeymonitor.h' |
578 | --- libunity-2d-private/src/hotkeymonitor.h 1970-01-01 00:00:00 +0000 |
579 | +++ libunity-2d-private/src/hotkeymonitor.h 2011-02-24 00:23:17 +0000 |
580 | @@ -0,0 +1,50 @@ |
581 | +/* |
582 | + * Copyright (C) 2011 Canonical, Ltd. |
583 | + * |
584 | + * Authors: |
585 | + * Ugo Riboni <ugo.riboni@canonical.com> |
586 | + * |
587 | + * This program is free software; you can redistribute it and/or modify |
588 | + * it under the terms of the GNU General Public License as published by |
589 | + * the Free Software Foundation; version 3. |
590 | + * |
591 | + * This program is distributed in the hope that it will be useful, |
592 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
593 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
594 | + * GNU General Public License for more details. |
595 | + * |
596 | + * You should have received a copy of the GNU General Public License |
597 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
598 | + */ |
599 | + |
600 | +#ifndef HotkeyMonitor_H |
601 | +#define HotkeyMonitor_H |
602 | + |
603 | +#include <QObject> |
604 | +#include <QList> |
605 | + |
606 | +class Hotkey; |
607 | + |
608 | +class HotkeyMonitor : public QObject |
609 | +{ |
610 | + Q_OBJECT |
611 | + |
612 | +public: |
613 | + static HotkeyMonitor& instance(); |
614 | + ~HotkeyMonitor(); |
615 | + |
616 | + Hotkey* getHotkeyFor(Qt::Key key, Qt::KeyboardModifiers modifiers); |
617 | + |
618 | +private: |
619 | + HotkeyMonitor(QObject* parent=0); |
620 | + |
621 | + static bool keyEventFilter(void* message); |
622 | + void processKeyEvent(uint x11Keycode, uint x11Modifiers, |
623 | + bool isPressEvent); |
624 | + |
625 | + QList<Hotkey*> m_hotkeys; |
626 | +}; |
627 | + |
628 | + |
629 | +#endif // HotkeyMonitor_H |
630 | + |
631 | |
632 | === modified file 'places/app/CMakeLists.txt' |
633 | --- places/app/CMakeLists.txt 2011-01-10 18:25:49 +0000 |
634 | +++ places/app/CMakeLists.txt 2011-02-24 00:23:17 +0000 |
635 | @@ -4,15 +4,11 @@ |
636 | |
637 | # Sources |
638 | set(places_SRCS |
639 | - keymonitor.cpp |
640 | - superkeymonitor.cpp |
641 | places.cpp |
642 | dashdeclarativeview.cpp |
643 | ) |
644 | |
645 | set(places_MOC_HDRS |
646 | - keymonitor.h |
647 | - superkeymonitor.h |
648 | dashdeclarativeview.h |
649 | ) |
650 | |
651 | |
652 | === removed file 'places/app/keymonitor.cpp' |
653 | --- places/app/keymonitor.cpp 2011-01-12 09:17:58 +0000 |
654 | +++ places/app/keymonitor.cpp 1970-01-01 00:00:00 +0000 |
655 | @@ -1,62 +0,0 @@ |
656 | -/* |
657 | - * Copyright (C) 2011 Canonical, Ltd. |
658 | - * |
659 | - * Authors: |
660 | - * Olivier Tilloy <olivier.tilloy@canonical.com> |
661 | - * |
662 | - * This program is free software; you can redistribute it and/or modify |
663 | - * it under the terms of the GNU General Public License as published by |
664 | - * the Free Software Foundation; version 3. |
665 | - * |
666 | - * This program is distributed in the hope that it will be useful, |
667 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
668 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
669 | - * GNU General Public License for more details. |
670 | - * |
671 | - * You should have received a copy of the GNU General Public License |
672 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
673 | - */ |
674 | - |
675 | -#include "keymonitor.h" |
676 | - |
677 | -#include <X11/Xlib.h> |
678 | - |
679 | -#include <QX11Info> |
680 | - |
681 | -KeyMonitor::KeyMonitor(int keycode, QObject* parent) |
682 | - : QObject(parent) |
683 | - , m_keycode(keycode) |
684 | - , m_grabbed(false) |
685 | -{ |
686 | -} |
687 | - |
688 | -KeyMonitor::~KeyMonitor() |
689 | -{ |
690 | - if (m_grabbed) { |
691 | - ungrabKey(); |
692 | - } |
693 | -} |
694 | - |
695 | -void |
696 | -KeyMonitor::grabKey() |
697 | -{ |
698 | - Display* display = QX11Info::display(); |
699 | - Window window = QX11Info::appRootWindow(); |
700 | - Bool owner = True; |
701 | - int pointer = GrabModeAsync; |
702 | - int keyboard = GrabModeAsync; |
703 | - XGrabKey(display, m_keycode, 0, window, owner, pointer, keyboard); |
704 | - /* Assume no X error. */ |
705 | - m_grabbed = true; |
706 | -} |
707 | - |
708 | -void |
709 | -KeyMonitor::ungrabKey() |
710 | -{ |
711 | - Display* display = QX11Info::display(); |
712 | - Window window = QX11Info::appRootWindow(); |
713 | - XUngrabKey(display, m_keycode, 0, window); |
714 | - /* Assume no X error. */ |
715 | - m_grabbed = false; |
716 | -} |
717 | - |
718 | |
719 | === removed file 'places/app/keymonitor.h' |
720 | --- places/app/keymonitor.h 2011-01-11 12:37:45 +0000 |
721 | +++ places/app/keymonitor.h 1970-01-01 00:00:00 +0000 |
722 | @@ -1,42 +0,0 @@ |
723 | -/* |
724 | - * Copyright (C) 2011 Canonical, Ltd. |
725 | - * |
726 | - * Authors: |
727 | - * Olivier Tilloy <olivier.tilloy@canonical.com> |
728 | - * |
729 | - * This program is free software; you can redistribute it and/or modify |
730 | - * it under the terms of the GNU General Public License as published by |
731 | - * the Free Software Foundation; version 3. |
732 | - * |
733 | - * This program is distributed in the hope that it will be useful, |
734 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
735 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
736 | - * GNU General Public License for more details. |
737 | - * |
738 | - * You should have received a copy of the GNU General Public License |
739 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
740 | - */ |
741 | - |
742 | -#ifndef KeyMonitor_H |
743 | -#define KeyMonitor_H |
744 | - |
745 | -#include <QObject> |
746 | - |
747 | -class KeyMonitor : public QObject |
748 | -{ |
749 | - Q_OBJECT |
750 | - |
751 | -public: |
752 | - KeyMonitor(int keycode, QObject* parent=0); |
753 | - ~KeyMonitor(); |
754 | - |
755 | - void grabKey(); |
756 | - void ungrabKey(); |
757 | - |
758 | -private: |
759 | - int m_keycode; |
760 | - bool m_grabbed; |
761 | -}; |
762 | - |
763 | -#endif // KeyMonitor_H |
764 | - |
765 | |
766 | === modified file 'places/app/places.cpp' |
767 | --- places/app/places.cpp 2011-02-02 16:57:00 +0000 |
768 | +++ places/app/places.cpp 2011-02-24 00:23:17 +0000 |
769 | @@ -30,8 +30,6 @@ |
770 | #include <X11/Xlib.h> |
771 | |
772 | #include "dashdeclarativeview.h" |
773 | -#include "superkeymonitor.h" |
774 | - |
775 | #include "config.h" |
776 | |
777 | /* Register a D-Bus service for activation and deactivation of the dash */ |
778 | @@ -43,7 +41,7 @@ |
779 | return false; |
780 | } |
781 | /* FIXME: use an adaptor class in order not to expose all of the view's |
782 | - properties and methods. */ |
783 | + properties and methods. */\ |
784 | if (!bus.registerObject("/Dash", view, QDBusConnection::ExportAllContents)) { |
785 | qCritical() << "Failed to register /Dash, this should not happen!"; |
786 | return false; |
787 | @@ -61,33 +59,6 @@ |
788 | return true; |
789 | } |
790 | |
791 | -static DashDeclarativeView* getView() |
792 | -{ |
793 | - QVariant viewProperty = QApplication::instance()->property("view"); |
794 | - return viewProperty.value<DashDeclarativeView*>(); |
795 | -} |
796 | - |
797 | -static bool eventFilter(void* message) |
798 | -{ |
799 | - XEvent* event = static_cast<XEvent*>(message); |
800 | - if (event->type == KeyRelease) |
801 | - { |
802 | - XKeyEvent* key = (XKeyEvent*) event; |
803 | - uint code = key->keycode; |
804 | - if (code == SuperKeyMonitor::SUPER_L || code == SuperKeyMonitor::SUPER_R) { |
805 | - /* Super (aka the "windows" key) shows/hides the dash. */ |
806 | - DashDeclarativeView* view = getView(); |
807 | - if (view->active()) { |
808 | - view->setActive(false); |
809 | - } |
810 | - else { |
811 | - view->activateHome(); |
812 | - } |
813 | - } |
814 | - } |
815 | - return false; |
816 | -} |
817 | - |
818 | int main(int argc, char *argv[]) |
819 | { |
820 | QApplication::setApplicationName("Unity 2D Dash"); |
821 | @@ -142,10 +113,6 @@ |
822 | view.fitToAvailableSpace(current_screen); |
823 | QObject::connect(QApplication::desktop(), SIGNAL(workAreaResized(int)), &view, SLOT(fitToAvailableSpace(int))); |
824 | |
825 | - /* Grab the "super" keys */ |
826 | - SuperKeyMonitor superKeys; /* Just needs to be instantiated to work. */ |
827 | - QAbstractEventDispatcher::instance()->setEventFilter(eventFilter); |
828 | - |
829 | application.setProperty("view", QVariant::fromValue(&view)); |
830 | return application.exec(); |
831 | } |
832 | |
833 | === removed file 'places/app/superkeymonitor.cpp' |
834 | --- places/app/superkeymonitor.cpp 2011-01-11 12:47:22 +0000 |
835 | +++ places/app/superkeymonitor.cpp 1970-01-01 00:00:00 +0000 |
836 | @@ -1,79 +0,0 @@ |
837 | -/* |
838 | - * Copyright (C) 2011 Canonical, Ltd. |
839 | - * |
840 | - * Authors: |
841 | - * Olivier Tilloy <olivier.tilloy@canonical.com> |
842 | - * |
843 | - * This program is free software; you can redistribute it and/or modify |
844 | - * it under the terms of the GNU General Public License as published by |
845 | - * the Free Software Foundation; version 3. |
846 | - * |
847 | - * This program is distributed in the hope that it will be useful, |
848 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
849 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
850 | - * GNU General Public License for more details. |
851 | - * |
852 | - * You should have received a copy of the GNU General Public License |
853 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
854 | - */ |
855 | - |
856 | -#include "superkeymonitor.h" |
857 | -#include "keymonitor.h" |
858 | - |
859 | -#include "gconfitem-qml-wrapper.h" |
860 | - |
861 | -SuperKeyMonitor::SuperKeyMonitor() |
862 | -{ |
863 | - m_left = new KeyMonitor(SUPER_L, this); |
864 | - m_right = new KeyMonitor(SUPER_R, this); |
865 | - |
866 | - m_enable_setting = new GConfItemQmlWrapper(this); |
867 | - m_enable_setting->setKey("/desktop/unity/launcher/super_key_enable"); |
868 | - if (getEnableSettingValue()) { |
869 | - startMonitoring(); |
870 | - } |
871 | - connect(m_enable_setting, SIGNAL(valueChanged()), SLOT(slotEnableSettingChanged())); |
872 | -} |
873 | - |
874 | -SuperKeyMonitor::~SuperKeyMonitor() |
875 | -{ |
876 | -} |
877 | - |
878 | -bool |
879 | -SuperKeyMonitor::getEnableSettingValue() const |
880 | -{ |
881 | - QVariant value = m_enable_setting->getValue(); |
882 | - if (value.isValid()) { |
883 | - return value.toBool(); |
884 | - } |
885 | - else { |
886 | - /* The key is not set, assume true. */ |
887 | - return true; |
888 | - } |
889 | -} |
890 | - |
891 | -void |
892 | -SuperKeyMonitor::slotEnableSettingChanged() |
893 | -{ |
894 | - if (getEnableSettingValue()) { |
895 | - startMonitoring(); |
896 | - } |
897 | - else { |
898 | - stopMonitoring(); |
899 | - } |
900 | -} |
901 | - |
902 | -void |
903 | -SuperKeyMonitor::startMonitoring() |
904 | -{ |
905 | - m_left->grabKey(); |
906 | - m_right->grabKey(); |
907 | -} |
908 | - |
909 | -void |
910 | -SuperKeyMonitor::stopMonitoring() |
911 | -{ |
912 | - m_left->ungrabKey(); |
913 | - m_right->ungrabKey(); |
914 | -} |
915 | - |
916 | |
917 | === removed file 'places/app/superkeymonitor.h' |
918 | --- places/app/superkeymonitor.h 2011-01-11 12:35:07 +0000 |
919 | +++ places/app/superkeymonitor.h 1970-01-01 00:00:00 +0000 |
920 | @@ -1,55 +0,0 @@ |
921 | -/* |
922 | - * Copyright (C) 2011 Canonical, Ltd. |
923 | - * |
924 | - * Authors: |
925 | - * Olivier Tilloy <olivier.tilloy@canonical.com> |
926 | - * |
927 | - * This program is free software; you can redistribute it and/or modify |
928 | - * it under the terms of the GNU General Public License as published by |
929 | - * the Free Software Foundation; version 3. |
930 | - * |
931 | - * This program is distributed in the hope that it will be useful, |
932 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
933 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
934 | - * GNU General Public License for more details. |
935 | - * |
936 | - * You should have received a copy of the GNU General Public License |
937 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
938 | - */ |
939 | - |
940 | -#ifndef SuperKeyMonitor_H |
941 | -#define SuperKeyMonitor_H |
942 | - |
943 | -#include <QObject> |
944 | - |
945 | -class KeyMonitor; |
946 | -class GConfItemQmlWrapper; |
947 | - |
948 | -class SuperKeyMonitor : public QObject |
949 | -{ |
950 | - Q_OBJECT |
951 | - |
952 | -public: |
953 | - SuperKeyMonitor(); |
954 | - ~SuperKeyMonitor(); |
955 | - |
956 | - static const uint SUPER_L = 133; |
957 | - static const uint SUPER_R = 134; |
958 | - |
959 | -private: |
960 | - KeyMonitor* m_left; |
961 | - KeyMonitor* m_right; |
962 | - |
963 | - GConfItemQmlWrapper* m_enable_setting; |
964 | - |
965 | - bool getEnableSettingValue() const; |
966 | - |
967 | - void startMonitoring(); |
968 | - void stopMonitoring(); |
969 | - |
970 | -private Q_SLOTS: |
971 | - void slotEnableSettingChanged(); |
972 | -}; |
973 | - |
974 | -#endif // SuperKeyMonitor_H |
975 | - |
Attempt to merge into lp:unity-2d failed due to conflicts:
text conflict in launcher/ LauncherItem. qml app/CMakeLists. txt 2d-private/ src/CMakeLists. txt app/places. cpp
text conflict in launcher/
text conflict in libunity-
text conflict in places/