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

Proposed by Gerry Boland on 2017-08-03
Status: Approved
Approved by: Gerry Boland on 2017-08-04
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 on 2017-08-25
Alberto Aguirre (community) 2017-08-03 Approve on 2017-08-03
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.
Alberto Aguirre (albaguirre) wrote :

LGTM.

review: Approve
398. By Gerry Boland on 2017-08-03

Remove another ref to papi

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 on 2017-08-25

Merge trunk and fix conflicts

Gerry Boland (gerboland) wrote :

CI needs to be reconfigured to build against artful

Unmerged revisions

399. By Gerry Boland on 2017-08-25

Merge trunk and fix conflicts

398. By Gerry Boland on 2017-08-03

Remove another ref to papi

397. By Gerry Boland on 2017-08-03

Reduce delta

396. By Gerry Boland on 2017-08-03

Restore basic platform services

395. By Gerry Boland on 2017-08-03

Remove clipboard implementation using content-hub

394. By Gerry Boland on 2017-08-03

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