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
=== modified file 'launcher/LauncherItem.qml'
--- launcher/LauncherItem.qml 2011-02-18 14:02:46 +0000
+++ launcher/LauncherItem.qml 2011-02-24 00:23:17 +0000
@@ -53,6 +53,9 @@
53 property bool backgroundFromIcon53 property bool backgroundFromIcon
54 property color defaultBackgroundColor: "#333333"54 property color defaultBackgroundColor: "#333333"
5555
56 property alias shortcutVisible: shortcut.visible
57 property alias shortcutText: shortcutText.text
58
56 property int pips: 059 property int pips: 0
57 property string pipSource: engineBaseUrl + "artwork/launcher_" +60 property string pipSource: engineBaseUrl + "artwork/launcher_" +
58 ((pips <= 1) ? "arrow" : "pip") + "_ltr.png"61 ((pips <= 1) ? "arrow" : "pip") + "_ltr.png"
@@ -263,6 +266,21 @@
263 }266 }
264 }267 }
265268
269 Rectangle {
270 id: shortcut
271 anchors.centerIn: parent
272 color: "#B3000000" // 0.7 opacity on black
273 radius: 2
274 width: 22
275 height: 22
276
277 Text {
278 id: shortcutText
279 anchors.centerIn: parent
280 color: "white"
281 }
282 }
283
266 Image {284 Image {
267 id: emblemIcon285 id: emblemIcon
268 anchors.left: parent.left286 anchors.left: parent.left
269287
=== modified file 'launcher/LauncherList.qml'
--- launcher/LauncherList.qml 2011-02-21 10:23:45 +0000
+++ launcher/LauncherList.qml 2011-02-24 00:23:17 +0000
@@ -31,6 +31,10 @@
31 emblem: (noOverlays && item.emblem) ? "image://icons/" + item.emblem : ""31 emblem: (noOverlays && item.emblem) ? "image://icons/" + item.emblem : ""
32 emblemVisible: (noOverlays) ? false : item.emblemVisible32 emblemVisible: (noOverlays) ? false : item.emblemVisible
3333
34 shortcutVisible: item.toString().indexOf("LauncherApplication") == 0 &&
35 index <= 9 && launcherView.superKeyPressed
36 shortcutText: index + 1
37
34 /* Best way I could find to check if the item is an application or the38 /* Best way I could find to check if the item is an application or the
35 workspaces switcher. There may be something cleaner and better. */39 workspaces switcher. There may be something cleaner and better. */
36 backgroundFromIcon: item.toString().indexOf("LauncherApplication") == 0 ||40 backgroundFromIcon: item.toString().indexOf("LauncherApplication") == 0 ||
@@ -121,5 +125,16 @@
121 /* Not all items are applications. */125 /* Not all items are applications. */
122 ignoreUnknownSignals: true126 ignoreUnknownSignals: true
123 }127 }
128
129 Connections {
130 target: launcherView
131 onKeyboardShortcutPressed: {
132 /* Only applications can be launched by keyboard shortcuts */
133 if (item.toString().indexOf("LauncherApplication") == 0 && index == itemIndex) {
134 item.menu.hide()
135 item.activate()
136 }
137 }
138 }
124 }139 }
125}140}
126141
=== modified file 'launcher/app/CMakeLists.txt'
--- launcher/app/CMakeLists.txt 2011-02-16 02:21:24 +0000
+++ launcher/app/CMakeLists.txt 2011-02-24 00:23:17 +0000
@@ -2,6 +2,7 @@
2pkg_check_modules(GTK REQUIRED gtk+-2.0)2pkg_check_modules(GTK REQUIRED gtk+-2.0)
3pkg_check_modules(X11 REQUIRED x11)3pkg_check_modules(X11 REQUIRED x11)
4pkg_check_modules(GEIS REQUIRED libutouch-geis)4pkg_check_modules(GEIS REQUIRED libutouch-geis)
5pkg_check_modules(QTGCONF REQUIRED libqtgconf)
56
6# Sources7# Sources
7set(launcher_SRCS8set(launcher_SRCS
@@ -34,6 +35,7 @@
34 ${GTK_INCLUDE_DIRS}35 ${GTK_INCLUDE_DIRS}
35 ${X11_INCLUDE_DIRS}36 ${X11_INCLUDE_DIRS}
36 ${GEIS_INCLUDE_DIRS}37 ${GEIS_INCLUDE_DIRS}
38 ${QTGCONF_INCLUDE_DIRS}
37 ${libunity-2d-private_SOURCE_DIR}/src39 ${libunity-2d-private_SOURCE_DIR}/src
38 )40 )
3941
@@ -45,6 +47,7 @@
45 ${GTK_LDFLAGS}47 ${GTK_LDFLAGS}
46 ${X11_LDFLAGS}48 ${X11_LDFLAGS}
47 ${GEIS_LDFLAGS}49 ${GEIS_LDFLAGS}
50 ${QTGCONF_LDFLAGS}
48 unity-2d-private51 unity-2d-private
49 )52 )
5053
5154
=== modified file 'launcher/app/launcher.cpp'
--- launcher/app/launcher.cpp 2011-02-22 16:54:40 +0000
+++ launcher/app/launcher.cpp 2011-02-24 00:23:17 +0000
@@ -29,6 +29,8 @@
29#include <QDeclarativeContext>29#include <QDeclarativeContext>
30#include <QDir>30#include <QDir>
3131
32#include <unity2dapplication.h>
33
32#include "config.h"34#include "config.h"
33#include "launcherview.h"35#include "launcherview.h"
34#include "launchercontrol.h"36#include "launchercontrol.h"
@@ -53,7 +55,7 @@
53 */55 */
54 QApplication::setGraphicsSystem("raster");56 QApplication::setGraphicsSystem("raster");
55 QApplication::setColorSpec(QApplication::ManyColor);57 QApplication::setColorSpec(QApplication::ManyColor);
56 QApplication application(argc, argv);58 Unity2dApplication application(argc, argv);
5759
58 GnomeSessionClient client(INSTALL_PREFIX "/share/applications/unity-2d-launcher.desktop");60 GnomeSessionClient client(INSTALL_PREFIX "/share/applications/unity-2d-launcher.desktop");
59 client.connectToSessionManager();61 client.connectToSessionManager();
6062
=== modified file 'launcher/app/launcherview.cpp'
--- launcher/app/launcherview.cpp 2011-02-16 11:11:46 +0000
+++ launcher/app/launcherview.cpp 2011-02-24 00:23:17 +0000
@@ -35,13 +35,95 @@
35#include <X11/Xatom.h>35#include <X11/Xatom.h>
3636
37#include "dragdropevent.h"37#include "dragdropevent.h"
38#include <keyboardmodifiersmonitor.h>
39#include <hotkey.h>
40#include <hotkeymonitor.h>
3841
39LauncherView::LauncherView() :42LauncherView::LauncherView() :
40 QDeclarativeView(), m_resizing(false), m_reserved(false),43 QDeclarativeView(), m_resizing(false), m_reserved(false),
41 m_dndCurrentLauncherItem(NULL), m_dndCurrentLauncherItemAccepted(false),44 m_dndCurrentLauncherItem(NULL), m_dndCurrentLauncherItemAccepted(false),
42 m_dndAccepted(false)45 m_dndAccepted(false), m_superKeyPressed(false)
43{46{
44 setAcceptDrops(true);47 setAcceptDrops(true);
48
49 m_enableSuperKey.setKey("/desktop/unity/launcher/super_key_enable");
50 QObject::connect(&m_enableSuperKey, SIGNAL(valueChanged()),
51 this, SLOT(updateSuperKeyMonitoring()));
52 updateSuperKeyMonitoring();
53}
54
55void
56LauncherView::updateSuperKeyMonitoring()
57{
58 KeyboardModifiersMonitor *modifiersMonitor = KeyboardModifiersMonitor::instance();
59
60 QVariant value = m_enableSuperKey.getValue();
61 if (!value.isValid() || value.toBool() == true) {
62 QObject::connect(modifiersMonitor,
63 SIGNAL(keyboardModifiersChanged(Qt::KeyboardModifiers)),
64 this, SLOT(setHotkeysForModifiers(Qt::KeyboardModifiers)));
65 setHotkeysForModifiers(modifiersMonitor->keyboardModifiers());
66 } else {
67 QObject::disconnect(modifiersMonitor,
68 SIGNAL(keyboardModifiersChanged(Qt::KeyboardModifiers)),
69 this, SLOT(setHotkeysForModifiers(Qt::KeyboardModifiers)));
70 m_superKeyPressed = false;
71 Q_EMIT superKeyPressedChanged(false);
72 changeKeyboardShortcutsState(false);
73 }
74}
75
76void
77LauncherView::setHotkeysForModifiers(Qt::KeyboardModifiers modifiers)
78{
79 /* This is the new new state of the Super key (AKA Meta key), while
80 m_superKeyPressed is the previous state of the key at the last modifiers change. */
81 bool superKeyPressed = modifiers.testFlag(Qt::MetaModifier);
82
83 if (m_superKeyPressed != superKeyPressed) {
84 m_superKeyPressed = superKeyPressed;
85 Q_EMIT superKeyPressedChanged(m_superKeyPressed);
86 changeKeyboardShortcutsState(m_superKeyPressed);
87 }
88}
89
90void
91LauncherView::changeKeyboardShortcutsState(bool enabled)
92{
93 /* We are going to connect 10 Hotkeys, but to make things simpler on the QML
94 side we want to have only one signal with the number of the item that needs to
95 be activated in response to the hotkey press.
96 So we connect all of them to a single slot where we emit a single signal with
97 an index based on which Hotkey was the sender. */
98 Qt::Key key = Qt::Key_0;
99 while (key <= Qt::Key_9) {
100 Hotkey *hotkey = HotkeyMonitor::instance().getHotkeyFor(key, Qt::MetaModifier);
101
102 if (enabled) {
103 QObject::connect(hotkey, SIGNAL(pressed()), this, SLOT(forwardHotkey()));
104 } else {
105 QObject::disconnect(hotkey, SIGNAL(pressed()), this, SLOT(forwardHotkey()));
106 }
107 key = (Qt::Key) (key + 1);
108 }
109}
110
111void
112LauncherView::forwardHotkey()
113{
114 Hotkey *hotkey = qobject_cast<Hotkey*>(sender());
115 if (hotkey != NULL) {
116 /* Shortcuts from 1 to 9 should activate the items with index
117 from 0 to 8. Shortcut for 0 should activate item with index 10.
118 In other words, the indexes are activated in the same order as
119 the keys appear on a standard keyboard. */
120 int itemIndex = hotkey->key() - Qt::Key_0;
121 itemIndex = (itemIndex == 0) ? 9 : itemIndex - 1;
122
123 if (itemIndex >= 0 && itemIndex <= 10) {
124 Q_EMIT keyboardShortcutPressed(itemIndex);
125 }
126 }
45}127}
46128
47QGraphicsObject*129QGraphicsObject*
48130
=== modified file 'launcher/app/launcherview.h'
--- launcher/app/launcherview.h 2011-02-16 11:11:46 +0000
+++ launcher/app/launcherview.h 2011-02-24 00:23:17 +0000
@@ -24,23 +24,36 @@
24#include <QUrl>24#include <QUrl>
25#include <QList>25#include <QList>
26#include <QDragEnterEvent>26#include <QDragEnterEvent>
27#include "gconfitem-qml-wrapper.h"
2728
28class QGraphicsObject;29class QGraphicsObject;
2930
30class LauncherView : public QDeclarativeView31class LauncherView : public QDeclarativeView
31{32{
32 Q_OBJECT33 Q_OBJECT
34 Q_PROPERTY(bool superKeyPressed READ superKeyPressed
35 NOTIFY superKeyPressedChanged)
3336
34public:37public:
35 explicit LauncherView();38 explicit LauncherView();
36 Q_INVOKABLE QList<QVariant> getColorsFromIcon(QUrl source, QSize size) const;39 Q_INVOKABLE QList<QVariant> getColorsFromIcon(QUrl source, QSize size) const;
3740
38signals:41 bool superKeyPressed() const { return m_superKeyPressed; }
42
43Q_SIGNALS:
39 void desktopFileDropped(QString path);44 void desktopFileDropped(QString path);
40 void webpageUrlDropped(const QUrl& url);45 void webpageUrlDropped(const QUrl& url);
46 void keyboardShortcutPressed(int itemIndex);
47 void superKeyPressedChanged(bool superKeyPressed);
48
49private Q_SLOTS:
50 void setHotkeysForModifiers(Qt::KeyboardModifiers modifiers);
51 void forwardHotkey();
52 void updateSuperKeyMonitoring();
4153
42private:54private:
43 QList<QUrl> getEventUrls(QDropEvent*);55 QList<QUrl> getEventUrls(QDropEvent*);
56 void changeKeyboardShortcutsState(bool enabled);
4457
45 /* Whether the launcher is already being resized */58 /* Whether the launcher is already being resized */
46 bool m_resizing;59 bool m_resizing;
@@ -63,6 +76,9 @@
63 bool m_dndCurrentLauncherItemAccepted;76 bool m_dndCurrentLauncherItemAccepted;
64 /* Whether the launcher itself handles the current dnd event */77 /* Whether the launcher itself handles the current dnd event */
65 bool m_dndAccepted;78 bool m_dndAccepted;
79
80 GConfItemQmlWrapper m_enableSuperKey;
81 bool m_superKeyPressed;
66};82};
6783
68#endif // LAUNCHERVIEW84#endif // LAUNCHERVIEW
6985
=== modified file 'launcher/tests/CMakeLists.txt'
--- launcher/tests/CMakeLists.txt 2011-01-27 16:23:33 +0000
+++ launcher/tests/CMakeLists.txt 2011-02-24 00:23:17 +0000
@@ -22,6 +22,7 @@
22 ${CMAKE_CURRENT_SOURCE_DIR}/../UnityApplications22 ${CMAKE_CURRENT_SOURCE_DIR}/../UnityApplications
23 ${CMAKE_CURRENT_BINARY_DIR}23 ${CMAKE_CURRENT_BINARY_DIR}
24 ${QT_QTTEST_INCLUDE_DIR}24 ${QT_QTTEST_INCLUDE_DIR}
25 ${QTGCONF_INCLUDE_DIRS}
25 )26 )
2627
27enable_testing()28enable_testing()
2829
=== modified file 'libunity-2d-private/src/CMakeLists.txt'
--- libunity-2d-private/src/CMakeLists.txt 2011-02-11 11:37:55 +0000
+++ libunity-2d-private/src/CMakeLists.txt 2011-02-24 00:23:17 +0000
@@ -2,6 +2,8 @@
2set(libunity-2d-private_SRCS2set(libunity-2d-private_SRCS
3 gnomesessionclient.cpp3 gnomesessionclient.cpp
4 keyboardmodifiersmonitor.cpp4 keyboardmodifiersmonitor.cpp
5 hotkeymonitor.cpp
6 hotkey.cpp
5 unity2dapplication.cpp7 unity2dapplication.cpp
6 unity2dpanel.cpp8 unity2dpanel.cpp
7 mimedata.cpp9 mimedata.cpp
810
=== added file 'libunity-2d-private/src/hotkey.cpp'
--- libunity-2d-private/src/hotkey.cpp 1970-01-01 00:00:00 +0000
+++ libunity-2d-private/src/hotkey.cpp 2011-02-24 00:23:17 +0000
@@ -0,0 +1,101 @@
1/*
2 * Copyright (C) 2011 Canonical, Ltd.
3 *
4 * Authors:
5 * Ugo Riboni <ugo.riboni@canonical.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "hotkey.h"
21
22#include <QX11Info>
23#include <QDebug>
24#include <QKeySequence>
25
26#include <X11/Xlib.h>
27#include <X11/XKBlib.h>
28#include <X11/extensions/XKB.h>
29
30Hotkey::Hotkey(Qt::Key key, Qt::KeyboardModifiers modifiers, QObject *parent) :
31 QObject(parent), m_connections(0),
32 m_key(key), m_modifiers(modifiers),
33 m_x11key(0), m_x11modifiers(0)
34{
35 /* Translate the QT modifiers to X11 modifiers */
36
37 if (modifiers.testFlag(Qt::ShiftModifier)) {
38 m_x11modifiers |= ShiftMask ;
39 }
40 if (modifiers.testFlag(Qt::ControlModifier)) {
41 m_x11modifiers |= ControlMask ;
42 }
43 if (modifiers.testFlag(Qt::AltModifier)) {
44 m_x11modifiers |= Mod1Mask;
45 }
46 if (modifiers.testFlag(Qt::MetaModifier)) {
47 m_x11modifiers |= Mod4Mask;
48 }
49
50 /* Translate the QT key to X11 keycode */
51
52 /* QKeySequence can be used to translate a Qt::Key in a format that is
53 understood by XStringToKeysym if the sequence is composed only by the key */
54 QString keyString = QKeySequence(key).toString();
55 KeySym keysym = XStringToKeysym(keyString.toLatin1().data());
56 if (keysym == NoSymbol) {
57 qWarning() << "Could not convert" << keyString << "to an x11 keysym";
58 } else {
59 m_x11key = XKeysymToKeycode(QX11Info::display(), keysym);
60 if (m_x11key == 0) {
61 qWarning() << "Could not get keycode for keysym" << keysym
62 << "(" << keyString << ")";
63 }
64 }
65}
66
67void
68Hotkey::connectNotify(const char * signal)
69{
70 Q_UNUSED(signal);
71 if (m_connections == 0) {
72 qDebug() << "Grabbing hotkey" << QKeySequence(m_key | m_modifiers).toString();
73 XGrabKey(QX11Info::display(), m_x11key, m_x11modifiers,
74 QX11Info::appRootWindow(), True, GrabModeAsync, GrabModeAsync);
75 }
76 m_connections++;
77}
78
79void
80Hotkey::disconnectNotify(const char * signal)
81{
82 Q_UNUSED(signal);
83 if (m_connections == 1) {
84 qDebug() << "Ungrabbing hotkey" << QKeySequence(m_key | m_modifiers).toString();
85 XUngrabKey(QX11Info::display(), m_x11key, m_x11modifiers,
86 QX11Info::appRootWindow());
87 }
88 m_connections--;
89}
90
91bool
92Hotkey::processNativeEvent(uint x11Keycode, uint x11Modifiers, bool isPressEvent)
93{
94 if (x11Keycode == m_x11key && x11Modifiers == m_x11modifiers) {
95 Q_EMIT (isPressEvent) ? pressed() : released();
96 return true;
97 }
98 return false;
99}
100
101#include "hotkey.moc"
0102
=== added file 'libunity-2d-private/src/hotkey.h'
--- libunity-2d-private/src/hotkey.h 1970-01-01 00:00:00 +0000
+++ libunity-2d-private/src/hotkey.h 2011-02-24 00:23:17 +0000
@@ -0,0 +1,59 @@
1/*
2 * Copyright (C) 2011 Canonical, Ltd.
3 *
4 * Authors:
5 * Ugo Riboni <ugo.riboni@canonical.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifndef Hotkey_H
21#define Hotkey_H
22
23#include <QObject>
24
25class Hotkey : public QObject
26{
27 friend class HotkeyMonitor;
28
29 Q_OBJECT
30 Q_PROPERTY(Qt::Key key READ key NOTIFY keyChanged)
31 Q_PROPERTY(Qt::KeyboardModifiers modifiers READ modifiers NOTIFY modifiersChanged)
32
33public:
34 Qt::Key key() const { return m_key; }
35 Qt::KeyboardModifiers modifiers() const { return m_modifiers; }
36
37Q_SIGNALS:
38 void keyChanged(Qt::Key key);
39 void modifiersChanged(Qt::KeyboardModifiers modifiers);
40 void pressed();
41 void released();
42
43protected:
44 virtual void connectNotify(const char * signal);
45 virtual void disconnectNotify(const char * signal);
46
47private:
48 Hotkey(Qt::Key key, Qt::KeyboardModifiers modifiers, QObject *parent);
49 bool processNativeEvent(uint x11Keycode, uint x11Modifiers, bool isPressEvent);
50
51private:
52 uint m_connections;
53 Qt::Key m_key;
54 Qt::KeyboardModifiers m_modifiers;
55 uint m_x11key;
56 uint m_x11modifiers;
57};
58
59#endif // Hotkey_H
060
=== added file 'libunity-2d-private/src/hotkeymonitor.cpp'
--- libunity-2d-private/src/hotkeymonitor.cpp 1970-01-01 00:00:00 +0000
+++ libunity-2d-private/src/hotkeymonitor.cpp 2011-02-24 00:23:17 +0000
@@ -0,0 +1,105 @@
1/*
2 * Copyright (C) 2011 Canonical, Ltd.
3 *
4 * Authors:
5 * Ugo Riboni <ugo.riboni@canonical.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "hotkeymonitor.h"
21#include "hotkey.h"
22
23#include <QDebug>
24
25#include <X11/X.h>
26#include <X11/Xlib.h>
27#include <X11/XKBlib.h>
28#include <X11/extensions/XKB.h>
29
30#include <QX11Info>
31#include <QAbstractEventDispatcher>
32
33HotkeyMonitor::HotkeyMonitor(QObject* parent)
34 : QObject(parent)
35{
36 int opcode, baseError, baseEvent;
37 if (XkbQueryExtension(QX11Info::display(), &opcode, &baseEvent,
38 &baseError, NULL, NULL) == False) {
39 qWarning() << "Failed to initialize Xkb extension. CapsLock and NumLock"
40 "active will prevent shortcuts from working.";
41 } else {
42 /* With this call we ignore CapsLock and NumLock when grabbing keys. */
43 XkbSetIgnoreLockMods(QX11Info::display(), XkbUseCoreKbd,
44 Mod2Mask | LockMask, Mod2Mask | LockMask,
45 0, 0);
46 }
47
48 QAbstractEventDispatcher::instance()->setEventFilter(HotkeyMonitor::keyEventFilter);
49}
50
51HotkeyMonitor&
52HotkeyMonitor::instance()
53{
54 static HotkeyMonitor monitor;
55 return monitor;
56}
57
58HotkeyMonitor::~HotkeyMonitor()
59{
60 qDeleteAll(m_hotkeys);
61}
62
63
64Hotkey*
65HotkeyMonitor::getHotkeyFor(Qt::Key key, Qt::KeyboardModifiers modifiers)
66{
67 Q_FOREACH(Hotkey* currentHotkey, m_hotkeys) {
68 if (currentHotkey->key() == key &&
69 currentHotkey->modifiers() == modifiers) {
70 return currentHotkey;
71 }
72 }
73
74 Hotkey *hotkey = new Hotkey(key, modifiers, this);
75 m_hotkeys.append(hotkey);
76 return hotkey;
77}
78
79bool
80HotkeyMonitor::keyEventFilter(void* message)
81{
82 XEvent* event = static_cast<XEvent*>(message);
83 if (event->type == KeyRelease || event->type == KeyPress)
84 {
85 XKeyEvent* key = (XKeyEvent*) event;
86 HotkeyMonitor::instance().processKeyEvent(key->keycode, key->state,
87 event->type == KeyPress);
88 }
89 return false;
90}
91
92void
93HotkeyMonitor::processKeyEvent(uint x11Keycode, uint x11Modifiers,
94 bool isPressEvent)
95{
96 Q_FOREACH(Hotkey* hotkey, m_hotkeys) {
97 if (hotkey->processNativeEvent(x11Keycode, x11Modifiers, isPressEvent)) {
98 return;
99 }
100 }
101 qWarning() << "Received x11 key event that wasn't processed by any hotkey:"
102 << x11Keycode << x11Modifiers << ((isPressEvent) ? "Press" : "Release");
103}
104
105#include "hotkeymonitor.moc"
0106
=== added file 'libunity-2d-private/src/hotkeymonitor.h'
--- libunity-2d-private/src/hotkeymonitor.h 1970-01-01 00:00:00 +0000
+++ libunity-2d-private/src/hotkeymonitor.h 2011-02-24 00:23:17 +0000
@@ -0,0 +1,50 @@
1/*
2 * Copyright (C) 2011 Canonical, Ltd.
3 *
4 * Authors:
5 * Ugo Riboni <ugo.riboni@canonical.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifndef HotkeyMonitor_H
21#define HotkeyMonitor_H
22
23#include <QObject>
24#include <QList>
25
26class Hotkey;
27
28class HotkeyMonitor : public QObject
29{
30 Q_OBJECT
31
32public:
33 static HotkeyMonitor& instance();
34 ~HotkeyMonitor();
35
36 Hotkey* getHotkeyFor(Qt::Key key, Qt::KeyboardModifiers modifiers);
37
38private:
39 HotkeyMonitor(QObject* parent=0);
40
41 static bool keyEventFilter(void* message);
42 void processKeyEvent(uint x11Keycode, uint x11Modifiers,
43 bool isPressEvent);
44
45 QList<Hotkey*> m_hotkeys;
46};
47
48
49#endif // HotkeyMonitor_H
50
051
=== modified file 'places/app/CMakeLists.txt'
--- places/app/CMakeLists.txt 2011-01-10 18:25:49 +0000
+++ places/app/CMakeLists.txt 2011-02-24 00:23:17 +0000
@@ -4,15 +4,11 @@
44
5# Sources5# Sources
6set(places_SRCS6set(places_SRCS
7 keymonitor.cpp
8 superkeymonitor.cpp
9 places.cpp7 places.cpp
10 dashdeclarativeview.cpp8 dashdeclarativeview.cpp
11 )9 )
1210
13set(places_MOC_HDRS11set(places_MOC_HDRS
14 keymonitor.h
15 superkeymonitor.h
16 dashdeclarativeview.h12 dashdeclarativeview.h
17 )13 )
1814
1915
=== removed file 'places/app/keymonitor.cpp'
--- places/app/keymonitor.cpp 2011-01-12 09:17:58 +0000
+++ places/app/keymonitor.cpp 1970-01-01 00:00:00 +0000
@@ -1,62 +0,0 @@
1/*
2 * Copyright (C) 2011 Canonical, Ltd.
3 *
4 * Authors:
5 * Olivier Tilloy <olivier.tilloy@canonical.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "keymonitor.h"
21
22#include <X11/Xlib.h>
23
24#include <QX11Info>
25
26KeyMonitor::KeyMonitor(int keycode, QObject* parent)
27 : QObject(parent)
28 , m_keycode(keycode)
29 , m_grabbed(false)
30{
31}
32
33KeyMonitor::~KeyMonitor()
34{
35 if (m_grabbed) {
36 ungrabKey();
37 }
38}
39
40void
41KeyMonitor::grabKey()
42{
43 Display* display = QX11Info::display();
44 Window window = QX11Info::appRootWindow();
45 Bool owner = True;
46 int pointer = GrabModeAsync;
47 int keyboard = GrabModeAsync;
48 XGrabKey(display, m_keycode, 0, window, owner, pointer, keyboard);
49 /* Assume no X error. */
50 m_grabbed = true;
51}
52
53void
54KeyMonitor::ungrabKey()
55{
56 Display* display = QX11Info::display();
57 Window window = QX11Info::appRootWindow();
58 XUngrabKey(display, m_keycode, 0, window);
59 /* Assume no X error. */
60 m_grabbed = false;
61}
62
630
=== removed file 'places/app/keymonitor.h'
--- places/app/keymonitor.h 2011-01-11 12:37:45 +0000
+++ places/app/keymonitor.h 1970-01-01 00:00:00 +0000
@@ -1,42 +0,0 @@
1/*
2 * Copyright (C) 2011 Canonical, Ltd.
3 *
4 * Authors:
5 * Olivier Tilloy <olivier.tilloy@canonical.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifndef KeyMonitor_H
21#define KeyMonitor_H
22
23#include <QObject>
24
25class KeyMonitor : public QObject
26{
27 Q_OBJECT
28
29public:
30 KeyMonitor(int keycode, QObject* parent=0);
31 ~KeyMonitor();
32
33 void grabKey();
34 void ungrabKey();
35
36private:
37 int m_keycode;
38 bool m_grabbed;
39};
40
41#endif // KeyMonitor_H
42
430
=== modified file 'places/app/places.cpp'
--- places/app/places.cpp 2011-02-02 16:57:00 +0000
+++ places/app/places.cpp 2011-02-24 00:23:17 +0000
@@ -30,8 +30,6 @@
30#include <X11/Xlib.h>30#include <X11/Xlib.h>
3131
32#include "dashdeclarativeview.h"32#include "dashdeclarativeview.h"
33#include "superkeymonitor.h"
34
35#include "config.h"33#include "config.h"
3634
37/* Register a D-Bus service for activation and deactivation of the dash */35/* Register a D-Bus service for activation and deactivation of the dash */
@@ -43,7 +41,7 @@
43 return false;41 return false;
44 }42 }
45 /* FIXME: use an adaptor class in order not to expose all of the view's43 /* FIXME: use an adaptor class in order not to expose all of the view's
46 properties and methods. */44 properties and methods. */\
47 if (!bus.registerObject("/Dash", view, QDBusConnection::ExportAllContents)) {45 if (!bus.registerObject("/Dash", view, QDBusConnection::ExportAllContents)) {
48 qCritical() << "Failed to register /Dash, this should not happen!";46 qCritical() << "Failed to register /Dash, this should not happen!";
49 return false;47 return false;
@@ -61,33 +59,6 @@
61 return true;59 return true;
62}60}
6361
64static DashDeclarativeView* getView()
65{
66 QVariant viewProperty = QApplication::instance()->property("view");
67 return viewProperty.value<DashDeclarativeView*>();
68}
69
70static bool eventFilter(void* message)
71{
72 XEvent* event = static_cast<XEvent*>(message);
73 if (event->type == KeyRelease)
74 {
75 XKeyEvent* key = (XKeyEvent*) event;
76 uint code = key->keycode;
77 if (code == SuperKeyMonitor::SUPER_L || code == SuperKeyMonitor::SUPER_R) {
78 /* Super (aka the "windows" key) shows/hides the dash. */
79 DashDeclarativeView* view = getView();
80 if (view->active()) {
81 view->setActive(false);
82 }
83 else {
84 view->activateHome();
85 }
86 }
87 }
88 return false;
89}
90
91int main(int argc, char *argv[])62int main(int argc, char *argv[])
92{63{
93 QApplication::setApplicationName("Unity 2D Dash");64 QApplication::setApplicationName("Unity 2D Dash");
@@ -142,10 +113,6 @@
142 view.fitToAvailableSpace(current_screen);113 view.fitToAvailableSpace(current_screen);
143 QObject::connect(QApplication::desktop(), SIGNAL(workAreaResized(int)), &view, SLOT(fitToAvailableSpace(int)));114 QObject::connect(QApplication::desktop(), SIGNAL(workAreaResized(int)), &view, SLOT(fitToAvailableSpace(int)));
144115
145 /* Grab the "super" keys */
146 SuperKeyMonitor superKeys; /* Just needs to be instantiated to work. */
147 QAbstractEventDispatcher::instance()->setEventFilter(eventFilter);
148
149 application.setProperty("view", QVariant::fromValue(&view));116 application.setProperty("view", QVariant::fromValue(&view));
150 return application.exec();117 return application.exec();
151}118}
152119
=== removed file 'places/app/superkeymonitor.cpp'
--- places/app/superkeymonitor.cpp 2011-01-11 12:47:22 +0000
+++ places/app/superkeymonitor.cpp 1970-01-01 00:00:00 +0000
@@ -1,79 +0,0 @@
1/*
2 * Copyright (C) 2011 Canonical, Ltd.
3 *
4 * Authors:
5 * Olivier Tilloy <olivier.tilloy@canonical.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "superkeymonitor.h"
21#include "keymonitor.h"
22
23#include "gconfitem-qml-wrapper.h"
24
25SuperKeyMonitor::SuperKeyMonitor()
26{
27 m_left = new KeyMonitor(SUPER_L, this);
28 m_right = new KeyMonitor(SUPER_R, this);
29
30 m_enable_setting = new GConfItemQmlWrapper(this);
31 m_enable_setting->setKey("/desktop/unity/launcher/super_key_enable");
32 if (getEnableSettingValue()) {
33 startMonitoring();
34 }
35 connect(m_enable_setting, SIGNAL(valueChanged()), SLOT(slotEnableSettingChanged()));
36}
37
38SuperKeyMonitor::~SuperKeyMonitor()
39{
40}
41
42bool
43SuperKeyMonitor::getEnableSettingValue() const
44{
45 QVariant value = m_enable_setting->getValue();
46 if (value.isValid()) {
47 return value.toBool();
48 }
49 else {
50 /* The key is not set, assume true. */
51 return true;
52 }
53}
54
55void
56SuperKeyMonitor::slotEnableSettingChanged()
57{
58 if (getEnableSettingValue()) {
59 startMonitoring();
60 }
61 else {
62 stopMonitoring();
63 }
64}
65
66void
67SuperKeyMonitor::startMonitoring()
68{
69 m_left->grabKey();
70 m_right->grabKey();
71}
72
73void
74SuperKeyMonitor::stopMonitoring()
75{
76 m_left->ungrabKey();
77 m_right->ungrabKey();
78}
79
800
=== removed file 'places/app/superkeymonitor.h'
--- places/app/superkeymonitor.h 2011-01-11 12:35:07 +0000
+++ places/app/superkeymonitor.h 1970-01-01 00:00:00 +0000
@@ -1,55 +0,0 @@
1/*
2 * Copyright (C) 2011 Canonical, Ltd.
3 *
4 * Authors:
5 * Olivier Tilloy <olivier.tilloy@canonical.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifndef SuperKeyMonitor_H
21#define SuperKeyMonitor_H
22
23#include <QObject>
24
25class KeyMonitor;
26class GConfItemQmlWrapper;
27
28class SuperKeyMonitor : public QObject
29{
30 Q_OBJECT
31
32public:
33 SuperKeyMonitor();
34 ~SuperKeyMonitor();
35
36 static const uint SUPER_L = 133;
37 static const uint SUPER_R = 134;
38
39private:
40 KeyMonitor* m_left;
41 KeyMonitor* m_right;
42
43 GConfItemQmlWrapper* m_enable_setting;
44
45 bool getEnableSettingValue() const;
46
47 void startMonitoring();
48 void stopMonitoring();
49
50private Q_SLOTS:
51 void slotEnableSettingChanged();
52};
53
54#endif // SuperKeyMonitor_H
55

Subscribers

People subscribed via source and target branches

to all changes: