Merge lp:~uriboni/unity-2d/launcher-keyboard-shortcuts into lp:unity-2d/3.0

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
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 :

Attempt to merge into lp:unity-2d failed due to conflicts:

text conflict in launcher/LauncherItem.qml
text conflict in launcher/app/CMakeLists.txt
text conflict in libunity-2d-private/src/CMakeLists.txt
text conflict in places/app/places.cpp

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-

Subscribers

People subscribed via source and target branches

to all changes: