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

Proposed by Olivier Tilloy
Status: Merged
Approved by: Ugo Riboni
Approved revision: 563
Merged at revision: 556
Proposed branch: lp:~osomon/unity-2d/launcher-items-keyboard-shortcuts
Merge into: lp:unity-2d/3.0
Diff against target: 200 lines (+77/-11)
7 files modified
launcher/LauncherList.qml (+10/-3)
launcher/UnityApplications/launcheritem.cpp (+30/-1)
launcher/UnityApplications/launcheritem.h (+10/-0)
launcher/UnityApplications/place.cpp (+15/-0)
launcher/UnityApplications/placeentry.cpp (+1/-0)
launcher/UnityApplications/trash.cpp (+1/-0)
libunity-2d-private/src/hotkey.cpp (+10/-7)
To merge this branch: bzr merge lp:~osomon/unity-2d/launcher-items-keyboard-shortcuts
Reviewer Review Type Date Requested Status
Ugo Riboni (community) Needs Fixing
Review via email: mp+59524@code.launchpad.net

Commit message

[launcher] Keyboard shortcuts for place entries (Meta+[letter]) and the trash (Meta+T).

To post a comment you must log in.
559. By Olivier Tilloy

No need to manually disconnect from the hotkey event, this is done automatically by Qt upon destruction.

Revision history for this message
Ugo Riboni (uriboni) wrote :

Functionally there's only one corner case where it doesn't work: if the shortcut key is some accented character, it's not displayed as a shortcut. For example if you edit /usr/share/unity/places/applications.place and make the shortcut key "é", it will not work (the key is not even grabbed).

review: Needs Fixing
Revision history for this message
Ugo Riboni (uriboni) wrote :

134 + if (value.size() == 1) {
135 + QChar c = value.at(0);
136 + if (c.isLetter()) {
137 + Qt::Key key = (Qt::Key) (Qt::Key_A + (c.toLower().toAscii() - 'a'));
138 + entry->setShortcutKey(key);
139 + }
140 + }

I am a fan of the principle "be strict in what you emit and relaxed in what you accept", and in this case if the string length is larger than 1 character, why don't you just pick the first character and emit a warning.
Or if you prefer just emit a warning and set no shortcut. But don't just silently do nothing.

review: Needs Fixing
560. By Olivier Tilloy

Print out a warning if the shortcut key is invalid (more than one single character).

561. By Olivier Tilloy

More reliable (and simple) conversion from QString to Qt::Key.

Revision history for this message
Ugo Riboni (uriboni) wrote :

It's still not working. I set the shortcut to "é" (one single accented character), and I get this warning message: unity-2d-launcher: [WARNING] void Place::setFileName(const QString&): Invalid shorcut key (should be one single character): "é"

review: Needs Fixing
Revision history for this message
Olivier Tilloy (osomon) wrote :

This is very likely because your text editor, when you are typing "é", is in fact inserting two characters (0xc3 + 0xa9) instead of one (0xc9). The visual representation is the same, but the underlying unicode representation isn’t, and as a consequence the string extracted from the place file is too long. At least the code now prints out a warning, it doesn’t ignore it silently.

Still, if you use an hexadecimal editor to set the shortcut to the correct unicode character (0xc9), grabbing the key fails lower down the stack with the following warning:

    Could not convert "É" to an x11 keysym

This happens during the conversion from a Qt::Key to an X11 keysym in the constructor for Hotkey. I’m trying to figure out how to fix the conversion.

562. By Olivier Tilloy

Fix the translation from Qt::Key to an X11 KeySym for unicode characters such as "É".

563. By Olivier Tilloy

Comment to explain why setting the shortcut key of a place entry to an accentuated character might fail.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'launcher/LauncherList.qml'
2--- launcher/LauncherList.qml 2011-04-29 16:11:04 +0000
3+++ launcher/LauncherList.qml 2011-05-03 15:41:14 +0000
4@@ -98,9 +98,16 @@
5 emblem: (noOverlays && item.emblem) ? "image://icons/" + item.emblem : ""
6 emblemVisible: (noOverlays) ? false : item.emblemVisible
7
8- shortcutVisible: item.toString().indexOf("LauncherApplication") == 0 &&
9- index <= 9 && launcherView.superKeyHeld
10- shortcutText: (index + 1) % 10
11+ shortcutVisible: launcherView.superKeyHeld &&
12+ ((item.toString().indexOf("LauncherApplication") == 0 && index <= 9) ||
13+ item.shortcutKey != 0)
14+ shortcutText: {
15+ if (item.toString().indexOf("LauncherApplication") == 0) {
16+ return (index + 1) % 10
17+ } else {
18+ return String.fromCharCode(item.shortcutKey).toLowerCase()
19+ }
20+ }
21
22 isBeingDragged: (reorder.draggedTileId != "") && (reorder.draggedTileId == desktopFile)
23 dragPosition: reorder.listCoordinates.y - list.contentY
24
25=== modified file 'launcher/UnityApplications/launcheritem.cpp'
26--- launcher/UnityApplications/launcheritem.cpp 2011-03-31 08:12:28 +0000
27+++ launcher/UnityApplications/launcheritem.cpp 2011-05-03 15:41:14 +0000
28@@ -20,7 +20,13 @@
29 #include "launcheritem.h"
30 #include "launchermenu.h"
31
32-LauncherItem::LauncherItem(QObject* parent): QObject(parent)
33+// libunity-2d
34+#include <hotkey.h>
35+#include <hotkeymonitor.h>
36+
37+LauncherItem::LauncherItem(QObject* parent)
38+ : QObject(parent)
39+ , m_shortcutKey((Qt::Key) 0)
40 {
41 m_menu = new LauncherContextualMenu;
42 m_menu->setLauncherItem(this);
43@@ -31,6 +37,29 @@
44 delete m_menu;
45 }
46
47+Qt::Key
48+LauncherItem::shortcutKey() const
49+{
50+ return m_shortcutKey;
51+}
52+
53+void
54+LauncherItem::setShortcutKey(Qt::Key key)
55+{
56+ if (m_shortcutKey != key) {
57+ if (m_shortcutKey != 0) {
58+ Hotkey* hotkey = HotkeyMonitor::instance().getHotkeyFor(m_shortcutKey, Qt::MetaModifier);
59+ disconnect(hotkey, SIGNAL(pressed()), this, SLOT(activate()));
60+ }
61+ m_shortcutKey = key;
62+ if (m_shortcutKey != 0) {
63+ Hotkey* hotkey = HotkeyMonitor::instance().getHotkeyFor(m_shortcutKey, Qt::MetaModifier);
64+ connect(hotkey, SIGNAL(pressed()), SLOT(activate()));
65+ }
66+ Q_EMIT shortcutKeyChanged(m_shortcutKey);
67+ }
68+}
69+
70 QObject*
71 LauncherItem::menu() const
72 {
73
74=== modified file 'launcher/UnityApplications/launcheritem.h'
75--- launcher/UnityApplications/launcheritem.h 2011-03-31 08:12:28 +0000
76+++ launcher/UnityApplications/launcheritem.h 2011-05-03 15:41:14 +0000
77@@ -22,6 +22,7 @@
78
79 #include <QObject>
80 #include <QString>
81+#include <Qt>
82
83 #include "dragdropevent.h"
84
85@@ -38,6 +39,7 @@
86 Q_PROPERTY(QString name READ name NOTIFY nameChanged)
87 Q_PROPERTY(QString icon READ icon NOTIFY iconChanged)
88 Q_PROPERTY(bool launching READ launching NOTIFY launchingChanged)
89+ Q_PROPERTY(Qt::Key shortcutKey READ shortcutKey WRITE setShortcutKey NOTIFY shortcutKeyChanged)
90 /* Export the menu as a plain QObject so that it can be used from QML */
91 Q_PROPERTY(QObject* menu READ menu NOTIFY menuChanged)
92
93@@ -53,8 +55,12 @@
94 virtual QString name() const = 0;
95 virtual QString icon() const = 0;
96 virtual bool launching() const = 0;
97+ Qt::Key shortcutKey() const;
98 QObject* menu() const;
99
100+ /* setters */
101+ void setShortcutKey(Qt::Key);
102+
103 /* methods */
104 Q_INVOKABLE virtual void activate() = 0;
105 Q_INVOKABLE virtual void createMenuActions() = 0;
106@@ -71,6 +77,7 @@
107 void nameChanged(QString);
108 void iconChanged(QString);
109 void launchingChanged(bool);
110+ void shortcutKeyChanged(Qt::Key);
111 void menuChanged(QObject*);
112
113 public Q_SLOTS:
114@@ -78,6 +85,9 @@
115 subclasses to implement custom behaviours. */
116 virtual void onDragEnter(DeclarativeDragDropEvent*);
117 virtual void onDrop(DeclarativeDragDropEvent*);
118+
119+private:
120+ Qt::Key m_shortcutKey;
121 };
122
123 #endif // LAUNCHERITEM_H
124
125=== modified file 'launcher/UnityApplications/place.cpp'
126--- launcher/UnityApplications/place.cpp 2011-04-28 13:09:25 +0000
127+++ launcher/UnityApplications/place.cpp 2011-05-03 15:41:14 +0000
128@@ -106,6 +106,21 @@
129 entry->setIcon(m_file->value("Icon").toString());
130 entry->setSearchHint(u2dTr(m_file->value("SearchHint").toString().toUtf8().constData(),
131 gettextDomain.toUtf8().constData()));
132+ if (m_file->contains("Shortcut")) {
133+ QString value = m_file->value("Shortcut").toString();
134+ if (value.size() == 1) {
135+ Qt::Key key = (Qt::Key) value.at(0).toUpper().unicode();
136+ entry->setShortcutKey(key);
137+ } else {
138+ /* Note: some text editors insert the decomposed form of
139+ e.g. accented characters (e.g. 0xc3 + 0xa9 for "É"
140+ instead of the canonical form 0xc9). Unfortunately Qt
141+ doesn’t seem to be able to perform composition, so in
142+ such cases setting the shortcut key fails. See
143+ http://www.unicode.org/reports/tr15/ for details. */
144+ UQ_WARNING << "Invalid shorcut key (should be one single character):" << value;
145+ }
146+ }
147 if (!m_file->contains("ShowEntry")) {
148 entry->setShowEntry(true);
149 } else {
150
151=== modified file 'launcher/UnityApplications/placeentry.cpp'
152--- launcher/UnityApplications/placeentry.cpp 2011-04-07 09:48:24 +0000
153+++ launcher/UnityApplications/placeentry.cpp 2011-05-03 15:41:14 +0000
154@@ -21,6 +21,7 @@
155 #include "place.h"
156 #include "launchermenu.h"
157
158+// libunity-2d
159 #include <debug_p.h>
160
161 #include <QDBusMetaType>
162
163=== modified file 'launcher/UnityApplications/trash.cpp'
164--- launcher/UnityApplications/trash.cpp 2011-04-28 13:09:25 +0000
165+++ launcher/UnityApplications/trash.cpp 2011-05-03 15:41:14 +0000
166@@ -33,6 +33,7 @@
167 Trash::Trash()
168 {
169 m_trash = g_file_new_for_uri(TRASH_URI);
170+ setShortcutKey(Qt::Key_T);
171 }
172
173 Trash::Trash(const Trash& other)
174
175=== modified file 'libunity-2d-private/src/hotkey.cpp'
176--- libunity-2d-private/src/hotkey.cpp 2011-04-28 13:09:25 +0000
177+++ libunity-2d-private/src/hotkey.cpp 2011-05-03 15:41:14 +0000
178@@ -72,13 +72,16 @@
179 QString keyString = QKeySequence(key).toString();
180 KeySym keysym = XStringToKeysym(keyString.toLatin1().data());
181 if (keysym == NoSymbol) {
182- UQ_WARNING << "Could not convert" << keyString << "to an x11 keysym";
183- } else {
184- m_x11key = XKeysymToKeycode(QX11Info::display(), keysym);
185- if (m_x11key == 0) {
186- UQ_WARNING << "Could not get keycode for keysym" << keysym
187- << "(" << keyString << ")";
188- }
189+ /* XStringToKeysym doesn’t work well with exotic characters (such as
190+ 'É'). Note that this fallback code path looks much simpler but doesn’t
191+ work for special keys such as the function keys (e.g. F1), which is
192+ why the translation with XStringToKeysym is attempted first. */
193+ keysym = (ushort) key;
194+ }
195+ m_x11key = XKeysymToKeycode(QX11Info::display(), keysym);
196+ if (m_x11key == 0) {
197+ UQ_WARNING << "Could not get keycode for keysym" << keysym
198+ << "(" << keyString << ")";
199 }
200 }
201

Subscribers

People subscribed via source and target branches