Merge lp:~gerboland/qtubuntu/xenial-artful-build into lp:qtubuntu

Proposed by Gerry Boland
Status: Superseded
Proposed branch: lp:~gerboland/qtubuntu/xenial-artful-build
Merge into: lp:qtubuntu
Diff against target: 3944 lines (+305/-3037)
38 files modified
debian/control (+15/-34)
debian/gles-patches/convert-to-gles.patch (+0/-154)
debian/gles-patches/series (+1/-1)
debian/qtubuntu-appmenutheme.install (+0/-1)
debian/rules (+0/-1)
src/shared/ubuntutheme.h (+5/-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/qmirclientbackingstore.cpp (+5/-1)
src/ubuntumirclient/qmirclientclipboard.cpp (+0/-180)
src/ubuntumirclient/qmirclientclipboard.h (+0/-92)
src/ubuntumirclient/qmirclientcursor.cpp (+68/-25)
src/ubuntumirclient/qmirclientglcontext.cpp (+7/-2)
src/ubuntumirclient/qmirclientglcontext.h (+5/-1)
src/ubuntumirclient/qmirclientintegration.cpp (+95/-130)
src/ubuntumirclient/qmirclientintegration.h (+3/-18)
src/ubuntumirclient/qmirclientplatformservices.cpp (+0/-75)
src/ubuntumirclient/qmirclientplatformservices.h (+0/-57)
src/ubuntumirclient/qmirclientscreen.cpp (+5/-1)
src/ubuntumirclient/qmirclientwindow.cpp (+85/-152)
src/ubuntumirclient/ubuntumirclient.pro (+10/-10)
To merge this branch: bzr merge lp:~gerboland/qtubuntu/xenial-artful-build
Reviewer Review Type Date Requested Status
Ubuntu Phablet Team Pending
Review via email: mp+332111@code.launchpad.net

This proposal has been superseded by a proposal from 2017-10-11.

Commit message

Support building on Qt5.7 and 5.9 (xenial and artful)

To post a comment you must log in.
401. By Gerry Boland

Support building on Qt5.7 and Qt5.9

402. By Gerry Boland

Comparing with 5.8 is clearer

Unmerged revisions

402. By Gerry Boland

Comparing with 5.8 is clearer

401. By Gerry Boland

Support building on Qt5.7 and Qt5.9

400. By MichaƂ Sawicz

Update convert-to-gles.patch

399. By Gerry Boland

Merge trunk and fix conflicts

398. By Gerry Boland

Remove another ref to papi

397. By Gerry Boland

Reduce delta

396. By Gerry Boland

Restore basic platform services

395. By Gerry Boland

Remove clipboard implementation using content-hub

394. By Gerry Boland

Merge papi-cleanup and fix

Preview Diff

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

Subscribers

People subscribed via source and target branches