Merge lp:~azzar1/hud/hud-wnck-actions-menu into lp:hud
- hud-wnck-actions-menu
- Merge into trunk.15.10
Status: | Merged |
---|---|
Approved by: | Marco Trevisan (Treviño) |
Approved revision: | 411 |
Merged at revision: | 405 |
Proposed branch: | lp:~azzar1/hud/hud-wnck-actions-menu |
Merge into: | lp:hud |
Diff against target: |
801 lines (+335/-116) 16 files modified
data/com.canonical.Unity.WindowStack.xml (+4/-0) service/CMakeLists.txt (+1/-0) service/DBusMenuCollector.cpp (+14/-56) service/DBusMenuCollector.h (+9/-29) service/DBusMenuWindowCollector.cpp (+141/-0) service/DBusMenuWindowCollector.h (+72/-0) service/Factory.cpp (+9/-4) service/Factory.h (+5/-2) service/ItemStore.cpp (+22/-0) service/ItemStore.h (+2/-0) service/WindowImpl.cpp (+1/-1) tests/unit/service/Mocks.h (+1/-1) tests/unit/service/TestWindow.cpp (+25/-23) window-stack-bridge/AbstractWindowStack.h (+2/-0) window-stack-bridge/BamfWindowStack.cpp (+21/-0) window-stack-bridge/BamfWindowStack.h (+6/-0) |
To merge this branch: | bzr merge lp:~azzar1/hud/hud-wnck-actions-menu |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Marco Trevisan (Treviño) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Review via email: mp+291101@code.launchpad.net |
Commit message
Introduce DBusMenuWindowC
Description of the change
Introduce DBusMenuWindowC
- 406. By Andrea Azzarone
-
Fix indent.
PS Jenkins bot (ps-jenkins) wrote : | # |
- 407. By Andrea Azzarone
-
Add missing files.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:407
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 408. By Andrea Azzarone
-
Allow to search using the mnemonic key.
- 409. By Andrea Azzarone
-
Fix DBusMenuWindowC
ollector: :isValid.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:409
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
Nice!
However, since Hud already relies on BAMF and it knows the paths we're handling, there's really no reason to export _WNCK_ACTION_
We can just use the window stack to get that.
So, please merge this with my branch, where I've implemented this: lp:~3v1n0/hud/stack-get-bus-address
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
Ah, about the searchByMnemonic thing... Maybe it should be enabled for all the menus?
Including the ones provided by GMenuModel (thus probably just keeping it as default, without adding a property)?
- 410. By Andrea Azzarone
-
Merge with lp:~3v1n0/hud/stack-get-bus-address.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:410
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
Ouch, forgot http://
(or just bzr pull lp:~3v1n0/hud/stack-get-bus-address)
- 411. By Andrea Azzarone
-
Merge with lp:~3v1n0/hud/stack-get-bus-address)
Andrea Azzarone (azzar1) wrote : | # |
> Ouch, forgot http://
>
> (or just bzr pull lp:~3v1n0/hud/stack-get-bus-address)
Done.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:411
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
CI failures are pretty random. Not nice, but nothing caused by this change.
Let's go with this.
Pete Woods (pete-woods) wrote : | # |
If you had exported the menu as a GMenu on your end, you probably wouldn't have had to touch HUD at all, as it already supports collecting multiple GMenus.
Andrea Azzarone (azzar1) wrote : | # |
> If you had exported the menu as a GMenu on your end, you probably wouldn't
> have had to touch HUD at all, as it already supports collecting multiple
> GMenus.
It was not possible to do so without an API break for libwnck.
Preview Diff
1 | === modified file 'data/com.canonical.Unity.WindowStack.xml' |
2 | --- data/com.canonical.Unity.WindowStack.xml 2013-12-18 10:12:17 +0000 |
3 | +++ data/com.canonical.Unity.WindowStack.xml 2016-04-12 11:12:57 +0000 |
4 | @@ -22,6 +22,10 @@ |
5 | <arg name="app_id" type="s" direction="in"/> |
6 | <arg name="property_names" type="as" direction="in"/> |
7 | </method> |
8 | + <method name="GetWindowBusAddress"> |
9 | + <arg name="address_path" type="as" direction="out"/> |
10 | + <arg name="window_id" type="u" direction="in"/> |
11 | + </method> |
12 | <method name="GetAppIdFromPid"> |
13 | <arg name="app_id" type="s" direction="out"/> |
14 | <arg name="pid" type="u" direction="in"/> |
15 | |
16 | === modified file 'service/CMakeLists.txt' |
17 | --- service/CMakeLists.txt 2015-08-20 13:44:43 +0000 |
18 | +++ service/CMakeLists.txt 2016-04-12 11:12:57 +0000 |
19 | @@ -16,6 +16,7 @@ |
20 | ApplicationListImpl.cpp |
21 | Collector.cpp |
22 | DBusMenuCollector.cpp |
23 | + DBusMenuWindowCollector.cpp |
24 | Factory.cpp |
25 | GMenuCollector.cpp |
26 | GMenuWindowCollector.cpp |
27 | |
28 | === modified file 'service/DBusMenuCollector.cpp' |
29 | --- service/DBusMenuCollector.cpp 2014-05-13 10:23:56 +0000 |
30 | +++ service/DBusMenuCollector.cpp 2016-04-12 11:12:57 +0000 |
31 | @@ -1,5 +1,5 @@ |
32 | /* |
33 | - * Copyright (C) 2013 Canonical, Ltd. |
34 | + * Copyright (C) 2013-2016 Canonical, Ltd. |
35 | * |
36 | * This program is free software: you can redistribute it and/or modify it |
37 | * under the terms of the GNU General Public License version 3, as published |
38 | @@ -14,63 +14,28 @@ |
39 | * with this program. If not, see <http://www.gnu.org/licenses/>. |
40 | * |
41 | * Author: Pete Woods <pete.woods@canonical.com> |
42 | + * Andrea Azzarone <andrea.azzarone@canonical.com> |
43 | */ |
44 | |
45 | -#include <common/DBusTypes.h> |
46 | -#include <common/Localisation.h> |
47 | #include <service/DBusMenuCollector.h> |
48 | -#include <service/AppmenuRegistrarInterface.h> |
49 | |
50 | #include <dbusmenuimporter.h> |
51 | +#include <QDebug> |
52 | #include <QMenu> |
53 | #include <stdexcept> |
54 | |
55 | -using namespace hud::common; |
56 | using namespace hud::service; |
57 | |
58 | -DBusMenuCollector::DBusMenuCollector(unsigned int windowId, |
59 | - QSharedPointer<ComCanonicalAppMenuRegistrarInterface> registrar) : |
60 | - m_windowId(windowId), m_registrar(registrar) { |
61 | - |
62 | - connect(registrar.data(), |
63 | - SIGNAL(WindowRegistered(uint, const QString &, const QDBusObjectPath &)), |
64 | - this, |
65 | - SLOT( WindowRegistered(uint, const QString &, const QDBusObjectPath &))); |
66 | - |
67 | - QDBusPendingReply<QString, QDBusObjectPath> windowReply = |
68 | - registrar->GetMenuForWindow(m_windowId); |
69 | - |
70 | - windowReply.waitForFinished(); |
71 | - if (windowReply.isError()) { |
72 | - return; |
73 | - } |
74 | - |
75 | - windowRegistered(windowReply.argumentAt<0>(), windowReply.argumentAt<1>()); |
76 | -} |
77 | - |
78 | -DBusMenuCollector::~DBusMenuCollector() { |
79 | -} |
80 | - |
81 | -void DBusMenuCollector::windowRegistered(const QString &service, |
82 | - const QDBusObjectPath &menuObjectPath) { |
83 | - |
84 | - if (service.isEmpty()) { |
85 | - return; |
86 | - } |
87 | - |
88 | - m_service = service; |
89 | - m_path = menuObjectPath; |
90 | - |
91 | - disconnect(m_registrar.data(), |
92 | - SIGNAL( |
93 | - WindowRegistered(uint, const QString &, const QDBusObjectPath &)), |
94 | - this, |
95 | - SLOT( |
96 | - WindowRegistered(uint, const QString &, const QDBusObjectPath &))); |
97 | +DBusMenuCollector::DBusMenuCollector(const QString &service, |
98 | + const QDBusObjectPath &menuObjectPath) : |
99 | + m_service(service), m_path(menuObjectPath) { |
100 | + |
101 | + if (m_service.isEmpty()) { |
102 | + return; |
103 | + } |
104 | |
105 | m_menuImporter.reset( |
106 | - new DBusMenuImporter(m_service, m_path.path(), |
107 | - DBusMenuImporterType::SYNCHRONOUS)); |
108 | + new DBusMenuImporter(m_service, m_path.path(), DBusMenuImporterType::SYNCHRONOUS)); |
109 | |
110 | CollectorToken::Ptr collectorToken(m_collectorToken); |
111 | if(collectorToken) { |
112 | @@ -78,6 +43,9 @@ |
113 | } |
114 | } |
115 | |
116 | +DBusMenuCollector::~DBusMenuCollector() { |
117 | +} |
118 | + |
119 | bool DBusMenuCollector::isValid() const { |
120 | return !m_menuImporter.isNull(); |
121 | } |
122 | @@ -173,13 +141,3 @@ |
123 | qDebug() << e.what(); |
124 | } |
125 | } |
126 | - |
127 | -void DBusMenuCollector::WindowRegistered(uint windowId, const QString &service, |
128 | - const QDBusObjectPath &menuObjectPath) { |
129 | - // Simply ignore updates for other windows |
130 | - if (windowId != m_windowId) { |
131 | - return; |
132 | - } |
133 | - |
134 | - windowRegistered(service, menuObjectPath); |
135 | -} |
136 | |
137 | === modified file 'service/DBusMenuCollector.h' |
138 | --- service/DBusMenuCollector.h 2014-03-26 09:00:05 +0000 |
139 | +++ service/DBusMenuCollector.h 2016-04-12 11:12:57 +0000 |
140 | @@ -1,5 +1,5 @@ |
141 | /* |
142 | - * Copyright (C) 2013 Canonical, Ltd. |
143 | + * Copyright (C) 2013-2016 Canonical, Ltd. |
144 | * |
145 | * This program is free software: you can redistribute it and/or modify it |
146 | * under the terms of the GNU General Public License version 3, as published |
147 | @@ -14,6 +14,7 @@ |
148 | * with this program. If not, see <http://www.gnu.org/licenses/>. |
149 | * |
150 | * Author: Pete Woods <pete.woods@canonical.com> |
151 | + * Andrea Azzarone <andrea.azzarone@canonical.com> |
152 | */ |
153 | |
154 | #ifndef HUD_SERVICE_DBUSMENUCOLLECTOR_H_ |
155 | @@ -21,10 +22,8 @@ |
156 | |
157 | #include <service/Collector.h> |
158 | |
159 | -#include <QDBusConnection> |
160 | -#include <memory> |
161 | +#include <QDBusObjectPath> |
162 | |
163 | -class ComCanonicalAppMenuRegistrarInterface; |
164 | class DBusMenuImporter; |
165 | |
166 | QT_BEGIN_NAMESPACE |
167 | @@ -34,46 +33,27 @@ |
168 | namespace hud { |
169 | namespace service { |
170 | |
171 | -class DBusMenuCollector: public Collector, public std::enable_shared_from_this< |
172 | - DBusMenuCollector> { |
173 | -Q_OBJECT |
174 | +class DBusMenuCollector: public Collector, |
175 | + public std::enable_shared_from_this<DBusMenuCollector> { |
176 | public: |
177 | typedef std::shared_ptr<DBusMenuCollector> Ptr; |
178 | |
179 | - DBusMenuCollector(unsigned int windowId, |
180 | - QSharedPointer<ComCanonicalAppMenuRegistrarInterface> appmenu); |
181 | - |
182 | + DBusMenuCollector(const QString &service, const QDBusObjectPath &menuObjectPath); |
183 | virtual ~DBusMenuCollector(); |
184 | |
185 | virtual bool isValid() const override; |
186 | - |
187 | virtual QList<CollectorToken::Ptr> activate() override; |
188 | |
189 | -protected Q_SLOTS: |
190 | - void WindowRegistered(uint windowId, const QString &service, |
191 | - const QDBusObjectPath &menuObjectPath); |
192 | - |
193 | -protected: |
194 | - virtual void deactivate(); |
195 | - |
196 | - void windowRegistered(const QString &service, |
197 | - const QDBusObjectPath &menuObjectPath); |
198 | - |
199 | -protected: |
200 | +protected: |
201 | + virtual void deactivate() override; |
202 | + |
203 | void openMenu(QMenu *menu, unsigned int &limit); |
204 | - |
205 | void hideMenu(QMenu *menu, unsigned int &limit); |
206 | |
207 | - unsigned int m_windowId; |
208 | - |
209 | - QSharedPointer<ComCanonicalAppMenuRegistrarInterface> m_registrar; |
210 | - |
211 | QWeakPointer<CollectorToken> m_collectorToken; |
212 | - |
213 | QSharedPointer<DBusMenuImporter> m_menuImporter; |
214 | |
215 | QString m_service; |
216 | - |
217 | QDBusObjectPath m_path; |
218 | }; |
219 | |
220 | |
221 | === added file 'service/DBusMenuWindowCollector.cpp' |
222 | --- service/DBusMenuWindowCollector.cpp 1970-01-01 00:00:00 +0000 |
223 | +++ service/DBusMenuWindowCollector.cpp 2016-04-12 11:12:57 +0000 |
224 | @@ -0,0 +1,141 @@ |
225 | +/* |
226 | + * Copyright (C) 2016 Canonical, Ltd. |
227 | + * |
228 | + * This program is free software: you can redistribute it and/or modify it |
229 | + * under the terms of the GNU General Public License version 3, as published |
230 | + * by the Free Software Foundation. |
231 | + * |
232 | + * This program is distributed in the hope that it will be useful, but |
233 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
234 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
235 | + * PURPOSE. See the GNU General Public License for more details. |
236 | + * |
237 | + * You should have received a copy of the GNU General Public License along |
238 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
239 | + * |
240 | + * Author: Andrea Azzarone <andrea.azzarone@canonical.com> |
241 | + */ |
242 | + |
243 | +#include <common/DBusTypes.h> |
244 | +#include <common/WindowStackInterface.h> |
245 | +#include <service/AppmenuRegistrarInterface.h> |
246 | +#include <service/DBusMenuWindowCollector.h> |
247 | +#include <service/Factory.h> |
248 | + |
249 | +#include <QStringList> |
250 | + |
251 | +using namespace hud::common; |
252 | +using namespace hud::service; |
253 | + |
254 | +DBusMenuWindowCollector::DBusMenuWindowCollector(unsigned int windowId, |
255 | + QSharedPointer<ComCanonicalUnityWindowStackInterface> windowStack, |
256 | + QSharedPointer<ComCanonicalAppMenuRegistrarInterface> registrar, |
257 | + Factory &factory) : |
258 | + m_windowId(windowId), m_registrar(registrar), m_factory(factory) { |
259 | + |
260 | + connect(registrar.data(), |
261 | + SIGNAL(WindowRegistered(uint, const QString &, const QDBusObjectPath &)), |
262 | + this, |
263 | + SLOT(WindowRegistered(uint, const QString &, const QDBusObjectPath &))); |
264 | + |
265 | + QDBusPendingReply<QStringList> windowDBusAddressReply( |
266 | + windowStack->GetWindowBusAddress(windowId)); |
267 | + |
268 | + // Window action menu |
269 | + windowDBusAddressReply.waitForFinished(); |
270 | + if (!windowDBusAddressReply.isError()) { |
271 | + QStringList windowDBusAddress(windowDBusAddressReply); |
272 | + |
273 | + if (windowDBusAddress.size() == 2) { |
274 | + const QString &name = windowDBusAddress.at(0); |
275 | + const QString &path = windowDBusAddress.at(1); |
276 | + |
277 | + if (!name.isEmpty() && !path.isEmpty()) |
278 | + m_am_collector = factory.newDBusMenuCollector(name, QDBusObjectPath(path)); |
279 | + } |
280 | + } |
281 | + |
282 | + // AppMenu |
283 | + QDBusPendingReply<QString, QDBusObjectPath> windowReply = |
284 | + registrar->GetMenuForWindow(m_windowId); |
285 | + |
286 | + windowReply.waitForFinished(); |
287 | + if (windowReply.isError()) { |
288 | + return; |
289 | + } |
290 | + |
291 | + windowRegistered(windowReply.argumentAt<0>(), windowReply.argumentAt<1>()); |
292 | +} |
293 | + |
294 | +DBusMenuWindowCollector::~DBusMenuWindowCollector() { |
295 | +} |
296 | + |
297 | +bool DBusMenuWindowCollector::isValid() const { |
298 | + return m_collector || m_am_collector; |
299 | +} |
300 | + |
301 | +static void setPropertyForAllActions(QMenu *menu) { |
302 | + if (!menu) |
303 | + return; |
304 | + |
305 | + for (QAction *action : menu->actions()) { |
306 | + if (!action->isEnabled()) { |
307 | + continue; |
308 | + } |
309 | + |
310 | + if (action->isSeparator()) { |
311 | + continue; |
312 | + } |
313 | + |
314 | + action->setProperty("searchByMnemonic", true); |
315 | + setPropertyForAllActions(action->menu()); |
316 | + } |
317 | +} |
318 | + |
319 | +QList<CollectorToken::Ptr> DBusMenuWindowCollector::activate() { |
320 | + QList<CollectorToken::Ptr> ret; |
321 | + |
322 | + if (m_am_collector) { |
323 | + QList<CollectorToken::Ptr> tokens = m_am_collector->activate(); |
324 | + |
325 | + for (CollectorToken::Ptr token : tokens) { |
326 | + setPropertyForAllActions(token->menu()); |
327 | + } |
328 | + |
329 | + ret.append(tokens); |
330 | + } |
331 | + |
332 | + if (m_collector) { |
333 | + ret.append(m_collector->activate()); |
334 | + } |
335 | + |
336 | + return ret; |
337 | +} |
338 | + |
339 | +void DBusMenuWindowCollector::deactivate() { |
340 | +} |
341 | + |
342 | +void DBusMenuWindowCollector::WindowRegistered(uint windowId, const QString &service, |
343 | + const QDBusObjectPath &menuObjectPath) { |
344 | + // Simply ignore updates for other windows |
345 | + if (windowId != m_windowId) { |
346 | + return; |
347 | + } |
348 | + |
349 | + windowRegistered(service, menuObjectPath); |
350 | +} |
351 | + |
352 | +void DBusMenuWindowCollector::windowRegistered(const QString &service, |
353 | + const QDBusObjectPath &menuObjectPath) { |
354 | + |
355 | + if (service.isEmpty()) { |
356 | + return; |
357 | + } |
358 | + |
359 | + disconnect(m_registrar.data(), |
360 | + SIGNAL(WindowRegistered(uint, const QString &, const QDBusObjectPath &)), |
361 | + this, |
362 | + SLOT(WindowRegistered(uint, const QString &, const QDBusObjectPath &))); |
363 | + |
364 | + m_collector = m_factory.newDBusMenuCollector(service, menuObjectPath); |
365 | +} |
366 | |
367 | === added file 'service/DBusMenuWindowCollector.h' |
368 | --- service/DBusMenuWindowCollector.h 1970-01-01 00:00:00 +0000 |
369 | +++ service/DBusMenuWindowCollector.h 2016-04-12 11:12:57 +0000 |
370 | @@ -0,0 +1,72 @@ |
371 | +/* |
372 | + * Copyright (C) 2016 Canonical, Ltd. |
373 | + * |
374 | + * This program is free software: you can redistribute it and/or modify it |
375 | + * under the terms of the GNU General Public License version 3, as published |
376 | + * by the Free Software Foundation. |
377 | + * |
378 | + * This program is distributed in the hope that it will be useful, but |
379 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
380 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
381 | + * PURPOSE. See the GNU General Public License for more details. |
382 | + * |
383 | + * You should have received a copy of the GNU General Public License along |
384 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
385 | + * |
386 | + * Author: Andrea Azzarone <andrea.azzarone@canonical.com> |
387 | + */ |
388 | + |
389 | +#ifndef HUD_SERVICE_DBUSMENUWINDOWCOLLECTOR_H_ |
390 | +#define HUD_SERVICE_DBUSMENUWINDOWCOLLECTOR_H_ |
391 | + |
392 | +#include <service/Collector.h> |
393 | + |
394 | +class ComCanonicalAppMenuRegistrarInterface; |
395 | +class ComCanonicalUnityWindowStackInterface; |
396 | + |
397 | +namespace qtgmenu { |
398 | +class QtGMenuImporter; |
399 | +} |
400 | + |
401 | +namespace hud { |
402 | +namespace service { |
403 | + |
404 | +class Factory; |
405 | + |
406 | +class DBusMenuWindowCollector: public Collector, |
407 | + public std::enable_shared_from_this<DBusMenuWindowCollector> { |
408 | +Q_OBJECT |
409 | +public: |
410 | + typedef std::shared_ptr<DBusMenuWindowCollector> Ptr; |
411 | + |
412 | + DBusMenuWindowCollector(unsigned int windowId, |
413 | + QSharedPointer<ComCanonicalUnityWindowStackInterface> windowStack, |
414 | + QSharedPointer<ComCanonicalAppMenuRegistrarInterface> registrar, |
415 | + Factory &factory); |
416 | + virtual ~DBusMenuWindowCollector(); |
417 | + |
418 | + virtual bool isValid() const override; |
419 | + virtual QList<CollectorToken::Ptr> activate() override; |
420 | + |
421 | +protected Q_SLOTS: |
422 | + void WindowRegistered(uint windowId, const QString &service, |
423 | + const QDBusObjectPath &menuObjectPath); |
424 | + |
425 | +protected: |
426 | + virtual void deactivate() override; |
427 | + |
428 | +private: |
429 | + void windowRegistered(const QString &service, |
430 | + const QDBusObjectPath &menuObjectPath); |
431 | + |
432 | + Collector::Ptr m_am_collector; |
433 | + Collector::Ptr m_collector; |
434 | + unsigned int m_windowId; |
435 | + QSharedPointer<ComCanonicalAppMenuRegistrarInterface> m_registrar; |
436 | + Factory &m_factory; |
437 | +}; |
438 | + |
439 | +} |
440 | +} |
441 | + |
442 | +#endif /* HUD_SERVICE_DBUSMENUWINDOWCOLLECTOR_H_ */ |
443 | |
444 | === modified file 'service/Factory.cpp' |
445 | --- service/Factory.cpp 2015-08-20 13:44:43 +0000 |
446 | +++ service/Factory.cpp 2016-04-12 11:12:57 +0000 |
447 | @@ -161,10 +161,9 @@ |
448 | return WindowContext::Ptr(new WindowContextImpl(*this)); |
449 | } |
450 | |
451 | -Collector::Ptr Factory::newDBusMenuCollector(unsigned int windowId, |
452 | - const QString &applicationId) { |
453 | - Q_UNUSED(applicationId); |
454 | - return Collector::Ptr(new DBusMenuCollector(windowId, singletonAppmenu())); |
455 | +Collector::Ptr Factory::newDBusMenuCollector(const QString &service, |
456 | + const QDBusObjectPath &menuObjectPath) { |
457 | + return Collector::Ptr(new DBusMenuCollector(service, menuObjectPath)); |
458 | } |
459 | |
460 | Collector::Ptr Factory::newGMenuCollector(const QString &name, |
461 | @@ -187,3 +186,9 @@ |
462 | new GMenuWindowCollector(windowId, applicationId, |
463 | singletonWindowStack(), *this)); |
464 | } |
465 | + |
466 | +Collector::Ptr Factory::newDBusMenuWindowCollector(unsigned int windowId) { |
467 | + return Collector::Ptr( |
468 | + new DBusMenuWindowCollector(windowId, |
469 | + singletonWindowStack(), singletonAppmenu(), *this)); |
470 | +} |
471 | |
472 | === modified file 'service/Factory.h' |
473 | --- service/Factory.h 2015-08-20 11:12:22 +0000 |
474 | +++ service/Factory.h 2016-04-12 11:12:57 +0000 |
475 | @@ -23,6 +23,7 @@ |
476 | #include <service/Application.h> |
477 | #include <service/ApplicationList.h> |
478 | #include <service/DBusMenuCollector.h> |
479 | +#include <service/DBusMenuWindowCollector.h> |
480 | #include <service/GMenuWindowCollector.h> |
481 | #include <service/GMenuCollector.h> |
482 | #include <service/ItemStore.h> |
483 | @@ -87,8 +88,8 @@ |
484 | virtual WindowToken::Ptr newWindowToken(const QString &applicationId, |
485 | QList<CollectorToken::Ptr> tokens); |
486 | |
487 | - virtual Collector::Ptr newDBusMenuCollector(unsigned int windowId, |
488 | - const QString &applicationId); |
489 | + virtual Collector::Ptr newDBusMenuCollector(const QString &service, |
490 | + const QDBusObjectPath &menuObjectPath); |
491 | |
492 | virtual Collector::Ptr newGMenuCollector(const QString &name, |
493 | const QMap<QString, QDBusObjectPath> &actions, |
494 | @@ -101,6 +102,8 @@ |
495 | virtual Collector::Ptr newGMenuWindowCollector(unsigned int windowId, |
496 | const QString &applicationId); |
497 | |
498 | + virtual Collector::Ptr newDBusMenuWindowCollector(unsigned int windowId); |
499 | + |
500 | protected: |
501 | QDBusConnection m_sessionBus; |
502 | |
503 | |
504 | === modified file 'service/ItemStore.cpp' |
505 | --- service/ItemStore.cpp 2014-03-24 17:19:58 +0000 |
506 | +++ service/ItemStore.cpp 2016-04-12 11:12:57 +0000 |
507 | @@ -61,6 +61,16 @@ |
508 | return action->text().remove(SINGLE_AMPERSAND).replace("&&", "&"); |
509 | } |
510 | |
511 | +static QChar getMnemonic(const QAction *action) { |
512 | + int ampersandIndex = action->text().indexOf(SINGLE_AMPERSAND); |
513 | + |
514 | + if (ampersandIndex < 0 || ampersandIndex >= action->text().length() - 1) { |
515 | + return 0; |
516 | + } |
517 | + |
518 | + return action->text()[ampersandIndex+1].toLower(); |
519 | +} |
520 | + |
521 | void ItemStore::indexMenu(const QMenu *menu, const QMenu *root, |
522 | const QStringList &stack, const QList<int> &index) { |
523 | int i(-1); |
524 | @@ -74,6 +84,8 @@ |
525 | continue; |
526 | } |
527 | |
528 | + bool searchByMnemonic(action->property("searchByMnemonic").toBool()); |
529 | + |
530 | QStringList text( |
531 | convertActionText(action).remove(BAD_CHARACTERS).split( |
532 | WHITESPACE)); |
533 | @@ -91,6 +103,11 @@ |
534 | } else { |
535 | Document document(m_nextId); |
536 | |
537 | + if (searchByMnemonic) { |
538 | + QChar mnemonic = getMnemonic(action); |
539 | + m_mnemonic2DocumentId[mnemonic] = m_nextId; |
540 | + } |
541 | + |
542 | WordList command; |
543 | for (const QString &word : text) { |
544 | command.addWord(Word(word.toUtf8().constData())); |
545 | @@ -199,6 +216,11 @@ |
546 | |
547 | int queryLength(query.length()); |
548 | |
549 | + if (queryLength == 1 && m_mnemonic2DocumentId.contains(query[0])) { |
550 | + int docId = m_mnemonic2DocumentId[query[0]]; |
551 | + addResult(docId, stringMatcher, queryLength, 1.0, results); |
552 | + } |
553 | + |
554 | size_t maxResults = std::min(matchResults.size(), size_t(20)); |
555 | |
556 | for (size_t i(0); i < maxResults; ++i) { |
557 | |
558 | === modified file 'service/ItemStore.h' |
559 | --- service/ItemStore.h 2014-03-19 23:26:48 +0000 |
560 | +++ service/ItemStore.h 2016-04-12 11:12:57 +0000 |
561 | @@ -94,6 +94,8 @@ |
562 | QMap<DocumentID, Item::Ptr> m_items; |
563 | |
564 | QMap<QString, Item::Ptr> m_toolbarItems; |
565 | + |
566 | + QMap<QChar, int> m_mnemonic2DocumentId; |
567 | }; |
568 | |
569 | } |
570 | |
571 | === modified file 'service/WindowImpl.cpp' |
572 | --- service/WindowImpl.cpp 2014-03-19 23:26:48 +0000 |
573 | +++ service/WindowImpl.cpp 2016-04-12 11:12:57 +0000 |
574 | @@ -78,7 +78,7 @@ |
575 | WindowContextImpl(factory), m_applicationId(applicationId), m_allWindowsContext( |
576 | allWindowsContext) { |
577 | |
578 | - m_dbusMenuCollector = factory.newDBusMenuCollector(windowId, applicationId); |
579 | + m_dbusMenuCollector = factory.newDBusMenuWindowCollector(windowId); |
580 | m_gMenuCollector = factory.newGMenuWindowCollector(windowId, applicationId); |
581 | } |
582 | |
583 | |
584 | === modified file 'tests/unit/service/Mocks.h' |
585 | --- tests/unit/service/Mocks.h 2014-03-19 23:26:48 +0000 |
586 | +++ tests/unit/service/Mocks.h 2016-04-12 11:12:57 +0000 |
587 | @@ -44,7 +44,7 @@ |
588 | |
589 | MOCK_METHOD0(singletonUsageTracker, UsageTracker::Ptr()); |
590 | |
591 | - MOCK_METHOD2(newDBusMenuCollector, Collector::Ptr(unsigned int, const QString &)); |
592 | + MOCK_METHOD1(newDBusMenuWindowCollector, Collector::Ptr(unsigned int)); |
593 | |
594 | MOCK_METHOD2(newGMenuWindowCollector, Collector::Ptr(unsigned int, const QString &)); |
595 | |
596 | |
597 | === modified file 'tests/unit/service/TestWindow.cpp' |
598 | --- tests/unit/service/TestWindow.cpp 2014-03-05 12:59:07 +0000 |
599 | +++ tests/unit/service/TestWindow.cpp 2016-04-12 11:12:57 +0000 |
600 | @@ -52,8 +52,8 @@ |
601 | allWindowsCollector.reset(new NiceMock<MockCollector>()); |
602 | ON_CALL(*allWindowsCollector, isValid()).WillByDefault(Return(true)); |
603 | |
604 | - dbusMenuCollector.reset(new NiceMock<MockCollector>()); |
605 | - ON_CALL(*dbusMenuCollector, isValid()).WillByDefault(Return(true)); |
606 | + dbusmenuWindowCollector.reset(new NiceMock<MockCollector>()); |
607 | + ON_CALL(*dbusmenuWindowCollector, isValid()).WillByDefault(Return(true)); |
608 | |
609 | gmenuWindowCollector.reset(new NiceMock<MockCollector>()); |
610 | ON_CALL(*gmenuWindowCollector, isValid()).WillByDefault(Return(true)); |
611 | @@ -66,8 +66,8 @@ |
612 | } |
613 | |
614 | Window::Ptr createWindow() { |
615 | - EXPECT_CALL(factory, newDBusMenuCollector(1234, QString("application-id"))).Times( |
616 | - 1).WillOnce(Return(dbusMenuCollector)); |
617 | + EXPECT_CALL(factory, newDBusMenuWindowCollector(1234)).Times( |
618 | + 1).WillOnce(Return(dbusmenuWindowCollector)); |
619 | EXPECT_CALL(factory, newGMenuWindowCollector(1234, QString("application-id"))).Times( |
620 | 1).WillOnce(Return(gmenuWindowCollector)); |
621 | |
622 | @@ -88,7 +88,7 @@ |
623 | |
624 | shared_ptr<MockCollector> allWindowsCollector; |
625 | |
626 | - shared_ptr<MockCollector> dbusMenuCollector; |
627 | + shared_ptr<MockCollector> dbusmenuWindowCollector; |
628 | |
629 | shared_ptr<MockCollector> gmenuWindowCollector; |
630 | |
631 | @@ -106,21 +106,22 @@ |
632 | ON_CALL(*allWindowsCollector, isValid()).WillByDefault(Return(false)); |
633 | ON_CALL(*windowCollector, isValid()).WillByDefault(Return(false)); |
634 | |
635 | - QMenu dbusMenuCollectorMenu; |
636 | - CollectorToken::Ptr dbusMenuCollectorToken( |
637 | - new CollectorToken(dbusMenuCollector, &dbusMenuCollectorMenu)); |
638 | - EXPECT_CALL(*dbusMenuCollector, activate()).Times(1).WillOnce( |
639 | - Return(QList<CollectorToken::Ptr>() << dbusMenuCollectorToken)); |
640 | + QMenu dbusmenuWindowCollectorMenu; |
641 | + CollectorToken::Ptr dbusmenuWindowCollectorToken( |
642 | + new CollectorToken(dbusmenuWindowCollector, |
643 | + &dbusmenuWindowCollectorMenu)); |
644 | + EXPECT_CALL(*dbusmenuWindowCollector, activate()).Times(1).WillOnce( |
645 | + Return(QList<CollectorToken::Ptr>() << dbusmenuWindowCollectorToken)); |
646 | |
647 | WindowToken::Ptr token(window->activate()); |
648 | - EXPECT_EQ(QList<CollectorToken::Ptr>() << dbusMenuCollectorToken, |
649 | + EXPECT_EQ(QList<CollectorToken::Ptr>() << dbusmenuWindowCollectorToken, |
650 | token->tokens()); |
651 | } |
652 | |
653 | TEST_F(TestWindow, ActivateOnlyWithGMenu) { |
654 | Window::Ptr window(createWindow()); |
655 | |
656 | - ON_CALL(*dbusMenuCollector, isValid()).WillByDefault(Return(false)); |
657 | + ON_CALL(*dbusmenuWindowCollector, isValid()).WillByDefault(Return(false)); |
658 | ON_CALL(*allWindowsCollector, isValid()).WillByDefault(Return(false)); |
659 | ON_CALL(*windowCollector, isValid()).WillByDefault(Return(false)); |
660 | |
661 | @@ -139,7 +140,7 @@ |
662 | TEST_F(TestWindow, ActivateOnlyWithValidAllWindowsContext) { |
663 | Window::Ptr window(createWindow()); |
664 | |
665 | - ON_CALL(*dbusMenuCollector, isValid()).WillByDefault(Return(false)); |
666 | + ON_CALL(*dbusmenuWindowCollector, isValid()).WillByDefault(Return(false)); |
667 | ON_CALL(*gmenuWindowCollector, isValid()).WillByDefault(Return(false)); |
668 | ON_CALL(*windowCollector, isValid()).WillByDefault(Return(false)); |
669 | |
670 | @@ -160,7 +161,7 @@ |
671 | TEST_F(TestWindow, ActivateOnlyWithValidWindowContext) { |
672 | Window::Ptr window(createWindow()); |
673 | |
674 | - ON_CALL(*dbusMenuCollector, isValid()).WillByDefault(Return(false)); |
675 | + ON_CALL(*dbusmenuWindowCollector, isValid()).WillByDefault(Return(false)); |
676 | ON_CALL(*gmenuWindowCollector, isValid()).WillByDefault(Return(false)); |
677 | ON_CALL(*allWindowsCollector, isValid()).WillByDefault(Return(false)); |
678 | |
679 | @@ -201,11 +202,12 @@ |
680 | EXPECT_CALL(*gmenuWindowCollector, activate()).Times(1).WillOnce( |
681 | Return(QList<CollectorToken::Ptr>() << gmenuWindowCollectorToken)); |
682 | |
683 | - QMenu dbusMenuCollectorMenu; |
684 | - CollectorToken::Ptr dbusMenuCollectorToken( |
685 | - new CollectorToken(dbusMenuCollector, &dbusMenuCollectorMenu)); |
686 | - EXPECT_CALL(*dbusMenuCollector, activate()).Times(1).WillOnce( |
687 | - Return(QList<CollectorToken::Ptr>() << dbusMenuCollectorToken)); |
688 | + QMenu dbusmenuWindowCollectorMenu; |
689 | + CollectorToken::Ptr dbusmenuWindowCollectorToken( |
690 | + new CollectorToken(dbusmenuWindowCollector, |
691 | + &dbusmenuWindowCollectorMenu)); |
692 | + EXPECT_CALL(*dbusmenuWindowCollector, activate()).Times(1).WillOnce( |
693 | + Return(QList<CollectorToken::Ptr>() << dbusmenuWindowCollectorToken)); |
694 | |
695 | QMenu allWindowsCollectorMenu; |
696 | CollectorToken::Ptr allWindowsCollectorToken( |
697 | @@ -217,7 +219,7 @@ |
698 | |
699 | WindowToken::Ptr token(window->activate()); |
700 | EXPECT_EQ( |
701 | - QList<CollectorToken::Ptr>() << dbusMenuCollectorToken |
702 | + QList<CollectorToken::Ptr>() << dbusmenuWindowCollectorToken |
703 | << gmenuWindowCollectorToken << allWindowsCollectorToken, |
704 | token->tokens()); |
705 | |
706 | @@ -230,8 +232,8 @@ |
707 | Return(QList<CollectorToken::Ptr>() << gmenuWindowCollectorTokenChanged)); |
708 | |
709 | // Re-prime the other collectors |
710 | - EXPECT_CALL(*dbusMenuCollector, activate()).Times(1).WillOnce( |
711 | - Return(QList<CollectorToken::Ptr>() << dbusMenuCollectorToken)); |
712 | + EXPECT_CALL(*dbusmenuWindowCollector, activate()).Times(1).WillOnce( |
713 | + Return(QList<CollectorToken::Ptr>() << dbusmenuWindowCollectorToken)); |
714 | EXPECT_CALL(*allWindowsCollector, activate()).Times(1).WillOnce( |
715 | Return(QList<CollectorToken::Ptr>() << allWindowsCollectorToken)); |
716 | |
717 | @@ -239,7 +241,7 @@ |
718 | EXPECT_NE(token, tokenChanged); |
719 | |
720 | EXPECT_EQ( |
721 | - QList<CollectorToken::Ptr>() << dbusMenuCollectorToken |
722 | + QList<CollectorToken::Ptr>() << dbusmenuWindowCollectorToken |
723 | << gmenuWindowCollectorTokenChanged |
724 | << allWindowsCollectorToken, tokenChanged->tokens()); |
725 | } |
726 | |
727 | === modified file 'window-stack-bridge/AbstractWindowStack.h' |
728 | --- window-stack-bridge/AbstractWindowStack.h 2013-12-18 15:19:38 +0000 |
729 | +++ window-stack-bridge/AbstractWindowStack.h 2016-04-12 11:12:57 +0000 |
730 | @@ -52,6 +52,8 @@ |
731 | virtual QStringList GetWindowProperties(uint windowId, const QString &appId, |
732 | const QStringList &names) = 0; |
733 | |
734 | + virtual QStringList GetWindowBusAddress(uint windowId) = 0; |
735 | + |
736 | Q_SIGNALS: |
737 | void FocusedWindowChanged(uint windowId, const QString &appId, uint stage); |
738 | |
739 | |
740 | === modified file 'window-stack-bridge/BamfWindowStack.cpp' |
741 | --- window-stack-bridge/BamfWindowStack.cpp 2013-12-18 15:19:38 +0000 |
742 | +++ window-stack-bridge/BamfWindowStack.cpp 2016-04-12 11:12:57 +0000 |
743 | @@ -84,6 +84,16 @@ |
744 | return m_windowId; |
745 | } |
746 | |
747 | +QString BamfWindow::service() const |
748 | +{ |
749 | + return m_window.service(); |
750 | +} |
751 | + |
752 | +QString BamfWindow::path() const |
753 | +{ |
754 | + return m_window.path(); |
755 | +} |
756 | + |
757 | const QString & BamfWindow::applicationId() { |
758 | return m_applicationId; |
759 | } |
760 | @@ -237,6 +247,17 @@ |
761 | return result; |
762 | } |
763 | |
764 | +QStringList BamfWindowStack::GetWindowBusAddress(uint windowId) { |
765 | + const auto window = m_windowsById[windowId]; |
766 | + |
767 | + if (window == nullptr) { |
768 | + sendErrorReply(QDBusError::InvalidArgs, "Unable to find windowId"); |
769 | + return {}; |
770 | + } |
771 | + |
772 | + return {window->service(), window->path()}; |
773 | +} |
774 | + |
775 | void BamfWindowStack::ActiveWindowChanged(const QString &oldWindowPath, |
776 | const QString &newWindowPath) { |
777 | Q_UNUSED(oldWindowPath); |
778 | |
779 | === modified file 'window-stack-bridge/BamfWindowStack.h' |
780 | --- window-stack-bridge/BamfWindowStack.h 2013-12-18 15:19:38 +0000 |
781 | +++ window-stack-bridge/BamfWindowStack.h 2016-04-12 11:12:57 +0000 |
782 | @@ -34,6 +34,10 @@ |
783 | |
784 | unsigned int windowId(); |
785 | |
786 | + QString service() const; |
787 | + |
788 | + QString path() const; |
789 | + |
790 | const QString & applicationId(); |
791 | |
792 | const QString xProp(const QString &property); |
793 | @@ -70,6 +74,8 @@ |
794 | QStringList GetWindowProperties(uint windowId, const QString &appId, |
795 | const QStringList &names) override; |
796 | |
797 | + QStringList GetWindowBusAddress(uint windowId) override; |
798 | + |
799 | protected Q_SLOTS: |
800 | void ActiveWindowChanged(const QString &oldWindow, |
801 | const QString &newWindow); |
FAILED: Continuous integration, rev:406 jenkins. qa.ubuntu. com/job/ hud-ci/ 307/ jenkins. qa.ubuntu. com/job/ hud-wily- amd64-ci/ 5/console jenkins. qa.ubuntu. com/job/ hud-wily- armhf-ci/ 5/console jenkins. qa.ubuntu. com/job/ hud-wily- i386-ci/ 5/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/hud- ci/307/ rebuild
http://