Merge lp:~aacid/qtubuntu/aboutToShow into lp:qtubuntu

Proposed by Albert Astals Cid on 2017-03-06
Status: Merged
Approved by: Lukáš Tinkl on 2017-03-16
Approved revision: 383
Merged at revision: 379
Proposed branch: lp:~aacid/qtubuntu/aboutToShow
Merge into: lp:qtubuntu
Diff against target: 504 lines (+283/-23)
6 files modified
src/ubuntuappmenu/gmenumodelexporter.cpp (+111/-13)
src/ubuntuappmenu/gmenumodelexporter.h (+21/-4)
src/ubuntuappmenu/gmenumodelplatformmenu.cpp (+0/-4)
src/ubuntuappmenu/qtubuntuextraactionhandler.cpp (+107/-0)
src/ubuntuappmenu/qtubuntuextraactionhandler.h (+40/-0)
src/ubuntuappmenu/ubuntuappmenu.pro (+4/-2)
To merge this branch: bzr merge lp:~aacid/qtubuntu/aboutToShow
Reviewer Review Type Date Requested Status
Lukáš Tinkl (community) 2017-03-06 Abstain on 2017-03-16
Charles Kerr (community) Approve on 2017-03-16
Unity8 CI Bot continuous-integration Approve on 2017-03-16
Review via email: mp+319080@code.launchpad.net

Commit Message

Set qtubuntu-tag and handle aboutToShow calls

To post a comment you must log in.
Unity8 CI Bot (unity8-ci-bot) wrote :

PASSED: Continuous integration, rev:380
https://unity8-jenkins.ubuntu.com/job/lp-qtubuntu-ci/195/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/4333
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/4361
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4194
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4194/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4194
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4194/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4194
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4194/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4194
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4194/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4194
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4194/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4194
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4194/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-qtubuntu-ci/195/rebuild

review: Approve (continuous-integration)
lp:~aacid/qtubuntu/aboutToShow updated on 2017-03-13
381. By Albert Astals Cid on 2017-03-13

Merge

Unity8 CI Bot (unity8-ci-bot) wrote :

PASSED: Continuous integration, rev:381
https://unity8-jenkins.ubuntu.com/job/lp-qtubuntu-ci/201/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/4409
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/4437
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4268
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4268/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4268
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4268/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4268
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4268/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4268
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4268/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4268
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4268/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4268
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4268/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-qtubuntu-ci/201/rebuild

review: Approve (continuous-integration)
Lukáš Tinkl (lukas-kde) wrote :

+ void timerEvent(QTimerEvent *e);

Missing override keyword?

Otherwise the code looks good and does the job

review: Needs Fixing
lp:~aacid/qtubuntu/aboutToShow updated on 2017-03-15
382. By Albert Astals Cid on 2017-03-15

override++

Albert Astals Cid (aacid) wrote :

> + void timerEvent(QTimerEvent *e);
>
> Missing override keyword?

Yep, we don't have -Wsuggest-override in qtubuntu

>
>
> Otherwise the code looks good and does the job

Unity8 CI Bot (unity8-ci-bot) wrote :

PASSED: Continuous integration, rev:382
https://unity8-jenkins.ubuntu.com/job/lp-qtubuntu-ci/205/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/4457
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/4485
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4314
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4314/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4314
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4314/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4314
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4314/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4314
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4314/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4314
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4314/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4314
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4314/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-qtubuntu-ci/205/rebuild

review: Approve (continuous-integration)
Ted Gould (ted) wrote :

This looks like it is implementing something similar to the HUD Awareness protocol that Allison wrote for LibreOffice's about-to-show menu generation. Can we use that? U8 will have to support sending the events anyway for LO.

Charles Kerr (charlesk) wrote :

I see a Needs Fixing one-liner and a handful of minor/optional suggestions, but looks pretty good overall.

Ted knows more about HUD than me and I can't comment on the question of possible duplication of effort

review: Needs Fixing
Albert Astals Cid (aacid) wrote :

> This looks like it is implementing something similar to the HUD Awareness
> protocol that Allison wrote for LibreOffice's about-to-show menu generation.
> Can we use that? U8 will have to support sending the events anyway for LO.

If by "the HUD Awareness protocol" you mean https://code.launchpad.net/~desrt/indicator-appmenu/hud-awareness/+merge/127937 I don't see how that would help at all

lp:~aacid/qtubuntu/aboutToShow updated on 2017-03-16
383. By Albert Astals Cid on 2017-03-16

Fix review comments

Unity8 CI Bot (unity8-ci-bot) wrote :

PASSED: Continuous integration, rev:383
https://unity8-jenkins.ubuntu.com/job/lp-qtubuntu-ci/210/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/4490
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/4518
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4345
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4345/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4345
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4345/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4345
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4345/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4345
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4345/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4345
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4345/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4345
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4345/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-qtubuntu-ci/210/rebuild

review: Approve (continuous-integration)
Charles Kerr (charlesk) :
review: Approve
Lukáš Tinkl (lukas-kde) :
review: Abstain

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/ubuntuappmenu/gmenumodelexporter.cpp'
2--- src/ubuntuappmenu/gmenumodelexporter.cpp 2016-09-30 08:35:16 +0000
3+++ src/ubuntuappmenu/gmenumodelexporter.cpp 2017-03-16 09:42:42 +0000
4@@ -18,8 +18,10 @@
5 #include "gmenumodelexporter.h"
6 #include "registry.h"
7 #include "logging.h"
8+#include "qtubuntuextraactionhandler.h"
9
10 #include <QDebug>
11+#include <QTimerEvent>
12
13 #include <functional>
14
15@@ -111,6 +113,7 @@
16 , m_gactionGroup(g_simple_action_group_new())
17 , m_exportedModel(0)
18 , m_exportedActions(0)
19+ , m_qtubuntuExtraHandler(nullptr)
20 , m_menuPath(QStringLiteral(MENU_OBJECT_PATH).arg(s_menuId++))
21 {
22 m_structureTimer.setSingleShot(true);
23@@ -129,16 +132,57 @@
24 // Clear the menu and actions that have been created.
25 void UbuntuGMenuModelExporter::clear()
26 {
27- Q_FOREACH(const QMetaObject::Connection& connection, m_propertyConnections) {
28- QObject::disconnect(connection);
29+ Q_FOREACH(const QVector<QMetaObject::Connection>& menuPropertyConnections, m_propertyConnections) {
30+ Q_FOREACH(const QMetaObject::Connection& connection, menuPropertyConnections) {
31+ QObject::disconnect(connection);
32+ }
33 }
34+ m_propertyConnections.clear();
35
36 g_menu_remove_all(m_gmainMenu);
37
38- Q_FOREACH(const QByteArray& action, m_actions) {
39- g_action_map_remove_action(G_ACTION_MAP(m_gactionGroup), action.constData());
40+ Q_FOREACH(const QSet<QByteArray>& menuActions, m_actions) {
41+ Q_FOREACH(const QByteArray& action, menuActions) {
42+ g_action_map_remove_action(G_ACTION_MAP(m_gactionGroup), action.constData());
43+ }
44 }
45 m_actions.clear();
46+
47+ m_gmenusForMenus.clear();
48+}
49+
50+void UbuntuGMenuModelExporter::timerEvent(QTimerEvent *e)
51+{
52+ // Find the menu, it's a very short list
53+ auto it = m_reloadMenuTimers.begin();
54+ for (; it != m_reloadMenuTimers.end(); ++it) {
55+ if (e->timerId() == it.value())
56+ break;
57+ }
58+
59+ if (it != m_reloadMenuTimers.end()) {
60+ UbuntuPlatformMenu* gplatformMenu = it.key();
61+ GMenu *menu = m_gmenusForMenus.value(gplatformMenu);
62+ if (menu) {
63+ Q_FOREACH(const QMetaObject::Connection& connection, m_propertyConnections[menu]) {
64+ QObject::disconnect(connection);
65+ }
66+ m_propertyConnections.remove(menu);
67+ Q_FOREACH(const QByteArray& action, m_actions[menu]) {
68+ g_action_map_remove_action(G_ACTION_MAP(m_gactionGroup), action.constData());
69+ }
70+ m_actions.remove(menu);
71+ g_menu_remove_all(menu);
72+ addSubmenuItems(gplatformMenu, menu);
73+ } else {
74+ qWarning() << "Got an update timer for a menu that has no GMenu" << gplatformMenu;
75+ }
76+
77+ m_reloadMenuTimers.erase(it);
78+ } else {
79+ qWarning() << "Got an update timer for a timer that was not running";
80+ }
81+ killTimer(e->timerId());
82 }
83
84 // Export the model on dbus
85@@ -175,6 +219,25 @@
86 qCDebug(ubuntuappmenu, "Exported actions on %s", g_dbus_connection_get_unique_name(m_connection));
87 }
88 }
89+
90+ if (!m_qtubuntuExtraHandler) {
91+ m_qtubuntuExtraHandler = new QtUbuntuExtraActionHandler();
92+ if (!m_qtubuntuExtraHandler->connect(m_connection, menuPath, this)) {
93+ delete m_qtubuntuExtraHandler;
94+ m_qtubuntuExtraHandler = nullptr;
95+ }
96+ }
97+}
98+
99+void UbuntuGMenuModelExporter::aboutToShow(quint64 tag)
100+{
101+ UbuntuPlatformMenu* gplatformMenu = m_submenusWithTag.value(tag);
102+ if (!gplatformMenu) {
103+ qWarning() << "Got an aboutToShow call with an unknown tag";
104+ return;
105+ }
106+
107+ gplatformMenu->aboutToShow();
108 }
109
110 // Unexport the model
111@@ -194,6 +257,11 @@
112 g_dbus_connection_unexport_action_group(m_connection, m_exportedActions);
113 m_exportedActions = 0;
114 }
115+ if (m_qtubuntuExtraHandler) {
116+ m_qtubuntuExtraHandler->disconnect(m_connection);
117+ delete m_qtubuntuExtraHandler;
118+ m_qtubuntuExtraHandler = nullptr;
119+ }
120 g_object_unref(m_connection);
121 m_connection = nullptr;
122 }
123@@ -207,6 +275,8 @@
124 if (!gplatformMenu) return nullptr;
125 GMenu* menu = g_menu_new();
126
127+ m_gmenusForMenus.insert(gplatformMenu, menu);
128+
129 QByteArray label;
130 if (forItem) {
131 label = UbuntuPlatformMenuItem::get_text(forItem).toUtf8();
132@@ -217,7 +287,32 @@
133 addSubmenuItems(gplatformMenu, menu);
134
135 GMenuItem* gmenuItem = g_menu_item_new_submenu(label.constData(), G_MENU_MODEL(menu));
136+ const quint64 tag = gplatformMenu->tag();
137+ if (tag != 0) {
138+ g_menu_item_set_attribute_value(gmenuItem, "qtubuntu-tag", g_variant_new_uint64 (tag));
139+ m_submenusWithTag.insert(gplatformMenu->tag(), gplatformMenu);
140+ }
141 g_object_unref(menu);
142+
143+ connect(gplatformMenu, &UbuntuPlatformMenu::structureChanged, this, [this, gplatformMenu, menu]
144+ {
145+ if (!m_reloadMenuTimers.contains(gplatformMenu)) {
146+ const int timerId = startTimer(0);
147+ m_reloadMenuTimers.insert(gplatformMenu, timerId);
148+ }
149+ });
150+
151+ connect(gplatformMenu, &UbuntuPlatformMenu::destroyed, this, [this, tag, gplatformMenu]
152+ {
153+ m_submenusWithTag.remove(tag);
154+ m_gmenusForMenus.remove(gplatformMenu);
155+ auto timerIdIt = m_reloadMenuTimers.find(gplatformMenu);
156+ if (timerIdIt != m_reloadMenuTimers.end()) {
157+ killTimer(*timerIdIt);
158+ m_reloadMenuTimers.erase(timerIdIt);
159+ }
160+ });
161+
162 return gmenuItem;
163 }
164
165@@ -256,7 +351,7 @@
166
167 // Create and return a gmenu item for the given platform menu item.
168 // Returned GMenuItem must be cleaned up using g_object_unref
169-GMenuItem *UbuntuGMenuModelExporter::createMenuItem(QPlatformMenuItem *platformMenuItem)
170+GMenuItem *UbuntuGMenuModelExporter::createMenuItem(QPlatformMenuItem *platformMenuItem, GMenu *parentMenu)
171 {
172 UbuntuPlatformMenuItem* gplatformMenuItem = static_cast<UbuntuPlatformMenuItem*>(platformMenuItem);
173 if (!gplatformMenuItem) return nullptr;
174@@ -269,7 +364,7 @@
175 g_menu_item_set_attribute(gmenuItem, "accel", "s", shortcut.constData());
176 g_menu_item_set_detailed_action(gmenuItem, ("unity." + actionLabel).constData());
177
178- addAction(actionLabel, gplatformMenuItem);
179+ addAction(actionLabel, gplatformMenuItem, parentMenu);
180 return gmenuItem;
181 }
182
183@@ -294,7 +389,7 @@
184 if (!gplatformMenuItem) return;
185
186 GMenuItem* gmenuItem = gplatformMenuItem->menu() ? createSubmenu(gplatformMenuItem->menu(), gplatformMenuItem) :
187- createMenuItem(gplatformMenuItem);
188+ createMenuItem(gplatformMenuItem, gmenu);
189 if (gmenuItem) {
190 g_menu_append_item(gmenu, gmenuItem);
191 g_object_unref(gmenuItem);
192@@ -302,14 +397,17 @@
193 }
194
195 // Create and add an action for a menu item.
196-void UbuntuGMenuModelExporter::addAction(const QByteArray &name, UbuntuPlatformMenuItem *gplatformMenuItem)
197+void UbuntuGMenuModelExporter::addAction(const QByteArray &name, UbuntuPlatformMenuItem *gplatformMenuItem, GMenu *parentMenu)
198 {
199 disconnect(gplatformMenuItem, &UbuntuPlatformMenuItem::checkedChanged, this, 0);
200 disconnect(gplatformMenuItem, &UbuntuPlatformMenuItem::enabledChanged, this, 0);
201
202- if (m_actions.contains(name)) {
203+ QSet<QByteArray> &actions = m_actions[parentMenu];
204+ QVector<QMetaObject::Connection> &propertyConnections = m_propertyConnections[parentMenu];
205+
206+ if (actions.contains(name)) {
207 g_action_map_remove_action(G_ACTION_MAP(m_gactionGroup), name.constData());
208- m_actions.remove(name);
209+ actions.remove(name);
210 }
211
212 bool checkable = UbuntuPlatformMenuItem::get_checkable(gplatformMenuItem);
213@@ -326,7 +424,7 @@
214 }
215 };
216 // save the connection to disconnect in UbuntuGMenuModelExporter::clear()
217- m_propertyConnections << connect(gplatformMenuItem, &UbuntuPlatformMenuItem::checkedChanged, this, updateChecked);
218+ propertyConnections << connect(gplatformMenuItem, &UbuntuPlatformMenuItem::checkedChanged, this, updateChecked);
219 } else {
220 action = g_simple_action_new(name.constData(), nullptr);
221 }
222@@ -340,11 +438,11 @@
223 };
224 updateEnabled(UbuntuPlatformMenuItem::get_enabled(gplatformMenuItem));
225 // save the connection to disconnect in UbuntuGMenuModelExporter::clear()
226- m_propertyConnections << connect(gplatformMenuItem, &UbuntuPlatformMenuItem::enabledChanged, this, updateEnabled);
227+ propertyConnections << connect(gplatformMenuItem, &UbuntuPlatformMenuItem::enabledChanged, this, updateEnabled);
228
229 g_signal_connect(action, "activate", G_CALLBACK(activate_cb), gplatformMenuItem);
230
231- m_actions.insert(name);
232+ actions.insert(name);
233 g_action_map_add_action(G_ACTION_MAP(m_gactionGroup), G_ACTION(action));
234 g_object_unref(action);
235 }
236
237=== modified file 'src/ubuntuappmenu/gmenumodelexporter.h'
238--- src/ubuntuappmenu/gmenumodelexporter.h 2016-09-30 08:35:16 +0000
239+++ src/ubuntuappmenu/gmenumodelexporter.h 2017-03-16 09:42:42 +0000
240@@ -22,9 +22,12 @@
241 #include <gio/gio.h>
242
243 #include <QTimer>
244+#include <QMap>
245 #include <QSet>
246 #include <QMetaObject>
247
248+class QtUbuntuExtraActionHandler;
249+
250 // Base class for a gmenumodel exporter
251 class UbuntuGMenuModelExporter : public QObject
252 {
253@@ -37,30 +40,44 @@
254
255 QString menuPath() const { return m_menuPath;}
256
257+ void aboutToShow(quint64 tag);
258+
259 protected:
260 UbuntuGMenuModelExporter(QObject *parent);
261
262 GMenuItem *createSubmenu(QPlatformMenu* platformMenu, UbuntuPlatformMenuItem* forItem);
263- GMenuItem *createMenuItem(QPlatformMenuItem* platformMenuItem);
264+ GMenuItem *createMenuItem(QPlatformMenuItem* platformMenuItem, GMenu *parentMenu);
265 GMenuItem *createSection(QList<QPlatformMenuItem*>::const_iterator iter, QList<QPlatformMenuItem*>::const_iterator end);
266- void addAction(const QByteArray& name, UbuntuPlatformMenuItem* gplatformItem);
267+ void addAction(const QByteArray& name, UbuntuPlatformMenuItem* gplatformItem, GMenu *parentMenu);
268
269 void addSubmenuItems(UbuntuPlatformMenu* gplatformMenu, GMenu* menu);
270 void processItemForGMenu(QPlatformMenuItem* item, GMenu* gmenu);
271
272 void clear();
273
274+ void timerEvent(QTimerEvent *e) override;
275+
276 protected:
277 GDBusConnection *m_connection;
278 GMenu *m_gmainMenu;
279 GSimpleActionGroup *m_gactionGroup;
280- QSet<QByteArray> m_actions;
281 guint m_exportedModel;
282 guint m_exportedActions;
283+ QtUbuntuExtraActionHandler *m_qtubuntuExtraHandler;
284 QTimer m_structureTimer;
285 QString m_menuPath;
286
287- QVector<QMetaObject::Connection> m_propertyConnections;
288+ // UbuntuPlatformMenu::tag -> UbuntuPlatformMenu
289+ QMap<quint64, UbuntuPlatformMenu*> m_submenusWithTag;
290+
291+ // UbuntuPlatformMenu -> reload TimerId (startTimer)
292+ QHash<UbuntuPlatformMenu*, int> m_reloadMenuTimers;
293+
294+ QHash<UbuntuPlatformMenu*, GMenu*> m_gmenusForMenus;
295+
296+ QHash<GMenu*, QSet<QByteArray>> m_actions;
297+ QHash<GMenu*, QVector<QMetaObject::Connection>> m_propertyConnections;
298+
299 };
300
301 // Class which exports a qt platform menu bar.
302
303=== modified file 'src/ubuntuappmenu/gmenumodelplatformmenu.cpp'
304--- src/ubuntuappmenu/gmenumodelplatformmenu.cpp 2017-03-02 09:53:52 +0000
305+++ src/ubuntuappmenu/gmenumodelplatformmenu.cpp 2017-03-16 09:42:42 +0000
306@@ -81,8 +81,6 @@
307 }
308 }
309 }
310- connect(static_cast<UbuntuPlatformMenu*>(menu), &UbuntuPlatformMenu::structureChanged,
311- this, &UbuntuPlatformMenuBar::structureChanged);
312 Q_EMIT menuInserted(menu);
313 }
314
315@@ -97,8 +95,6 @@
316 break;
317 }
318 }
319- disconnect(static_cast<UbuntuPlatformMenu*>(menu), &UbuntuPlatformMenu::structureChanged,
320- this, &UbuntuPlatformMenuBar::structureChanged);
321 Q_EMIT menuRemoved(menu);
322 }
323
324
325=== added file 'src/ubuntuappmenu/qtubuntuextraactionhandler.cpp'
326--- src/ubuntuappmenu/qtubuntuextraactionhandler.cpp 1970-01-01 00:00:00 +0000
327+++ src/ubuntuappmenu/qtubuntuextraactionhandler.cpp 2017-03-16 09:42:42 +0000
328@@ -0,0 +1,107 @@
329+/*
330+ * Copyright (C) 2017 Canonical, Ltd.
331+ *
332+ * This program is free software: you can redistribute it and/or modify it under
333+ * the terms of the GNU Lesser General Public License version 3, as published by
334+ * the Free Software Foundation.
335+ *
336+ * This program is distributed in the hope that it will be useful, but WITHOUT
337+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
338+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
339+ * Lesser General Public License for more details.
340+ *
341+ * You should have received a copy of the GNU Lesser General Public License
342+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
343+ */
344+
345+#include "qtubuntuextraactionhandler.h"
346+
347+#include "gmenumodelexporter.h"
348+#include "logging.h"
349+
350+static const gchar introspection_xml[] =
351+ "<node>"
352+ " <interface name='qtubuntu.actions.extra'>"
353+ " <method name='aboutToShow'>"
354+ " <arg type='t' name='tag' direction='in'/>"
355+ " </method>"
356+ " </interface>"
357+ "</node>";
358+
359+static void handle_method_call (GDBusConnection *,
360+ const gchar *,
361+ const gchar *,
362+ const gchar *,
363+ const gchar *method_name,
364+ GVariant *parameters,
365+ GDBusMethodInvocation *invocation,
366+ gpointer user_data)
367+{
368+
369+ if (g_strcmp0 (method_name, "aboutToShow") == 0)
370+ {
371+ if (g_variant_check_format_string(parameters, "(t)", false)) {
372+ auto obj = static_cast<UbuntuGMenuModelExporter*>(user_data);
373+ guint64 tag;
374+
375+ g_variant_get (parameters, "(t)", &tag);
376+ obj->aboutToShow(tag);
377+ }
378+
379+ g_dbus_method_invocation_return_value (invocation, NULL);
380+ } else {
381+ g_dbus_method_invocation_return_error(invocation,
382+ G_DBUS_ERROR,
383+ G_DBUS_ERROR_UNKNOWN_METHOD,
384+ "Unknown method");
385+ }
386+}
387+
388+
389+static const GDBusInterfaceVTable interface_vtable =
390+{
391+ handle_method_call,
392+ NULL,
393+ NULL,
394+ NULL
395+};
396+
397+QtUbuntuExtraActionHandler::QtUbuntuExtraActionHandler()
398+ : m_registration_id(0)
399+{
400+ m_introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
401+}
402+
403+QtUbuntuExtraActionHandler::~QtUbuntuExtraActionHandler()
404+{
405+ g_clear_pointer(&m_introspection_data, g_dbus_node_info_unref);
406+}
407+
408+bool QtUbuntuExtraActionHandler::connect(GDBusConnection *connection, const QByteArray &menuPath, UbuntuGMenuModelExporter *gmenuexporter)
409+{
410+ if (m_registration_id != 0) {
411+ qCWarning(ubuntuappmenu, "Called connect in an already connected QtUbuntuExtraActionHandler");
412+ return false;
413+ }
414+
415+ GError *error = nullptr;
416+ m_registration_id = g_dbus_connection_register_object (connection, menuPath.constData(),
417+ m_introspection_data->interfaces[0],
418+ &interface_vtable,
419+ gmenuexporter,
420+ nullptr,
421+ &error);
422+
423+ if (!m_registration_id) {
424+ qCWarning(ubuntuappmenu, "Failed to extra actions - %s", error ? error->message : "unknown error");
425+ g_clear_error(&error);
426+ }
427+
428+ return m_registration_id != 0;
429+}
430+
431+void QtUbuntuExtraActionHandler::disconnect(GDBusConnection *connection) {
432+ if (m_registration_id) {
433+ g_dbus_connection_unregister_object (connection, m_registration_id);
434+ }
435+}
436
437=== added file 'src/ubuntuappmenu/qtubuntuextraactionhandler.h'
438--- src/ubuntuappmenu/qtubuntuextraactionhandler.h 1970-01-01 00:00:00 +0000
439+++ src/ubuntuappmenu/qtubuntuextraactionhandler.h 2017-03-16 09:42:42 +0000
440@@ -0,0 +1,40 @@
441+/*
442+ * Copyright (C) 2017 Canonical, Ltd.
443+ *
444+ * This program is free software: you can redistribute it and/or modify it under
445+ * the terms of the GNU Lesser General Public License version 3, as published by
446+ * the Free Software Foundation.
447+ *
448+ * This program is distributed in the hope that it will be useful, but WITHOUT
449+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
450+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
451+ * Lesser General Public License for more details.
452+ *
453+ * You should have received a copy of the GNU Lesser General Public License
454+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
455+ */
456+
457+#ifndef QTUBUNTUEXTRAACTIONHANDLER_H
458+#define QTUBUNTUEXTRAACTIONHANDLER_H
459+
460+#include <gio/gio.h>
461+
462+class QByteArray;
463+
464+class UbuntuGMenuModelExporter;
465+
466+class QtUbuntuExtraActionHandler
467+{
468+public:
469+ QtUbuntuExtraActionHandler();
470+ ~QtUbuntuExtraActionHandler();
471+
472+ bool connect(GDBusConnection *connection, const QByteArray &menuPath, UbuntuGMenuModelExporter *gmenuexporter);
473+ void disconnect(GDBusConnection *connection);
474+
475+private:
476+ GDBusNodeInfo *m_introspection_data;
477+ guint m_registration_id;
478+};
479+
480+#endif
481
482=== modified file 'src/ubuntuappmenu/ubuntuappmenu.pro'
483--- src/ubuntuappmenu/ubuntuappmenu.pro 2016-06-21 16:33:19 +0000
484+++ src/ubuntuappmenu/ubuntuappmenu.pro 2017-03-16 09:42:42 +0000
485@@ -22,7 +22,8 @@
486 logging.h \
487 menuregistrar.h \
488 registry.h \
489- themeplugin.h
490+ themeplugin.h \
491+ qtubuntuextraactionhandler.h
492
493 SOURCES += \
494 theme.cpp \
495@@ -30,7 +31,8 @@
496 gmenumodelplatformmenu.cpp \
497 menuregistrar.cpp \
498 registry.cpp \
499- themeplugin.cpp
500+ themeplugin.cpp \
501+ qtubuntuextraactionhandler.cpp
502
503 OTHER_FILES += \
504 ubuntuappmenu.json

Subscribers

People subscribed via source and target branches