Merge lp:~gerboland/qtubuntu/remove-content-hub-and-ual into lp:qtubuntu

Proposed by Gerry Boland
Status: Approved
Approved by: Gerry Boland
Approved revision: 398
Proposed branch: lp:~gerboland/qtubuntu/remove-content-hub-and-ual
Merge into: lp:qtubuntu
Diff against target: 3616 lines (+244/-2858)
31 files modified
debian/control (+15/-34)
debian/qtubuntu-appmenutheme.install (+0/-1)
debian/rules (+0/-1)
src/src.pro (+1/-1)
src/ubuntuappmenu/com.ubuntu.MenuRegistrar.xml (+0/-83)
src/ubuntuappmenu/gmenumodelexporter.cpp (+0/-475)
src/ubuntuappmenu/gmenumodelexporter.h (+0/-100)
src/ubuntuappmenu/gmenumodelplatformmenu.cpp (+0/-518)
src/ubuntuappmenu/gmenumodelplatformmenu.h (+0/-181)
src/ubuntuappmenu/logging.h (+0/-27)
src/ubuntuappmenu/menuregistrar.cpp (+0/-137)
src/ubuntuappmenu/menuregistrar.h (+0/-59)
src/ubuntuappmenu/qtubuntuextraactionhandler.cpp (+0/-107)
src/ubuntuappmenu/qtubuntuextraactionhandler.h (+0/-40)
src/ubuntuappmenu/registry.cpp (+0/-97)
src/ubuntuappmenu/registry.h (+0/-56)
src/ubuntuappmenu/theme.cpp (+0/-67)
src/ubuntuappmenu/theme.h (+0/-36)
src/ubuntuappmenu/themeplugin.cpp (+0/-36)
src/ubuntuappmenu/themeplugin.h (+0/-34)
src/ubuntuappmenu/ubuntuappmenu.json (+0/-3)
src/ubuntuappmenu/ubuntuappmenu.pro (+0/-44)
src/ubuntumirclient/qmirclientclipboard.cpp (+0/-180)
src/ubuntumirclient/qmirclientclipboard.h (+0/-92)
src/ubuntumirclient/qmirclientcursor.cpp (+68/-25)
src/ubuntumirclient/qmirclientintegration.cpp (+74/-117)
src/ubuntumirclient/qmirclientintegration.h (+3/-18)
src/ubuntumirclient/qmirclientplatformservices.cpp (+0/-75)
src/ubuntumirclient/qmirclientplatformservices.h (+0/-57)
src/ubuntumirclient/qmirclientwindow.cpp (+80/-150)
src/ubuntumirclient/ubuntumirclient.pro (+3/-7)
To merge this branch: bzr merge lp:~gerboland/qtubuntu/remove-content-hub-and-ual
Reviewer Review Type Date Requested Status
Unity8 CI Bot continuous-integration Needs Fixing
Alberto Aguirre (community) Approve
Review via email: mp+328528@code.launchpad.net

Commit message

Completely remove dependency on platform-api and content-hub

Use Qt's built-in platform services for URL launching, which platform-api used to deal with.
Totally remove clipboard support

Based on https://code.launchpad.net/~albaguirre/qtubuntu/papi-cleanup/+merge/324886

To post a comment you must log in.
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

LGTM.

review: Approve
398. By Gerry Boland

Remove another ref to papi

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

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

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

review: Approve (continuous-integration)
399. By Gerry Boland

Merge trunk and fix conflicts

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Gerry Boland (gerboland) wrote :

CI needs to be reconfigured to build against artful

Unmerged revisions

399. By Gerry Boland

Merge trunk and fix conflicts

398. By Gerry Boland

Remove another ref to papi

397. By Gerry Boland

Reduce delta

396. By Gerry Boland

Restore basic platform services

395. By Gerry Boland

Remove clipboard implementation using content-hub

394. By Gerry Boland

Merge papi-cleanup and fix

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2017-01-10 06:41:48 +0000
3+++ debian/control 2017-08-25 11:54:50 +0000
4@@ -3,17 +3,14 @@
5 Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
6 Build-Depends: debhelper (>= 9),
7 libatspi2.0-dev,
8- libcontent-hub-dev (>= 0.2),
9- libegl1-mesa-dev,
10+ libegl1-mesa-dev (>= 17.0.2),
11 libfontconfig1-dev,
12 libfreetype6-dev,
13- libgles2-mesa-dev,
14+ libgles2-mesa-dev (>= 17.0.2),
15 libglib2.0-dev,
16 libinput-dev,
17- libmirclient-dev (>= 0.25.0),
18- libmirclient-debug-extension-dev,
19+ libmirclient-dev (>= 0.26.1),
20 libmtdev-dev,
21- libubuntu-application-api-dev (>= 2.9.0),
22 libudev-dev,
23 libxkbcommon-dev,
24 libxrender-dev,
25@@ -30,20 +27,18 @@
26 Architecture: arm64 armhf
27 Multi-Arch: same
28 Conflicts: qtubuntu-desktop,
29+ qtubuntu-appmenutheme,
30 Replaces: qtubuntu (<< 0.52),
31 qtubuntu-desktop,
32+ qtubuntu-appmenutheme,
33 Breaks: ubuntu-touch-session (<< 0.107),
34 unity8 (<< 7.85),
35 Provides: qtubuntu,
36-Depends: ubuntu-application-api3-touch,
37- ${misc:Depends},
38+ qtubuntu-appmenutheme
39+Depends: ${misc:Depends},
40 ${shlibs:Depends},
41-Description: Qt plugins for Ubuntu Platform API (mobile)
42- QtUbuntu is a set of Qt5 components for the Ubuntu Platform API. It contains a
43- QPA (Qt Platform Abstraction) plugin based on the Ubuntu Platform API and a
44- legacy QPA plugin based on the compatibility layers. It also provides Qt
45- bindings for Ubuntu Platform API features that are not exposed through the QPA
46- plugins.
47+Description: Qt plugins for Mir support on Ubuntu (mobile)
48+ QtUbuntu is a QPA plugin for Qt5 adding support for the Mir display server.
49 .
50 This variant of the package is for Android-based phones and tablets.
51
52@@ -51,30 +46,16 @@
53 Architecture: any
54 Multi-Arch: same
55 Conflicts: qtubuntu-android,
56+ qtubuntu-appmenutheme,
57 Replaces: qtubuntu (<< 0.52),
58 qtubuntu-android,
59+ qtubuntu-appmenutheme,
60 Breaks: unity8 (<< 7.85),
61 Provides: qtubuntu,
62-Depends: ubuntu-application-api3-desktop,
63- ${misc:Depends},
64+ qtubuntu-appmenutheme,
65+Depends: ${misc:Depends},
66 ${shlibs:Depends},
67-Description: Qt plugins for Ubuntu Platform API (desktop)
68- QtUbuntu is a set of Qt5 components for the Ubuntu Platform API. It contains a
69- QPA (Qt Platform Abstraction) plugin based on the Ubuntu Platform API and a
70- legacy QPA plugin based on the compatibility layers. It also provides Qt
71- bindings for Ubuntu Platform API features that are not exposed through the QPA
72- plugins.
73+Description: Qt plugins for Mir support on Ubuntu (desktop)
74+ QtUbuntu is a QPA plugin for Qt5 adding support for the Mir display server.
75 .
76 This variant of the package is for GNU-based desktops.
77-
78-Package: qtubuntu-appmenutheme
79-Architecture: any
80-Multi-Arch: same
81-Depends: ${misc:Depends},
82- ${shlibs:Depends},
83-Description: Qt platform theme for exported application menus
84- Appmenutheme enables the export of application menus to a global menu bar.
85- It is implemented in a QPA platform theme plugin.
86- .
87- This package will work for applications designed for Qt5, as well as QML
88- applications
89
90=== removed file 'debian/qtubuntu-appmenutheme.install'
91--- debian/qtubuntu-appmenutheme.install 2016-06-17 12:40:26 +0000
92+++ debian/qtubuntu-appmenutheme.install 1970-01-01 00:00:00 +0000
93@@ -1,1 +0,0 @@
94-usr/lib/*/qt5/plugins/platformthemes/*
95
96=== modified file 'debian/rules'
97--- debian/rules 2016-06-17 12:40:26 +0000
98+++ debian/rules 2017-08-25 11:54:50 +0000
99@@ -62,4 +62,3 @@
100 dh_install --sourcedir=$(TMP1_DIR) -pqtubuntu-android
101 endif
102 dh_install --sourcedir=$(TMP2_DIR) -pqtubuntu-desktop
103- dh_install --sourcedir=$(TMP2_DIR) -pqtubuntu-appmenutheme
104
105=== modified file 'src/src.pro'
106--- src/src.pro 2016-06-21 16:33:19 +0000
107+++ src/src.pro 2017-08-25 11:54:50 +0000
108@@ -1,3 +1,3 @@
109 TEMPLATE = subdirs
110
111-SUBDIRS += ubuntumirclient ubuntuappmenu
112+SUBDIRS += ubuntumirclient
113
114=== removed directory 'src/ubuntuappmenu'
115=== removed file 'src/ubuntuappmenu/com.ubuntu.MenuRegistrar.xml'
116--- src/ubuntuappmenu/com.ubuntu.MenuRegistrar.xml 2016-09-29 10:24:29 +0000
117+++ src/ubuntuappmenu/com.ubuntu.MenuRegistrar.xml 1970-01-01 00:00:00 +0000
118@@ -1,83 +0,0 @@
119-<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
120-<node xmlns:dox="http://www.ayatana.org/dbus/dox.dtd">
121- <dox:d><![CDATA[
122- @mainpage
123-
124- An interface to register menus that are associated with a window in an application. The
125- main interface is documented here: @ref com::ubuntu::MenuRegistrar.
126-
127- The actual menus are transported using the gmenumodel protocol
128- ]]></dox:d>
129- <interface name="com.ubuntu.MenuRegistrar" xmlns:dox="http://www.ayatana.org/dbus/dox.dtd">
130- <dox:d>
131- An interface to register a menu from an application to be displayed in another
132- window. This manages that association between processes and/or Mir surface IDs and the dbus
133- address and object that provides the menus using the org.gtk.Menus interface.
134- </dox:d>
135- <method name="RegisterAppMenu">
136- <dox:d><![CDATA[
137- Associates a gmenumodel with an application
138-
139- /note this method assumes that the connection from the caller is the DBus connection
140- to use for the object. Applications that use multiple DBus connections will need to
141- ensure this method is called with the same connection that implements the object.
142- ]]></dox:d>
143- <arg name="pid" type="u" direction="in">
144- <dox:d>The process ID of the application for which the menu is associated</dox:d>
145- </arg>
146- <arg name="menuObjectPath" type="o" direction="in">
147- <dox:d>The dbus path where the gmenumodel interface for the application menu has been exported</dox:d>
148- </arg>
149- <arg name="actionObjectPath" type="o" direction="in">
150- <dox:d>The dbus path where the gactionmenu interface for the application menu actions has been exported</dox:d>
151- </arg>
152- <arg name="service" type="s" direction="in">
153- <dox:d>The dbus conection name of the client application to be registered (e.g. :1.23 or org.example.service)</dox:d>
154- </arg>
155- </method>
156- <method name="UnregisterAppMenu">
157- <dox:d>
158- A method to allow removing an application menu from the database.
159- </dox:d>
160- <arg name="pid" type="u" direction="in">
161- <dox:d>The process id of the application</dox:d>
162- </arg>
163- <arg name="menuObjectPath" type="o" direction="in">
164- <dox:d>The dbus path for the registered application menu to be unregistered</dox:d>
165- </arg>
166- </method>
167-
168- <method name="RegisterSurfaceMenu">
169- <dox:d><![CDATA[
170- Associates a gmenumodel with a surface
171-
172- /note this method assumes that the connection from the caller is the DBus connection
173- to use for the object. Applications that use multiple DBus connections will need to
174- ensure this method is called with the same connection that implements the object.
175- ]]></dox:d>
176- <arg name="surface" type="s" direction="in">
177- <dox:d>The surface ID of the surface</dox:d>
178- </arg>
179- <arg name="menuObjectPath" type="o" direction="in">
180- <dox:d>The dbus path where the gmenumodel interface for the surface menu has been exported</dox:d>
181- </arg>
182- <arg name="actionObjectPath" type="o" direction="in">
183- <dox:d>The dbus path where the gactionmenu interface for the surface menu actions has been exported</dox:d>
184- </arg>
185- <arg name="service" type="s" direction="in">
186- <dox:d>The dbus conection name of the client application to be registered (e.g. :1.23 or org.example.service)</dox:d>
187- </arg>
188- </method>
189- <method name="UnregisterSurfaceMenu">
190- <dox:d>
191- A method to allow removing a surface menu from the database.
192- </dox:d>
193- <arg name="surfaceId" type="s" direction="in">
194- <dox:d>The surface id of the surface</dox:d>
195- </arg>
196- <arg name="menuObjectPath" type="o" direction="in">
197- <dox:d>The dbus path for the registered surface menu to be unregistered</dox:d>
198- </arg>
199- </method>
200- </interface>
201-</node>
202
203=== removed file 'src/ubuntuappmenu/gmenumodelexporter.cpp'
204--- src/ubuntuappmenu/gmenumodelexporter.cpp 2017-03-27 08:23:00 +0000
205+++ src/ubuntuappmenu/gmenumodelexporter.cpp 1970-01-01 00:00:00 +0000
206@@ -1,475 +0,0 @@
207-/*
208- * Copyright (C) 2016 Canonical, Ltd.
209- *
210- * This program is free software: you can redistribute it and/or modify it under
211- * the terms of the GNU Lesser General Public License version 3, as published by
212- * the Free Software Foundation.
213- *
214- * This program is distributed in the hope that it will be useful, but WITHOUT
215- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
216- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
217- * Lesser General Public License for more details.
218- *
219- * You should have received a copy of the GNU Lesser General Public License
220- * along with this program. If not, see <http://www.gnu.org/licenses/>.
221- */
222-
223-// Local
224-#include "gmenumodelexporter.h"
225-#include "registry.h"
226-#include "logging.h"
227-#include "qtubuntuextraactionhandler.h"
228-
229-#include <QDebug>
230-#include <QTimerEvent>
231-
232-#include <functional>
233-
234-namespace {
235-
236-// Derive an action name from the label by removing spaces and Capitilizing the words.
237-// Also remove mnemonics from the label.
238-inline QString getActionString(QString label)
239-{
240- QRegExp re("\\W");
241- label = label.replace(QRegExp("(&|_)"), "");
242- QStringList parts = label.split(re, QString::SkipEmptyParts);
243-
244- QString result;
245- Q_FOREACH(const QString& part, parts) {
246- result += part[0].toUpper();
247- result += part.right(part.length()-1);
248- }
249- return result;
250-}
251-
252-static void activate_cb(GSimpleAction *action, GVariant *, gpointer user_data)
253-{
254- qCDebug(ubuntuappmenu, "Activate menu action '%s'", g_action_get_name(G_ACTION(action)));
255- auto item = static_cast<UbuntuPlatformMenuItem*>(user_data);
256- item->activated();
257-}
258-
259-static uint s_menuId = 0;
260-
261-#define MENU_OBJECT_PATH "/com/ubuntu/Menu/%1"
262-
263-} // namespace
264-
265-
266-UbuntuMenuBarExporter::UbuntuMenuBarExporter(UbuntuPlatformMenuBar * bar)
267- : UbuntuGMenuModelExporter(bar)
268-{
269- qCDebug(ubuntuappmenu, "UbuntuMenuBarExporter::UbuntuMenuBarExporter");
270-
271- connect(bar, &UbuntuPlatformMenuBar::structureChanged, this, [this]() {
272- m_structureTimer.start();
273- });
274- connect(&m_structureTimer, &QTimer::timeout, this, [this, bar]() {
275- clear();
276- Q_FOREACH(QPlatformMenu *platformMenu, bar->menus()) {
277- GMenuItem* item = createSubmenu(platformMenu, nullptr);
278- if (item) {
279- g_menu_append_item(m_gmainMenu, item);
280- g_object_unref(item);
281- }
282-
283- UbuntuPlatformMenu* gplatformMenu = static_cast<UbuntuPlatformMenu*>(platformMenu);
284- if (gplatformMenu) {
285- // Sadly we don't have a better way to propagate a enabled change in a top level menu
286- // than reseting the whole menubar
287- connect(gplatformMenu, &UbuntuPlatformMenu::enabledChanged, bar, &UbuntuPlatformMenuBar::structureChanged);
288- }
289- }
290- });
291-
292- connect(bar, &UbuntuPlatformMenuBar::ready, this, [this]() {
293- exportModels();
294- });
295-}
296-
297-UbuntuMenuBarExporter::~UbuntuMenuBarExporter()
298-{
299- qCDebug(ubuntuappmenu, "UbuntuMenuBarExporter::~UbuntuMenuBarExporter");
300-}
301-
302-UbuntuMenuExporter::UbuntuMenuExporter(UbuntuPlatformMenu *menu)
303- : UbuntuGMenuModelExporter(menu)
304-{
305- qCDebug(ubuntuappmenu, "UbuntuMenuExporter::UbuntuMenuExporter");
306-
307- connect(menu, &UbuntuPlatformMenu::structureChanged, this, [this]() {
308- m_structureTimer.start();
309- });
310- connect(&m_structureTimer, &QTimer::timeout, this, [this, menu]() {
311- clear();
312- addSubmenuItems(menu, m_gmainMenu);
313- });
314- addSubmenuItems(menu, m_gmainMenu);
315-}
316-
317-UbuntuMenuExporter::~UbuntuMenuExporter()
318-{
319- qCDebug(ubuntuappmenu, "UbuntuMenuExporter::~UbuntuMenuExporter");
320-}
321-
322-UbuntuGMenuModelExporter::UbuntuGMenuModelExporter(QObject *parent)
323- : QObject(parent)
324- , m_connection(nullptr)
325- , m_gmainMenu(g_menu_new())
326- , m_gactionGroup(g_simple_action_group_new())
327- , m_exportedModel(0)
328- , m_exportedActions(0)
329- , m_qtubuntuExtraHandler(nullptr)
330- , m_menuPath(QStringLiteral(MENU_OBJECT_PATH).arg(s_menuId++))
331-{
332- m_structureTimer.setSingleShot(true);
333- m_structureTimer.setInterval(0);
334-}
335-
336-UbuntuGMenuModelExporter::~UbuntuGMenuModelExporter()
337-{
338- unexportModels();
339- clear();
340-
341- g_object_unref(m_gmainMenu);
342- g_object_unref(m_gactionGroup);
343-}
344-
345-// Clear the menu and actions that have been created.
346-void UbuntuGMenuModelExporter::clear()
347-{
348- Q_FOREACH(const QVector<QMetaObject::Connection>& menuPropertyConnections, m_propertyConnections) {
349- Q_FOREACH(const QMetaObject::Connection& connection, menuPropertyConnections) {
350- QObject::disconnect(connection);
351- }
352- }
353- m_propertyConnections.clear();
354-
355- g_menu_remove_all(m_gmainMenu);
356-
357- Q_FOREACH(const QSet<QByteArray>& menuActions, m_actions) {
358- Q_FOREACH(const QByteArray& action, menuActions) {
359- g_action_map_remove_action(G_ACTION_MAP(m_gactionGroup), action.constData());
360- }
361- }
362- m_actions.clear();
363-
364- m_gmenusForMenus.clear();
365-}
366-
367-void UbuntuGMenuModelExporter::timerEvent(QTimerEvent *e)
368-{
369- // Find the menu, it's a very short list
370- auto it = m_reloadMenuTimers.begin();
371- for (; it != m_reloadMenuTimers.end(); ++it) {
372- if (e->timerId() == it.value())
373- break;
374- }
375-
376- if (it != m_reloadMenuTimers.end()) {
377- UbuntuPlatformMenu* gplatformMenu = it.key();
378- GMenu *menu = m_gmenusForMenus.value(gplatformMenu);
379- if (menu) {
380- Q_FOREACH(const QMetaObject::Connection& connection, m_propertyConnections[menu]) {
381- QObject::disconnect(connection);
382- }
383- m_propertyConnections.remove(menu);
384- Q_FOREACH(const QByteArray& action, m_actions[menu]) {
385- g_action_map_remove_action(G_ACTION_MAP(m_gactionGroup), action.constData());
386- }
387- m_actions.remove(menu);
388- g_menu_remove_all(menu);
389- addSubmenuItems(gplatformMenu, menu);
390- } else {
391- qWarning() << "Got an update timer for a menu that has no GMenu" << gplatformMenu;
392- }
393-
394- m_reloadMenuTimers.erase(it);
395- } else {
396- qWarning() << "Got an update timer for a timer that was not running";
397- }
398- killTimer(e->timerId());
399-}
400-
401-// Export the model on dbus
402-void UbuntuGMenuModelExporter::exportModels()
403-{
404- GError *error = nullptr;
405- m_connection = g_bus_get_sync (G_BUS_TYPE_SESSION, nullptr, &error);
406- if (!m_connection) {
407- qCWarning(ubuntuappmenu, "Failed to retreive session bus - %s", error ? error->message : "unknown error");
408- g_error_free (error);
409- return;
410- }
411-
412- QByteArray menuPath(m_menuPath.toUtf8());
413-
414- if (m_exportedModel == 0) {
415- m_exportedModel = g_dbus_connection_export_menu_model(m_connection, menuPath.constData(), G_MENU_MODEL(m_gmainMenu), &error);
416- if (m_exportedModel == 0) {
417- qCWarning(ubuntuappmenu, "Failed to export menu - %s", error ? error->message : "unknown error");
418- g_error_free (error);
419- error = nullptr;
420- } else {
421- qCDebug(ubuntuappmenu, "Exported menu on %s", g_dbus_connection_get_unique_name(m_connection));
422- }
423- }
424-
425- if (m_exportedActions == 0) {
426- m_exportedActions = g_dbus_connection_export_action_group(m_connection, menuPath.constData(), G_ACTION_GROUP(m_gactionGroup), &error);
427- if (m_exportedActions == 0) {
428- qCWarning(ubuntuappmenu, "Failed to export actions - %s", error ? error->message : "unknown error");
429- g_error_free (error);
430- error = nullptr;
431- } else {
432- qCDebug(ubuntuappmenu, "Exported actions on %s", g_dbus_connection_get_unique_name(m_connection));
433- }
434- }
435-
436- if (!m_qtubuntuExtraHandler) {
437- m_qtubuntuExtraHandler = new QtUbuntuExtraActionHandler();
438- if (!m_qtubuntuExtraHandler->connect(m_connection, menuPath, this)) {
439- delete m_qtubuntuExtraHandler;
440- m_qtubuntuExtraHandler = nullptr;
441- }
442- }
443-}
444-
445-void UbuntuGMenuModelExporter::aboutToShow(quint64 tag)
446-{
447- UbuntuPlatformMenu* gplatformMenu = m_submenusWithTag.value(tag);
448- if (!gplatformMenu) {
449- qWarning() << "Got an aboutToShow call with an unknown tag";
450- return;
451- }
452-
453- gplatformMenu->aboutToShow();
454-}
455-
456-// Unexport the model
457-void UbuntuGMenuModelExporter::unexportModels()
458-{
459- GError *error = nullptr;
460- if (!m_connection) {
461- qCWarning(ubuntuappmenu, "Failed to retreive session bus - %s", error ? error->message : "unknown error");
462- return;
463- }
464-
465- if (m_exportedModel != 0) {
466- g_dbus_connection_unexport_menu_model(m_connection, m_exportedModel);
467- m_exportedModel = 0;
468- }
469- if (m_exportedActions != 0) {
470- g_dbus_connection_unexport_action_group(m_connection, m_exportedActions);
471- m_exportedActions = 0;
472- }
473- if (m_qtubuntuExtraHandler) {
474- m_qtubuntuExtraHandler->disconnect(m_connection);
475- delete m_qtubuntuExtraHandler;
476- m_qtubuntuExtraHandler = nullptr;
477- }
478- g_object_unref(m_connection);
479- m_connection = nullptr;
480-}
481-
482-// Create a submenu for the given platform menu.
483-// Returns a gmenuitem entry for the menu, which must be cleaned up using g_object_unref.
484-// If forItem is suplied, use it's label.
485-GMenuItem *UbuntuGMenuModelExporter::createSubmenu(QPlatformMenu *platformMenu, UbuntuPlatformMenuItem *forItem)
486-{
487- UbuntuPlatformMenu* gplatformMenu = static_cast<UbuntuPlatformMenu*>(platformMenu);
488- if (!gplatformMenu) return nullptr;
489- GMenu* menu = g_menu_new();
490-
491- m_gmenusForMenus.insert(gplatformMenu, menu);
492-
493- QByteArray label;
494- bool enabled;
495- if (forItem) {
496- label = UbuntuPlatformMenuItem::get_text(forItem).toUtf8();
497- enabled = UbuntuPlatformMenuItem::get_enabled(forItem);
498- } else {
499- label = UbuntuPlatformMenu::get_text(gplatformMenu).toUtf8();
500- enabled = UbuntuPlatformMenu::get_enabled(gplatformMenu);
501- }
502-
503- addSubmenuItems(gplatformMenu, menu);
504-
505- Q_FOREACH(QPlatformMenuItem *childItem, gplatformMenu->menuItems()) {
506- UbuntuPlatformMenuItem* gplatformMenuItem = static_cast<UbuntuPlatformMenuItem*>(childItem);
507- if (!gplatformMenuItem) continue;
508-
509- // Sadly we don't have a better way to propagate a enabled change in a item-that-is-submenu
510- // than reseting the whole parent menu
511- if (gplatformMenuItem->menu()) {
512- connect(gplatformMenuItem, &UbuntuPlatformMenuItem::enabledChanged, gplatformMenu, &UbuntuPlatformMenu::structureChanged);
513- }
514- connect(gplatformMenuItem, &UbuntuPlatformMenuItem::visibleChanged, gplatformMenu, &UbuntuPlatformMenu::structureChanged);
515- }
516-
517- GMenuItem* gmenuItem = g_menu_item_new_submenu(label.constData(), G_MENU_MODEL(menu));
518- const quint64 tag = gplatformMenu->tag();
519- if (tag != 0) {
520- g_menu_item_set_attribute_value(gmenuItem, "qtubuntu-tag", g_variant_new_uint64 (tag));
521- m_submenusWithTag.insert(gplatformMenu->tag(), gplatformMenu);
522- }
523- g_object_unref(menu);
524-
525- g_menu_item_set_attribute_value(gmenuItem, "submenu-enabled", g_variant_new_boolean(enabled));
526-
527- connect(gplatformMenu, &UbuntuPlatformMenu::structureChanged, this, [this, gplatformMenu]
528- {
529- if (!m_reloadMenuTimers.contains(gplatformMenu)) {
530- const int timerId = startTimer(0);
531- m_reloadMenuTimers.insert(gplatformMenu, timerId);
532- }
533- });
534-
535- connect(gplatformMenu, &UbuntuPlatformMenu::destroyed, this, [this, tag, gplatformMenu]
536- {
537- m_submenusWithTag.remove(tag);
538- m_gmenusForMenus.remove(gplatformMenu);
539- auto timerIdIt = m_reloadMenuTimers.find(gplatformMenu);
540- if (timerIdIt != m_reloadMenuTimers.end()) {
541- killTimer(*timerIdIt);
542- m_reloadMenuTimers.erase(timerIdIt);
543- }
544- });
545-
546- return gmenuItem;
547-}
548-
549-// Add a platform menu's items to the given gmenu.
550-// The items are inserted into menus sections, split by the menu separators.
551-void UbuntuGMenuModelExporter::addSubmenuItems(UbuntuPlatformMenu* gplatformMenu, GMenu* menu)
552-{
553- auto iter = gplatformMenu->menuItems().begin();
554- auto lastSectionStart = iter;
555- // Iterate through all the menu items adding sections when a separator is found.
556- for (; iter != gplatformMenu->menuItems().end(); ++iter) {
557- UbuntuPlatformMenuItem* gplatformMenuItem = static_cast<UbuntuPlatformMenuItem*>(*iter);
558- if (!gplatformMenuItem) continue;
559-
560- // don't add a section until we have separator
561- if (UbuntuPlatformMenuItem::get_separator(gplatformMenuItem)) {
562- if (lastSectionStart != gplatformMenu->menuItems().begin()) {
563- GMenuItem* section = createSection(lastSectionStart, iter);
564- g_menu_append_item(menu, section);
565- g_object_unref(section);
566- }
567- lastSectionStart = iter + 1;
568- } else if (lastSectionStart == gplatformMenu->menuItems().begin()) {
569- processItemForGMenu(gplatformMenuItem, menu);
570- }
571- }
572-
573- // Add the last section
574- if (lastSectionStart != gplatformMenu->menuItems().begin() &&
575- lastSectionStart != gplatformMenu->menuItems().end()) {
576- GMenuItem* gsectionItem = createSection(lastSectionStart, gplatformMenu->menuItems().end());
577- g_menu_append_item(menu, gsectionItem);
578- g_object_unref(gsectionItem);
579- }
580-}
581-
582-// Create and return a gmenu item for the given platform menu item.
583-// Returned GMenuItem must be cleaned up using g_object_unref
584-GMenuItem *UbuntuGMenuModelExporter::createMenuItem(QPlatformMenuItem *platformMenuItem, GMenu *parentMenu)
585-{
586- UbuntuPlatformMenuItem* gplatformMenuItem = static_cast<UbuntuPlatformMenuItem*>(platformMenuItem);
587- if (!gplatformMenuItem) return nullptr;
588-
589- if (!UbuntuPlatformMenuItem::get_visible(gplatformMenuItem))
590- return nullptr;
591-
592- QByteArray label(UbuntuPlatformMenuItem::get_text(gplatformMenuItem).toUtf8());
593- QByteArray actionLabel(getActionString(UbuntuPlatformMenuItem::get_text(gplatformMenuItem)).toUtf8());
594- QByteArray shortcut(UbuntuPlatformMenuItem::get_shortcut(gplatformMenuItem).toString(QKeySequence::NativeText).toUtf8());
595-
596- GMenuItem* gmenuItem = g_menu_item_new(label.constData(), nullptr);
597- g_menu_item_set_attribute(gmenuItem, "accel", "s", shortcut.constData());
598- g_menu_item_set_detailed_action(gmenuItem, ("unity." + actionLabel).constData());
599-
600- addAction(actionLabel, gplatformMenuItem, parentMenu);
601- return gmenuItem;
602-}
603-
604-// Create a menu section for a section of separated menu items.
605-// Returned GMenuItem must be cleaned up using g_object_unref
606-GMenuItem *UbuntuGMenuModelExporter::createSection(QList<QPlatformMenuItem *>::const_iterator iter, QList<QPlatformMenuItem *>::const_iterator end)
607-{
608- GMenu* gsectionMenu = g_menu_new();
609- for (; iter != end; ++iter) {
610- processItemForGMenu(*iter, gsectionMenu);
611- }
612- GMenuItem* gsectionItem = g_menu_item_new_section("", G_MENU_MODEL(gsectionMenu));
613- g_object_unref(gsectionMenu);
614- return gsectionItem;
615-}
616-
617-// Add the given platform menu item to the menu.
618-// If it has an attached submenu, then create and add the submenu.
619-void UbuntuGMenuModelExporter::processItemForGMenu(QPlatformMenuItem *platformMenuItem, GMenu *gmenu)
620-{
621- UbuntuPlatformMenuItem* gplatformMenuItem = static_cast<UbuntuPlatformMenuItem*>(platformMenuItem);
622- if (!gplatformMenuItem) return;
623-
624- GMenuItem* gmenuItem = gplatformMenuItem->menu() ? createSubmenu(gplatformMenuItem->menu(), gplatformMenuItem) :
625- createMenuItem(gplatformMenuItem, gmenu);
626- if (gmenuItem) {
627- g_menu_append_item(gmenu, gmenuItem);
628- g_object_unref(gmenuItem);
629- }
630-}
631-
632-// Create and add an action for a menu item.
633-void UbuntuGMenuModelExporter::addAction(const QByteArray &name, UbuntuPlatformMenuItem *gplatformMenuItem, GMenu *parentMenu)
634-{
635- disconnect(gplatformMenuItem, &UbuntuPlatformMenuItem::checkedChanged, this, 0);
636- disconnect(gplatformMenuItem, &UbuntuPlatformMenuItem::enabledChanged, this, 0);
637-
638- QSet<QByteArray> &actions = m_actions[parentMenu];
639- QVector<QMetaObject::Connection> &propertyConnections = m_propertyConnections[parentMenu];
640-
641- if (actions.contains(name)) {
642- g_action_map_remove_action(G_ACTION_MAP(m_gactionGroup), name.constData());
643- actions.remove(name);
644- }
645-
646- bool checkable = UbuntuPlatformMenuItem::get_checkable(gplatformMenuItem);
647-
648- GSimpleAction* action = nullptr;
649- if (checkable) {
650- bool checked = UbuntuPlatformMenuItem::get_checked(gplatformMenuItem);
651- action = g_simple_action_new_stateful(name.constData(), nullptr, g_variant_new_boolean(checked));
652-
653- std::function<void(bool)> updateChecked = [gplatformMenuItem, action](bool checked) {
654- auto type = g_action_get_state_type(G_ACTION(action));
655- if (type && g_variant_type_equal(type, G_VARIANT_TYPE_BOOLEAN)) {
656- g_simple_action_set_state(action, g_variant_new_boolean(checked ? TRUE : FALSE));
657- }
658- };
659- // save the connection to disconnect in UbuntuGMenuModelExporter::clear()
660- propertyConnections << connect(gplatformMenuItem, &UbuntuPlatformMenuItem::checkedChanged, this, updateChecked);
661- } else {
662- action = g_simple_action_new(name.constData(), nullptr);
663- }
664-
665- // Enabled update
666- std::function<void(bool)> updateEnabled = [gplatformMenuItem, action](bool enabled) {
667- GValue value = G_VALUE_INIT;
668- g_value_init (&value, G_TYPE_BOOLEAN);
669- g_value_set_boolean(&value, enabled ? TRUE : FALSE);
670- g_object_set_property(G_OBJECT(action), "enabled", &value);
671- };
672- updateEnabled(UbuntuPlatformMenuItem::get_enabled(gplatformMenuItem));
673- // save the connection to disconnect in UbuntuGMenuModelExporter::clear()
674- propertyConnections << connect(gplatformMenuItem, &UbuntuPlatformMenuItem::enabledChanged, this, updateEnabled);
675-
676- g_signal_connect(action, "activate", G_CALLBACK(activate_cb), gplatformMenuItem);
677-
678- actions.insert(name);
679- g_action_map_add_action(G_ACTION_MAP(m_gactionGroup), G_ACTION(action));
680- g_object_unref(action);
681-}
682
683=== removed file 'src/ubuntuappmenu/gmenumodelexporter.h'
684--- src/ubuntuappmenu/gmenumodelexporter.h 2017-03-15 08:47:51 +0000
685+++ src/ubuntuappmenu/gmenumodelexporter.h 1970-01-01 00:00:00 +0000
686@@ -1,100 +0,0 @@
687-/*
688- * Copyright (C) 2016 Canonical, Ltd.
689- *
690- * This program is free software: you can redistribute it and/or modify it under
691- * the terms of the GNU Lesser General Public License version 3, as published by
692- * the Free Software Foundation.
693- *
694- * This program is distributed in the hope that it will be useful, but WITHOUT
695- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
696- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
697- * Lesser General Public License for more details.
698- *
699- * You should have received a copy of the GNU Lesser General Public License
700- * along with this program. If not, see <http://www.gnu.org/licenses/>.
701- */
702-
703-#ifndef GMENUMODELEXPORTER_H
704-#define GMENUMODELEXPORTER_H
705-
706-#include "gmenumodelplatformmenu.h"
707-
708-#include <gio/gio.h>
709-
710-#include <QTimer>
711-#include <QMap>
712-#include <QSet>
713-#include <QMetaObject>
714-
715-class QtUbuntuExtraActionHandler;
716-
717-// Base class for a gmenumodel exporter
718-class UbuntuGMenuModelExporter : public QObject
719-{
720- Q_OBJECT
721-public:
722- virtual ~UbuntuGMenuModelExporter();
723-
724- void exportModels();
725- void unexportModels();
726-
727- QString menuPath() const { return m_menuPath;}
728-
729- void aboutToShow(quint64 tag);
730-
731-protected:
732- UbuntuGMenuModelExporter(QObject *parent);
733-
734- GMenuItem *createSubmenu(QPlatformMenu* platformMenu, UbuntuPlatformMenuItem* forItem);
735- GMenuItem *createMenuItem(QPlatformMenuItem* platformMenuItem, GMenu *parentMenu);
736- GMenuItem *createSection(QList<QPlatformMenuItem*>::const_iterator iter, QList<QPlatformMenuItem*>::const_iterator end);
737- void addAction(const QByteArray& name, UbuntuPlatformMenuItem* gplatformItem, GMenu *parentMenu);
738-
739- void addSubmenuItems(UbuntuPlatformMenu* gplatformMenu, GMenu* menu);
740- void processItemForGMenu(QPlatformMenuItem* item, GMenu* gmenu);
741-
742- void clear();
743-
744- void timerEvent(QTimerEvent *e) override;
745-
746-protected:
747- GDBusConnection *m_connection;
748- GMenu *m_gmainMenu;
749- GSimpleActionGroup *m_gactionGroup;
750- guint m_exportedModel;
751- guint m_exportedActions;
752- QtUbuntuExtraActionHandler *m_qtubuntuExtraHandler;
753- QTimer m_structureTimer;
754- QString m_menuPath;
755-
756- // UbuntuPlatformMenu::tag -> UbuntuPlatformMenu
757- QMap<quint64, UbuntuPlatformMenu*> m_submenusWithTag;
758-
759- // UbuntuPlatformMenu -> reload TimerId (startTimer)
760- QHash<UbuntuPlatformMenu*, int> m_reloadMenuTimers;
761-
762- QHash<UbuntuPlatformMenu*, GMenu*> m_gmenusForMenus;
763-
764- QHash<GMenu*, QSet<QByteArray>> m_actions;
765- QHash<GMenu*, QVector<QMetaObject::Connection>> m_propertyConnections;
766-
767-};
768-
769-// Class which exports a qt platform menu bar.
770-class UbuntuMenuBarExporter : public UbuntuGMenuModelExporter
771-{
772-public:
773- UbuntuMenuBarExporter(UbuntuPlatformMenuBar *parent);
774- ~UbuntuMenuBarExporter();
775-};
776-
777-// Class which exports a qt platform menu.
778-// This will allow exporting of context menus.
779-class UbuntuMenuExporter : public UbuntuGMenuModelExporter
780-{
781-public:
782- UbuntuMenuExporter(UbuntuPlatformMenu *parent);
783- ~UbuntuMenuExporter();
784-};
785-
786-#endif // GMENUMODELEXPORTER_H
787
788=== removed file 'src/ubuntuappmenu/gmenumodelplatformmenu.cpp'
789--- src/ubuntuappmenu/gmenumodelplatformmenu.cpp 2017-03-27 08:23:00 +0000
790+++ src/ubuntuappmenu/gmenumodelplatformmenu.cpp 1970-01-01 00:00:00 +0000
791@@ -1,518 +0,0 @@
792-/*
793- * Copyright (C) 2016 Canonical, Ltd.
794- *
795- * This program is free software: you can redistribute it and/or modify it under
796- * the terms of the GNU Lesser General Public License version 3, as published by
797- * the Free Software Foundation.
798- *
799- * This program is distributed in the hope that it will be useful, but WITHOUT
800- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
801- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
802- * Lesser General Public License for more details.
803- *
804- * You should have received a copy of the GNU Lesser General Public License
805- * along with this program. If not, see <http://www.gnu.org/licenses/>.
806- */
807-
808-// Local
809-#include "gmenumodelplatformmenu.h"
810-#include "gmenumodelexporter.h"
811-#include "registry.h"
812-#include "menuregistrar.h"
813-#include "logging.h"
814-
815-// Qt
816-#include <QDebug>
817-#include <QWindow>
818-#include <QCoreApplication>
819-
820-#define BAR_DEBUG_MSG qCDebug(ubuntuappmenu).nospace() << "UbuntuPlatformMenuBar[" << (void*)this <<"]::" << __func__
821-#define MENU_DEBUG_MSG qCDebug(ubuntuappmenu).nospace() << "UbuntuPlatformMenu[" << (void*)this <<"]::" << __func__
822-#define ITEM_DEBUG_MSG qCDebug(ubuntuappmenu).nospace() << "UbuntuPlatformMenuItem[" << (void*)this <<"]::" << __func__
823-
824-namespace {
825-
826-int logRecusion = 0;
827-
828-}
829-
830-QDebug operator<<(QDebug stream, UbuntuPlatformMenuBar* bar) {
831- if (bar) return bar->operator<<(stream);
832- return stream;
833-}
834-QDebug operator<<(QDebug stream, UbuntuPlatformMenu* menu) {
835- if (menu) return menu->operator<<(stream);
836- return stream;
837-}
838-QDebug operator<<(QDebug stream, UbuntuPlatformMenuItem* menuItem) {
839- if (menuItem) return menuItem->operator<<(stream);
840- return stream;
841-}
842-
843-UbuntuPlatformMenuBar::UbuntuPlatformMenuBar()
844- : m_exporter(new UbuntuMenuBarExporter(this))
845- , m_registrar(new UbuntuMenuRegistrar())
846- , m_ready(false)
847-{
848- BAR_DEBUG_MSG << "()";
849-
850- connect(this, &UbuntuPlatformMenuBar::menuInserted, this, &UbuntuPlatformMenuBar::structureChanged);
851- connect(this,&UbuntuPlatformMenuBar::menuRemoved, this, &UbuntuPlatformMenuBar::structureChanged);
852-}
853-
854-UbuntuPlatformMenuBar::~UbuntuPlatformMenuBar()
855-{
856- BAR_DEBUG_MSG << "()";
857-}
858-
859-void UbuntuPlatformMenuBar::insertMenu(QPlatformMenu *menu, QPlatformMenu *before)
860-{
861- BAR_DEBUG_MSG << "(menu=" << menu << ", before=" << before << ")";
862-
863- if (m_menus.contains(menu)) return;
864-
865- if (!before) {
866- m_menus.push_back(menu);
867- } else {
868- for (auto iter = m_menus.begin(); iter != m_menus.end(); ++iter) {
869- if (*iter == before) {
870- m_menus.insert(iter, menu);
871- break;
872- }
873- }
874- }
875- Q_EMIT menuInserted(menu);
876-}
877-
878-void UbuntuPlatformMenuBar::removeMenu(QPlatformMenu *menu)
879-{
880- BAR_DEBUG_MSG << "(menu=" << menu << ")";
881-
882- QMutableListIterator<QPlatformMenu*> iterator(m_menus);
883- while(iterator.hasNext()) {
884- if (iterator.next() == menu) {
885- iterator.remove();
886- break;
887- }
888- }
889- Q_EMIT menuRemoved(menu);
890-}
891-
892-void UbuntuPlatformMenuBar::syncMenu(QPlatformMenu *menu)
893-{
894- BAR_DEBUG_MSG << "(menu=" << menu << ")";
895-
896- Q_UNUSED(menu)
897-}
898-
899-void UbuntuPlatformMenuBar::handleReparent(QWindow *parentWindow)
900-{
901- BAR_DEBUG_MSG << "(parentWindow=" << parentWindow << ")";
902-
903- setReady(true);
904- m_registrar->registerMenuForWindow(parentWindow, QDBusObjectPath(m_exporter->menuPath()));
905-}
906-
907-QPlatformMenu *UbuntuPlatformMenuBar::menuForTag(quintptr tag) const
908-{
909- Q_FOREACH(QPlatformMenu* menu, m_menus) {
910- if (menu->tag() == tag) {
911- return menu;
912- }
913- }
914- return nullptr;
915-}
916-
917-const QList<QPlatformMenu *> UbuntuPlatformMenuBar::menus() const
918-{
919- return m_menus;
920-}
921-
922-QDebug UbuntuPlatformMenuBar::operator<<(QDebug stream)
923-{
924- stream.nospace().noquote() << QString("%1").arg("", logRecusion, QLatin1Char('\t'))
925- << "UbuntuPlatformMenuBar(this=" << (void*)this << ")" << endl;
926- Q_FOREACH(QPlatformMenu* menu, m_menus) {
927- auto myMenu = static_cast<UbuntuPlatformMenu*>(menu);
928- if (myMenu) {
929- logRecusion++;
930- stream << myMenu;
931- logRecusion--;
932- }
933- }
934-
935- return stream;
936-}
937-
938-#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
939-QPlatformMenu *UbuntuPlatformMenuBar::createMenu() const
940-{
941- return new UbuntuPlatformMenu();
942-}
943-#endif
944-
945-void UbuntuPlatformMenuBar::setReady(bool isReady)
946-{
947- if (m_ready != isReady) {
948- m_ready = isReady;
949- Q_EMIT ready();
950- }
951-}
952-
953-//////////////////////////////////////////////////////////////
954-
955-UbuntuPlatformMenu::UbuntuPlatformMenu()
956- : m_tag(reinterpret_cast<quintptr>(this))
957- , m_parentWindow(nullptr)
958- , m_exporter(nullptr)
959- , m_registrar(nullptr)
960-{
961- MENU_DEBUG_MSG << "()";
962-
963- connect(this, &UbuntuPlatformMenu::menuItemInserted, this, &UbuntuPlatformMenu::structureChanged);
964- connect(this, &UbuntuPlatformMenu::menuItemRemoved, this, &UbuntuPlatformMenu::structureChanged);
965-}
966-
967-UbuntuPlatformMenu::~UbuntuPlatformMenu()
968-{
969- MENU_DEBUG_MSG << "()";
970-}
971-
972-void UbuntuPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before)
973-{
974- MENU_DEBUG_MSG << "(menuItem=" << menuItem << ", before=" << before << ")";
975-
976- if (m_menuItems.contains(menuItem)) return;
977-
978- if (!before) {
979- m_menuItems.push_back(menuItem);
980- } else {
981- for (auto iter = m_menuItems.begin(); iter != m_menuItems.end(); ++iter) {
982- if (*iter == before) {
983- m_menuItems.insert(iter, menuItem);
984- break;
985- }
986- }
987- }
988-
989- Q_EMIT menuItemInserted(menuItem);
990-}
991-
992-void UbuntuPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem)
993-{
994- MENU_DEBUG_MSG << "(menuItem=" << menuItem << ")";
995-
996- QMutableListIterator<QPlatformMenuItem*> iterator(m_menuItems);
997- while(iterator.hasNext()) {
998- if (iterator.next() == menuItem) {
999- iterator.remove();
1000- break;
1001- }
1002- }
1003- Q_EMIT menuItemRemoved(menuItem);
1004-}
1005-
1006-void UbuntuPlatformMenu::syncMenuItem(QPlatformMenuItem *menuItem)
1007-{
1008- MENU_DEBUG_MSG << "(menuItem=" << menuItem << ")";
1009-
1010- Q_UNUSED(menuItem)
1011-}
1012-
1013-void UbuntuPlatformMenu::syncSeparatorsCollapsible(bool enable)
1014-{
1015- MENU_DEBUG_MSG << "(enable=" << enable << ")";
1016- Q_UNUSED(enable)
1017-}
1018-
1019-void UbuntuPlatformMenu::setTag(quintptr tag)
1020-{
1021- MENU_DEBUG_MSG << "(tag=" << tag << ")";
1022- m_tag = tag;
1023-}
1024-
1025-quintptr UbuntuPlatformMenu::tag() const
1026-{
1027- return m_tag;
1028-}
1029-
1030-void UbuntuPlatformMenu::setText(const QString &text)
1031-{
1032- MENU_DEBUG_MSG << "(text=" << text << ")";
1033- if (m_text != text) {
1034- m_text = text;
1035- }
1036-}
1037-
1038-void UbuntuPlatformMenu::setIcon(const QIcon &icon)
1039-{
1040- MENU_DEBUG_MSG << "(icon=" << icon.name() << ")";
1041-
1042- if (!icon.isNull() || (!m_icon.isNull() && icon.isNull())) {
1043- m_icon = icon;
1044- }
1045-}
1046-
1047-void UbuntuPlatformMenu::setEnabled(bool enabled)
1048-{
1049- MENU_DEBUG_MSG << "(enabled=" << enabled << ")";
1050-
1051- if (m_enabled != enabled) {
1052- m_enabled = enabled;
1053- Q_EMIT enabledChanged(enabled);
1054- }
1055-}
1056-
1057-void UbuntuPlatformMenu::setVisible(bool isVisible)
1058-{
1059- MENU_DEBUG_MSG << "(visible=" << isVisible << ")";
1060-
1061- if (m_visible != isVisible) {
1062- m_visible = isVisible;
1063- }
1064-}
1065-
1066-void UbuntuPlatformMenu::setMinimumWidth(int width)
1067-{
1068- MENU_DEBUG_MSG << "(width=" << width << ")";
1069-
1070- Q_UNUSED(width)
1071-}
1072-
1073-void UbuntuPlatformMenu::setFont(const QFont &font)
1074-{
1075- MENU_DEBUG_MSG << "(font=" << font << ")";
1076-
1077- Q_UNUSED(font)
1078-}
1079-
1080-void UbuntuPlatformMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item)
1081-{
1082- MENU_DEBUG_MSG << "(parentWindow=" << parentWindow << ", targetRect=" << targetRect << ", item=" << item << ")";
1083-
1084- if (!m_exporter) {
1085- m_exporter.reset(new UbuntuMenuExporter(this));
1086- m_exporter->exportModels();
1087- }
1088-
1089- if (parentWindow != m_parentWindow) {
1090- if (m_parentWindow) {
1091- m_registrar->unregisterMenu();
1092- }
1093-
1094- m_parentWindow = parentWindow;
1095-
1096- if (m_parentWindow) {
1097- if (!m_registrar) m_registrar.reset(new UbuntuMenuRegistrar);
1098- m_registrar->registerMenuForWindow(const_cast<QWindow*>(m_parentWindow),
1099- QDBusObjectPath(m_exporter->menuPath()));
1100- }
1101- }
1102-
1103- Q_UNUSED(targetRect);
1104- Q_UNUSED(item);
1105- setVisible(true);
1106-}
1107-
1108-void UbuntuPlatformMenu::dismiss()
1109-{
1110- MENU_DEBUG_MSG << "()";
1111-
1112- if (m_registrar) { m_registrar->unregisterMenu(); }
1113- if (m_exporter) { m_exporter->unexportModels(); }
1114-}
1115-
1116-QPlatformMenuItem *UbuntuPlatformMenu::menuItemAt(int position) const
1117-{
1118- if (position < 0 || position >= m_menuItems.count()) return nullptr;
1119- return m_menuItems.at(position);
1120-}
1121-
1122-QPlatformMenuItem *UbuntuPlatformMenu::menuItemForTag(quintptr tag) const
1123-{
1124- Q_FOREACH(QPlatformMenuItem* menuItem, m_menuItems) {
1125- if (menuItem->tag() == tag) {
1126- return menuItem;
1127- }
1128- }
1129- return nullptr;
1130-}
1131-
1132-QPlatformMenuItem *UbuntuPlatformMenu::createMenuItem() const
1133-{
1134- return new UbuntuPlatformMenuItem();
1135-}
1136-
1137-#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
1138-QPlatformMenu *UbuntuPlatformMenu::createSubMenu() const
1139-{
1140- return new UbuntuPlatformMenu();
1141-}
1142-#endif
1143-
1144-const QList<QPlatformMenuItem *> UbuntuPlatformMenu::menuItems() const
1145-{
1146- return m_menuItems;
1147-}
1148-
1149-QDebug UbuntuPlatformMenu::operator<<(QDebug stream)
1150-{
1151- stream.nospace().noquote() << QString("%1").arg("", logRecusion, QLatin1Char('\t'))
1152- << "UbuntuPlatformMenu(this=" << (void*)this << ", text=\"" << m_text << "\")" << endl;
1153- Q_FOREACH(QPlatformMenuItem* item, m_menuItems) {
1154- logRecusion++;
1155- auto myItem = static_cast<UbuntuPlatformMenuItem*>(item);
1156- if (myItem) {
1157- stream << myItem;
1158- }
1159- logRecusion--;
1160- }
1161- return stream;
1162-}
1163-
1164-//////////////////////////////////////////////////////////////
1165-
1166-UbuntuPlatformMenuItem::UbuntuPlatformMenuItem()
1167- : m_menu(nullptr)
1168- , m_tag(reinterpret_cast<quintptr>(this))
1169-{
1170- ITEM_DEBUG_MSG << "()";
1171-}
1172-
1173-UbuntuPlatformMenuItem::~UbuntuPlatformMenuItem()
1174-{
1175- ITEM_DEBUG_MSG << "()";
1176-}
1177-
1178-void UbuntuPlatformMenuItem::setTag(quintptr tag)
1179-{
1180- ITEM_DEBUG_MSG << "(tag=" << tag << ")";
1181- m_tag = tag;
1182-}
1183-
1184-quintptr UbuntuPlatformMenuItem::tag() const
1185-{
1186- return m_tag;
1187-}
1188-
1189-void UbuntuPlatformMenuItem::setText(const QString &text)
1190-{
1191- ITEM_DEBUG_MSG << "(text=" << text << ")";
1192- if (m_text != text) {
1193- m_text = text;
1194- }
1195-}
1196-
1197-void UbuntuPlatformMenuItem::setIcon(const QIcon &icon)
1198-{
1199- ITEM_DEBUG_MSG << "(icon=" << icon.name() << ")";
1200-
1201- if (!icon.isNull() || (!m_icon.isNull() && icon.isNull())) {
1202- m_icon = icon;
1203- }
1204-}
1205-
1206-void UbuntuPlatformMenuItem::setVisible(bool isVisible)
1207-{
1208- ITEM_DEBUG_MSG << "(visible=" << isVisible << ")";
1209- if (m_visible != isVisible) {
1210- m_visible = isVisible;
1211- Q_EMIT visibleChanged(m_visible);
1212- }
1213-}
1214-
1215-void UbuntuPlatformMenuItem::setIsSeparator(bool isSeparator)
1216-{
1217- ITEM_DEBUG_MSG << "(separator=" << isSeparator << ")";
1218- if (m_separator != isSeparator) {
1219- m_separator = isSeparator;
1220- }
1221-}
1222-
1223-void UbuntuPlatformMenuItem::setFont(const QFont &font)
1224-{
1225- ITEM_DEBUG_MSG << "(font=" << font << ")";
1226- Q_UNUSED(font);
1227-}
1228-
1229-void UbuntuPlatformMenuItem::setRole(QPlatformMenuItem::MenuRole role)
1230-{
1231- ITEM_DEBUG_MSG << "(role=" << role << ")";
1232- Q_UNUSED(role);
1233-}
1234-
1235-void UbuntuPlatformMenuItem::setCheckable(bool checkable)
1236-{
1237- ITEM_DEBUG_MSG << "(checkable=" << checkable << ")";
1238- if (m_checkable != checkable) {
1239- m_checkable = checkable;
1240- }
1241-}
1242-
1243-void UbuntuPlatformMenuItem::setChecked(bool isChecked)
1244-{
1245- ITEM_DEBUG_MSG << "(checked=" << isChecked << ")";
1246- if (m_checked != isChecked) {
1247- m_checked = isChecked;
1248- Q_EMIT checkedChanged(isChecked);
1249- }
1250-}
1251-
1252-void UbuntuPlatformMenuItem::setShortcut(const QKeySequence &shortcut)
1253-{
1254- ITEM_DEBUG_MSG << "(shortcut=" << shortcut << ")";
1255- if (m_shortcut != shortcut) {
1256- m_shortcut = shortcut;
1257- }
1258-}
1259-
1260-void UbuntuPlatformMenuItem::setEnabled(bool enabled)
1261-{
1262- ITEM_DEBUG_MSG << "(enabled=" << enabled << ")";
1263- if (m_enabled != enabled) {
1264- m_enabled = enabled;
1265- Q_EMIT enabledChanged(enabled);
1266- }
1267-}
1268-
1269-void UbuntuPlatformMenuItem::setIconSize(int size)
1270-{
1271- ITEM_DEBUG_MSG << "(size=" << size << ")";
1272- Q_UNUSED(size);
1273-}
1274-
1275-void UbuntuPlatformMenuItem::setMenu(QPlatformMenu *menu)
1276-{
1277- ITEM_DEBUG_MSG << "(menu=" << menu << ")";
1278- if (m_menu != menu) {
1279- m_menu = menu;
1280-
1281- if (menu) {
1282- connect(menu, &QObject::destroyed,
1283- this, [this] { setMenu(nullptr); });
1284- }
1285- }
1286-}
1287-
1288-QPlatformMenu *UbuntuPlatformMenuItem::menu() const
1289-{
1290- return m_menu;
1291-}
1292-
1293-QDebug UbuntuPlatformMenuItem::operator<<(QDebug stream)
1294-{
1295- QString properties = "text=\"" + m_text + "\"";
1296-
1297- stream.nospace().noquote() << QString("%1").arg("", logRecusion, QLatin1Char('\t'))
1298- << "UbuntuPlatformMenuItem(this=" << (void*)this << ", "
1299- << (m_separator ? "Separator" : properties) << ")" << endl;
1300- if (m_menu) {
1301- auto myMenu = static_cast<UbuntuPlatformMenu*>(m_menu);
1302- if (myMenu) {
1303- logRecusion++;
1304- stream << myMenu;
1305- logRecusion--;
1306- }
1307- }
1308- return stream;
1309-}
1310
1311=== removed file 'src/ubuntuappmenu/gmenumodelplatformmenu.h'
1312--- src/ubuntuappmenu/gmenumodelplatformmenu.h 2017-03-27 08:23:00 +0000
1313+++ src/ubuntuappmenu/gmenumodelplatformmenu.h 1970-01-01 00:00:00 +0000
1314@@ -1,181 +0,0 @@
1315-/*
1316- * Copyright (C) 2016 Canonical, Ltd.
1317- *
1318- * This program is free software: you can redistribute it and/or modify it under
1319- * the terms of the GNU Lesser General Public License version 3, as published by
1320- * the Free Software Foundation.
1321- *
1322- * This program is distributed in the hope that it will be useful, but WITHOUT
1323- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1324- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1325- * Lesser General Public License for more details.
1326- *
1327- * You should have received a copy of the GNU Lesser General Public License
1328- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1329- */
1330-
1331-#ifndef EXPORTEDPLATFORMMENUBAR_H
1332-#define EXPORTEDPLATFORMMENUBAR_H
1333-
1334-#include <qpa/qplatformmenu.h>
1335-
1336-// Local
1337-class UbuntuGMenuModelExporter;
1338-class UbuntuMenuRegistrar;
1339-class QWindow;
1340-
1341-class UbuntuPlatformMenuBar : public QPlatformMenuBar
1342-{
1343- Q_OBJECT
1344-public:
1345- UbuntuPlatformMenuBar();
1346- ~UbuntuPlatformMenuBar();
1347-
1348- QString exportedPath() const;
1349-
1350- virtual void insertMenu(QPlatformMenu *menu, QPlatformMenu* before) override;
1351- virtual void removeMenu(QPlatformMenu *menu) override;
1352- virtual void syncMenu(QPlatformMenu *menu) override;
1353- virtual void handleReparent(QWindow *newParentWindow) override;
1354- virtual QPlatformMenu *menuForTag(quintptr tag) const override;
1355-
1356- const QList<QPlatformMenu*> menus() const;
1357-
1358- QDebug operator<<(QDebug stream);
1359-
1360-#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
1361- virtual QPlatformMenu *createMenu() const override;
1362-#endif
1363-
1364-Q_SIGNALS:
1365- void menuInserted(QPlatformMenu *menu);
1366- void menuRemoved(QPlatformMenu *menu);
1367-
1368- void structureChanged();
1369- void ready();
1370-
1371-private:
1372- void setReady(bool);
1373-
1374- QList<QPlatformMenu*> m_menus;
1375- QScopedPointer<UbuntuGMenuModelExporter> m_exporter;
1376- QScopedPointer<UbuntuMenuRegistrar> m_registrar;
1377- bool m_ready;
1378-};
1379-
1380-#define MENU_PROPERTY(class, name, type, defaultValue) \
1381- static type get_##name(const class *menuItem) { return menuItem->m_##name; } \
1382- type m_##name = defaultValue;
1383-
1384-class Q_DECL_EXPORT UbuntuPlatformMenu : public QPlatformMenu
1385-{
1386- Q_OBJECT
1387-public:
1388- UbuntuPlatformMenu();
1389- ~UbuntuPlatformMenu();
1390-
1391- virtual void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) override;
1392- virtual void removeMenuItem(QPlatformMenuItem *menuItem) override;
1393- virtual void syncMenuItem(QPlatformMenuItem *menuItem) override;
1394- virtual void syncSeparatorsCollapsible(bool enable) override;
1395-
1396- virtual void setTag(quintptr tag) override;
1397- virtual quintptr tag() const override;
1398-
1399- virtual void setText(const QString &text) override;
1400- virtual void setIcon(const QIcon &icon) override;
1401- virtual void setEnabled(bool isEnabled) override;
1402- virtual void setVisible(bool isVisible) override;
1403- virtual void setMinimumWidth(int width) override;
1404- virtual void setFont(const QFont &font) override;
1405-
1406- virtual void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) override;
1407-
1408- virtual void dismiss() override; // Closes this and all its related menu popups
1409-
1410- virtual QPlatformMenuItem *menuItemAt(int position) const override;
1411- virtual QPlatformMenuItem *menuItemForTag(quintptr tag) const override;
1412-
1413- virtual QPlatformMenuItem *createMenuItem() const override;
1414-#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
1415- virtual QPlatformMenu *createSubMenu() const override;
1416-#endif
1417-
1418- int id() const;
1419-
1420- const QList<QPlatformMenuItem*> menuItems() const;
1421-
1422- QDebug operator<<(QDebug stream);
1423-
1424-Q_SIGNALS:
1425- void menuItemInserted(QPlatformMenuItem *menuItem);
1426- void menuItemRemoved(QPlatformMenuItem *menuItem);
1427- void structureChanged();
1428- void enabledChanged(bool);
1429-
1430-private:
1431- MENU_PROPERTY(UbuntuPlatformMenu, visible, bool, true)
1432- MENU_PROPERTY(UbuntuPlatformMenu, text, QString, QString())
1433- MENU_PROPERTY(UbuntuPlatformMenu, enabled, bool, true)
1434- MENU_PROPERTY(UbuntuPlatformMenu, icon, QIcon, QIcon())
1435-
1436- quintptr m_tag;
1437- QList<QPlatformMenuItem*> m_menuItems;
1438- const QWindow* m_parentWindow;
1439- QScopedPointer<UbuntuGMenuModelExporter> m_exporter;
1440- QScopedPointer<UbuntuMenuRegistrar> m_registrar;
1441-
1442- friend class UbuntuGMenuModelExporter;
1443-};
1444-
1445-
1446-class Q_DECL_EXPORT UbuntuPlatformMenuItem : public QPlatformMenuItem
1447-{
1448- Q_OBJECT
1449-public:
1450- UbuntuPlatformMenuItem();
1451- ~UbuntuPlatformMenuItem();
1452-
1453- virtual void setTag(quintptr tag) override;
1454- virtual quintptr tag() const override;
1455-
1456- virtual void setText(const QString &text) override;
1457- virtual void setIcon(const QIcon &icon) override;
1458- virtual void setMenu(QPlatformMenu *menu) override;
1459- virtual void setVisible(bool isVisible) override;
1460- virtual void setIsSeparator(bool isSeparator) override;
1461- virtual void setFont(const QFont &font) override;
1462- virtual void setRole(MenuRole role) override;
1463- virtual void setCheckable(bool checkable) override;
1464- virtual void setChecked(bool isChecked) override;
1465- virtual void setShortcut(const QKeySequence& shortcut) override;
1466- virtual void setEnabled(bool enabled) override;
1467- virtual void setIconSize(int size) override;
1468-
1469- QPlatformMenu* menu() const;
1470-
1471- QDebug operator<<(QDebug stream);
1472-
1473-Q_SIGNALS:
1474- void checkedChanged(bool);
1475- void enabledChanged(bool);
1476- void visibleChanged(bool);
1477-
1478-private:
1479- MENU_PROPERTY(UbuntuPlatformMenuItem, separator, bool, false)
1480- MENU_PROPERTY(UbuntuPlatformMenuItem, visible, bool, true)
1481- MENU_PROPERTY(UbuntuPlatformMenuItem, text, QString, QString())
1482- MENU_PROPERTY(UbuntuPlatformMenuItem, enabled, bool, true)
1483- MENU_PROPERTY(UbuntuPlatformMenuItem, checkable, bool, false)
1484- MENU_PROPERTY(UbuntuPlatformMenuItem, checked, bool, false)
1485- MENU_PROPERTY(UbuntuPlatformMenuItem, shortcut, QKeySequence, QKeySequence())
1486- MENU_PROPERTY(UbuntuPlatformMenuItem, icon, QIcon, QIcon())
1487- MENU_PROPERTY(UbuntuPlatformMenuItem, iconSize, int, 16)
1488- MENU_PROPERTY(UbuntuPlatformMenuItem, menu, QPlatformMenu*, nullptr)
1489-
1490-
1491- quintptr m_tag;
1492- friend class UbuntuGMenuModelExporter;
1493-};
1494-
1495-#endif // EXPORTEDPLATFORMMENUBAR_H
1496
1497=== removed file 'src/ubuntuappmenu/logging.h'
1498--- src/ubuntuappmenu/logging.h 2016-08-24 10:08:05 +0000
1499+++ src/ubuntuappmenu/logging.h 1970-01-01 00:00:00 +0000
1500@@ -1,27 +0,0 @@
1501-/*
1502- * Copyright (C) 2016 Canonical, Ltd.
1503- *
1504- * This program is free software: you can redistribute it and/or modify it under
1505- * the terms of the GNU Lesser General Public License version 3, as published by
1506- * the Free Software Foundation.
1507- *
1508- * This program is distributed in the hope that it will be useful, but WITHOUT
1509- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1510- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1511- * Lesser General Public License for more details.
1512- *
1513- * You should have received a copy of the GNU Lesser General Public License
1514- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515- */
1516-
1517-#ifndef QUBUNTUTHEMELOGGING_H
1518-#define QUBUNTUTHEMELOGGING_H
1519-
1520-#include <QLoggingCategory>
1521-
1522-#define ASSERT(cond) ((!(cond)) ? qt_assert(#cond,__FILE__,__LINE__) : qt_noop())
1523-
1524-Q_DECLARE_LOGGING_CATEGORY(ubuntuappmenu)
1525-Q_DECLARE_LOGGING_CATEGORY(ubuntuappmenuRegistrar)
1526-
1527-#endif // QUBUNTUTHEMELOGGING_H
1528
1529=== removed file 'src/ubuntuappmenu/menuregistrar.cpp'
1530--- src/ubuntuappmenu/menuregistrar.cpp 2016-09-30 16:10:35 +0000
1531+++ src/ubuntuappmenu/menuregistrar.cpp 1970-01-01 00:00:00 +0000
1532@@ -1,137 +0,0 @@
1533-/*
1534- * Copyright (C) 2016 Canonical, Ltd.
1535- *
1536- * This program is free software: you can redistribute it and/or modify it under
1537- * the terms of the GNU Lesser General Public License version 3, as published by
1538- * the Free Software Foundation.
1539- *
1540- * This program is distributed in the hope that it will be useful, but WITHOUT
1541- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1542- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1543- * Lesser General Public License for more details.
1544- *
1545- * You should have received a copy of the GNU Lesser General Public License
1546- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1547- */
1548-
1549-#include "menuregistrar.h"
1550-#include "registry.h"
1551-#include "logging.h"
1552-
1553-#include <QDebug>
1554-#include <QDBusObjectPath>
1555-#include <QGuiApplication>
1556-#include <qpa/qplatformnativeinterface.h>
1557-#include <qpa/qplatformwindow.h>
1558-
1559-namespace {
1560-
1561-bool isMirClient() {
1562- return qGuiApp->platformName() == "ubuntumirclient";
1563-}
1564-
1565-}
1566-
1567-UbuntuMenuRegistrar::UbuntuMenuRegistrar()
1568- : m_connection(nullptr)
1569- , m_registeredProcessId(~0)
1570-{
1571- GError *error = NULL;
1572- m_connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
1573- if (!m_connection) {
1574- qCWarning(ubuntuappmenuRegistrar, "Failed to retreive session bus - %s", error ? error->message : "unknown error");
1575- g_error_free (error);
1576- return;
1577- }
1578- m_service = g_dbus_connection_get_unique_name(m_connection);
1579- connect(UbuntuMenuRegistry::instance(), &UbuntuMenuRegistry::serviceChanged, this, &UbuntuMenuRegistrar::onRegistrarServiceChanged);
1580-
1581- if (isMirClient()) {
1582- auto nativeInterface = qGuiApp->platformNativeInterface();
1583- connect(nativeInterface, &QPlatformNativeInterface::windowPropertyChanged, this, [this](QPlatformWindow* window, const QString &property) {
1584- if (property != QStringLiteral("persistentSurfaceId")) {
1585- return;
1586- }
1587- if (window->window() == m_window) {
1588- registerMenuForWindow(m_window, m_path);
1589- }
1590- });
1591- }
1592-}
1593-
1594-UbuntuMenuRegistrar::~UbuntuMenuRegistrar()
1595-{
1596- if (m_connection) {
1597- g_object_unref(m_connection);
1598- }
1599- unregisterMenu();
1600-}
1601-
1602-void UbuntuMenuRegistrar::registerMenuForWindow(QWindow* window, const QDBusObjectPath& path)
1603-{
1604- unregisterMenu();
1605-
1606- m_window = window;
1607- m_path = path;
1608-
1609- registerMenu();
1610-}
1611-
1612-void UbuntuMenuRegistrar::registerMenu()
1613-{
1614- if (UbuntuMenuRegistry::instance()->isConnected() && m_window) {
1615- if (isMirClient()) {
1616- registerSurfaceMenu();
1617- } else {
1618- registerApplicationMenu();
1619- }
1620- }
1621-}
1622-
1623-void UbuntuMenuRegistrar::unregisterMenu()
1624-{
1625- if (!m_registeredSurfaceId.isEmpty()) {
1626- unregisterSurfaceMenu();
1627- } else if (m_registeredProcessId != ~0) {
1628- unregisterApplicationMenu();
1629- }
1630-}
1631-
1632-void UbuntuMenuRegistrar::registerSurfaceMenu()
1633-{
1634- auto nativeInterface = qGuiApp->platformNativeInterface();
1635- QByteArray persistentSurfaceId = nativeInterface->windowProperty(m_window->handle(), "persistentSurfaceId", QByteArray()).toByteArray();
1636- if (persistentSurfaceId.isEmpty()) return;
1637-
1638- UbuntuMenuRegistry::instance()->registerSurfaceMenu(persistentSurfaceId, m_path, m_service);
1639- m_registeredSurfaceId = persistentSurfaceId;
1640-}
1641-
1642-void UbuntuMenuRegistrar::unregisterSurfaceMenu()
1643-{
1644- if (UbuntuMenuRegistry::instance()->isConnected()) {
1645- UbuntuMenuRegistry::instance()->unregisterSurfaceMenu(m_registeredSurfaceId, m_path);
1646- }
1647- m_registeredSurfaceId.clear();
1648-}
1649-
1650-void UbuntuMenuRegistrar::registerApplicationMenu()
1651-{
1652- pid_t pid = getpid();
1653- UbuntuMenuRegistry::instance()->registerApplicationMenu(pid, m_path, m_service);
1654- m_registeredProcessId = pid;
1655-}
1656-
1657-void UbuntuMenuRegistrar::unregisterApplicationMenu()
1658-{
1659- if (UbuntuMenuRegistry::instance()->isConnected()) {
1660- UbuntuMenuRegistry::instance()->unregisterApplicationMenu(m_registeredProcessId, m_path);
1661- }
1662- m_registeredProcessId = ~0;
1663-}
1664-
1665-void UbuntuMenuRegistrar::onRegistrarServiceChanged()
1666-{
1667- unregisterMenu();
1668- registerMenu();
1669-}
1670
1671=== removed file 'src/ubuntuappmenu/menuregistrar.h'
1672--- src/ubuntuappmenu/menuregistrar.h 2016-09-30 08:35:16 +0000
1673+++ src/ubuntuappmenu/menuregistrar.h 1970-01-01 00:00:00 +0000
1674@@ -1,59 +0,0 @@
1675-/*
1676- * Copyright (C) 2016 Canonical, Ltd.
1677- *
1678- * This program is free software: you can redistribute it and/or modify it under
1679- * the terms of the GNU Lesser General Public License version 3, as published by
1680- * the Free Software Foundation.
1681- *
1682- * This program is distributed in the hope that it will be useful, but WITHOUT
1683- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1684- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1685- * Lesser General Public License for more details.
1686- *
1687- * You should have received a copy of the GNU Lesser General Public License
1688- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1689- */
1690-
1691-#ifndef MENUREGISTRAR_H
1692-#define MENUREGISTRAR_H
1693-
1694-#include <QObject>
1695-#include <QWindow>
1696-#include <QPointer>
1697-#include <QDBusObjectPath>
1698-
1699-#include <gio/gio.h>
1700-
1701-class UbuntuMenuRegistrar : public QObject
1702-{
1703- Q_OBJECT
1704-public:
1705- UbuntuMenuRegistrar();
1706- ~UbuntuMenuRegistrar();
1707-
1708- void registerMenuForWindow(QWindow* window, const QDBusObjectPath& path);
1709- void unregisterMenu();
1710-
1711-private Q_SLOTS:
1712- void registerSurfaceMenu();
1713- void onRegistrarServiceChanged();
1714-
1715-private:
1716- void registerMenu();
1717-
1718- void registerApplicationMenu();
1719- void unregisterApplicationMenu();
1720-
1721- void unregisterSurfaceMenu();
1722-
1723- GDBusConnection *m_connection;
1724- QString m_service;
1725- QDBusObjectPath m_path;
1726- QPointer<QWindow> m_window;
1727- QString m_registeredSurfaceId;
1728- pid_t m_registeredProcessId;
1729-};
1730-
1731-
1732-#endif // MENUREGISTRAR_H
1733-
1734
1735=== removed file 'src/ubuntuappmenu/qtubuntuextraactionhandler.cpp'
1736--- src/ubuntuappmenu/qtubuntuextraactionhandler.cpp 2017-03-16 09:42:27 +0000
1737+++ src/ubuntuappmenu/qtubuntuextraactionhandler.cpp 1970-01-01 00:00:00 +0000
1738@@ -1,107 +0,0 @@
1739-/*
1740- * Copyright (C) 2017 Canonical, Ltd.
1741- *
1742- * This program is free software: you can redistribute it and/or modify it under
1743- * the terms of the GNU Lesser General Public License version 3, as published by
1744- * the Free Software Foundation.
1745- *
1746- * This program is distributed in the hope that it will be useful, but WITHOUT
1747- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1748- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1749- * Lesser General Public License for more details.
1750- *
1751- * You should have received a copy of the GNU Lesser General Public License
1752- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1753- */
1754-
1755-#include "qtubuntuextraactionhandler.h"
1756-
1757-#include "gmenumodelexporter.h"
1758-#include "logging.h"
1759-
1760-static const gchar introspection_xml[] =
1761- "<node>"
1762- " <interface name='qtubuntu.actions.extra'>"
1763- " <method name='aboutToShow'>"
1764- " <arg type='t' name='tag' direction='in'/>"
1765- " </method>"
1766- " </interface>"
1767- "</node>";
1768-
1769-static void handle_method_call (GDBusConnection *,
1770- const gchar *,
1771- const gchar *,
1772- const gchar *,
1773- const gchar *method_name,
1774- GVariant *parameters,
1775- GDBusMethodInvocation *invocation,
1776- gpointer user_data)
1777-{
1778-
1779- if (g_strcmp0 (method_name, "aboutToShow") == 0)
1780- {
1781- if (g_variant_check_format_string(parameters, "(t)", false)) {
1782- auto obj = static_cast<UbuntuGMenuModelExporter*>(user_data);
1783- guint64 tag;
1784-
1785- g_variant_get (parameters, "(t)", &tag);
1786- obj->aboutToShow(tag);
1787- }
1788-
1789- g_dbus_method_invocation_return_value (invocation, NULL);
1790- } else {
1791- g_dbus_method_invocation_return_error(invocation,
1792- G_DBUS_ERROR,
1793- G_DBUS_ERROR_UNKNOWN_METHOD,
1794- "Unknown method");
1795- }
1796-}
1797-
1798-
1799-static const GDBusInterfaceVTable interface_vtable =
1800-{
1801- handle_method_call,
1802- NULL,
1803- NULL,
1804- NULL
1805-};
1806-
1807-QtUbuntuExtraActionHandler::QtUbuntuExtraActionHandler()
1808- : m_registration_id(0)
1809-{
1810- m_introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
1811-}
1812-
1813-QtUbuntuExtraActionHandler::~QtUbuntuExtraActionHandler()
1814-{
1815- g_clear_pointer(&m_introspection_data, g_dbus_node_info_unref);
1816-}
1817-
1818-bool QtUbuntuExtraActionHandler::connect(GDBusConnection *connection, const QByteArray &menuPath, UbuntuGMenuModelExporter *gmenuexporter)
1819-{
1820- if (m_registration_id != 0) {
1821- qCWarning(ubuntuappmenu, "Called connect in an already connected QtUbuntuExtraActionHandler");
1822- return false;
1823- }
1824-
1825- GError *error = nullptr;
1826- m_registration_id = g_dbus_connection_register_object (connection, menuPath.constData(),
1827- m_introspection_data->interfaces[0],
1828- &interface_vtable,
1829- gmenuexporter,
1830- nullptr,
1831- &error);
1832-
1833- if (!m_registration_id) {
1834- qCWarning(ubuntuappmenu, "Failed to extra actions - %s", error ? error->message : "unknown error");
1835- g_clear_error(&error);
1836- }
1837-
1838- return m_registration_id != 0;
1839-}
1840-
1841-void QtUbuntuExtraActionHandler::disconnect(GDBusConnection *connection) {
1842- if (m_registration_id) {
1843- g_dbus_connection_unregister_object (connection, m_registration_id);
1844- }
1845-}
1846
1847=== removed file 'src/ubuntuappmenu/qtubuntuextraactionhandler.h'
1848--- src/ubuntuappmenu/qtubuntuextraactionhandler.h 2017-03-06 16:19:29 +0000
1849+++ src/ubuntuappmenu/qtubuntuextraactionhandler.h 1970-01-01 00:00:00 +0000
1850@@ -1,40 +0,0 @@
1851-/*
1852- * Copyright (C) 2017 Canonical, Ltd.
1853- *
1854- * This program is free software: you can redistribute it and/or modify it under
1855- * the terms of the GNU Lesser General Public License version 3, as published by
1856- * the Free Software Foundation.
1857- *
1858- * This program is distributed in the hope that it will be useful, but WITHOUT
1859- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1860- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1861- * Lesser General Public License for more details.
1862- *
1863- * You should have received a copy of the GNU Lesser General Public License
1864- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1865- */
1866-
1867-#ifndef QTUBUNTUEXTRAACTIONHANDLER_H
1868-#define QTUBUNTUEXTRAACTIONHANDLER_H
1869-
1870-#include <gio/gio.h>
1871-
1872-class QByteArray;
1873-
1874-class UbuntuGMenuModelExporter;
1875-
1876-class QtUbuntuExtraActionHandler
1877-{
1878-public:
1879- QtUbuntuExtraActionHandler();
1880- ~QtUbuntuExtraActionHandler();
1881-
1882- bool connect(GDBusConnection *connection, const QByteArray &menuPath, UbuntuGMenuModelExporter *gmenuexporter);
1883- void disconnect(GDBusConnection *connection);
1884-
1885-private:
1886- GDBusNodeInfo *m_introspection_data;
1887- guint m_registration_id;
1888-};
1889-
1890-#endif
1891
1892=== removed file 'src/ubuntuappmenu/registry.cpp'
1893--- src/ubuntuappmenu/registry.cpp 2016-09-29 15:12:29 +0000
1894+++ src/ubuntuappmenu/registry.cpp 1970-01-01 00:00:00 +0000
1895@@ -1,97 +0,0 @@
1896-/*
1897- * Copyright (C) 2016 Canonical, Ltd.
1898- *
1899- * This program is free software: you can redistribute it and/or modify it under
1900- * the terms of the GNU Lesser General Public License version 3, as published by
1901- * the Free Software Foundation.
1902- *
1903- * This program is distributed in the hope that it will be useful, but WITHOUT
1904- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1905- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1906- * Lesser General Public License for more details.
1907- *
1908- * You should have received a copy of the GNU Lesser General Public License
1909- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1910- */
1911-
1912-#include "registry.h"
1913-#include "logging.h"
1914-#include "menuregistrar_interface.h"
1915-
1916-#include <QDBusObjectPath>
1917-#include <QDBusServiceWatcher>
1918-
1919-Q_LOGGING_CATEGORY(ubuntuappmenuRegistrar, "ubuntuappmenu.registrar", QtWarningMsg)
1920-
1921-#define REGISTRAR_SERVICE "com.ubuntu.MenuRegistrar"
1922-#define REGISTRY_OBJECT_PATH "/com/ubuntu/MenuRegistrar"
1923-
1924-UbuntuMenuRegistry *UbuntuMenuRegistry::instance()
1925-{
1926- static UbuntuMenuRegistry* registry(new UbuntuMenuRegistry());
1927- return registry;
1928-}
1929-
1930-UbuntuMenuRegistry::UbuntuMenuRegistry(QObject* parent)
1931- : QObject(parent)
1932- , m_serviceWatcher(new QDBusServiceWatcher(REGISTRAR_SERVICE, QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this))
1933- , m_interface(new ComUbuntuMenuRegistrarInterface(REGISTRAR_SERVICE, REGISTRY_OBJECT_PATH, QDBusConnection::sessionBus(), this))
1934- , m_connected(m_interface->isValid())
1935-{
1936- connect(m_serviceWatcher.data(), &QDBusServiceWatcher::serviceOwnerChanged, this, &UbuntuMenuRegistry::serviceOwnerChanged);
1937-}
1938-
1939-UbuntuMenuRegistry::~UbuntuMenuRegistry()
1940-{
1941-}
1942-
1943-void UbuntuMenuRegistry::registerApplicationMenu(pid_t pid, QDBusObjectPath menuObjectPath, const QString &service)
1944-{
1945- qCDebug(ubuntuappmenuRegistrar, "UbuntuMenuRegistry::registerMenu(pid=%d, menuObjectPath=%s, service=%s)",
1946- pid,
1947- qPrintable(menuObjectPath.path()),
1948- qPrintable(service));
1949-
1950- m_interface->RegisterAppMenu(pid, menuObjectPath, menuObjectPath, service);
1951-}
1952-
1953-void UbuntuMenuRegistry::unregisterApplicationMenu(pid_t pid, QDBusObjectPath menuObjectPath)
1954-{
1955- qCDebug(ubuntuappmenuRegistrar, "UbuntuMenuRegistry::unregisterSurfaceMenu(pid=%d, menuObjectPath=%s)",
1956- pid,
1957- qPrintable(menuObjectPath.path()));
1958-
1959- m_interface->UnregisterAppMenu(pid, menuObjectPath);
1960-}
1961-
1962-void UbuntuMenuRegistry::registerSurfaceMenu(const QString &surfaceId, QDBusObjectPath menuObjectPath, const QString &service)
1963-{
1964- qCDebug(ubuntuappmenuRegistrar, "UbuntuMenuRegistry::registerMenu(surfaceId=%s, menuObjectPath=%s, service=%s)",
1965- qPrintable(surfaceId),
1966- qPrintable(menuObjectPath.path()),
1967- qPrintable(service));
1968-
1969- m_interface->RegisterSurfaceMenu(surfaceId, menuObjectPath, menuObjectPath, service);
1970-}
1971-
1972-void UbuntuMenuRegistry::unregisterSurfaceMenu(const QString &surfaceId, QDBusObjectPath menuObjectPath)
1973-{
1974- qCDebug(ubuntuappmenuRegistrar, "UbuntuMenuRegistry::unregisterSurfaceMenu(surfaceId=%s, menuObjectPath=%s)",
1975- qPrintable(surfaceId),
1976- qPrintable(menuObjectPath.path()));
1977-
1978- m_interface->UnregisterSurfaceMenu(surfaceId, menuObjectPath);
1979-}
1980-
1981-
1982-void UbuntuMenuRegistry::serviceOwnerChanged(const QString &serviceName, const QString& oldOwner, const QString &newOwner)
1983-{
1984- qCDebug(ubuntuappmenuRegistrar, "UbuntuMenuRegistry::serviceOwnerChanged(newOwner=%s)", qPrintable(newOwner));
1985-
1986- if (serviceName != REGISTRAR_SERVICE) return;
1987-
1988- if (oldOwner != newOwner) {
1989- m_connected = !newOwner.isEmpty();
1990- Q_EMIT serviceChanged();
1991- }
1992-}
1993
1994=== removed file 'src/ubuntuappmenu/registry.h'
1995--- src/ubuntuappmenu/registry.h 2016-09-29 15:03:17 +0000
1996+++ src/ubuntuappmenu/registry.h 1970-01-01 00:00:00 +0000
1997@@ -1,56 +0,0 @@
1998-/*
1999- * Copyright (C) 2016 Canonical, Ltd.
2000- *
2001- * This program is free software: you can redistribute it and/or modify it under
2002- * the terms of the GNU Lesser General Public License version 3, as published by
2003- * the Free Software Foundation.
2004- *
2005- * This program is distributed in the hope that it will be useful, but WITHOUT
2006- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2007- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2008- * Lesser General Public License for more details.
2009- *
2010- * You should have received a copy of the GNU Lesser General Public License
2011- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2012- */
2013-
2014-#ifndef UBUNTU_MENU_REGISTRY_H
2015-#define UBUNTU_MENU_REGISTRY_H
2016-
2017-#include <QObject>
2018-#include <QScopedPointer>
2019-
2020-class ComUbuntuMenuRegistrarInterface;
2021-class QDBusObjectPath;
2022-class QDBusServiceWatcher;
2023-
2024-class UbuntuMenuRegistry : public QObject
2025-{
2026- Q_OBJECT
2027-public:
2028- UbuntuMenuRegistry(QObject* parent = nullptr);
2029- virtual ~UbuntuMenuRegistry();
2030-
2031- static UbuntuMenuRegistry *instance();
2032-
2033- void registerApplicationMenu(pid_t pid, QDBusObjectPath menuObjectPath, const QString &service);
2034- void unregisterApplicationMenu(pid_t pid, QDBusObjectPath menuObjectPath);
2035-
2036- void registerSurfaceMenu(const QString &surfaceId, QDBusObjectPath menuObjectPath, const QString &service);
2037- void unregisterSurfaceMenu(const QString &surfaceId, QDBusObjectPath menuObjectPath);
2038-
2039- bool isConnected() const { return m_connected; }
2040-
2041-Q_SIGNALS:
2042- void serviceChanged();
2043-
2044-private Q_SLOTS:
2045- void serviceOwnerChanged(const QString &serviceName, const QString& oldOwner, const QString &newOwner);
2046-
2047-private:
2048- QScopedPointer<QDBusServiceWatcher> m_serviceWatcher;
2049- QScopedPointer<ComUbuntuMenuRegistrarInterface> m_interface;
2050- bool m_connected;
2051-};
2052-
2053-#endif // UBUNTU_MENU_REGISTRY_H
2054
2055=== removed file 'src/ubuntuappmenu/theme.cpp'
2056--- src/ubuntuappmenu/theme.cpp 2017-03-29 14:16:47 +0000
2057+++ src/ubuntuappmenu/theme.cpp 1970-01-01 00:00:00 +0000
2058@@ -1,67 +0,0 @@
2059-/*
2060- * Copyright (C) 2016-2017 Canonical, Ltd.
2061- *
2062- * This program is free software: you can redistribute it and/or modify it under
2063- * the terms of the GNU Lesser General Public License version 3, as published by
2064- * the Free Software Foundation.
2065- *
2066- * This program is distributed in the hope that it will be useful, but WITHOUT
2067- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2068- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2069- * Lesser General Public License for more details.
2070- *
2071- * You should have received a copy of the GNU Lesser General Public License
2072- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2073- */
2074-
2075-#include "theme.h"
2076-#include "gmenumodelplatformmenu.h"
2077-#include "logging.h"
2078-
2079-#include <QtCore/QVariant>
2080-#include <QDebug>
2081-
2082-Q_LOGGING_CATEGORY(ubuntuappmenu, "ubuntuappmenu", QtWarningMsg)
2083-const char *UbuntuAppMenuTheme::name = "ubuntuappmenu";
2084-
2085-namespace {
2086-
2087-bool useLocalMenu() {
2088- QByteArray menuProxy = qgetenv("UBUNTU_MENUPROXY");
2089- bool menuProxyIsZero = !menuProxy.isEmpty() && menuProxy.at(0) == '0';
2090- return menuProxyIsZero;
2091-}
2092-
2093-}
2094-
2095-UbuntuAppMenuTheme::UbuntuAppMenuTheme():
2096- UbuntuTheme()
2097-{
2098- qCDebug(ubuntuappmenu, "UbuntuAppMenuTheme::UbuntuAppMenuTheme() - useLocalMenu=%s", useLocalMenu() ? "true" : "false");
2099-}
2100-
2101-QPlatformMenuItem *UbuntuAppMenuTheme::createPlatformMenuItem() const
2102-{
2103- if (useLocalMenu()) return QGenericUnixTheme::createPlatformMenuItem();
2104- return new UbuntuPlatformMenuItem();
2105-}
2106-
2107-QPlatformMenu *UbuntuAppMenuTheme::createPlatformMenu() const
2108-{
2109- if (useLocalMenu()) return QGenericUnixTheme::createPlatformMenu();
2110- return new UbuntuPlatformMenu();
2111-}
2112-
2113-QPlatformMenuBar *UbuntuAppMenuTheme::createPlatformMenuBar() const
2114-{
2115- if (useLocalMenu()) return QGenericUnixTheme::createPlatformMenuBar();
2116- return new UbuntuPlatformMenuBar();
2117-}
2118-
2119-QPlatformSystemTrayIcon *UbuntuAppMenuTheme::createPlatformSystemTrayIcon() const
2120-{
2121- // We can't use QGenericUnixTheme implementation since it needs the platformMenu to
2122- // be a subclass of QDBusPlatformMenu and ours isn't
2123- // TODO Investigate if we're fine with not supporting system trays or we should fix it
2124- return nullptr;
2125-}
2126
2127=== removed file 'src/ubuntuappmenu/theme.h'
2128--- src/ubuntuappmenu/theme.h 2017-03-29 14:16:47 +0000
2129+++ src/ubuntuappmenu/theme.h 1970-01-01 00:00:00 +0000
2130@@ -1,36 +0,0 @@
2131-/*
2132- * Copyright (C) 2016-2017 Canonical, Ltd.
2133- *
2134- * This program is free software: you can redistribute it and/or modify it under
2135- * the terms of the GNU Lesser General Public License version 3, as published by
2136- * the Free Software Foundation.
2137- *
2138- * This program is distributed in the hope that it will be useful, but WITHOUT
2139- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2140- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2141- * Lesser General Public License for more details.
2142- *
2143- * You should have received a copy of the GNU Lesser General Public License
2144- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2145- */
2146-
2147-#ifndef UBUNTU_THEME_H
2148-#define UBUNTU_THEME_H
2149-
2150-#include "../shared/ubuntutheme.h"
2151-
2152-class UbuntuAppMenuTheme : public UbuntuTheme
2153-{
2154-public:
2155- static const char* name;
2156- UbuntuAppMenuTheme();
2157- ~UbuntuAppMenuTheme() = default;
2158-
2159- // For the menus
2160- QPlatformMenuItem* createPlatformMenuItem() const override;
2161- QPlatformMenu* createPlatformMenu() const override;
2162- QPlatformMenuBar* createPlatformMenuBar() const override;
2163- QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const override;
2164-};
2165-
2166-#endif // UBUNTU_THEME_H
2167
2168=== removed file 'src/ubuntuappmenu/themeplugin.cpp'
2169--- src/ubuntuappmenu/themeplugin.cpp 2016-09-29 15:03:17 +0000
2170+++ src/ubuntuappmenu/themeplugin.cpp 1970-01-01 00:00:00 +0000
2171@@ -1,36 +0,0 @@
2172-/*
2173- * Copyright (C) 2016 Canonical, Ltd.
2174- *
2175- * This program is free software: you can redistribute it and/or modify it under
2176- * the terms of the GNU Lesser General Public License version 3, as published by
2177- * the Free Software Foundation.
2178- *
2179- * This program is distributed in the hope that it will be useful, but WITHOUT
2180- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2181- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2182- * Lesser General Public License for more details.
2183- *
2184- * You should have received a copy of the GNU Lesser General Public License
2185- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2186- */
2187-
2188-#include "themeplugin.h"
2189-#include "theme.h"
2190-
2191-#include <QDebug>
2192-
2193-///////////////////////////////////////////////////////////
2194-
2195-UbuntuAppMenuThemePlugin::UbuntuAppMenuThemePlugin(QObject *parent)
2196- : QPlatformThemePlugin(parent)
2197-{
2198-}
2199-
2200-QPlatformTheme *
2201-UbuntuAppMenuThemePlugin::create(const QString &key, const QStringList&)
2202-{
2203- if (key.compare(QLatin1String(UbuntuAppMenuTheme::name), Qt::CaseInsensitive))
2204- return 0;
2205-
2206- return new UbuntuAppMenuTheme();
2207-}
2208
2209=== removed file 'src/ubuntuappmenu/themeplugin.h'
2210--- src/ubuntuappmenu/themeplugin.h 2016-06-21 16:33:19 +0000
2211+++ src/ubuntuappmenu/themeplugin.h 1970-01-01 00:00:00 +0000
2212@@ -1,34 +0,0 @@
2213-/*
2214- * Copyright (C) 2016 Canonical, Ltd.
2215- *
2216- * This program is free software: you can redistribute it and/or modify it under
2217- * the terms of the GNU Lesser General Public License version 3, as published by
2218- * the Free Software Foundation.
2219- *
2220- * This program is distributed in the hope that it will be useful, but WITHOUT
2221- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2222- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2223- * Lesser General Public License for more details.
2224- *
2225- * You should have received a copy of the GNU Lesser General Public License
2226- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2227- */
2228-
2229-#ifndef UBUNTUTHEMEPLUGIN_H
2230-#define UBUNTUTHEMEPLUGIN_H
2231-
2232-#include <qpa/qplatformthemeplugin.h>
2233-
2234-class UbuntuAppMenuThemePlugin : public QPlatformThemePlugin
2235-{
2236- Q_OBJECT
2237- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformThemeFactoryInterface.5.1" FILE "ubuntuappmenu.json")
2238-public:
2239- UbuntuAppMenuThemePlugin(QObject *parent = 0);
2240-
2241- virtual QPlatformTheme *create(const QString &key, const QStringList &paramList);
2242-
2243- static const char *name;
2244-};
2245-
2246-#endif
2247
2248=== removed file 'src/ubuntuappmenu/ubuntuappmenu.json'
2249--- src/ubuntuappmenu/ubuntuappmenu.json 2016-06-21 16:33:19 +0000
2250+++ src/ubuntuappmenu/ubuntuappmenu.json 1970-01-01 00:00:00 +0000
2251@@ -1,3 +0,0 @@
2252-{
2253- "Keys": [ "ubuntuappmenu" ]
2254-}
2255
2256=== removed file 'src/ubuntuappmenu/ubuntuappmenu.pro'
2257--- src/ubuntuappmenu/ubuntuappmenu.pro 2017-07-07 08:17:58 +0000
2258+++ src/ubuntuappmenu/ubuntuappmenu.pro 1970-01-01 00:00:00 +0000
2259@@ -1,44 +0,0 @@
2260-TARGET = ubuntuappmenu
2261-TEMPLATE = lib
2262-
2263-QT -= gui
2264-QT += core-private theme_support-private dbus
2265-
2266-CONFIG += plugin no_keywords
2267-
2268-# CONFIG += c++11 # only enables C++0x
2269-QMAKE_CXXFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden -std=c++11 -Werror -Wall
2270-QMAKE_LFLAGS += -std=c++11 -Wl,-no-undefined
2271-
2272-CONFIG += link_pkgconfig
2273-PKGCONFIG += gio-2.0
2274-
2275-DBUS_INTERFACES += com.ubuntu.MenuRegistrar.xml
2276-
2277-HEADERS += \
2278- theme.h \
2279- gmenumodelexporter.h \
2280- gmenumodelplatformmenu.h \
2281- logging.h \
2282- menuregistrar.h \
2283- registry.h \
2284- themeplugin.h \
2285- qtubuntuextraactionhandler.h \
2286- ../shared/ubuntutheme.h
2287-
2288-SOURCES += \
2289- theme.cpp \
2290- gmenumodelexporter.cpp \
2291- gmenumodelplatformmenu.cpp \
2292- menuregistrar.cpp \
2293- registry.cpp \
2294- themeplugin.cpp \
2295- qtubuntuextraactionhandler.cpp
2296-
2297-OTHER_FILES += \
2298- ubuntuappmenu.json
2299-
2300-# Installation path
2301-target.path += $$[QT_INSTALL_PLUGINS]/platformthemes
2302-
2303-INSTALLS += target
2304
2305=== removed file 'src/ubuntumirclient/qmirclientclipboard.cpp'
2306--- src/ubuntumirclient/qmirclientclipboard.cpp 2017-03-02 10:49:22 +0000
2307+++ src/ubuntumirclient/qmirclientclipboard.cpp 1970-01-01 00:00:00 +0000
2308@@ -1,180 +0,0 @@
2309-/****************************************************************************
2310-**
2311-** Copyright (C) 2016 Canonical, Ltd.
2312-** Contact: https://www.qt.io/licensing/
2313-**
2314-** This file is part of the plugins of the Qt Toolkit.
2315-**
2316-** $QT_BEGIN_LICENSE:LGPL$
2317-** Commercial License Usage
2318-** Licensees holding valid commercial Qt licenses may use this file in
2319-** accordance with the commercial license agreement provided with the
2320-** Software or, alternatively, in accordance with the terms contained in
2321-** a written agreement between you and The Qt Company. For licensing terms
2322-** and conditions see https://www.qt.io/terms-conditions. For further
2323-** information use the contact form at https://www.qt.io/contact-us.
2324-**
2325-** GNU Lesser General Public License Usage
2326-** Alternatively, this file may be used under the terms of the GNU Lesser
2327-** General Public License version 3 as published by the Free Software
2328-** Foundation and appearing in the file LICENSE.LGPL3 included in the
2329-** packaging of this file. Please review the following information to
2330-** ensure the GNU Lesser General Public License version 3 requirements
2331-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
2332-**
2333-** GNU General Public License Usage
2334-** Alternatively, this file may be used under the terms of the GNU
2335-** General Public License version 2.0 or (at your option) the GNU General
2336-** Public license version 3 or any later version approved by the KDE Free
2337-** Qt Foundation. The licenses are as published by the Free Software
2338-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
2339-** included in the packaging of this file. Please review the following
2340-** information to ensure the GNU General Public License requirements will
2341-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
2342-** https://www.gnu.org/licenses/gpl-3.0.html.
2343-**
2344-** $QT_END_LICENSE$
2345-**
2346-****************************************************************************/
2347-
2348-
2349-#include "qmirclientclipboard.h"
2350-#include "qmirclientlogging.h"
2351-#include "qmirclientwindow.h"
2352-
2353-#include <QDBusPendingCallWatcher>
2354-#include <QGuiApplication>
2355-#include <QSignalBlocker>
2356-#include <QtCore/QMimeData>
2357-#include <QtCore/QStringList>
2358-
2359-// content-hub
2360-#include <com/ubuntu/content/hub.h>
2361-
2362-// get this cumbersome nested namespace out of the way
2363-using namespace com::ubuntu::content;
2364-
2365-QMirClientClipboard::QMirClientClipboard()
2366- : mMimeData(new QMimeData)
2367- , mContentHub(Hub::Client::instance())
2368-{
2369- connect(mContentHub, &Hub::pasteboardChanged, this, [this]() {
2370- if (mClipboardState == QMirClientClipboard::SyncedClipboard) {
2371- mClipboardState = QMirClientClipboard::OutdatedClipboard;
2372- emitChanged(QClipboard::Clipboard);
2373- }
2374- });
2375-
2376- connect(qGuiApp, &QGuiApplication::applicationStateChanged,
2377- this, &QMirClientClipboard::onApplicationStateChanged);
2378-
2379- requestMimeData();
2380-}
2381-
2382-QMirClientClipboard::~QMirClientClipboard()
2383-{
2384- delete mMimeData;
2385-}
2386-
2387-QMimeData* QMirClientClipboard::mimeData(QClipboard::Mode mode)
2388-{
2389- if (mode != QClipboard::Clipboard)
2390- return nullptr;
2391-
2392- // Blocks dataChanged() signal from being emitted. Makes no sense to emit it from
2393- // inside the data getter.
2394- const QSignalBlocker blocker(this);
2395-
2396- if (mClipboardState == OutdatedClipboard) {
2397- updateMimeData();
2398- } else if (mClipboardState == SyncingClipboard) {
2399- mPasteReply->waitForFinished();
2400- }
2401-
2402- return mMimeData;
2403-}
2404-
2405-void QMirClientClipboard::setMimeData(QMimeData* mimeData, QClipboard::Mode mode)
2406-{
2407- QWindow *focusWindow = QGuiApplication::focusWindow();
2408- if (focusWindow && mode == QClipboard::Clipboard && mimeData != nullptr) {
2409- QString surfaceId = static_cast<QMirClientWindow*>(focusWindow->handle())->persistentSurfaceId();
2410-
2411- QDBusPendingCall reply = mContentHub->createPaste(surfaceId, *mimeData);
2412-
2413- // Don't care whether it succeeded
2414- QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
2415- connect(watcher, &QDBusPendingCallWatcher::finished,
2416- watcher, &QObject::deleteLater);
2417-
2418- mMimeData = mimeData;
2419- mClipboardState = SyncedClipboard;
2420- emitChanged(QClipboard::Clipboard);
2421- }
2422-}
2423-
2424-bool QMirClientClipboard::supportsMode(QClipboard::Mode mode) const
2425-{
2426- return mode == QClipboard::Clipboard;
2427-}
2428-
2429-bool QMirClientClipboard::ownsMode(QClipboard::Mode mode) const
2430-{
2431- Q_UNUSED(mode);
2432- return false;
2433-}
2434-
2435-void QMirClientClipboard::onApplicationStateChanged(Qt::ApplicationState state)
2436-{
2437- if (state == Qt::ApplicationActive) {
2438- // Only focused or active applications might be allowed to paste, so we probably
2439- // missed changes in the clipboard while we were hidden, inactive or, more importantly,
2440- // suspended.
2441- requestMimeData();
2442- }
2443-}
2444-
2445-void QMirClientClipboard::updateMimeData()
2446-{
2447- if (qGuiApp->applicationState() != Qt::ApplicationActive) {
2448- // Don't even bother asking as content-hub would probably ignore our request (and should).
2449- return;
2450- }
2451-
2452- QWindow *focusWindow = QGuiApplication::focusWindow();
2453- if (focusWindow) {
2454- delete mMimeData;
2455- QString surfaceId = static_cast<QMirClientWindow*>(focusWindow->handle())->persistentSurfaceId();
2456- mMimeData = mContentHub->latestPaste(surfaceId);
2457- mClipboardState = SyncedClipboard;
2458- emitChanged(QClipboard::Clipboard);
2459- }
2460-}
2461-
2462-void QMirClientClipboard::requestMimeData()
2463-{
2464- if (qGuiApp->applicationState() != Qt::ApplicationActive) {
2465- // Don't even bother asking as content-hub would probably ignore our request (and should).
2466- return;
2467- }
2468-
2469- QWindow *focusWindow = QGuiApplication::focusWindow();
2470- if (!focusWindow) {
2471- return;
2472- }
2473-
2474- QString surfaceId = static_cast<QMirClientWindow*>(focusWindow->handle())->persistentSurfaceId();
2475- QDBusPendingCall reply = mContentHub->requestLatestPaste(surfaceId);
2476- mClipboardState = SyncingClipboard;
2477-
2478- mPasteReply = new QDBusPendingCallWatcher(reply, this);
2479- connect(mPasteReply, &QDBusPendingCallWatcher::finished,
2480- this, [this]() {
2481- delete mMimeData;
2482- mMimeData = mContentHub->paste(*mPasteReply);
2483- mClipboardState = SyncedClipboard;
2484- mPasteReply->deleteLater();
2485- mPasteReply = nullptr;
2486- emitChanged(QClipboard::Clipboard);
2487- });
2488-}
2489
2490=== removed file 'src/ubuntumirclient/qmirclientclipboard.h'
2491--- src/ubuntumirclient/qmirclientclipboard.h 2017-02-07 15:37:20 +0000
2492+++ src/ubuntumirclient/qmirclientclipboard.h 1970-01-01 00:00:00 +0000
2493@@ -1,92 +0,0 @@
2494-/****************************************************************************
2495-**
2496-** Copyright (C) 2016 Canonical, Ltd.
2497-** Contact: https://www.qt.io/licensing/
2498-**
2499-** This file is part of the plugins of the Qt Toolkit.
2500-**
2501-** $QT_BEGIN_LICENSE:LGPL$
2502-** Commercial License Usage
2503-** Licensees holding valid commercial Qt licenses may use this file in
2504-** accordance with the commercial license agreement provided with the
2505-** Software or, alternatively, in accordance with the terms contained in
2506-** a written agreement between you and The Qt Company. For licensing terms
2507-** and conditions see https://www.qt.io/terms-conditions. For further
2508-** information use the contact form at https://www.qt.io/contact-us.
2509-**
2510-** GNU Lesser General Public License Usage
2511-** Alternatively, this file may be used under the terms of the GNU Lesser
2512-** General Public License version 3 as published by the Free Software
2513-** Foundation and appearing in the file LICENSE.LGPL3 included in the
2514-** packaging of this file. Please review the following information to
2515-** ensure the GNU Lesser General Public License version 3 requirements
2516-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
2517-**
2518-** GNU General Public License Usage
2519-** Alternatively, this file may be used under the terms of the GNU
2520-** General Public License version 2.0 or (at your option) the GNU General
2521-** Public license version 3 or any later version approved by the KDE Free
2522-** Qt Foundation. The licenses are as published by the Free Software
2523-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
2524-** included in the packaging of this file. Please review the following
2525-** information to ensure the GNU General Public License requirements will
2526-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
2527-** https://www.gnu.org/licenses/gpl-3.0.html.
2528-**
2529-** $QT_END_LICENSE$
2530-**
2531-****************************************************************************/
2532-
2533-
2534-#ifndef QMIRCLIENTCLIPBOARD_H
2535-#define QMIRCLIENTCLIPBOARD_H
2536-
2537-#include <qpa/qplatformclipboard.h>
2538-
2539-#include <QMimeData>
2540-#include <QPointer>
2541-
2542-namespace com {
2543- namespace ubuntu {
2544- namespace content {
2545- class Hub;
2546- }
2547- }
2548-}
2549-
2550-class QDBusPendingCallWatcher;
2551-
2552-class QMirClientClipboard : public QObject, public QPlatformClipboard
2553-{
2554- Q_OBJECT
2555-public:
2556- QMirClientClipboard();
2557- virtual ~QMirClientClipboard();
2558-
2559- // QPlatformClipboard methods.
2560- QMimeData* mimeData(QClipboard::Mode mode = QClipboard::Clipboard) override;
2561- void setMimeData(QMimeData* data, QClipboard::Mode mode = QClipboard::Clipboard) override;
2562- bool supportsMode(QClipboard::Mode mode) const override;
2563- bool ownsMode(QClipboard::Mode mode) const override;
2564-
2565-private Q_SLOTS:
2566- void onApplicationStateChanged(Qt::ApplicationState state);
2567-
2568-private:
2569- void updateMimeData();
2570- void requestMimeData();
2571-
2572- QMimeData *mMimeData;
2573-
2574- enum {
2575- OutdatedClipboard, // Our mimeData is outdated, need to fetch latest from ContentHub
2576- SyncingClipboard, // Our mimeData is outdated and we are waiting for ContentHub to reply with the latest paste
2577- SyncedClipboard // Our mimeData is in sync with what ContentHub has
2578- } mClipboardState{OutdatedClipboard};
2579-
2580- com::ubuntu::content::Hub *mContentHub;
2581-
2582- QDBusPendingCallWatcher *mPasteReply{nullptr};
2583-};
2584-
2585-#endif // QMIRCLIENTCLIPBOARD_H
2586
2587=== modified file 'src/ubuntumirclient/qmirclientcursor.cpp'
2588--- src/ubuntumirclient/qmirclientcursor.cpp 2017-03-28 17:12:13 +0000
2589+++ src/ubuntumirclient/qmirclientcursor.cpp 2017-08-25 11:54:50 +0000
2590@@ -138,11 +138,17 @@
2591 {
2592 public:
2593 CursorWindowSpec(MirConnection *connection, const char *name)
2594- : spec(mir_create_window_spec(connection))
2595+ : CursorWindowSpec(connection)
2596 {
2597 mir_window_spec_set_cursor_name(spec, name);
2598 }
2599
2600+ CursorWindowSpec(MirConnection *connection, MirRenderSurface *surface, int hotspotX, int hotspotY)
2601+ : CursorWindowSpec(connection)
2602+ {
2603+ mir_window_spec_set_cursor_render_surface(spec, surface, hotspotX, hotspotY);
2604+ }
2605+
2606 ~CursorWindowSpec()
2607 {
2608 mir_window_spec_release(spec);
2609@@ -153,8 +159,60 @@
2610 mir_window_apply_spec(window, spec);
2611 }
2612 private:
2613+ CursorWindowSpec(MirConnection *connection) : spec(mir_create_window_spec(connection)) {}
2614 MirWindowSpec * const spec;
2615 };
2616+
2617+class BufferStream
2618+{
2619+public:
2620+ BufferStream(MirRenderSurface *surface, int width, int height)
2621+ : stream(mir_render_surface_get_buffer_stream(surface, width, height, mir_pixel_format_argb_8888))
2622+ {
2623+ }
2624+
2625+ void draw(QImage const& image)
2626+ {
2627+ MirGraphicsRegion region;
2628+ const bool validRegion = mir_buffer_stream_get_graphics_region(stream, &region);
2629+ if (!validRegion)
2630+ throw std::runtime_error("Could not get graphics region to draw into");
2631+
2632+ auto regionLine = region.vaddr;
2633+ Q_ASSERT(image.bytesPerLine() <= region.stride);
2634+
2635+ for (int i = 0; i < image.height(); ++i) {
2636+ memcpy(regionLine, image.scanLine(i), image.bytesPerLine());
2637+ regionLine += region.stride;
2638+ }
2639+ mir_buffer_stream_swap_buffers_sync(stream);
2640+ }
2641+
2642+private:
2643+ MirBufferStream * const stream;
2644+};
2645+
2646+class RenderSurface
2647+{
2648+public:
2649+ RenderSurface(MirConnection *connection, int width, int height)
2650+ : surface(mir_connection_create_render_surface_sync(connection, width, height)),
2651+ stream(surface, width, height)
2652+ {
2653+ if (!mir_render_surface_is_valid(surface)) {
2654+ throw std::runtime_error(mir_render_surface_get_error_message(surface));
2655+ }
2656+ }
2657+
2658+ ~RenderSurface() { mir_render_surface_release(surface); }
2659+ operator MirRenderSurface *() const { return surface; }
2660+ void draw(QImage const& image) { stream.draw(image); }
2661+
2662+private:
2663+ MirRenderSurface * const surface;
2664+ BufferStream stream;
2665+};
2666+
2667 } // anonymous namespace
2668
2669 void QMirClientCursor::changeCursor(QCursor *windowCursor, QWindow *window)
2670@@ -196,30 +254,15 @@
2671 image = image.convertToFormat(QImage::Format_ARGB32);
2672 }
2673
2674- MirBufferStream *bufferStream = mir_connection_create_buffer_stream_sync(mConnection,
2675- image.width(), image.height(), mir_pixel_format_argb_8888, mir_buffer_usage_software);
2676-
2677- {
2678- MirGraphicsRegion region;
2679- mir_buffer_stream_get_graphics_region(bufferStream, &region);
2680-
2681- char *regionLine = region.vaddr;
2682- Q_ASSERT(image.bytesPerLine() <= region.stride);
2683- for (int i = 0; i < image.height(); ++i) {
2684- memcpy(regionLine, image.scanLine(i), image.bytesPerLine());
2685- regionLine += region.stride;
2686- }
2687- }
2688-
2689- mir_buffer_stream_swap_buffers_sync(bufferStream);
2690-
2691- {
2692- auto configuration = mir_cursor_configuration_from_buffer_stream(bufferStream, cursor.hotSpot().x(), cursor.hotSpot().y());
2693- mir_window_configure_cursor(window, configuration);
2694- mir_cursor_configuration_destroy(configuration);
2695- }
2696-
2697- mir_buffer_stream_release_sync(bufferStream);
2698+ try {
2699+ RenderSurface surface(mConnection, image.width(), image.height());
2700+ surface.draw(image);
2701+
2702+ CursorWindowSpec spec(mConnection, surface, cursor.hotSpot().x(), cursor.hotSpot().y());
2703+ spec.apply(window);
2704+ } catch(std::exception const& e) {
2705+ qWarning("Error applying pixmap cursor: %s", e.what());
2706+ }
2707 }
2708
2709 void QMirClientCursor::applyDefaultCursorConfiguration(MirWindow *window)
2710
2711=== modified file 'src/ubuntumirclient/qmirclientintegration.cpp'
2712--- src/ubuntumirclient/qmirclientintegration.cpp 2017-07-07 08:17:58 +0000
2713+++ src/ubuntumirclient/qmirclientintegration.cpp 2017-08-25 11:54:50 +0000
2714@@ -41,7 +41,6 @@
2715 // Local
2716 #include "qmirclientintegration.h"
2717 #include "qmirclientbackingstore.h"
2718-#include "qmirclientclipboard.h"
2719 #include "qmirclientdebugextension.h"
2720 #include "qmirclientdesktopwindow.h"
2721 #include "qmirclientglcontext.h"
2722@@ -61,67 +60,93 @@
2723 #include <QtEglSupport/private/qeglconvenience_p.h>
2724 #include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h>
2725 #include <QtEventDispatcherSupport/private/qgenericunixeventdispatcher_p.h>
2726+#include <QtServiceSupport/private/qgenericunixservices_p.h>
2727 #include <QtEglSupport/private/qeglpbuffer_p.h>
2728 #include <QtLinuxAccessibilitySupport/private/bridge_p.h>
2729 #include <QOpenGLContext>
2730 #include <QOffscreenSurface>
2731
2732-// platform-api
2733-#include <ubuntu/application/lifecycle_delegate.h>
2734-#include <ubuntu/application/id.h>
2735-#include <ubuntu/application/options.h>
2736-
2737-static void resumedCallback(const UApplicationOptions */*options*/, void *context)
2738-{
2739- auto integration = static_cast<QMirClientClientIntegration*>(context);
2740- integration->appStateController()->setResumed();
2741+namespace
2742+{
2743+class UbuntuIconTheme : public QGenericUnixTheme
2744+{
2745+public:
2746+ UbuntuIconTheme()
2747+ {}
2748+
2749+ // From QPlatformTheme
2750+ QVariant themeHint(ThemeHint hint) const override
2751+ {
2752+ if (hint == QPlatformTheme::SystemIconThemeName)
2753+ {
2754+ QByteArray iconTheme = qgetenv("QTUBUNTU_ICON_THEME");
2755+ if (iconTheme.isEmpty())
2756+ {
2757+ return QVariant(QStringLiteral("ubuntu-mobile"));
2758+ }
2759+ else
2760+ {
2761+ return QVariant(QString(iconTheme));
2762+ }
2763+ }
2764+ else
2765+ {
2766+ return QGenericUnixTheme::themeHint(hint);
2767+ }
2768+ }
2769+};
2770+
2771+QByteArray generateSessionNameFromQmlFile(QStringList &args)
2772+{
2773+ Q_FOREACH (QString arg, args) {
2774+ if (arg.endsWith(".qml")) {
2775+ QFileInfo fileInfo(arg);
2776+ return fileInfo.fileName().toLocal8Bit();
2777+ }
2778+ }
2779+
2780+ // give up
2781+ return "qmlscene";
2782 }
2783
2784-static void aboutToStopCallback(UApplicationArchive */*archive*/, void *context)
2785+QByteArray generateSessionName(QStringList args)
2786 {
2787- auto integration = static_cast<QMirClientClientIntegration*>(context);
2788- auto inputContext = integration->inputContext();
2789- if (inputContext) {
2790- inputContext->hideInputPanel();
2791+ // Try to come up with some meaningful session name to uniquely identify this session,
2792+ // helping with shell debugging
2793+ if (args.count() == 0) {
2794+ return QByteArray("QtUbuntu");
2795+ } if (args[0].contains("qmlscene")) {
2796+ return generateSessionNameFromQmlFile(args);
2797 } else {
2798- qCWarning(mirclient) << "aboutToStopCallback(): no input context";
2799+ // use the executable name
2800+ QFileInfo fileInfo(args[0]);
2801+ return fileInfo.fileName().toLocal8Bit();
2802 }
2803- integration->appStateController()->setSuspended();
2804 }
2805
2806+MirConnection *make_mir_connection()
2807+{
2808+ auto sessionName = generateSessionName(QCoreApplication::arguments());
2809+ auto mirConnection = mir_connect_sync(nullptr, sessionName.data());
2810+ if (!mir_connection_is_valid(mirConnection))
2811+ {
2812+ qCritical("Mir returned: \"%s\"", mir_connection_get_error_message(mirConnection));
2813+ mir_connection_release(mirConnection);
2814+ exit(EXIT_FAILURE);
2815+ }
2816+ return mirConnection;
2817+}
2818+}
2819
2820 QMirClientClientIntegration::QMirClientClientIntegration(int argc, char **argv)
2821 : QPlatformIntegration()
2822 , mNativeInterface(new QMirClientNativeInterface(this))
2823 , mFontDb(new QGenericUnixFontDatabase)
2824- , mServices(new QMirClientPlatformServices)
2825+ , mPlatformServices(new QGenericUnixServices)
2826 , mAppStateController(new QMirClientAppStateController)
2827 , mScaleFactor(1.0)
2828+ , mMirConnection(make_mir_connection())
2829 {
2830- QByteArray sessionName;
2831- {
2832- QStringList args = QCoreApplication::arguments();
2833- setupOptions(args);
2834- sessionName = generateSessionName(args);
2835- setupDescription(sessionName);
2836- }
2837-
2838- // Create new application instance
2839- mInstance = u_application_instance_new_from_description_with_options(mDesc, mOptions);
2840-
2841- if (mInstance == nullptr) {
2842- qCritical("[QPA] QMirClientClientIntegration: connection to Mir server failed.\n");
2843-
2844- // TODO: add API to platform-api to fetch Mir's error message (bug:1655970).
2845- // Workaround by retrying the connection here in order to get the message.
2846- auto mirConnection = mir_connect_sync(nullptr, sessionName.data());
2847- qCritical("Mir returned: \"%s\"", mir_connection_get_error_message(mirConnection));
2848- mir_connection_release(mirConnection);
2849- exit(EXIT_FAILURE);
2850- }
2851-
2852- mMirConnection = u_application_instance_get_mir_connection(mInstance);
2853-
2854 // Choose the default surface format suited to the Mir platform
2855 QSurfaceFormat defaultFormat;
2856 defaultFormat.setRedBufferSize(8);
2857@@ -130,8 +155,7 @@
2858 QSurfaceFormat::setDefaultFormat(defaultFormat);
2859
2860 // Initialize EGL.
2861- mEglNativeDisplay = mir_connection_get_egl_native_display(mMirConnection);
2862- ASSERT((mEglDisplay = eglGetDisplay(mEglNativeDisplay)) != EGL_NO_DISPLAY);
2863+ ASSERT((mEglDisplay = eglGetDisplay(mMirConnection)) != EGL_NO_DISPLAY);
2864 ASSERT(eglInitialize(mEglDisplay, nullptr, nullptr) == EGL_TRUE);
2865
2866 // Has debug mode been requsted, either with "-testability" switch or QT_LOAD_TESTABILITY env var
2867@@ -185,70 +209,7 @@
2868 eglTerminate(mEglDisplay);
2869 delete mInput;
2870 delete mInputContext;
2871- delete mServices;
2872-}
2873-
2874-QPlatformServices *QMirClientClientIntegration::services() const
2875-{
2876- return mServices;
2877-}
2878-
2879-void QMirClientClientIntegration::setupOptions(QStringList &args)
2880-{
2881- int argc = args.size() + 1;
2882- char **argv = new char*[argc];
2883- for (int i = 0; i < argc - 1; i++)
2884- argv[i] = qstrdup(args.at(i).toLocal8Bit());
2885- argv[argc - 1] = nullptr;
2886-
2887- mOptions = u_application_options_new_from_cmd_line(argc - 1, argv);
2888-
2889- for (int i = 0; i < argc; i++)
2890- delete [] argv[i];
2891- delete [] argv;
2892-}
2893-
2894-void QMirClientClientIntegration::setupDescription(QByteArray &sessionName)
2895-{
2896- mDesc = u_application_description_new();
2897-
2898- UApplicationId* id = u_application_id_new_from_stringn(sessionName.data(), sessionName.count());
2899- u_application_description_set_application_id(mDesc, id);
2900-
2901- UApplicationLifecycleDelegate* delegate = u_application_lifecycle_delegate_new();
2902- u_application_lifecycle_delegate_set_application_resumed_cb(delegate, &resumedCallback);
2903- u_application_lifecycle_delegate_set_application_about_to_stop_cb(delegate, &aboutToStopCallback);
2904- u_application_lifecycle_delegate_set_context(delegate, this);
2905- u_application_description_set_application_lifecycle_delegate(mDesc, delegate);
2906-}
2907-
2908-QByteArray QMirClientClientIntegration::generateSessionName(QStringList &args)
2909-{
2910- // Try to come up with some meaningful session name to uniquely identify this session,
2911- // helping with shell debugging
2912-
2913- if (args.count() == 0) {
2914- return QByteArray("QtUbuntu");
2915- } if (args[0].contains("qmlscene")) {
2916- return generateSessionNameFromQmlFile(args);
2917- } else {
2918- // use the executable name
2919- QFileInfo fileInfo(args[0]);
2920- return fileInfo.fileName().toLocal8Bit();
2921- }
2922-}
2923-
2924-QByteArray QMirClientClientIntegration::generateSessionNameFromQmlFile(QStringList &args)
2925-{
2926- Q_FOREACH (QString arg, args) {
2927- if (arg.endsWith(".qml")) {
2928- QFileInfo fileInfo(arg);
2929- return fileInfo.fileName().toLocal8Bit();
2930- }
2931- }
2932-
2933- // give up
2934- return "qmlscene";
2935+ mir_connection_release(mMirConnection);
2936 }
2937
2938 QPlatformWindow* QMirClientClientIntegration::createPlatformWindow(QWindow* window) const
2939@@ -262,6 +223,11 @@
2940 }
2941 }
2942
2943+QPlatformServices *QMirClientClientIntegration::services() const
2944+{
2945+ return mPlatformServices.data();
2946+}
2947+
2948 bool QMirClientClientIntegration::hasCapability(QPlatformIntegration::Capability cap) const
2949 {
2950 switch (cap) {
2951@@ -350,15 +316,6 @@
2952 return QPlatformIntegration::styleHint(hint);
2953 }
2954
2955-QPlatformClipboard* QMirClientClientIntegration::clipboard() const
2956-{
2957- static QPlatformClipboard *clipboard = nullptr;
2958- if (!clipboard) {
2959- clipboard = new QMirClientClipboard;
2960- }
2961- return clipboard;
2962-}
2963-
2964 QPlatformNativeInterface* QMirClientClientIntegration::nativeInterface() const
2965 {
2966 return mNativeInterface;
2967
2968=== modified file 'src/ubuntumirclient/qmirclientintegration.h'
2969--- src/ubuntumirclient/qmirclientintegration.h 2017-03-15 09:21:47 +0000
2970+++ src/ubuntumirclient/qmirclientintegration.h 2017-08-25 11:54:50 +0000
2971@@ -45,13 +45,8 @@
2972 #include <QSharedPointer>
2973
2974 #include "qmirclientappstatecontroller.h"
2975-#include "qmirclientplatformservices.h"
2976 #include "qmirclientscreenobserver.h"
2977
2978-// platform-api
2979-#include <ubuntu/application/description.h>
2980-#include <ubuntu/application/instance.h>
2981-
2982 #include <EGL/egl.h>
2983
2984 class QMirClientDebugExtension;
2985@@ -81,7 +76,6 @@
2986 QPlatformServices *services() const override;
2987 QPlatformWindow* createPlatformWindow(QWindow* window) const override;
2988 QPlatformInputContext* inputContext() const override { return mInputContext; }
2989- QPlatformClipboard* clipboard() const override;
2990 void initialize() override;
2991 QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override;
2992 QPlatformAccessibility *accessibility() const override;
2993@@ -89,7 +83,7 @@
2994 // New methods.
2995 MirConnection *mirConnection() const { return mMirConnection; }
2996 EGLDisplay eglDisplay() const { return mEglDisplay; }
2997- EGLNativeDisplayType eglNativeDisplay() const { return mEglNativeDisplay; }
2998+ EGLNativeDisplayType eglNativeDisplay() const { return mMirConnection; }
2999 QMirClientAppStateController *appStateController() const { return mAppStateController.data(); }
3000 QMirClientScreenObserver *screenObserver() const { return mScreenObserver.data(); }
3001 QMirClientDebugExtension *debugExtension() const { return mDebugExtension.data(); }
3002@@ -100,32 +94,23 @@
3003 private:
3004 void setupOptions(QStringList &args);
3005 void setupDescription(QByteArray &sessionName);
3006- static QByteArray generateSessionName(QStringList &args);
3007- static QByteArray generateSessionNameFromQmlFile(QStringList &args);
3008
3009 QMirClientNativeInterface* mNativeInterface;
3010 QPlatformFontDatabase* mFontDb;
3011
3012- QMirClientPlatformServices* mServices;
3013-
3014 QMirClientInput* mInput;
3015 QPlatformInputContext* mInputContext;
3016 mutable QScopedPointer<QPlatformAccessibility> mAccessibility;
3017+ const QScopedPointer<QPlatformServices> mPlatformServices;
3018+ const QScopedPointer<QMirClientAppStateController> mAppStateController;
3019 QScopedPointer<QMirClientDebugExtension> mDebugExtension;
3020 QScopedPointer<QMirClientScreenObserver> mScreenObserver;
3021- QScopedPointer<QMirClientAppStateController> mAppStateController;
3022 qreal mScaleFactor;
3023
3024 MirConnection *mMirConnection;
3025
3026- // Platform API stuff
3027- UApplicationOptions* mOptions;
3028- UApplicationDescription* mDesc;
3029- UApplicationInstance* mInstance;
3030-
3031 // EGL related
3032 EGLDisplay mEglDisplay{EGL_NO_DISPLAY};
3033- EGLNativeDisplayType mEglNativeDisplay;
3034 };
3035
3036 #endif // QMIRCLIENTINTEGRATION_H
3037
3038=== removed file 'src/ubuntumirclient/qmirclientplatformservices.cpp'
3039--- src/ubuntumirclient/qmirclientplatformservices.cpp 2017-02-07 15:37:20 +0000
3040+++ src/ubuntumirclient/qmirclientplatformservices.cpp 1970-01-01 00:00:00 +0000
3041@@ -1,75 +0,0 @@
3042-/****************************************************************************
3043-**
3044-** Copyright (C) 2016 Canonical, Ltd.
3045-** Contact: https://www.qt.io/licensing/
3046-**
3047-** This file is part of the plugins of the Qt Toolkit.
3048-**
3049-** $QT_BEGIN_LICENSE:LGPL$
3050-** Commercial License Usage
3051-** Licensees holding valid commercial Qt licenses may use this file in
3052-** accordance with the commercial license agreement provided with the
3053-** Software or, alternatively, in accordance with the terms contained in
3054-** a written agreement between you and The Qt Company. For licensing terms
3055-** and conditions see https://www.qt.io/terms-conditions. For further
3056-** information use the contact form at https://www.qt.io/contact-us.
3057-**
3058-** GNU Lesser General Public License Usage
3059-** Alternatively, this file may be used under the terms of the GNU Lesser
3060-** General Public License version 3 as published by the Free Software
3061-** Foundation and appearing in the file LICENSE.LGPL3 included in the
3062-** packaging of this file. Please review the following information to
3063-** ensure the GNU Lesser General Public License version 3 requirements
3064-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
3065-**
3066-** GNU General Public License Usage
3067-** Alternatively, this file may be used under the terms of the GNU
3068-** General Public License version 2.0 or (at your option) the GNU General
3069-** Public license version 3 or any later version approved by the KDE Free
3070-** Qt Foundation. The licenses are as published by the Free Software
3071-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
3072-** included in the packaging of this file. Please review the following
3073-** information to ensure the GNU General Public License requirements will
3074-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
3075-** https://www.gnu.org/licenses/gpl-3.0.html.
3076-**
3077-** $QT_END_LICENSE$
3078-**
3079-****************************************************************************/
3080-
3081-
3082-#include "qmirclientplatformservices.h"
3083-
3084-#include <QUrl>
3085-
3086-#include <ubuntu/application/url_dispatcher/service.h>
3087-#include <ubuntu/application/url_dispatcher/session.h>
3088-
3089-bool QMirClientPlatformServices::openUrl(const QUrl &url)
3090-{
3091- return callDispatcher(url);
3092-}
3093-
3094-bool QMirClientPlatformServices::openDocument(const QUrl &url)
3095-{
3096- return callDispatcher(url);
3097-}
3098-
3099-bool QMirClientPlatformServices::callDispatcher(const QUrl &url)
3100-{
3101- UAUrlDispatcherSession* session = ua_url_dispatcher_session();
3102- if (!session)
3103- return false;
3104-
3105- ua_url_dispatcher_session_open(session, url.toEncoded().constData(), NULL, NULL);
3106-
3107- free(session);
3108-
3109- // We are returning true here because the other option
3110- // is spawning a nested event loop and wait for the
3111- // callback. But there is no guarantee on how fast
3112- // the callback is going to be so we prefer to avoid the
3113- // nested event loop. Long term plan is improve Qt API
3114- // to support an async openUrl
3115- return true;
3116-}
3117
3118=== removed file 'src/ubuntumirclient/qmirclientplatformservices.h'
3119--- src/ubuntumirclient/qmirclientplatformservices.h 2017-07-07 08:17:58 +0000
3120+++ src/ubuntumirclient/qmirclientplatformservices.h 1970-01-01 00:00:00 +0000
3121@@ -1,57 +0,0 @@
3122-/****************************************************************************
3123-**
3124-** Copyright (C) 2016 Canonical, Ltd.
3125-** Contact: https://www.qt.io/licensing/
3126-**
3127-** This file is part of the plugins of the Qt Toolkit.
3128-**
3129-** $QT_BEGIN_LICENSE:LGPL$
3130-** Commercial License Usage
3131-** Licensees holding valid commercial Qt licenses may use this file in
3132-** accordance with the commercial license agreement provided with the
3133-** Software or, alternatively, in accordance with the terms contained in
3134-** a written agreement between you and The Qt Company. For licensing terms
3135-** and conditions see https://www.qt.io/terms-conditions. For further
3136-** information use the contact form at https://www.qt.io/contact-us.
3137-**
3138-** GNU Lesser General Public License Usage
3139-** Alternatively, this file may be used under the terms of the GNU Lesser
3140-** General Public License version 3 as published by the Free Software
3141-** Foundation and appearing in the file LICENSE.LGPL3 included in the
3142-** packaging of this file. Please review the following information to
3143-** ensure the GNU Lesser General Public License version 3 requirements
3144-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
3145-**
3146-** GNU General Public License Usage
3147-** Alternatively, this file may be used under the terms of the GNU
3148-** General Public License version 2.0 or (at your option) the GNU General
3149-** Public license version 3 or any later version approved by the KDE Free
3150-** Qt Foundation. The licenses are as published by the Free Software
3151-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
3152-** included in the packaging of this file. Please review the following
3153-** information to ensure the GNU General Public License requirements will
3154-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
3155-** https://www.gnu.org/licenses/gpl-3.0.html.
3156-**
3157-** $QT_END_LICENSE$
3158-**
3159-****************************************************************************/
3160-
3161-
3162-#ifndef QMIRCLIENTPLATFORMSERVICES_H
3163-#define QMIRCLIENTPLATFORMSERVICES_H
3164-
3165-#include <qpa/qplatformservices.h>
3166-#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h>
3167-#include <QtEventDispatcherSupport/private/qgenericunixeventdispatcher_p.h>
3168-
3169-class QMirClientPlatformServices : public QPlatformServices {
3170-public:
3171- bool openUrl(const QUrl &url) override;
3172- bool openDocument(const QUrl &url) override;
3173-
3174-private:
3175- bool callDispatcher(const QUrl &url);
3176-};
3177-
3178-#endif // QMIRCLIENTPLATFORMSERVICES_H
3179
3180=== modified file 'src/ubuntumirclient/qmirclientwindow.cpp'
3181--- src/ubuntumirclient/qmirclientwindow.cpp 2017-07-07 08:17:58 +0000
3182+++ src/ubuntumirclient/qmirclientwindow.cpp 2017-08-25 11:54:50 +0000
3183@@ -75,12 +75,6 @@
3184
3185 using Spec = std::unique_ptr<MirWindowSpec, MirSpecDeleter>;
3186
3187-EGLNativeWindowType nativeWindowFor(MirWindow *surf)
3188-{
3189- auto stream = mir_window_get_buffer_stream(surf);
3190- return reinterpret_cast<EGLNativeWindowType>(mir_buffer_stream_get_egl_native_window(stream));
3191-}
3192-
3193 const char *qtWindowStateToStr(Qt::WindowState state)
3194 {
3195 switch (state) {
3196@@ -114,24 +108,6 @@
3197 Q_UNREACHABLE();
3198 }
3199
3200-const char *mirPixelFormatToStr(MirPixelFormat pixelFormat)
3201-{
3202- switch (pixelFormat) {
3203- case mir_pixel_format_invalid: return "invalid";
3204- case mir_pixel_format_abgr_8888: return "ABGR8888";
3205- case mir_pixel_format_xbgr_8888: return "XBGR8888";
3206- case mir_pixel_format_argb_8888: return "ARGB8888";
3207- case mir_pixel_format_xrgb_8888: return "XRGB8888";
3208- case mir_pixel_format_bgr_888: return "BGR888";
3209- case mir_pixel_format_rgb_888: return "RGB888";
3210- case mir_pixel_format_rgb_565: return "RGB565";
3211- case mir_pixel_format_rgba_5551: return "RGBA5551";
3212- case mir_pixel_format_rgba_4444: return "RGBA4444";
3213- case mir_pixel_formats: Q_UNREACHABLE();
3214- }
3215- Q_UNREACHABLE();
3216-}
3217-
3218 const char *mirWindowTypeToStr(MirWindowType type)
3219 {
3220 switch (type) {
3221@@ -221,12 +197,23 @@
3222 return requiresParent(qtWindowTypeToMirWindowType(type));
3223 }
3224
3225-Spec makeSurfaceSpec(QWindow *window, MirPixelFormat pixelFormat, QMirClientWindow *parentWindowHandle,
3226- MirConnection *connection)
3227-{
3228- const auto geometry = window->geometry();
3229- const int width = geometry.width() > 0 ? geometry.width() : 1;
3230- const int height = geometry.height() > 0 ? geometry.height() : 1;
3231+QRect geometryFor(QWindow *window)
3232+{
3233+ auto geometry = window->geometry();
3234+ if (geometry.width() < 1)
3235+ geometry.setWidth(1);
3236+ if (geometry.height() < 1)
3237+ geometry.setHeight(1);
3238+
3239+ return geometry;
3240+}
3241+
3242+Spec makeWindowSpec(QWindow *window, QMirClientWindow *parentWindowHandle,
3243+ MirRenderSurface *surface, MirConnection *connection)
3244+{
3245+ const auto geometry = geometryFor(window);
3246+ const int width = geometry.width();
3247+ const int height = geometry.height();
3248 auto type = qtWindowTypeToMirWindowType(window->type());
3249
3250 MirRectangle location{geometry.x(), geometry.y(), 0, 0};
3251@@ -272,7 +259,6 @@
3252 // There's no helper function for satellite windows. Guess they're not very popular
3253 spec = Spec{mir_create_window_spec(connection)};
3254 mir_window_spec_set_type(spec.get(), mir_window_type_satellite);
3255- mir_window_spec_set_buffer_usage(spec.get(), mir_buffer_usage_hardware);
3256 mir_window_spec_set_parent(spec.get(), parent);
3257 mir_window_spec_set_width(spec.get(), width);
3258 mir_window_spec_set_height(spec.get(), height);
3259@@ -282,9 +268,9 @@
3260 break;
3261 }
3262
3263- mir_window_spec_set_pixel_format(spec.get(), pixelFormat);
3264+ mir_window_spec_add_render_surface(spec.get(), surface, width, height, 0, 0);
3265
3266- qCDebug(mirclient, "makeSurfaceSpec(window=%p): %s spec (type=0x%x, position=(%d, %d)px, size=(%dx%d)px)",
3267+ qCDebug(mirclient, "makeWindowSpec(window=%p): %s spec (type=0x%x, position=(%d, %d)px, size=(%dx%d)px)",
3268 window, mirWindowTypeToStr(type), window->type(), location.left, location.top, width, height);
3269
3270 return spec;
3271@@ -331,14 +317,29 @@
3272 mir_window_spec_set_input_shape(spec, rects, count);
3273 }
3274
3275+MirRenderSurface *createMirSurface(QWindow *window, MirConnection *connection)
3276+{
3277+ const auto geometry = geometryFor(window);
3278+ const int width = geometry.width();
3279+ const int height = geometry.height();
3280+
3281+ auto surface = mir_connection_create_render_surface_sync(connection, width, height);
3282+ if (!mir_render_surface_is_valid(surface))
3283+ {
3284+ auto errorMsg = mir_render_surface_get_error_message(surface);
3285+ qFatal("Failed to create mir surface: %s", errorMsg);
3286+ }
3287+ return surface;
3288+}
3289+
3290 MirWindow *createMirWindow(QWindow *window, int mirOutputId, QMirClientWindow *parentWindowHandle,
3291- MirPixelFormat pixelFormat, MirConnection *connection,
3292- MirWindowEventCallback inputCallback, void *inputContext)
3293+ MirRenderSurface *surface, MirConnection *connection,
3294+ MirWindowEventCallback eventCallback, void *context)
3295 {
3296- auto spec = makeSurfaceSpec(window, pixelFormat, parentWindowHandle, connection);
3297+ auto spec = makeWindowSpec(window, parentWindowHandle, surface, connection);
3298
3299 // Install event handler as early as possible
3300- mir_window_spec_set_event_handler(spec.get(), inputCallback, inputContext);
3301+ mir_window_spec_set_event_handler(spec.get(), eventCallback, context);
3302
3303 const auto title = window->title().toUtf8();
3304 mir_window_spec_set_name(spec.get(), title.constData());
3305@@ -358,9 +359,14 @@
3306 mir_window_spec_set_state(spec.get(), mir_window_state_hidden);
3307 }
3308
3309- auto surface = mir_create_window_sync(spec.get());
3310- Q_ASSERT(mir_window_is_valid(surface));
3311- return surface;
3312+ auto mirWindow = mir_create_window_sync(spec.get());
3313+ if (!mir_window_is_valid(mirWindow))
3314+ {
3315+ auto errorMsg = mir_window_get_error_message(mirWindow);
3316+ qFatal("Failed to create mir window: %s", errorMsg);
3317+ }
3318+
3319+ return mirWindow;
3320 }
3321
3322 QMirClientWindow *getParentIfNecessary(QWindow *window, QMirClientInput *input)
3323@@ -377,18 +383,6 @@
3324 return parentWindowHandle;
3325 }
3326
3327-MirPixelFormat disableAlphaBufferIfPossible(MirPixelFormat pixelFormat)
3328-{
3329- switch (pixelFormat) {
3330- case mir_pixel_format_abgr_8888:
3331- return mir_pixel_format_xbgr_8888;
3332- case mir_pixel_format_argb_8888:
3333- return mir_pixel_format_xrgb_8888;
3334- default: // can do nothing, leave it alone
3335- return pixelFormat;
3336- }
3337-}
3338-
3339 // FIXME - in order to work around https://bugs.launchpad.net/mir/+bug/1346633
3340 // we need to guess the panel height (3GU)
3341 int panelHeight()
3342@@ -426,7 +420,6 @@
3343
3344 void onSwapBuffersDone();
3345 void handleSurfaceResized(int width, int height);
3346- int needsRepaint() const;
3347
3348 MirWindowState state() const { return mir_window_get_state(mMirWindow); }
3349 void setState(MirWindowState state);
3350@@ -448,7 +441,7 @@
3351 QString persistentSurfaceId();
3352
3353 private:
3354- static void surfaceEventCallback(MirWindow* surface, const MirEvent *event, void* context);
3355+ static void windowEventCallback(MirWindow* surface, const MirEvent *event, void* context);
3356 void postEvent(const MirEvent *event);
3357
3358 QWindow * const mWindow;
3359@@ -458,14 +451,12 @@
3360 QMirClientWindow * mParentWindowHandle{nullptr};
3361
3362 MirWindow* mMirWindow;
3363+ MirRenderSurface* mMirSurface;
3364 const EGLDisplay mEglDisplay;
3365 EGLSurface mEglSurface;
3366
3367- bool mNeedsRepaint;
3368 bool mParented;
3369- QSize mBufferSize;
3370 QSurfaceFormat mFormat;
3371- MirPixelFormat mPixelFormat;
3372
3373 QMutex mTargetSizeMutex;
3374 QSize mTargetSize;
3375@@ -479,7 +470,6 @@
3376 , mInput(input)
3377 , mConnection(connection)
3378 , mEglDisplay(display)
3379- , mNeedsRepaint(false)
3380 , mParented(mWindow->transientParent() || mWindow->parent())
3381 , mFormat(mWindow->requestedFormat())
3382 , mShellChrome(mWindow->flags() & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal)
3383@@ -506,50 +496,33 @@
3384
3385 mFormat = q_glFormatFromConfig(display, config, mFormat);
3386
3387- // Have Mir decide the pixel format most suited to the chosen EGLConfig. This is the only way
3388- // Mir will know what EGLConfig has been chosen - it cannot deduce it from the buffers.
3389- mPixelFormat = mir_connection_get_egl_pixel_format(connection, display, config);
3390- // But the chosen EGLConfig might have an alpha buffer enabled, even if not requested by the client.
3391- // If that's the case, try to edit the chosen pixel format in order to disable the alpha buffer.
3392- // This is an optimization for the compositor, as it can avoid blending this surface.
3393- if (mWindow->requestedFormat().alphaBufferSize() < 0) {
3394- mPixelFormat = disableAlphaBufferIfPossible(mPixelFormat);
3395- }
3396-
3397 const auto outputId = static_cast<QMirClientScreen *>(mWindow->screen()->handle())->mirOutputId();
3398
3399 mParentWindowHandle = getParentIfNecessary(mWindow, input);
3400
3401- mMirWindow = createMirWindow(mWindow, outputId, mParentWindowHandle, mPixelFormat, connection, surfaceEventCallback, this);
3402- mEglSurface = eglCreateWindowSurface(mEglDisplay, config, nativeWindowFor(mMirWindow), nullptr);
3403+ mMirSurface = createMirSurface(mWindow, connection);
3404+ mMirWindow = createMirWindow(mWindow, outputId, mParentWindowHandle, mMirSurface, connection, windowEventCallback, this);
3405+ mEglSurface = eglCreateWindowSurface(mEglDisplay, config, reinterpret_cast<EGLNativeWindowType>(mMirSurface), nullptr);
3406
3407 mNeedsExposeCatchup = mir_window_get_visibility(mMirWindow) == mir_window_visibility_occluded;
3408
3409- // Window manager can give us a final size different from what we asked for
3410- // so let's check what we ended up getting
3411- MirWindowParameters parameters;
3412- mir_window_get_parameters(mMirWindow, &parameters);
3413-
3414+ // Assume that the buffer size matches the surface size at creation time
3415 auto geom = mWindow->geometry();
3416- geom.setWidth(parameters.width);
3417- geom.setHeight(parameters.height);
3418-
3419- // Assume that the buffer size matches the surface size at creation time
3420- mBufferSize = geom.size();
3421- platformWindow->QPlatformWindow::setGeometry(geom);
3422- QWindowSystemInterface::handleGeometryChange(mWindow, geom);
3423
3424 qCDebug(mirclient) << "Created surface with geometry:" << geom << "title:" << mWindow->title();
3425 qCDebug(mirclientGraphics)
3426 << "Requested format:" << mWindow->requestedFormat()
3427- << "\nActual format:" << mFormat
3428- << "with associated Mir pixel format:" << mirPixelFormatToStr(mPixelFormat);
3429+ << "\nActual format:" << mFormat;
3430 }
3431
3432 UbuntuSurface::~UbuntuSurface()
3433 {
3434- if (mEglSurface != EGL_NO_SURFACE)
3435+ if (mEglSurface != EGL_NO_SURFACE) {
3436 eglDestroySurface(mEglDisplay, mEglSurface);
3437+ }
3438+ if (mMirSurface) {
3439+ mir_render_surface_release(mMirSurface);
3440+ }
3441 if (mMirWindow) {
3442 mir_window_release_sync(mMirWindow);
3443 }
3444@@ -606,30 +579,23 @@
3445 {
3446 QMutexLocker lock(&mTargetSizeMutex);
3447
3448- // mir's resize event is mainly a signal that we need to redraw our content. We use the
3449- // width/height as identifiers to figure out if this is the latest surface resize event
3450- // that has posted, discarding any old ones. This avoids issuing too many redraw events.
3451- // see TODO in postEvent as the ideal way we should handle this.
3452- // The actual buffer size may or may have not changed at this point, so let the rendering
3453- // thread drive the window geometry updates.
3454- mNeedsRepaint = mTargetSize.width() == width && mTargetSize.height() == height;
3455-}
3456-
3457-int UbuntuSurface::needsRepaint() const
3458-{
3459- if (mNeedsRepaint) {
3460- if (mTargetSize != mBufferSize) {
3461- //If the buffer hasn't changed yet, we need at least two redraws,
3462- //once to get the new buffer size and propagate the geometry changes
3463- //and the second to redraw the content at the new size
3464- return 2;
3465- } else {
3466- // The buffer size has already been updated so we only need one redraw
3467- // to render at the new size
3468- return 1;
3469- }
3470+ // There could have been a flurry of resize events, only process the latest event
3471+ const bool needsResize = mTargetSize.width() == width && mTargetSize.height() == height;
3472+ if (needsResize) {
3473+ // Resize the buffers
3474+ mir_render_surface_set_size(mMirSurface, width, height);
3475+
3476+ //Resize the window
3477+ Spec spec{mir_create_window_spec(mConnection)};
3478+ mir_window_spec_add_render_surface(spec.get(), mMirSurface, width, height, 0, 0);
3479+ mir_window_apply_spec(mMirWindow, spec.get());
3480+
3481+ QRect newGeometry = mPlatformWindow->geometry();
3482+ newGeometry.setSize(mTargetSize);
3483+
3484+ mPlatformWindow->QPlatformWindow::setGeometry(newGeometry);
3485+ QWindowSystemInterface::handleGeometryChange(mWindow, newGeometry);
3486 }
3487- return 0;
3488 }
3489
3490 void UbuntuSurface::setState(MirWindowState state)
3491@@ -653,35 +619,13 @@
3492 static int sFrameNumber = 0;
3493 ++sFrameNumber;
3494
3495- EGLint eglSurfaceWidth = -1;
3496- EGLint eglSurfaceHeight = -1;
3497- eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &eglSurfaceWidth);
3498- eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &eglSurfaceHeight);
3499-
3500- const bool validSize = eglSurfaceWidth > 0 && eglSurfaceHeight > 0;
3501-
3502- if (validSize && (mBufferSize.width() != eglSurfaceWidth || mBufferSize.height() != eglSurfaceHeight)) {
3503-
3504- qCDebug(mirclientBufferSwap, "onSwapBuffersDone(window=%p) [%d] - size changed (%d, %d) => (%d, %d)",
3505- mWindow, sFrameNumber, mBufferSize.width(), mBufferSize.height(), eglSurfaceWidth, eglSurfaceHeight);
3506-
3507- mBufferSize.rwidth() = eglSurfaceWidth;
3508- mBufferSize.rheight() = eglSurfaceHeight;
3509-
3510- QRect newGeometry = mPlatformWindow->geometry();
3511- newGeometry.setSize(mBufferSize);
3512-
3513- mPlatformWindow->QPlatformWindow::setGeometry(newGeometry);
3514- QWindowSystemInterface::handleGeometryChange(mWindow, newGeometry);
3515- } else {
3516- qCDebug(mirclientBufferSwap, "onSwapBuffersDone(window=%p) [%d] - buffer size (%d,%d)",
3517- mWindow, sFrameNumber, mBufferSize.width(), mBufferSize.height());
3518- }
3519+ qCDebug(mirclientBufferSwap, "onSwapBuffersDone(window=%p) [%d]",
3520+ mWindow, sFrameNumber);
3521 }
3522
3523-void UbuntuSurface::surfaceEventCallback(MirWindow *surface, const MirEvent *event, void* context)
3524+void UbuntuSurface::windowEventCallback(MirWindow *window, const MirEvent *event, void* context)
3525 {
3526- Q_UNUSED(surface);
3527+ Q_UNUSED(window);
3528 Q_ASSERT(context != nullptr);
3529
3530 auto s = static_cast<UbuntuSurface *>(context);
3531@@ -692,9 +636,8 @@
3532 {
3533 const auto eventType = mir_event_get_type(event);
3534 if (mir_event_type_resize == eventType) {
3535- // TODO: The current event queue just accumulates all resize events;
3536- // It would be nicer if we could update just one event if that event has not been dispatched.
3537- // As a workaround, we use the width/height as an identifier of this latest event
3538+ // The event queue just accumulates all resize events;
3539+ // Use the width and height as an identifier of this latest event
3540 // so the event handler (handleSurfaceResized) can discard/ignore old ones.
3541 const auto resizeEvent = mir_event_get_resize_event(event);
3542 const auto width = mir_resize_event_get_width(resizeEvent);
3543@@ -786,19 +729,6 @@
3544 qCDebug(mirclient, "handleSurfaceResize(window=%p, size=(%dx%d)px", window(), width, height);
3545
3546 mSurface->handleSurfaceResized(width, height);
3547-
3548- // This resize event could have occurred just after the last buffer swap for this window.
3549- // This means the client may still be holding a buffer with the older size. The first redraw call
3550- // will then render at the old size. After swapping the client now will get a new buffer with the
3551- // updated size but it still needs re-rendering so another redraw may be needed.
3552- // A mir API to drop the currently held buffer would help here, so that we wouldn't have to redraw twice
3553- auto const numRepaints = mSurface->needsRepaint();
3554- lock.unlock();
3555- qCDebug(mirclient, "handleSurfaceResize(window=%p) redraw %d times", window(), numRepaints);
3556- for (int i = 0; i < numRepaints; i++) {
3557- qCDebug(mirclient, "handleSurfaceResize(window=%p) repainting size=(%dx%d)dp", window(), geometry().size().width(), geometry().size().height());
3558- QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
3559- }
3560 }
3561
3562 void QMirClientWindow::handleSurfaceExposeChange(bool exposed)
3563
3564=== modified file 'src/ubuntumirclient/ubuntumirclient.pro'
3565--- src/ubuntumirclient/ubuntumirclient.pro 2017-07-07 08:17:58 +0000
3566+++ src/ubuntumirclient/ubuntumirclient.pro 2017-08-25 11:54:50 +0000
3567@@ -4,22 +4,21 @@
3568 QT += \
3569 core-private dbus linuxaccessibility_support-private \
3570 theme_support-private eventdispatcher_support-private \
3571- fontdatabase_support-private egl_support-private
3572+ fontdatabase_support-private egl_support-private service_support-private
3573
3574 CONFIG += plugin no_keywords qpa/genericunixfontdatabase
3575
3576-DEFINES += MESA_EGL_NO_X11_HEADERS
3577+DEFINES += MESA_EGL_NO_X11_HEADERS MIR_DEPRECATE_RENDERSURFACES=0 MIR_ENABLE_DEPRECATIONS=0
3578 # CONFIG += c++11 # only enables C++0x
3579 QMAKE_CXXFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden -std=c++11 -Werror -Wall
3580 QMAKE_CXXFLAGS += -Wno-error=deprecated-declarations
3581 QMAKE_LFLAGS += -std=c++11 -Wl,-no-undefined
3582
3583 CONFIG += link_pkgconfig
3584-PKGCONFIG += egl mirclient ubuntu-platform-api xkbcommon libcontent-hub
3585+PKGCONFIG += egl mirclient xkbcommon
3586
3587 SOURCES = \
3588 qmirclientbackingstore.cpp \
3589- qmirclientclipboard.cpp \
3590 qmirclientcursor.cpp \
3591 qmirclientdebugextension.cpp \
3592 qmirclientdesktopwindow.cpp \
3593@@ -27,7 +26,6 @@
3594 qmirclientinput.cpp \
3595 qmirclientintegration.cpp \
3596 qmirclientnativeinterface.cpp \
3597- qmirclientplatformservices.cpp \
3598 qmirclientplugin.cpp \
3599 qmirclientscreen.cpp \
3600 qmirclientscreenobserver.cpp \
3601@@ -36,7 +34,6 @@
3602
3603 HEADERS = \
3604 qmirclientbackingstore.h \
3605- qmirclientclipboard.h \
3606 qmirclientcursor.h \
3607 qmirclientdebugextension.h \
3608 qmirclientdesktopwindow.h \
3609@@ -45,7 +42,6 @@
3610 qmirclientintegration.h \
3611 qmirclientnativeinterface.h \
3612 qmirclientorientationchangeevent_p.h \
3613- qmirclientplatformservices.h \
3614 qmirclientplugin.h \
3615 qmirclientscreenobserver.h \
3616 qmirclientscreen.h \

Subscribers

People subscribed via source and target branches