Merge lp:~unity-team/qtmir/miral-qt-integration into lp:qtmir

Proposed by Daniel d'Andrada
Status: Superseded
Proposed branch: lp:~unity-team/qtmir/miral-qt-integration
Merge into: lp:qtmir
Prerequisite: lp:~gerboland/qtmir/revert557
Diff against target: 12864 lines (+5192/-3670)
139 files modified
CMakeLists.txt (+7/-4)
debian/changelog (+6/-0)
debian/control (+6/-2)
debian/gles-patches/convert-to-gles.patch (+1/-1)
demos/paths.h.in (+19/-1)
demos/qml-demo-shell/CMakeLists.txt (+1/-0)
demos/qml-demo-shell/WindowModelDebugView.qml (+72/-0)
demos/qml-demo-shell/main.cpp (+10/-6)
demos/qml-demo-shell/pointerposition.cpp (+56/-0)
demos/qml-demo-shell/pointerposition.h (+49/-0)
demos/qml-demo-shell/windowModel.qml (+136/-0)
src/common/appnotifier.h (+39/-0)
src/common/debughelpers.cpp (+50/-16)
src/common/debughelpers.h (+2/-0)
src/common/mirqtconversion.h (+102/-0)
src/common/windowcontrollerinterface.h (+58/-0)
src/common/windowmodelnotifier.h (+95/-0)
src/modules/Unity/Application/CMakeLists.txt (+4/-3)
src/modules/Unity/Application/application.cpp (+7/-6)
src/modules/Unity/Application/application.h (+1/-8)
src/modules/Unity/Application/application_manager.cpp (+40/-75)
src/modules/Unity/Application/application_manager.h (+7/-9)
src/modules/Unity/Application/dbusfocusinfo.cpp (+12/-18)
src/modules/Unity/Application/dbusfocusinfo.h (+0/-1)
src/modules/Unity/Application/mirfocuscontroller.cpp (+0/-69)
src/modules/Unity/Application/mirfocuscontroller.h (+0/-49)
src/modules/Unity/Application/mirsurface.cpp (+476/-248)
src/modules/Unity/Application/mirsurface.h (+61/-51)
src/modules/Unity/Application/mirsurfaceinterface.h (+6/-12)
src/modules/Unity/Application/mirsurfaceitem.cpp (+4/-33)
src/modules/Unity/Application/mirsurfaceitem.h (+1/-5)
src/modules/Unity/Application/mirsurfacelistmodel.cpp (+10/-4)
src/modules/Unity/Application/mirsurfacemanager.cpp (+0/-188)
src/modules/Unity/Application/mirsurfacemanager.h (+0/-99)
src/modules/Unity/Application/plugin.cpp (+6/-18)
src/modules/Unity/Application/session.cpp (+42/-28)
src/modules/Unity/Application/session.h (+11/-12)
src/modules/Unity/Application/session_interface.h (+8/-6)
src/modules/Unity/Application/sessionmanager.cpp (+24/-37)
src/modules/Unity/Application/sessionmanager.h (+11/-8)
src/modules/Unity/Application/surfacemanager.cpp (+174/-0)
src/modules/Unity/Application/surfacemanager.h (+73/-0)
src/modules/Unity/Application/windowmodel.cpp (+235/-0)
src/modules/Unity/Application/windowmodel.h (+83/-0)
src/modules/Unity/Screens/CMakeLists.txt (+1/-1)
src/modules/Unity/Screens/plugin.cpp (+1/-1)
src/modules/Unity/Screens/qquickscreenwindow.cpp (+6/-6)
src/modules/Unity/Screens/qquickscreenwindow.h (+6/-6)
src/modules/Unity/Screens/screens.cpp (+1/-1)
src/modules/Unity/Screens/screens.h (+2/-29)
src/platforms/mirserver/CMakeLists.txt (+39/-25)
src/platforms/mirserver/creationhints.cpp (+0/-67)
src/platforms/mirserver/creationhints.h (+0/-56)
src/platforms/mirserver/cursor.cpp (+1/-1)
src/platforms/mirserver/customscreenconfiguration.h (+4/-2)
src/platforms/mirserver/mirdisplayconfigurationpolicy.cpp (+26/-1)
src/platforms/mirserver/mirdisplayconfigurationpolicy.h (+6/-14)
src/platforms/mirserver/miropenglcontext.cpp (+12/-0)
src/platforms/mirserver/mirserver.cpp (+0/-234)
src/platforms/mirserver/mirserver.h (+0/-71)
src/platforms/mirserver/mirserverhooks.cpp (+184/-0)
src/platforms/mirserver/mirserverhooks.h (+54/-0)
src/platforms/mirserver/mirserverintegration.cpp (+2/-2)
src/platforms/mirserver/mirserverstatuslistener.h (+6/-0)
src/platforms/mirserver/mirsingleton.cpp (+1/-0)
src/platforms/mirserver/mirwindowmanager.cpp (+0/-227)
src/platforms/mirserver/mirwindowmanager.h (+0/-49)
src/platforms/mirserver/nativeinterface.cpp (+1/-5)
src/platforms/mirserver/nativeinterface.h (+2/-2)
src/platforms/mirserver/offscreensurface.cpp (+0/-8)
src/platforms/mirserver/openglcontextfactory.cpp (+51/-0)
src/platforms/mirserver/openglcontextfactory.h (+47/-0)
src/platforms/mirserver/promptsession.h (+62/-0)
src/platforms/mirserver/promptsessionlistener.cpp (+2/-45)
src/platforms/mirserver/promptsessionlistener.h (+19/-21)
src/platforms/mirserver/promptsessionmanager.cpp (+47/-0)
src/platforms/mirserver/promptsessionmanager.h (+49/-0)
src/platforms/mirserver/qmirserver.cpp (+25/-52)
src/platforms/mirserver/qmirserver.h (+4/-7)
src/platforms/mirserver/qmirserver_p.cpp (+117/-25)
src/platforms/mirserver/qmirserver_p.h (+56/-10)
src/platforms/mirserver/qteventfeeder.cpp (+47/-23)
src/platforms/mirserver/qteventfeeder.h (+6/-12)
src/platforms/mirserver/screen.cpp (+26/-27)
src/platforms/mirserver/screen.h (+9/-14)
src/platforms/mirserver/screenscontroller.cpp (+1/-0)
src/platforms/mirserver/screenscontroller.h (+4/-1)
src/platforms/mirserver/screensmodel.cpp (+11/-5)
src/platforms/mirserver/screensmodel.h (+8/-4)
src/platforms/mirserver/screentypes.h (+60/-0)
src/platforms/mirserver/sessionauthorizer.cpp (+5/-10)
src/platforms/mirserver/sessionauthorizer.h (+7/-7)
src/platforms/mirserver/sessionlistener.cpp (+0/-96)
src/platforms/mirserver/sessionlistener.h (+0/-63)
src/platforms/mirserver/setqtcompositor.cpp (+55/-0)
src/platforms/mirserver/setqtcompositor.h (+47/-0)
src/platforms/mirserver/surfaceobserver.cpp (+36/-172)
src/platforms/mirserver/surfaceobserver.h (+9/-40)
src/platforms/mirserver/windowcontroller.cpp (+103/-0)
src/platforms/mirserver/windowcontroller.h (+54/-0)
src/platforms/mirserver/windowmanagementpolicy.cpp (+335/-0)
src/platforms/mirserver/windowmanagementpolicy.h (+96/-0)
tests/framework/CMakeLists.txt (+2/-0)
tests/framework/fake_displayconfigurationoutput.h (+15/-1)
tests/framework/fake_mirsurface.cpp (+31/-10)
tests/framework/fake_mirsurface.h (+18/-23)
tests/framework/fake_session.cpp (+7/-5)
tests/framework/fake_session.h (+5/-4)
tests/framework/fake_surface.h (+5/-4)
tests/framework/mock_mir_session.h (+14/-4)
tests/framework/mock_session.h (+5/-4)
tests/framework/mock_surface.h (+5/-2)
tests/framework/qtmir_test.cpp (+28/-4)
tests/framework/qtmir_test.h (+8/-5)
tests/framework/stub_scene_surface.h (+108/-0)
tests/framework/stub_windowcontroller.h (+44/-0)
tests/mirserver/CMakeLists.txt (+0/-1)
tests/mirserver/Screen/screen_test.cpp (+2/-2)
tests/mirserver/ScreensModel/screensmodel_test.cpp (+3/-1)
tests/mirserver/ScreensModel/stub_display.h (+10/-0)
tests/mirserver/ScreensModel/testable_screensmodel.h (+3/-2)
tests/mirserver/WindowManager/CMakeLists.txt (+0/-27)
tests/mirserver/WindowManager/stub_session.cpp (+0/-147)
tests/mirserver/WindowManager/stub_session.h (+0/-64)
tests/mirserver/WindowManager/stub_surface.cpp (+0/-208)
tests/mirserver/WindowManager/stub_surface.h (+0/-70)
tests/mirserver/WindowManager/window_manager.cpp (+0/-331)
tests/modules/Application/CMakeLists.txt (+1/-0)
tests/modules/Application/application_test.cpp (+10/-10)
tests/modules/ApplicationManager/CMakeLists.txt (+1/-0)
tests/modules/ApplicationManager/application_manager_test.cpp (+202/-192)
tests/modules/CMakeLists.txt (+1/-1)
tests/modules/SessionManager/CMakeLists.txt (+1/-0)
tests/modules/SessionManager/session_manager_test.cpp (+24/-16)
tests/modules/SessionManager/session_test.cpp (+14/-13)
tests/modules/WindowManager/CMakeLists.txt (+12/-6)
tests/modules/WindowManager/mirsurface_test.cpp (+67/-52)
tests/modules/WindowManager/mirsurfaceitem_test.cpp (+2/-2)
tests/modules/WindowManager/windowmodel_test.cpp (+786/-0)
To merge this branch: bzr merge lp:~unity-team/qtmir/miral-qt-integration
Reviewer Review Type Date Requested Status
Unity8 CI Bot (community) continuous-integration Needs Fixing
Mir development team Pending
Review via email: mp+310001@code.launchpad.net

This proposal has been superseded by a proposal from 2016-12-01.

Commit message

Depend on MirAL

Import code from lp:miral/miral-qt (revision 435) where we had a fork of qtmir and were rewriting it to use MirAL's APIs

To post a comment you must log in.
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
572. By Daniel d'Andrada

Bump miral version dependency

573. By Daniel d'Andrada

TopLevelWindowModel - fix handling of prompt surfaces

Since TopLevelWindowModel swallowed SurfaceManager it must process miral messages
for *all* qtmir::MirSurfaces, not only for the top-level ones.

+ Remove unused findWindowWithSurface() method

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
574. By Daniel d'Andrada

Clean up debug messages

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
575. By Daniel d'Andrada

Fix MirSurface::setReady()

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
576. By Daniel d'Andrada

Let TopLevelWindowModel unset the surface

Otherwise it will mess up with TopLevelWindowModel logic.

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
577. By Daniel d'Andrada

Fix package build

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
578. By Daniel d'Andrada

Fix memory leak when removing an application

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

MirAL0.4 fixed the pkgconfig file, can now use it

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

Fix handling of command line arguments

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
581. By Daniel d'Andrada

Move TopLevelWindowModel out of qtmir. Export a SurfaceManager instead

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
582. By Daniel d'Andrada

MirSurface::activate()

Let shell decide whether to activate a surface when a client
requests a surface to be raised

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
583. By Daniel d'Andrada

MirSurface: Improve logging and don't use miral::Window of a dead surface

+ Update mirSurfaceTypeToStr

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
584. By Daniel d'Andrada

Merge trunk

[ Albert Astals Cid ]
* Build with Qt 5.7 (LP: #1642608, #1642954)
[ Gerry Boland ]
* Fix FTBFS due to new googletest framework release (1.8)
* Revert Lttng test-crash workaround from rev 557
[ Jonas G. Drange ]
* relax auth of clients to allow USS to set base mir display config

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
585. By Daniel d'Andrada

Fix order of entries in debian/changelog

586. By Daniel d'Andrada

Add missing license header

587. By Daniel d'Andrada

findApplicationWithSurface is const

588. By Daniel d'Andrada

Mir 0.25 compat (merging upcoming trunk)

589. By Daniel d'Andrada

Bump dependency version of other mir packages

590. By Daniel d'Andrada

Fix bad merge

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2016-11-03 16:08:12 +0000
3+++ CMakeLists.txt 2016-12-01 11:46:42 +0000
4@@ -3,7 +3,7 @@
5 project(qtmir)
6
7 set(QTMIR_VERSION_MAJOR 0)
8-set(QTMIR_VERSION_MINOR 1)
9+set(QTMIR_VERSION_MINOR 2)
10 set(QTMIR_VERSION_PATCH 0)
11
12 if(${PROJECT_BINARY_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
13@@ -30,6 +30,10 @@
14 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -fPIC -Wall -fno-strict-aliasing -Werror -Wextra")
15 set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
16
17+if ("${CMAKE_CXX_COMPILER}" MATCHES "clang")
18+ set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-return-type-c-linkage -Wno-mismatched-tags -Wno-inconsistent-missing-override -Wno-implicit-exception-spec-mismatch -Wno-unknown-pragmas")
19+endif()
20+
21
22 include(EnableCoverageReport)
23 #####################################################################
24@@ -70,6 +74,7 @@
25 pkg_check_modules(MIRSERVER mirserver>=0.24 REQUIRED)
26 pkg_check_modules(MIRCLIENT mirclient>=0.24 REQUIRED)
27 pkg_check_modules(MIRRENDERERGLDEV mir-renderer-gl-dev>=0.24 REQUIRED)
28+pkg_check_modules(MIRAL miral>=0.4 REQUIRED)
29
30 pkg_check_modules(XKBCOMMON xkbcommon REQUIRED)
31 pkg_check_modules(GLIB glib-2.0 REQUIRED)
32@@ -83,15 +88,13 @@
33 pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)
34 pkg_check_modules(QTDBUSTEST libqtdbustest-1 REQUIRED)
35 pkg_check_modules(QTDBUSMOCK libqtdbusmock-1 REQUIRED)
36-pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=22)
37+pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=23)
38 pkg_check_modules(CGMANAGER libcgmanager REQUIRED)
39 pkg_check_modules(CONTENT_HUB libcontent-hub>=0.2 REQUIRED)
40
41 include_directories(SYSTEM ${APPLICATION_API_INCLUDE_DIRS})
42
43
44-add_definitions(-DMIR_REQUIRE_DEPRECATED_EVENT_OPT_IN=1)
45-
46 # Use the fast string builder
47 add_definitions(-DQT_USE_QSTRINGBUILDER)
48
49
50=== modified file 'debian/changelog'
51--- debian/changelog 2016-11-23 20:46:06 +0000
52+++ debian/changelog 2016-12-01 11:46:42 +0000
53@@ -12,6 +12,12 @@
54
55 -- Michał Sawicz <michal.sawicz@canonical.com> Wed, 23 Nov 2016 20:46:06 +0000
56
57+qtmir (0.5.0+16.10.20161011.1-0ubuntu1) UNRELEASED; urgency=medium
58+
59+ * First release using MirAL
60+
61+ -- Gerry Boland <gerry.boland@canonical.com> Fri, 14 Oct 2016 16:51:26 +0100
62+
63 qtmir (0.4.8+17.04.20161024-0ubuntu1) zesty; urgency=medium
64
65 [ Andrea Bernabei ]
66
67=== modified file 'debian/control'
68--- debian/control 2016-09-08 22:51:27 +0000
69+++ debian/control 2016-12-01 11:46:42 +0000
70@@ -13,6 +13,7 @@
71 libglib2.0-dev,
72 libgsettings-qt-dev,
73 liblttng-ust-dev,
74+ libmiral-dev (>= 0.4),
75 libmirclient-dev (>= 0.24.0),
76 libmircommon-dev (>= 0.24.0),
77 libmirserver-dev (>= 0.24.0),
78@@ -24,7 +25,7 @@
79 libubuntu-app-launch2-dev (>= 0.9),
80 libubuntu-application-api-dev (>= 2.1.0),
81 libudev-dev,
82- libunity-api-dev (>= 7.119),
83+ libunity-api-dev (>= 8.0),
84 liburl-dispatcher1-dev,
85 libxkbcommon-dev,
86 libxrender-dev,
87@@ -41,6 +42,9 @@
88 quilt,
89 # libmirserver-dev should have brought this dep. Bug lp:1617435
90 uuid-dev,
91+# mirtest pkgconfig requires these, but doesn't have a deb dependency. Bug lp:1633537
92+ libboost-filesystem-dev,
93+ libboost-system-dev,
94 Standards-Version: 3.9.5
95 Homepage: https://launchpad.net/qtmir
96 # if you don't have have commit access to this branch but would like to upload
97@@ -98,7 +102,7 @@
98 Conflicts: libqtmir,
99 libunity-mir1,
100 Provides: unity-application-impl,
101- unity-application-impl-22,
102+ unity-application-impl-23,
103 Description: Qt plugin for Unity specific Mir APIs
104 QtMir provides Qt/QML bindings for Mir features that are exposed through the
105 qtmir-desktop or qtmir-android QPA plugin such as Application management
106
107=== modified file 'debian/gles-patches/convert-to-gles.patch'
108--- debian/gles-patches/convert-to-gles.patch 2016-11-23 19:46:24 +0000
109+++ debian/gles-patches/convert-to-gles.patch 2016-12-01 11:46:42 +0000
110@@ -84,7 +84,7 @@
111 -Conflicts: libqtmir,
112 - libunity-mir1,
113 -Provides: unity-application-impl,
114-- unity-application-impl-22,
115+- unity-application-impl-23,
116 -Description: Qt plugin for Unity specific Mir APIs
117 - QtMir provides Qt/QML bindings for Mir features that are exposed through the
118 - qtmir-desktop or qtmir-android QPA plugin such as Application management
119
120=== modified file 'demos/paths.h.in'
121--- demos/paths.h.in 2015-09-01 16:16:47 +0000
122+++ demos/paths.h.in 2016-12-01 11:46:42 +0000
123@@ -37,4 +37,22 @@
124 return QString("@CMAKE_SOURCE_DIR@/demos/");
125 }
126 }
127-#endif
128\ No newline at end of file
129+
130+inline QString qmlPluginDirectory() {
131+ if (isRunningInstalled()) {
132+ return QString("@QML_MODULE_INSTALL_DIR@/");
133+ } else {
134+ return QString("@CMAKE_BINARY_DIR@/src/modules/");
135+ }
136+}
137+
138+inline QString qpaPluginDirectory() {
139+ if (isRunningInstalled()) {
140+ return QString("@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@/qt5/plugins/platforms/");
141+ } else {
142+ return QString("@CMAKE_BINARY_DIR@/src/platforms/mirserver/");
143+ }
144+}
145+
146+#endif
147+
148
149=== modified file 'demos/qml-demo-shell/CMakeLists.txt'
150--- demos/qml-demo-shell/CMakeLists.txt 2016-06-06 18:12:07 +0000
151+++ demos/qml-demo-shell/CMakeLists.txt 2016-12-01 11:46:42 +0000
152@@ -8,6 +8,7 @@
153 )
154
155 add_executable(${DEMO_SHELL}
156+ pointerposition.cpp
157 main.cpp
158 )
159
160
161=== added file 'demos/qml-demo-shell/WindowModelDebugView.qml'
162--- demos/qml-demo-shell/WindowModelDebugView.qml 1970-01-01 00:00:00 +0000
163+++ demos/qml-demo-shell/WindowModelDebugView.qml 2016-12-01 11:46:42 +0000
164@@ -0,0 +1,72 @@
165+import QtQuick 2.0
166+import Unity.Application 0.1
167+
168+Column {
169+ id: root
170+ width: childrenRect.width
171+ height: childrenRect.height
172+ focus: false
173+
174+ property alias model: repeater.model
175+
176+ function stateString(state) {
177+ switch(state) {
178+ case Mir.HiddenState: return "Hidden"
179+ case Mir.RestoredState: return "Restored"
180+ case Mir.MinimizedState: return "Minimized"
181+ case Mir.MaximizedState: return "Maximized"
182+ case Mir.VertMaximizedState: return "VertMax"
183+ case Mir.FullscreenState: return "Fullscreen"
184+ case Mir.HorizMaximizedState: return "HorizMax"
185+ case Mir.UnknownState: return "Unknown"
186+ }
187+ return "Invalid"
188+ }
189+ function typeString(type) {
190+ switch(type) {
191+ case Mir.UnknownType: return "Unknown"
192+ case Mir.NormalType: return "Normal"
193+ case Mir.UtilityType: return "Utility"
194+ case Mir.DialogType: return "Dialog"
195+ case Mir.GlossType: return "Gloss"
196+ case Mir.FreeStyleType: return "FreeStyle"
197+ case Mir.MenuType: return "Menu"
198+ case Mir.InputMethodType: return "InputMethod"
199+ case Mir.SatelliteType: return "Satellite"
200+ case Mir.TipType: return "Tip"
201+ }
202+ return "Invalid"
203+ }
204+
205+ function geometryString(surface) {
206+ return surface.position.x + "," + surface.position.y + " " + surface.size.width + "x" + surface.size.height
207+ }
208+
209+
210+ Text {
211+ text: "Index\t\Name\tVisible\tState\tType\tGeometry"
212+ height: (visible) ? implicitHeight : 0
213+ visible: repeater.count > 0
214+ color: "white"
215+
216+ Rectangle {
217+ anchors.fill: parent
218+ color: "blue"
219+ z: -1
220+ }
221+ }
222+ Repeater {
223+ id: repeater
224+ delegate: Text {
225+ text: index + "\t" + surface.name + "\t" + surface.visible + "\t"
226+ + stateString(surface.state) + "\t" + typeString(surface.type) + "\t" + geometryString(surface)
227+ font.bold: surface.focused
228+
229+ Rectangle {
230+ anchors.fill: parent
231+ color: (index % 2) ? "white" : "lightblue"
232+ z: -1
233+ }
234+ }
235+ }
236+}
237
238=== modified file 'demos/qml-demo-shell/main.cpp'
239--- demos/qml-demo-shell/main.cpp 2015-09-17 11:20:00 +0000
240+++ demos/qml-demo-shell/main.cpp 2016-12-01 11:46:42 +0000
241@@ -15,34 +15,38 @@
242 */
243
244 // Qt
245-#include <QCommandLineParser>
246 #include <QtQuick/QQuickView>
247 #include <QtGui/QGuiApplication>
248 #include <QtQml/QQmlEngine>
249 #include <QtQml/QQmlContext>
250-#include <QLibrary>
251 #include <QDebug>
252-#include <csignal>
253 #include <libintl.h>
254 #include "../paths.h"
255
256-#include <private/qobject_p.h>
257+#include "pointerposition.h"
258
259 // REMOVEME - Should be able to use qmlscene, but in order to use the mir benchmarking we need
260 // to parse command line switches. Wait until MIR_SOCKET supported by the benchmark framework.
261
262 int main(int argc, const char *argv[])
263 {
264+ setenv("QT_QPA_PLATFORM_PLUGIN_PATH", qPrintable(::qpaPluginDirectory()), 1 /* overwrite */);
265+ setenv("QT_QPA_PLATFORM", "mirserver", 1 /* overwrite */);
266+
267 QGuiApplication::setApplicationName("qml-demo-shell");
268 QGuiApplication *application;
269
270 application = new QGuiApplication(argc, (char**)argv);
271 QQuickView* view = new QQuickView();
272+ view->engine()->addImportPath(::qmlPluginDirectory());
273 view->setResizeMode(QQuickView::SizeRootObjectToView);
274- view->setColor("black");
275+ view->setColor("lightgray");
276 view->setTitle("Demo Shell");
277
278- QUrl source(::qmlDirectory() + "qtmir-demo-shell/qml-demo-shell.qml");
279+ qmlRegisterSingletonType<PointerPosition>("Mir.Pointer", 0, 1, "PointerPosition",
280+ [](QQmlEngine*, QJSEngine*) -> QObject* { return PointerPosition::instance(); });
281+
282+ QUrl source(::qmlDirectory() + "qml-demo-shell/windowModel.qml");
283
284 view->setSource(source);
285 QObject::connect(view->engine(), SIGNAL(quit()), application, SLOT(quit()));
286
287=== added file 'demos/qml-demo-shell/pointerposition.cpp'
288--- demos/qml-demo-shell/pointerposition.cpp 1970-01-01 00:00:00 +0000
289+++ demos/qml-demo-shell/pointerposition.cpp 2016-12-01 11:46:42 +0000
290@@ -0,0 +1,56 @@
291+/*
292+ * Copyright (C) 2016 Canonical, Ltd.
293+ *
294+ * This program is free software; you can redistribute it and/or modify
295+ * it under the terms of the GNU General Public License as published by
296+ * the Free Software Foundation; version 3.
297+ *
298+ * This program is distributed in the hope that it will be useful,
299+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
300+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
301+ * GNU General Public License for more details.
302+ *
303+ * You should have received a copy of the GNU General Public License
304+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
305+ */
306+
307+#include "pointerposition.h"
308+
309+#include <QGuiApplication>
310+#include <QMouseEvent>
311+
312+PointerPosition *PointerPosition::instance()
313+{
314+ static PointerPosition *pointerPosition = nullptr;
315+ if (!pointerPosition) {
316+ pointerPosition = new PointerPosition();
317+ }
318+ return pointerPosition;
319+}
320+
321+bool PointerPosition::eventFilter(QObject */*object*/, QEvent *event)
322+{
323+ if (event->type() == QEvent::MouseMove) {
324+ auto mouseEvent = static_cast<QMouseEvent*>(event);
325+ if (m_x != mouseEvent->globalX()) {
326+ m_x = mouseEvent->globalX();
327+ Q_EMIT xChanged();
328+ }
329+ if (m_y != mouseEvent->globalY()) {
330+ m_y = mouseEvent->globalY();
331+ Q_EMIT yChanged();
332+ }
333+ }
334+ return false;
335+}
336+
337+PointerPosition::PointerPosition()
338+ : QObject()
339+{
340+ qGuiApp->installEventFilter(this);
341+}
342+
343+PointerPosition::~PointerPosition()
344+{
345+ qGuiApp->removeEventFilter(this);
346+}
347
348=== added file 'demos/qml-demo-shell/pointerposition.h'
349--- demos/qml-demo-shell/pointerposition.h 1970-01-01 00:00:00 +0000
350+++ demos/qml-demo-shell/pointerposition.h 2016-12-01 11:46:42 +0000
351@@ -0,0 +1,49 @@
352+/*
353+ * Copyright (C) 2016 Canonical, Ltd.
354+ *
355+ * This program is free software; you can redistribute it and/or modify
356+ * it under the terms of the GNU General Public License as published by
357+ * the Free Software Foundation; version 3.
358+ *
359+ * This program is distributed in the hope that it will be useful,
360+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
361+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
362+ * GNU General Public License for more details.
363+ *
364+ * You should have received a copy of the GNU General Public License
365+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
366+ */
367+
368+#ifndef POINTERPOSITION_H
369+#define POINTERPOSITION_H
370+
371+#include <QObject>
372+
373+class PointerPosition : public QObject
374+{
375+ Q_OBJECT
376+ Q_PROPERTY(int x READ x NOTIFY xChanged)
377+ Q_PROPERTY(int y READ y NOTIFY yChanged)
378+
379+public:
380+ static PointerPosition *instance();
381+
382+ int x() const { return m_x; }
383+ int y() const { return m_y; }
384+
385+Q_SIGNALS:
386+ void xChanged();
387+ void yChanged();
388+
389+protected:
390+ bool eventFilter(QObject *object, QEvent *event);
391+
392+private:
393+ Q_DISABLE_COPY(PointerPosition)
394+ PointerPosition();
395+ ~PointerPosition();
396+
397+ int m_x{0}, m_y{0};
398+};
399+
400+#endif // POINTERPOSITION_H
401
402=== added file 'demos/qml-demo-shell/windowModel.qml'
403--- demos/qml-demo-shell/windowModel.qml 1970-01-01 00:00:00 +0000
404+++ demos/qml-demo-shell/windowModel.qml 2016-12-01 11:46:42 +0000
405@@ -0,0 +1,136 @@
406+import QtQuick 2.4
407+import Unity.Application 0.1
408+import Mir.Pointer 0.1
409+
410+FocusScope {
411+ id: root
412+ focus: true
413+
414+ WindowModel {
415+ id: windowModel;
416+ }
417+
418+ Item {
419+ id: windowViewContainer
420+ anchors.fill: parent
421+
422+ Repeater {
423+ model: windowModel
424+
425+ delegate: MirSurfaceItem {
426+ id: surfaceItem
427+ surface: model.surface
428+ consumesInput: true // QUESTION: why is this non-default?
429+ x: surface.position.x
430+ y: surface.position.y
431+ width: surface.size.width
432+ height: surface.size.height
433+ focus: surface.focused
434+ visible: surface.visible
435+
436+ Rectangle {
437+ anchors { top: parent.bottom; right: parent.right }
438+ width: childrenRect.width
439+ height: childrenRect.height
440+ color: surface.focused ? "red" : "lightsteelblue"
441+ opacity: 0.8
442+ Text {
443+ text: surface.position.x + "," + surface.position.y + " " + surface.size.width + "x" + surface.size.height
444+ font.pixelSize: 10
445+ }
446+ }
447+
448+ Rectangle { anchors.fill: parent; z: -1; color: "black"; opacity: 0.3 }
449+ }
450+ }
451+ }
452+
453+ Button {
454+ anchors { right: parent.right; top: parent.top }
455+ height: 30
456+ width: 80
457+ text: "Quit"
458+ onClicked: Qt.quit()
459+ }
460+
461+ WindowModelDebugView {
462+ anchors { right: parent.right; bottom: parent.bottom }
463+ model: windowModel
464+ }
465+
466+ Text {
467+ anchors { left: parent.left; bottom: parent.bottom }
468+ text: "Move window: Ctrl+click\n
469+Resize window: Ctrl+Right click"
470+ }
471+
472+ Rectangle {
473+ id: mousePointer
474+ color: "black"
475+ width: 6
476+ height: 10
477+ x: PointerPosition.x
478+ y: PointerPosition.y
479+ }
480+
481+ MouseArea {
482+ anchors.fill: parent
483+ acceptedButtons: Qt.LeftButton | Qt.RightButton
484+ hoverEnabled: false
485+ property variant window: null
486+ property int initialWindowXPosition
487+ property int initialWindowYPosition
488+ property int initialWindowWidth
489+ property int initialWindowHeight
490+ property int initialMouseXPosition
491+ property int initialMouseYPosition
492+ property var action
493+
494+ function moveWindowBy(window, delta) {
495+ window.surface.requestedPosition = Qt.point(initialWindowXPosition + delta.x,
496+ initialWindowYPosition + delta.y);
497+ }
498+ function resizeWindowBy(window, delta) {
499+ window.surface.resize(Qt.size(initialWindowWidth + delta.x,
500+ initialWindowHeight + delta.y))
501+ }
502+
503+ onPressed: {
504+ if (mouse.modifiers & Qt.ControlModifier) {
505+ window = windowViewContainer.childAt(mouse.x, mouse.y)
506+ if (!window) return;
507+
508+ if (mouse.button == Qt.LeftButton) {
509+ initialWindowXPosition = window.surface.position.x
510+ initialWindowYPosition = window.surface.position.y
511+ action = moveWindowBy
512+ } else if (mouse.button == Qt.RightButton) {
513+ initialWindowHeight = window.surface.size.height
514+ initialWindowWidth = window.surface.size.width
515+ action = resizeWindowBy
516+ }
517+ initialMouseXPosition = mouse.x
518+ initialMouseYPosition = mouse.y
519+ } else {
520+ mouse.accepted = false
521+ }
522+ }
523+
524+ onPositionChanged: {
525+ if (!window) {
526+ mouse.accepted = false
527+ return
528+ }
529+ action(window, Qt.point(mouse.x - initialMouseXPosition, mouse.y - initialMouseYPosition))
530+ }
531+
532+ onReleased: {
533+ if (!window) {
534+ mouse.accepted = false
535+ return
536+ }
537+ action(window, Qt.point(mouse.x - initialMouseXPosition, mouse.y - initialMouseYPosition))
538+ window = null;
539+ }
540+ }
541+}
542
543=== added file 'src/common/appnotifier.h'
544--- src/common/appnotifier.h 1970-01-01 00:00:00 +0000
545+++ src/common/appnotifier.h 2016-12-01 11:46:42 +0000
546@@ -0,0 +1,39 @@
547+/*
548+ * Copyright (C) 2016 Canonical, Ltd.
549+ *
550+ * This program is free software: you can redistribute it and/or modify it under
551+ * the terms of the GNU Lesser General Public License version 3, as published by
552+ * the Free Software Foundation.
553+ *
554+ * This program is distributed in the hope that it will be useful, but WITHOUT
555+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
556+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
557+ * Lesser General Public License for more details.
558+ *
559+ * You should have received a copy of the GNU Lesser General Public License
560+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
561+ */
562+
563+#ifndef APPNOTIFIER_H
564+#define APPNOTIFIER_H
565+
566+#include <QObject>
567+#include <miral/application_info.h>
568+
569+namespace qtmir {
570+
571+class AppNotifier : public QObject
572+{
573+ Q_OBJECT
574+
575+Q_SIGNALS:
576+ void appAdded(const miral::ApplicationInfo &app);
577+ void appRemoved(const miral::ApplicationInfo &app);
578+ void appCreatedWindow(const miral::ApplicationInfo &app);
579+};
580+
581+} // namespace qtmir
582+
583+Q_DECLARE_METATYPE(miral::ApplicationInfo)
584+
585+#endif // APPNOTIFIER_H
586
587=== modified file 'src/common/debughelpers.cpp'
588--- src/common/debughelpers.cpp 2016-06-06 19:25:20 +0000
589+++ src/common/debughelpers.cpp 2016-12-01 11:46:42 +0000
590@@ -21,6 +21,7 @@
591
592 // Unity API
593 #include <unity/shell/application/ApplicationInfoInterface.h>
594+#include <unity/shell/application/Mir.h>
595
596 const char *touchPointStateToString(Qt::TouchPointState state)
597 {
598@@ -114,23 +115,18 @@
599 const char *mirSurfaceTypeToStr(int value)
600 {
601 switch (value) {
602- case mir_surface_type_normal:
603- return "normal";
604- case mir_surface_type_utility:
605- return "utility";
606- case mir_surface_type_dialog:
607- return "dialog";
608- case mir_surface_type_overlay:
609- return "overlay";
610- case mir_surface_type_freestyle:
611- return "freestyle";
612- case mir_surface_type_popover:
613- return "popover";
614- case mir_surface_type_inputmethod:
615- return "inputmethod";
616- default:
617- return "???";
618+ case mir_surface_type_normal: return "normal"; /**< AKA "regular" */
619+ case mir_surface_type_utility: return "utility"; /**< AKA "floating regular" */
620+ case mir_surface_type_dialog: return "dialog";
621+ case mir_surface_type_gloss: return "gloss";
622+ case mir_surface_type_freestyle: return "freestyle";
623+ case mir_surface_type_menu: return "menu";
624+ case mir_surface_type_inputmethod: return "input Method"; /**< AKA "OSK" or handwriting etc. */
625+ case mir_surface_type_satellite: return "satellite"; /**< AKA "toolbox"/"toolbar" */
626+ case mir_surface_type_tip: return "tip"; /**< AKA "tooltip" */
627+ case mir_surface_types: Q_UNREACHABLE();
628 }
629+ Q_UNREACHABLE();
630 }
631
632 const char *mirSurfaceStateToStr(int value)
633@@ -148,6 +144,8 @@
634 return "vertmaximized";
635 case mir_surface_state_fullscreen:
636 return "fullscreen";
637+ case mir_surface_state_hidden:
638+ return "hidden";
639 default:
640 return "???";
641 }
642@@ -349,3 +347,39 @@
643 return "???";
644 }
645 }
646+
647+const char *unityapiMirStateToStr(int state)
648+{
649+ switch (state) {
650+ case Mir::UnknownState:
651+ return "unknown";
652+ case Mir::RestoredState:
653+ return "restored";
654+ case Mir::MinimizedState:
655+ return "minimized";
656+ case Mir::MaximizedState:
657+ return "maximized";
658+ case Mir::VertMaximizedState:
659+ return "vertMaximized";
660+ case Mir::FullscreenState:
661+ return "fullscreen";
662+ case Mir::HorizMaximizedState:
663+ return "horizMaximized";
664+ case Mir::MaximizedLeftState:
665+ return "maximizedLeft";
666+ case Mir::MaximizedRightState:
667+ return "maximizedRight";
668+ case Mir::MaximizedTopLeftState:
669+ return "maximizedTopLeft";
670+ case Mir::MaximizedTopRightState:
671+ return "maximizedTopRight";
672+ case Mir::MaximizedBottomLeftState:
673+ return "maximizedBottomLeft";
674+ case Mir::MaximizedBottomRightState:
675+ return "maximizedBottomRight";
676+ case Mir::HiddenState:
677+ return "hidden";
678+ default:
679+ return "???";
680+ }
681+}
682
683=== modified file 'src/common/debughelpers.h'
684--- src/common/debughelpers.h 2015-11-10 11:07:23 +0000
685+++ src/common/debughelpers.h 2016-12-01 11:46:42 +0000
686@@ -43,4 +43,6 @@
687
688 const char *qtCursorShapeToStr(Qt::CursorShape shape);
689
690+const char *unityapiMirStateToStr(int state);
691+
692 #endif // UBUNTUGESTURES_DEBUG_HELPER_H
693
694=== added file 'src/common/mirqtconversion.h'
695--- src/common/mirqtconversion.h 1970-01-01 00:00:00 +0000
696+++ src/common/mirqtconversion.h 2016-12-01 11:46:42 +0000
697@@ -0,0 +1,102 @@
698+#ifndef MIRQTCONVERSION_H
699+#define MIRQTCONVERSION_H
700+
701+#include <QSize>
702+#include <QPoint>
703+#include <QRect>
704+
705+#include <mir/geometry/size.h>
706+#include <mir/geometry/point.h>
707+#include <mir/geometry/rectangle.h>
708+
709+#include <mir_toolkit/common.h>
710+
711+#include <unity/shell/application/Mir.h>
712+
713+namespace qtmir {
714+
715+/*
716+ * Some handy conversions from Mir types to Qt types and back
717+ */
718+
719+inline QSize toQSize(const mir::geometry::Size size)
720+{
721+ return QSize(size.width.as_int(), size.height.as_int());
722+}
723+
724+inline mir::geometry::Size toMirSize(const QSize size)
725+{
726+ namespace mg = mir::geometry;
727+ return mg::Size{ mg::Width{ size.width()}, mg::Height{ size.height()} };
728+}
729+
730+inline QPoint toQPoint(const mir::geometry::Point point)
731+{
732+ return QPoint(point.x.as_int(), point.y.as_int());
733+}
734+
735+inline mir::geometry::Point toMirPoint(const QPoint point)
736+{
737+ namespace mg = mir::geometry;
738+ return mg::Point{ mg::X{ point.x()}, mg::Y{ point.y()} };
739+}
740+
741+inline QRect toQRect(const mir::geometry::Rectangle rect)
742+{
743+ return QRect(rect.top_left.x.as_int(), rect.top_left.y.as_int(),
744+ rect.size.width.as_int(), rect.size.height.as_int());
745+}
746+
747+inline mir::geometry::Rectangle toMirRectangle(const QRect rect)
748+{
749+ namespace mg = mir::geometry;
750+ return mg::Rectangle{
751+ mg::Point{ mg::X{ rect.x()}, mg::Y{ rect.y()} },
752+ mg::Size{ mg::Width{ rect.width()}, mg::Height{ rect.height()} }
753+ };
754+}
755+
756+inline Mir::State toQtState(MirSurfaceState state)
757+{
758+ switch (state) {
759+ case mir_surface_state_unknown: return Mir::UnknownState;
760+ case mir_surface_state_restored: return Mir::RestoredState;
761+ case mir_surface_state_minimized: return Mir::MinimizedState;
762+ case mir_surface_state_maximized: return Mir::MaximizedState;
763+ case mir_surface_state_vertmaximized: return Mir::VertMaximizedState;
764+ case mir_surface_state_fullscreen: return Mir::FullscreenState;
765+ case mir_surface_state_horizmaximized: return Mir::HorizMaximizedState;
766+ case mir_surface_state_hidden: return Mir::HiddenState;
767+ case mir_surface_states: Q_UNREACHABLE();
768+ }
769+ Q_UNREACHABLE();
770+}
771+
772+inline MirSurfaceState toMirState(Mir::State state)
773+{
774+ switch (state) {
775+ case Mir::UnknownState: return mir_surface_state_unknown;
776+ case Mir::RestoredState: return mir_surface_state_restored;
777+ case Mir::MinimizedState: return mir_surface_state_minimized;
778+ case Mir::MaximizedState: return mir_surface_state_maximized;
779+ case Mir::VertMaximizedState: return mir_surface_state_vertmaximized;
780+ case Mir::FullscreenState: return mir_surface_state_fullscreen;
781+ case Mir::HorizMaximizedState: return mir_surface_state_horizmaximized;
782+
783+ // FIXME: Map to the corresponding MirSurfaceState enum value once available
784+ case Mir::MaximizedLeftState:
785+ case Mir::MaximizedRightState:
786+ case Mir::MaximizedTopLeftState:
787+ case Mir::MaximizedTopRightState:
788+ case Mir::MaximizedBottomLeftState:
789+ case Mir::MaximizedBottomRightState:
790+ return mir_surface_state_restored;
791+
792+ case Mir::HiddenState: return mir_surface_state_hidden;
793+ default: Q_UNREACHABLE();
794+ }
795+}
796+
797+} // namespace qtmir
798+
799+#endif // MIRQTCONVERSION_H
800
801=== added file 'src/common/windowcontrollerinterface.h'
802--- src/common/windowcontrollerinterface.h 1970-01-01 00:00:00 +0000
803+++ src/common/windowcontrollerinterface.h 2016-12-01 11:46:42 +0000
804@@ -0,0 +1,58 @@
805+/*
806+ * Copyright (C) 2016 Canonical, Ltd.
807+ *
808+ * This program is free software: you can redistribute it and/or modify it under
809+ * the terms of the GNU Lesser General Public License version 3, as published by
810+ * the Free Software Foundation.
811+ *
812+ * This program is distributed in the hope that it will be useful, but WITHOUT
813+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
814+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
815+ * Lesser General Public License for more details.
816+ *
817+ * You should have received a copy of the GNU Lesser General Public License
818+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
819+ */
820+
821+#ifndef WINDOWCONTROLLERINTERFACE_H
822+#define WINDOWCONTROLLERINTERFACE_H
823+
824+#include <miral/window.h>
825+
826+#include <mir_toolkit/event.h>
827+
828+#include <QPoint>
829+#include <QSize>
830+
831+// Unity API
832+#include <unity/shell/application/Mir.h>
833+
834+namespace qtmir {
835+
836+class MirSurface;
837+
838+class WindowControllerInterface {
839+public:
840+ WindowControllerInterface() = default;
841+ virtual ~WindowControllerInterface() = default;
842+
843+ // activate() asks Mir to bring particular window to the front and recommend to shell that it be focused
844+ virtual void activate (const miral::Window &window) = 0;
845+ virtual void raise(const miral::Window &window) = 0;
846+
847+ virtual void resize(const miral::Window &window, const QSize &size) = 0;
848+ virtual void move (const miral::Window &window, const QPoint &topLeft) = 0;
849+
850+ virtual void requestClose(const miral::Window &window) = 0;
851+ virtual void forceClose(const miral::Window &window) = 0;
852+
853+ virtual void requestState(const miral::Window &window, const Mir::State state) = 0;
854+
855+ virtual void deliverKeyboardEvent(const miral::Window &window, const MirKeyboardEvent *event) = 0;
856+ virtual void deliverTouchEvent (const miral::Window &window, const MirTouchEvent *event) = 0;
857+ virtual void deliverPointerEvent (const miral::Window &window, const MirPointerEvent *event) = 0;
858+};
859+
860+} // namespace qtmir
861+
862+#endif // WINDOWCONTROLLERINTERFACE_H
863
864=== added file 'src/common/windowmodelnotifier.h'
865--- src/common/windowmodelnotifier.h 1970-01-01 00:00:00 +0000
866+++ src/common/windowmodelnotifier.h 2016-12-01 11:46:42 +0000
867@@ -0,0 +1,95 @@
868+/*
869+ * Copyright (C) 2016 Canonical, Ltd.
870+ *
871+ * This program is free software: you can redistribute it and/or modify it under
872+ * the terms of the GNU Lesser General Public License version 3, as published by
873+ * the Free Software Foundation.
874+ *
875+ * This program is distributed in the hope that it will be useful, but WITHOUT
876+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
877+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
878+ * Lesser General Public License for more details.
879+ *
880+ * You should have received a copy of the GNU Lesser General Public License
881+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
882+ */
883+
884+#ifndef WINDOWMODELNOTIFIER_H
885+#define WINDOWMODELNOTIFIER_H
886+
887+#include <QObject>
888+#include <QPoint>
889+#include <QSize>
890+
891+#include <miral/window_info.h>
892+
893+// Unity API
894+#include <unity/shell/application/Mir.h>
895+
896+namespace qtmir {
897+
898+class NewWindow {
899+public:
900+ NewWindow() = default;
901+ NewWindow(const miral::WindowInfo &windowInfo)
902+ : windowInfo(windowInfo)
903+ , surface(windowInfo.window())
904+ {}
905+
906+ miral::WindowInfo windowInfo;
907+
908+ // hold copy of Surface shared pointer, as miral::Window has just a weak pointer to the Surface
909+ // but MirSurface needs to share ownership of the Surface with Mir
910+ std::shared_ptr<mir::scene::Surface> surface;
911+};
912+
913+struct ExtraWindowInfo {
914+ QString persistentId;
915+
916+ // FIXME Use MirSurfaceState when possible.
917+ Mir::State previousState{Mir::UnknownState};
918+
919+ // FIXME: Remove when possible. This exists just because MirSurfaceState has no equivalent
920+ // for the following states:
921+ // Mir::MaximizedLeftState:
922+ // Mir::MaximizedRightState:
923+ // Mir::MaximizedTopLeftState:
924+ // Mir::MaximizedTopRightState:
925+ // Mir::MaximizedBottomLeftState:
926+ // Mir::MaximizedBottomRightState:
927+ Mir::State state{Mir::UnknownState};
928+};
929+
930+std::shared_ptr<ExtraWindowInfo> getExtraInfo(const miral::WindowInfo &windowInfo);
931+
932+class WindowModelNotifier : public QObject
933+{
934+ Q_OBJECT
935+public:
936+ WindowModelNotifier() = default;
937+
938+Q_SIGNALS: // **Must used Queued Connection or else events will be out of order**
939+ void windowAdded(const qtmir::NewWindow &window);
940+ void windowRemoved(const miral::WindowInfo &window);
941+ void windowReady(const miral::WindowInfo &window);
942+ void windowMoved(const miral::WindowInfo &window, const QPoint topLeft);
943+ void windowResized(const miral::WindowInfo &window, const QSize size);
944+ void windowStateChanged(const miral::WindowInfo &window, Mir::State state);
945+ void windowFocusChanged(const miral::WindowInfo &window, bool focused);
946+ void windowsRaised(const std::vector<miral::Window> &windows); // results in deep copy when passed over Queued connection:(
947+ void windowRequestedRaise(const miral::WindowInfo &window);
948+ void modificationsStarted();
949+ void modificationsEnded();
950+
951+private:
952+ Q_DISABLE_COPY(WindowModelNotifier)
953+};
954+
955+} // namespace qtmir
956+
957+Q_DECLARE_METATYPE(qtmir::NewWindow)
958+Q_DECLARE_METATYPE(miral::WindowInfo)
959+Q_DECLARE_METATYPE(std::vector<miral::Window>)
960+Q_DECLARE_METATYPE(MirSurfaceState)
961+
962+#endif // WINDOWMODELNOTIFIER_H
963
964=== modified file 'src/modules/Unity/Application/CMakeLists.txt'
965--- src/modules/Unity/Application/CMakeLists.txt 2016-07-30 21:19:45 +0000
966+++ src/modules/Unity/Application/CMakeLists.txt 2016-12-01 11:46:42 +0000
967@@ -8,6 +8,7 @@
968 ${GLIB_INCLUDE_DIRS}
969 ${GIO_INCLUDE_DIRS}
970 ${GIO_UNIX_INCLUDE_DIRS}
971+ ${MIRAL_INCLUDE_DIRS}
972 ${MIRSERVER_INCLUDE_DIRS}
973 ${MIRRENDERERGLDEV_INCLUDE_DIRS}
974 ${PROCESS_CPP_INCLUDE_DIRS}
975@@ -35,8 +36,6 @@
976 ../../../common/debughelpers.cpp
977 dbusfocusinfo.cpp
978 plugin.cpp
979- mirsurfacemanager.cpp
980- mirfocuscontroller.cpp
981 mirsurface.cpp
982 mirsurfaceinterface.h
983 mirsurfaceitem.cpp
984@@ -46,20 +45,22 @@
985 session.cpp
986 sessionmanager.cpp
987 sharedwakelock.cpp
988+ surfacemanager.cpp
989 upstart/applicationinfo.cpp
990 upstart/taskcontroller.cpp
991 timer.cpp
992 timesource.cpp
993 tracepoints.c
994 settings.cpp
995+ windowmodel.cpp
996 # We need to run moc on these headers
997 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
998 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
999 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/Mir.h
1000- ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirFocusControllerInterface.h
1001 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceInterface.h
1002 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceItemInterface.h
1003 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceListInterface.h
1004+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/SurfaceManagerInterface.h
1005 # Feed the automoc monster
1006 session_interface.h
1007 applicationinfo.h
1008
1009=== modified file 'src/modules/Unity/Application/application.cpp'
1010--- src/modules/Unity/Application/application.cpp 2016-08-10 06:52:18 +0000
1011+++ src/modules/Unity/Application/application.cpp 2016-12-01 11:46:42 +0000
1012@@ -409,11 +409,7 @@
1013
1014 bool Application::focused() const
1015 {
1016- bool someSurfaceHasFocus = false; // to be proven wrong
1017- for (int i = 0; i < m_proxySurfaceList->rowCount() && !someSurfaceHasFocus; ++i) {
1018- someSurfaceHasFocus |= m_proxySurfaceList->get(i)->focused();
1019- }
1020- return someSurfaceHasFocus;
1021+ return m_session && m_session->focused();
1022 }
1023
1024 bool Application::fullscreen() const
1025@@ -512,6 +508,10 @@
1026 connect(m_session, &SessionInterface::hasClosingSurfacesChanged, this, &Application::updateState);
1027 connect(m_session, &SessionInterface::focusRequested, this, &Application::focusRequested);
1028 connect(m_session->surfaceList(), &MirSurfaceListModel::emptyChanged, this, &Application::updateState);
1029+ connect(m_session, &SessionInterface::focusedChanged, this, [&](bool focused) {
1030+ qCDebug(QTMIR_APPLICATIONS).nospace() << "Application[" << appId() <<"]::focusedChanged(" << focused << ")";
1031+ Q_EMIT focusedChanged(focused);
1032+ });
1033
1034 if (oldFullscreen != fullscreen())
1035 Q_EMIT fullscreenChanged(fullscreen());
1036@@ -852,7 +852,8 @@
1037 {
1038 if (m_proxySurfaceList->rowCount() > 0) {
1039 DEBUG_MSG << "() - Requesting focus for most recent app surface";
1040- m_proxySurfaceList->get(0)->requestFocus();
1041+ auto surface = static_cast<MirSurfaceInterface*>(m_proxySurfaceList->get(0));
1042+ surface->requestFocus();
1043 } else {
1044 DEBUG_MSG << "() - emitting focusRequested()";
1045 Q_EMIT focusRequested();
1046
1047=== modified file 'src/modules/Unity/Application/application.h'
1048--- src/modules/Unity/Application/application.h 2016-08-10 06:52:18 +0000
1049+++ src/modules/Unity/Application/application.h 2016-12-01 11:46:42 +0000
1050@@ -31,12 +31,6 @@
1051 #include "mirsurfacelistmodel.h"
1052 #include "session_interface.h"
1053
1054-namespace mir {
1055- namespace scene {
1056- class Session;
1057- }
1058-}
1059-
1060 namespace qtmir
1061 {
1062
1063@@ -109,6 +103,7 @@
1064 unity::shell::application::MirSurfaceListInterface* surfaceList() const override;
1065 unity::shell::application::MirSurfaceListInterface* promptSurfaceList() const override;
1066 int surfaceCount() const override { return surfaceList()->count(); }
1067+ void close() override;
1068
1069 ProcessState processState() const { return m_processState; }
1070 void setProcessState(ProcessState value);
1071@@ -125,8 +120,6 @@
1072
1073 pid_t pid() const;
1074
1075- void close();
1076-
1077 // internal as in "not exposed in unity-api", so qtmir-internal.
1078 InternalState internalState() const { return m_state; }
1079
1080
1081=== modified file 'src/modules/Unity/Application/application_manager.cpp'
1082--- src/modules/Unity/Application/application_manager.cpp 2016-08-26 09:08:55 +0000
1083+++ src/modules/Unity/Application/application_manager.cpp 2016-12-01 11:46:42 +0000
1084@@ -19,7 +19,7 @@
1085 #include "application.h"
1086 #include "applicationinfo.h"
1087 #include "dbusfocusinfo.h"
1088-#include "mirfocuscontroller.h"
1089+#include "mirsurfaceinterface.h"
1090 #include "session.h"
1091 #include "sharedwakelock.h"
1092 #include "proc_info.h"
1093@@ -31,12 +31,11 @@
1094 #include "nativeinterface.h"
1095 #include "sessionauthorizer.h"
1096 #include "logging.h"
1097-#include <mirwindowmanager.h>
1098+
1099+//miral
1100+#include <miral/application.h>
1101
1102 // mir
1103-#include <mir/scene/surface.h>
1104-#include <mir/graphics/display.h>
1105-#include <mir/graphics/display_buffer.h>
1106 #include <mir/geometry/rectangles.h>
1107
1108 // Qt
1109@@ -82,15 +81,8 @@
1110
1111 void connectToTaskController(ApplicationManager *manager, TaskController *controller)
1112 {
1113- // TaskController::processStarting blocks Ubuntu-App-Launch from executing the process, have it return
1114- // as fast as possible! Using a Queued connection will push an event on the event queue before the
1115- // (blocking) event for authorizeSession is pushed on the same queue - so the application's processState
1116- // will be up-to-date when authorizeSession is called.
1117- //
1118- // TODO: Unfortunately making this queued unearths a crash (likely in Qt) (LP: #1616842).
1119 QObject::connect(controller, &TaskController::processStarting,
1120 manager, &ApplicationManager::onProcessStarting);
1121-
1122 QObject::connect(controller, &TaskController::processStopped,
1123 manager, &ApplicationManager::onProcessStopped);
1124 QObject::connect(controller, &TaskController::processSuspended,
1125@@ -115,7 +107,6 @@
1126 return nullptr;
1127 }
1128
1129- MirWindowManager *windowManager = static_cast<MirWindowManager*>(nativeInterface->nativeResourceForIntegration("WindowManager"));
1130 SessionAuthorizer *sessionAuthorizer = static_cast<SessionAuthorizer*>(nativeInterface->nativeResourceForIntegration("SessionAuthorizer"));
1131
1132 QSharedPointer<TaskController> taskController(new upstart::TaskController());
1133@@ -137,9 +128,10 @@
1134
1135 connectToSessionAuthorizer(appManager, sessionAuthorizer);
1136 connectToTaskController(appManager, taskController.data());
1137- connect(windowManager, &MirWindowManager::sessionAboutToCreateSurface,
1138- appManager, &ApplicationManager::onSessionAboutToCreateSurface,
1139- Qt::BlockingQueuedConnection);
1140+// TODO - re-implement this functionality using the new Mir WindowManagement API
1141+// connect(windowManager, &MirWindowManager::sessionAboutToCreateSurface,
1142+// appManager, &ApplicationManager::onSessionAboutToCreateSurface,
1143+// Qt::BlockingQueuedConnection);
1144
1145 // Emit signal to notify Upstart that Mir is ready to receive client connections
1146 // see http://upstart.ubuntu.com/cookbook/#expect-stop
1147@@ -179,17 +171,6 @@
1148 {
1149 qCDebug(QTMIR_APPLICATIONS) << "ApplicationManager::ApplicationManager (this=%p)" << this;
1150 setObjectName(QStringLiteral("qtmir::ApplicationManager"));
1151-
1152- /*
1153- All begin[...]Rows() and end[...]Rows() functions cause signal emissions which can
1154- be processed by slots immediately and then trigger yet more model changes.
1155-
1156- The connection below is queued to avoid stacked model change attempts cause by the above,
1157- such as attempting to raise the newly focused application while another one is still
1158- getting removed from the model.
1159- */
1160- connect(MirFocusController::instance(), &MirFocusController::focusedSurfaceChanged,
1161- this, &ApplicationManager::updateFocusedApplication, Qt::QueuedConnection);
1162 }
1163
1164 ApplicationManager::~ApplicationManager()
1165@@ -273,18 +254,12 @@
1166
1167 QString ApplicationManager::focusedApplicationId() const
1168 {
1169- Application *focusedApplication = nullptr;
1170- auto surface = static_cast<qtmir::MirSurfaceInterface*>(MirFocusController::instance()->focusedSurface());
1171- if (surface) {
1172- auto self = const_cast<ApplicationManager*>(this);
1173- focusedApplication = self->findApplication(surface);
1174- }
1175-
1176- if (focusedApplication) {
1177- return focusedApplication->appId();
1178- } else {
1179- return QString();
1180- }
1181+ for (const auto application : m_applications) {
1182+ if (application->focused()) {
1183+ return application->appId();
1184+ }
1185+ }
1186+ return QString();
1187 }
1188
1189 /**
1190@@ -602,16 +577,22 @@
1191 authorized = true;
1192 }
1193
1194+
1195+unityapi::ApplicationInfoInterface *ApplicationManager::findApplicationWithSurface(unityapi::MirSurfaceInterface* surface)
1196+{
1197+ if (!surface)
1198+ return nullptr;
1199+
1200+ auto qtmirSurface = static_cast<qtmir::MirSurfaceInterface*>(surface);
1201+
1202+ return findApplicationWithPid(miral::pid_of(qtmirSurface->session()->session()));
1203+}
1204+
1205 Application* ApplicationManager::findApplicationWithSession(const std::shared_ptr<ms::Session> &session)
1206 {
1207- return findApplicationWithSession(session.get());
1208-}
1209-
1210-Application* ApplicationManager::findApplicationWithSession(const ms::Session *session)
1211-{
1212 if (!session)
1213 return nullptr;
1214- return findApplicationWithPid(session->process_id());
1215+ return findApplicationWithPid(miral::pid_of(session));
1216 }
1217
1218 Application* ApplicationManager::findApplicationWithPid(const pid_t pid) const
1219@@ -640,7 +621,20 @@
1220 Q_ASSERT(!m_modelUnderChange);
1221 m_modelUnderChange = true;
1222
1223- connect(application, &Application::focusedChanged, this, [this](bool) { onAppDataChanged(RoleFocused); });
1224+ /*
1225+ All begin[...]Rows() and end[...]Rows() functions cause signal emissions which can
1226+ be processed by slots immediately and then trigger yet more model changes.
1227+
1228+ The connection below is queued to avoid stacked model change attempts cause by the above,
1229+ such as attempting to raise the newly focused application while another one is still
1230+ getting removed from the model.
1231+ */
1232+ // TODO: That might not be the case anymore with miral. Investigate if we can do a direct connection now
1233+ connect(application, &Application::focusedChanged, this, [this](bool) {
1234+ onAppDataChanged(RoleFocused);
1235+ Q_EMIT focusedApplicationIdChanged();
1236+ }, Qt::QueuedConnection);
1237+
1238 connect(application, &Application::stateChanged, this, [this](Application::State) { onAppDataChanged(RoleState); });
1239 connect(application, &Application::closing, this, [this, application]() { onApplicationClosing(application); });
1240 connect(application, &unityapi::ApplicationInfoInterface::focusRequested, this, [this, application]() {
1241@@ -805,35 +799,6 @@
1242 }
1243 }
1244
1245-void ApplicationManager::updateFocusedApplication()
1246-{
1247- Application *focusedApplication = nullptr;
1248- Application *previouslyFocusedApplication = nullptr;
1249-
1250- auto surface = static_cast<qtmir::MirSurfaceInterface*>(MirFocusController::instance()->focusedSurface());
1251- if (surface) {
1252- focusedApplication = findApplication(surface);
1253- }
1254-
1255- surface = static_cast<qtmir::MirSurfaceInterface*>(MirFocusController::instance()->previouslyFocusedSurface());
1256- if (surface) {
1257- previouslyFocusedApplication = findApplication(surface);
1258- }
1259-
1260- if (focusedApplication != previouslyFocusedApplication) {
1261- if (focusedApplication) {
1262- DEBUG_MSG << "() focused " << focusedApplication->appId();
1263- Q_EMIT focusedApplication->focusedChanged(true);
1264- this->move(this->m_applications.indexOf(focusedApplication), 0);
1265- }
1266- if (previouslyFocusedApplication) {
1267- DEBUG_MSG << "() unfocused " << previouslyFocusedApplication->appId();
1268- Q_EMIT previouslyFocusedApplication->focusedChanged(false);
1269- }
1270- Q_EMIT focusedApplicationIdChanged();
1271- }
1272-}
1273-
1274 Application *ApplicationManager::findApplication(qtmir::MirSurfaceInterface* surface)
1275 {
1276 Q_FOREACH (Application *app, m_applications) {
1277
1278=== modified file 'src/modules/Unity/Application/application_manager.h'
1279--- src/modules/Unity/Application/application_manager.h 2016-08-08 13:10:40 +0000
1280+++ src/modules/Unity/Application/application_manager.h 2016-12-01 11:46:42 +0000
1281@@ -24,13 +24,13 @@
1282 #include <QObject>
1283 #include <QStringList>
1284
1285-// Unity API
1286-#include <unity/shell/application/ApplicationManagerInterface.h>
1287-
1288 // local
1289 #include "application.h"
1290 #include "taskcontroller.h"
1291
1292+// Unity API
1293+#include <unity/shell/application/ApplicationManagerInterface.h>
1294+
1295 namespace mir {
1296 namespace scene {
1297 class Session;
1298@@ -51,7 +51,6 @@
1299
1300 class DBusFocusInfo;
1301 class DBusWindowStack;
1302-class MirSurfaceManager;
1303 class ProcInfo;
1304 class SharedWakelock;
1305 class SettingsInterface;
1306@@ -80,10 +79,11 @@
1307 QObject *parent = 0);
1308 virtual ~ApplicationManager();
1309
1310- // ApplicationManagerInterface
1311+ // unity::shell::application::ApplicationManagerInterface
1312 QString focusedApplicationId() const override;
1313 Q_INVOKABLE qtmir::Application* get(int index) const override;
1314 Q_INVOKABLE qtmir::Application* findApplication(const QString &appId) const override;
1315+ unity::shell::application::ApplicationInfoInterface *findApplicationWithSurface(unity::shell::application::MirSurfaceInterface* surface) override;
1316 Q_INVOKABLE bool requestFocusApplication(const QString &appId) override;
1317 Q_INVOKABLE qtmir::Application* startApplication(const QString &appId, const QStringList &arguments = QStringList()) override;
1318 Q_INVOKABLE bool stopApplication(const QString &appId) override;
1319@@ -117,14 +117,13 @@
1320 void onSessionAboutToCreateSurface(const std::shared_ptr<mir::scene::Session> &session,
1321 int type, QSize &size);
1322 void onApplicationClosing(Application *application);
1323- void updateFocusedApplication();
1324
1325 private:
1326+ Application* findApplicationWithSession(const std::shared_ptr<mir::scene::Session> &session);
1327 void setFocused(Application *application);
1328 void add(Application *application);
1329 void remove(Application* application);
1330- Application* findApplicationWithSession(const std::shared_ptr<mir::scene::Session> &session);
1331- Application* findApplicationWithSession(const mir::scene::Session *session);
1332+
1333 QModelIndex findIndex(Application* application);
1334 void resumeApplication(Application *application);
1335 QString toString() const;
1336@@ -146,7 +145,6 @@
1337
1338 friend class Application;
1339 friend class DBusWindowStack;
1340- friend class MirSurfaceManager;
1341 friend class SessionManager;
1342 };
1343
1344
1345=== modified file 'src/modules/Unity/Application/dbusfocusinfo.cpp'
1346--- src/modules/Unity/Application/dbusfocusinfo.cpp 2016-08-30 12:32:13 +0000
1347+++ src/modules/Unity/Application/dbusfocusinfo.cpp 2016-12-01 11:46:42 +0000
1348@@ -75,29 +75,23 @@
1349 SessionInterface* DBusFocusInfo::findSessionWithPid(const QSet<pid_t> &pidSet)
1350 {
1351 Q_FOREACH (Application* application, m_applications) {
1352- SessionInterface *sessionWithPid = findSessionWithPid(application->session(), pidSet);
1353- if (sessionWithPid) {
1354- return sessionWithPid;
1355+ auto session = application->session();
1356+ if (pidSet.contains(session->pid())) {
1357+ return session;
1358+ }
1359+ SessionInterface *chosenChildSession = nullptr;
1360+ session->foreachChildSession([&](SessionInterface* childSession) {
1361+ if (pidSet.contains(childSession->pid())) {
1362+ chosenChildSession = childSession;
1363+ }
1364+ });
1365+ if (chosenChildSession) {
1366+ return chosenChildSession;
1367 }
1368 }
1369 return nullptr;
1370 }
1371
1372-SessionInterface* DBusFocusInfo::findSessionWithPid(SessionInterface* session, const QSet<pid_t> &pidSet)
1373-{
1374- if (pidSet.contains(session->pid())) {
1375- return session;
1376- }
1377-
1378- SessionInterface *sessionWithPid = nullptr;
1379- session->foreachChildSession([&](SessionInterface* childSession) {
1380- if (!sessionWithPid) {
1381- sessionWithPid = findSessionWithPid(childSession, pidSet);
1382- }
1383- });
1384- return sessionWithPid;
1385-}
1386-
1387 bool DBusFocusInfo::isSurfaceFocused(const QString &serializedId)
1388 {
1389 // TODO: Implement a penalty for negative queries, such as stalling for some time before answering
1390
1391=== modified file 'src/modules/Unity/Application/dbusfocusinfo.h'
1392--- src/modules/Unity/Application/dbusfocusinfo.h 2016-08-30 12:29:32 +0000
1393+++ src/modules/Unity/Application/dbusfocusinfo.h 2016-12-01 11:46:42 +0000
1394@@ -54,7 +54,6 @@
1395 private:
1396 QSet<pid_t> fetchAssociatedPids(pid_t pid);
1397 SessionInterface* findSessionWithPid(const QSet<pid_t> &pidSet);
1398- SessionInterface* findSessionWithPid(SessionInterface* session, const QSet<pid_t> &pidSet);
1399 MirSurfaceInterface *findQmlSurface(const QString &serializedId);
1400
1401 const QList<Application*> &m_applications;
1402
1403=== removed file 'src/modules/Unity/Application/mirfocuscontroller.cpp'
1404--- src/modules/Unity/Application/mirfocuscontroller.cpp 2016-04-05 18:58:38 +0000
1405+++ src/modules/Unity/Application/mirfocuscontroller.cpp 1970-01-01 00:00:00 +0000
1406@@ -1,69 +0,0 @@
1407-/*
1408- * Copyright (C) 2016 Canonical, Ltd.
1409- *
1410- * This program is free software; you can redistribute it and/or modify
1411- * it under the terms of the GNU General Public License as published by
1412- * the Free Software Foundation; version 3.
1413- *
1414- * This program is distributed in the hope that it will be useful,
1415- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1416- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1417- * GNU General Public License for more details.
1418- *
1419- * You should have received a copy of the GNU General Public License
1420- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1421- */
1422-
1423-#include "mirfocuscontroller.h"
1424-
1425-#include "mirsurfaceinterface.h"
1426-
1427-// mirserver
1428-#include <logging.h>
1429-
1430-namespace unityapp = unity::shell::application;
1431-using namespace qtmir;
1432-
1433-#define DEBUG_MSG qCDebug(QTMIR_SURFACES).nospace() << "MirFocusController::" << __func__
1434-
1435-MirFocusController *MirFocusController::m_instance = nullptr;
1436-
1437-void MirFocusController::setFocusedSurface(unityapp::MirSurfaceInterface *unityAppSurface)
1438-{
1439- auto surface = static_cast<qtmir::MirSurfaceInterface*>(unityAppSurface);
1440-
1441- if (m_focusedSurface == surface) {
1442- return;
1443- }
1444-
1445- DEBUG_MSG << "(" << surface << ")";
1446-
1447- m_previouslyFocusedSurface = m_focusedSurface;
1448- m_focusedSurface = surface;
1449-
1450- if (m_previouslyFocusedSurface) {
1451- m_previouslyFocusedSurface->setFocused(false);
1452- }
1453-
1454- if (m_focusedSurface) {
1455- m_focusedSurface->setFocused(true);
1456- m_focusedSurface->raise();
1457- }
1458-
1459- if (m_previouslyFocusedSurface != m_focusedSurface) {
1460- Q_EMIT focusedSurfaceChanged();
1461- }
1462-}
1463-
1464-unity::shell::application::MirSurfaceInterface* MirFocusController::focusedSurface() const
1465-{
1466- return m_focusedSurface;
1467-}
1468-
1469-MirFocusController* MirFocusController::instance()
1470-{
1471- if (!m_instance) {
1472- m_instance = new MirFocusController;
1473- }
1474- return m_instance;
1475-}
1476
1477=== removed file 'src/modules/Unity/Application/mirfocuscontroller.h'
1478--- src/modules/Unity/Application/mirfocuscontroller.h 2016-03-28 18:02:26 +0000
1479+++ src/modules/Unity/Application/mirfocuscontroller.h 1970-01-01 00:00:00 +0000
1480@@ -1,49 +0,0 @@
1481-/*
1482- * Copyright (C) 2016 Canonical, Ltd.
1483- *
1484- * This program is free software; you can redistribute it and/or modify
1485- * it under the terms of the GNU General Public License as published by
1486- * the Free Software Foundation; version 3.
1487- *
1488- * This program is distributed in the hope that it will be useful,
1489- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1490- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1491- * GNU General Public License for more details.
1492- *
1493- * You should have received a copy of the GNU General Public License
1494- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1495- */
1496-
1497-#ifndef QTMIR_MIRFOCUSCONTROLLER_H
1498-#define QTMIR_MIRFOCUSCONTROLLER_H
1499-
1500-// unity-api
1501-#include <unity/shell/application/MirFocusControllerInterface.h>
1502-
1503-#include <QPointer>
1504-
1505-#include "mirsurfaceinterface.h"
1506-
1507-namespace qtmir {
1508-
1509-class MirSurfaceInterface;
1510-
1511-class MirFocusController : public unity::shell::application::MirFocusControllerInterface
1512-{
1513- Q_OBJECT
1514-public:
1515- MirFocusController(){}
1516- static MirFocusController* instance();
1517-
1518- void setFocusedSurface(unity::shell::application::MirSurfaceInterface *surface) override;
1519- unity::shell::application::MirSurfaceInterface* focusedSurface() const override;
1520- MirSurfaceInterface* previouslyFocusedSurface() { return m_previouslyFocusedSurface.data(); }
1521-private:
1522- static MirFocusController *m_instance;
1523- QPointer<MirSurfaceInterface> m_previouslyFocusedSurface;
1524- QPointer<MirSurfaceInterface> m_focusedSurface;
1525-};
1526-
1527-} // namespace qtmir
1528-
1529-#endif // QTMIR_MIRFOCUSCONTROLLER_H
1530
1531=== modified file 'src/modules/Unity/Application/mirsurface.cpp'
1532--- src/modules/Unity/Application/mirsurface.cpp 2016-10-11 20:50:50 +0000
1533+++ src/modules/Unity/Application/mirsurface.cpp 2016-12-01 11:46:42 +0000
1534@@ -16,11 +16,14 @@
1535
1536 #include "mirsurface.h"
1537 #include "mirsurfacelistmodel.h"
1538+#include "namedcursor.h"
1539+#include "session_interface.h"
1540 #include "timer.h"
1541 #include "timestamp.h"
1542
1543 // from common dir
1544 #include <debughelpers.h>
1545+#include "mirqtconversion.h"
1546
1547 // mirserver
1548 #include <eventbuilder.h>
1549@@ -29,11 +32,9 @@
1550
1551 // Mir
1552 #include <mir/geometry/rectangle.h>
1553-#include <mir/events/event_builders.h>
1554-#include <mir/shell/shell.h>
1555 #include <mir/scene/surface.h>
1556-#include <mir/scene/session.h>
1557-#include <mir_toolkit/event.h>
1558+#include <mir/scene/surface_observer.h>
1559+#include <mir/version.h>
1560
1561 // mirserver
1562 #include <logging.h>
1563@@ -42,60 +43,125 @@
1564 #include <QQmlEngine>
1565 #include <QScreen>
1566
1567+// std
1568+#include <limits>
1569+
1570 using namespace qtmir;
1571
1572 #define DEBUG_MSG qCDebug(QTMIR_SURFACES).nospace() << "MirSurface[" << (void*)this << "," << appId() << "]::" << __func__
1573 #define WARNING_MSG qCWarning(QTMIR_SURFACES).nospace() << "MirSurface[" << (void*)this << "," << appId() << "]::" << __func__
1574
1575-MirSurface::MirSurface(std::shared_ptr<mir::scene::Surface> surface,
1576- const QString& persistentId,
1577- SessionInterface* session,
1578- mir::shell::Shell* shell,
1579- std::shared_ptr<SurfaceObserver> observer,
1580- const CreationHints &creationHints)
1581+namespace {
1582+
1583+enum class DirtyState {
1584+ Clean = 0,
1585+ Name = 1 << 1,
1586+ Type = 1 << 2,
1587+ State = 1 << 3,
1588+ RestoreRect = 1 << 4,
1589+ Children = 1 << 5,
1590+ MinSize = 1 << 6,
1591+ MaxSize = 1 << 7,
1592+};
1593+Q_DECLARE_FLAGS(DirtyStates, DirtyState)
1594+
1595+} // namespace {
1596+
1597+class MirSurface::SurfaceObserverImpl : public SurfaceObserver, public mir::scene::SurfaceObserver
1598+{
1599+public:
1600+ SurfaceObserverImpl();
1601+ virtual ~SurfaceObserverImpl();
1602+
1603+ void setListener(QObject *listener);
1604+
1605+ void attrib_changed(MirSurfaceAttrib, int) override;
1606+ void resized_to(mir::geometry::Size const&) override;
1607+ void moved_to(mir::geometry::Point const&) override {}
1608+ void hidden_set_to(bool) override {}
1609+
1610+ // Get new frame notifications from Mir, called from a Mir thread.
1611+ void frame_posted(int frames_available, mir::geometry::Size const& size ) override;
1612+
1613+ void alpha_set_to(float) override {}
1614+ void transformation_set_to(glm::mat4 const&) override {}
1615+ void reception_mode_set_to(mir::input::InputReceptionMode) override {}
1616+ void cursor_image_set_to(mir::graphics::CursorImage const&) override;
1617+ void orientation_set_to(MirOrientation) override {}
1618+ void client_surface_close_requested() override {}
1619+ void keymap_changed(MirInputDeviceId, std::string const& model, std::string const& layout,
1620+ std::string const& variant, std::string const& options) override;
1621+ void renamed(char const * name) override;
1622+ void cursor_image_removed() override;
1623+
1624+#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 25, 0)
1625+ void placed_relative(mir::geometry::Rectangle const& placement) override;
1626+#endif
1627+
1628+private:
1629+ QCursor createQCursorFromMirCursorImage(const mir::graphics::CursorImage &cursorImage);
1630+ QObject *m_listener;
1631+ bool m_framesPosted;
1632+ QMap<QByteArray, Qt::CursorShape> m_cursorNameToShape;
1633+};
1634+
1635+
1636+MirSurface::MirSurface(NewWindow newWindowInfo,
1637+ WindowControllerInterface* controller,
1638+ SessionInterface *session)
1639 : MirSurfaceInterface()
1640- , m_surface(surface)
1641+ , m_window{newWindowInfo.windowInfo.window()}
1642+ , m_extraInfo{getExtraInfo(newWindowInfo.windowInfo)}
1643+ , m_name{QString::fromStdString(newWindowInfo.windowInfo.name())}
1644+ , m_type{newWindowInfo.windowInfo.type()}
1645+ , m_minWidth{newWindowInfo.windowInfo.min_width().as_int()}
1646+ , m_minHeight{newWindowInfo.windowInfo.min_height().as_int()}
1647+ , m_maxWidth{newWindowInfo.windowInfo.max_width().as_int()}
1648+ , m_maxHeight{newWindowInfo.windowInfo.max_height().as_int()}
1649+ , m_incWidth{newWindowInfo.windowInfo.width_inc().as_int()}
1650+ , m_incHeight{newWindowInfo.windowInfo.height_inc().as_int()}
1651+ , m_surface(newWindowInfo.surface)
1652 , m_session(session)
1653- , m_shell(shell)
1654- , m_persistentId(persistentId)
1655- , m_firstFrameDrawn(false)
1656+ , m_controller(controller)
1657 , m_orientationAngle(Mir::Angle0)
1658 , m_textureUpdated(false)
1659 , m_currentFrameNumber(0)
1660+ , m_visible(newWindowInfo.windowInfo.is_visible())
1661 , m_live(true)
1662+ , m_surfaceObserver(std::make_shared<SurfaceObserverImpl>())
1663+ , m_position(toQPoint(m_window.top_left()))
1664+ , m_size(toQSize(m_window.size()))
1665+ , m_state(toQtState(newWindowInfo.windowInfo.state()))
1666 , m_shellChrome(Mir::NormalChrome)
1667 {
1668- DEBUG_MSG << "()";
1669-
1670- m_minimumWidth = creationHints.minWidth;
1671- m_minimumHeight = creationHints.minHeight;
1672- m_maximumWidth = creationHints.maxWidth;
1673- m_maximumHeight = creationHints.maxHeight;
1674- m_widthIncrement = creationHints.widthIncrement;
1675- m_heightIncrement = creationHints.heightIncrement;
1676- m_shellChrome = creationHints.shellChrome;
1677-
1678- m_surfaceObserver = observer;
1679- if (observer) {
1680- connect(observer.get(), &SurfaceObserver::framesPosted, this, &MirSurface::onFramesPostedObserved);
1681- connect(observer.get(), &SurfaceObserver::attributeChanged, this, &MirSurface::onAttributeChanged);
1682- connect(observer.get(), &SurfaceObserver::nameChanged, this, &MirSurface::nameChanged);
1683- connect(observer.get(), &SurfaceObserver::cursorChanged, this, &MirSurface::setCursor);
1684- connect(observer.get(), &SurfaceObserver::minimumWidthChanged, this, &MirSurface::setMinimumWidth);
1685- connect(observer.get(), &SurfaceObserver::minimumHeightChanged, this, &MirSurface::setMinimumHeight);
1686- connect(observer.get(), &SurfaceObserver::maximumWidthChanged, this, &MirSurface::setMaximumWidth);
1687- connect(observer.get(), &SurfaceObserver::maximumHeightChanged, this, &MirSurface::setMaximumHeight);
1688- connect(observer.get(), &SurfaceObserver::widthIncrementChanged, this, &MirSurface::setWidthIncrement);
1689- connect(observer.get(), &SurfaceObserver::heightIncrementChanged, this, &MirSurface::setHeightIncrement);
1690- connect(observer.get(), &SurfaceObserver::shellChromeChanged, this, [&](MirShellChrome shell_chrome) {
1691- setShellChrome(static_cast<Mir::ShellChrome>(shell_chrome));
1692- });
1693- connect(observer.get(), &SurfaceObserver::inputBoundsChanged, this, &MirSurface::setInputBounds);
1694- connect(observer.get(), &SurfaceObserver::confinesMousePointerChanged, this, &MirSurface::confinesMousePointerChanged);
1695- observer->setListener(this);
1696- }
1697-
1698- connect(session, &QObject::destroyed, this, &MirSurface::onSessionDestroyed);
1699+ DEBUG_MSG << "("
1700+ << "type=" << mirSurfaceTypeToStr(m_type)
1701+ << ",state=" << unityapiMirStateToStr(m_state)
1702+ << ")";
1703+
1704+ SurfaceObserver::registerObserverForSurface(m_surfaceObserver.get(), m_surface.get());
1705+ m_surface->add_observer(m_surfaceObserver);
1706+
1707+ //m_shellChrome = creationHints.shellChrome; TODO - where will this come from now?
1708+
1709+ connect(m_surfaceObserver.get(), &SurfaceObserver::framesPosted, this, &MirSurface::onFramesPostedObserved);
1710+ connect(m_surfaceObserver.get(), &SurfaceObserver::attributeChanged, this, &MirSurface::onAttributeChanged);
1711+ connect(m_surfaceObserver.get(), &SurfaceObserver::nameChanged, this, &MirSurface::onNameChanged);
1712+ connect(m_surfaceObserver.get(), &SurfaceObserver::cursorChanged, this, &MirSurface::setCursor);
1713+ connect(m_surfaceObserver.get(), &SurfaceObserver::minimumWidthChanged, this, &MirSurface::onMinimumWidthChanged);
1714+ connect(m_surfaceObserver.get(), &SurfaceObserver::minimumHeightChanged, this, &MirSurface::onMinimumHeightChanged);
1715+ connect(m_surfaceObserver.get(), &SurfaceObserver::maximumWidthChanged, this, &MirSurface::onMaximumWidthChanged);
1716+ connect(m_surfaceObserver.get(), &SurfaceObserver::maximumHeightChanged, this, &MirSurface::onMaximumHeightChanged);
1717+ connect(m_surfaceObserver.get(), &SurfaceObserver::widthIncrementChanged, this, &MirSurface::onWidthIncrementChanged);
1718+ connect(m_surfaceObserver.get(), &SurfaceObserver::heightIncrementChanged, this, &MirSurface::onHeightIncrementChanged);
1719+ connect(m_surfaceObserver.get(), &SurfaceObserver::shellChromeChanged, this, [&](MirShellChrome shell_chrome) {
1720+ setShellChrome(static_cast<Mir::ShellChrome>(shell_chrome));
1721+ });
1722+ connect(m_surfaceObserver.get(), &SurfaceObserver::inputBoundsChanged, this, &MirSurface::setInputBounds);
1723+ connect(m_surfaceObserver.get(), &SurfaceObserver::confinesMousePointerChanged, this, &MirSurface::confinesMousePointerChanged);
1724+ m_surfaceObserver->setListener(this);
1725+
1726+ //connect(session, &QObject::destroyed, this, &MirSurface::onSessionDestroyed); // TODO try using Shared pointer for lifecycle
1727 connect(session, &SessionInterface::stateChanged, this, [this]() {
1728 if (clientIsRunning() && m_pendingResize.isValid()) {
1729 resize(m_pendingResize.width(), m_pendingResize.height());
1730@@ -124,10 +190,8 @@
1731
1732 setCloseTimer(new Timer);
1733
1734- QTimer::singleShot(m_minimumAgeForOcclusion, this, [this]() {
1735- m_oldEnoughToBeOccluded = true;
1736- updateVisibility();
1737- });
1738+ m_requestedPosition.rx() = std::numeric_limits<int>::min();
1739+ m_requestedPosition.ry() = std::numeric_limits<int>::min();
1740 }
1741
1742 MirSurface::~MirSurface()
1743@@ -146,11 +210,6 @@
1744
1745 void MirSurface::onFramesPostedObserved()
1746 {
1747- if (!m_firstFrameDrawn) {
1748- m_firstFrameDrawn = true;
1749- Q_EMIT firstFrameDrawn();
1750- }
1751-
1752 // restart the frame dropper so that items have enough time to render the next frame.
1753 m_frameDropperTimer.start();
1754
1755@@ -164,14 +223,6 @@
1756 DEBUG_MSG << " type = " << mirSurfaceTypeToStr(state());
1757 Q_EMIT typeChanged(type());
1758 break;
1759- case mir_surface_attrib_state:
1760- DEBUG_MSG << " state = " << mirSurfaceStateToStr(state());
1761- Q_EMIT stateChanged(state());
1762- break;
1763- case mir_surface_attrib_visibility:
1764- DEBUG_MSG << " visible = " << visible();
1765- Q_EMIT visibleChanged(visible());
1766- break;
1767 default:
1768 break;
1769 }
1770@@ -179,7 +230,7 @@
1771
1772 Mir::Type MirSurface::type() const
1773 {
1774- switch (m_surface->type()) {
1775+ switch (m_type) {
1776 case mir_surface_type_normal:
1777 return Mir::NormalType;
1778
1779@@ -218,7 +269,7 @@
1780
1781 const void* const userId = (void*)123; // TODO: Multimonitor support
1782
1783- int framesPending = m_surface->buffers_ready_for_compositor(userId);
1784+ const int framesPending = m_surface->buffers_ready_for_compositor(userId);
1785 if (framesPending > 0) {
1786 m_textureUpdated = false;
1787
1788@@ -290,7 +341,7 @@
1789 texture->setBuffer(renderables[0]->buffer());
1790 ++m_currentFrameNumber;
1791
1792- if (texture->textureSize() != m_size) {
1793+ if (texture->textureSize() != size()) {
1794 m_size = texture->textureSize();
1795 QMetaObject::invokeMethod(this, "emitSizeChanged", Qt::QueuedConnection);
1796 }
1797@@ -325,6 +376,8 @@
1798 if (m_focused == value)
1799 return;
1800
1801+ DEBUG_MSG << "(" << value << ")";
1802+
1803 m_focused = value;
1804 Q_EMIT focusedChanged(value);
1805 }
1806@@ -358,17 +411,30 @@
1807 return;
1808 }
1809
1810+ // TODO Figure out what to do here
1811+ /*
1812 if (m_activelyFocusedViews.isEmpty()) {
1813 DEBUG_MSG << "() unfocused";
1814- m_shell->set_surface_attribute(m_session->session(), m_surface, mir_surface_attrib_focus, mir_surface_unfocused);
1815+ m_controller->setActiveFocus(m_window, false);
1816 } else {
1817 DEBUG_MSG << "() focused";
1818- m_shell->set_surface_attribute(m_session->session(), m_surface, mir_surface_attrib_focus, mir_surface_focused);
1819+ m_controller->setActiveFocus(m_window, true);
1820 }
1821+ */
1822
1823 m_neverSetSurfaceFocus = false;
1824 }
1825
1826+void MirSurface::updateVisible()
1827+{
1828+ const bool visible = !(m_state == Mir::HiddenState || m_state == Mir::MinimizedState) && m_surface->visible();
1829+
1830+ if (m_visible != visible) {
1831+ m_visible = visible;
1832+ Q_EMIT visibleChanged(visible);
1833+ }
1834+}
1835+
1836 void MirSurface::close()
1837 {
1838 if (m_closingState != NotClosing) {
1839@@ -381,8 +447,8 @@
1840 Q_EMIT closeRequested();
1841 m_closeTimer->start();
1842
1843- if (m_surface) {
1844- m_surface->request_client_surface_close();
1845+ if (m_window) {
1846+ m_controller->requestClose(m_window);
1847 }
1848 }
1849
1850@@ -393,19 +459,28 @@
1851 return;
1852 }
1853
1854- int mirWidth = m_surface->size().width.as_int();
1855- int mirHeight = m_surface->size().height.as_int();
1856-
1857- bool mirSizeIsDifferent = width != mirWidth || height != mirHeight;
1858+ bool mirSizeIsDifferent = width != m_size.width() || height != m_size.height();
1859
1860 if (mirSizeIsDifferent) {
1861- mir::geometry::Size newMirSize(width, height);
1862- m_surface->resize(newMirSize);
1863- DEBUG_MSG << " old (" << mirWidth << "," << mirHeight << ")"
1864+ m_controller->resize(m_window, QSize(width, height));
1865+ DEBUG_MSG << " old (" << m_size.width() << "," << m_size.height() << ")"
1866 << ", new (" << width << "," << height << ")";
1867 }
1868 }
1869
1870+QPoint MirSurface::position() const
1871+{
1872+ return m_position;
1873+}
1874+
1875+void MirSurface::setPosition(const QPoint newPosition)
1876+{
1877+ if (m_position != newPosition) {
1878+ m_position = newPosition;
1879+ Q_EMIT positionChanged(newPosition);
1880+ }
1881+}
1882+
1883 QSize MirSurface::size() const
1884 {
1885 return m_size;
1886@@ -413,26 +488,7 @@
1887
1888 Mir::State MirSurface::state() const
1889 {
1890- switch (m_surface->state()) {
1891- case mir_surface_state_unknown:
1892- return Mir::UnknownState;
1893- case mir_surface_state_restored:
1894- return Mir::RestoredState;
1895- case mir_surface_state_minimized:
1896- return Mir::MinimizedState;
1897- case mir_surface_state_maximized:
1898- return Mir::MaximizedState;
1899- case mir_surface_state_vertmaximized:
1900- return Mir::VertMaximizedState;
1901- case mir_surface_state_fullscreen:
1902- return Mir::FullscreenState;
1903- case mir_surface_state_horizmaximized:
1904- return Mir::HorizMaximizedState;
1905- case mir_surface_state_hidden:
1906- return Mir::HiddenState;
1907- default:
1908- return Mir::UnknownState;
1909- }
1910+ return m_state;
1911 }
1912
1913 Mir::OrientationAngle MirSurface::orientationAngle() const
1914@@ -477,54 +533,18 @@
1915
1916 QString MirSurface::name() const
1917 {
1918- return QString::fromStdString(m_surface->name());
1919+ return m_name;
1920 }
1921
1922 QString MirSurface::persistentId() const
1923 {
1924- return m_persistentId;
1925+ return m_extraInfo->persistentId;
1926 }
1927
1928-void MirSurface::setState(Mir::State qmlState)
1929+void MirSurface::requestState(Mir::State state)
1930 {
1931- int mirState;
1932-
1933- switch (qmlState) {
1934- default:
1935- case Mir::UnknownState:
1936- mirState = mir_surface_state_unknown;
1937- break;
1938-
1939- case Mir::RestoredState:
1940- mirState = mir_surface_state_restored;
1941- break;
1942-
1943- case Mir::MinimizedState:
1944- mirState = mir_surface_state_minimized;
1945- break;
1946-
1947- case Mir::MaximizedState:
1948- mirState = mir_surface_state_maximized;
1949- break;
1950-
1951- case Mir::VertMaximizedState:
1952- mirState = mir_surface_state_vertmaximized;
1953- break;
1954-
1955- case Mir::FullscreenState:
1956- mirState = mir_surface_state_fullscreen;
1957- break;
1958-
1959- case Mir::HorizMaximizedState:
1960- mirState = mir_surface_state_horizmaximized;
1961- break;
1962-
1963- case Mir::HiddenState:
1964- mirState = mir_surface_state_hidden;
1965- break;
1966- }
1967-
1968- m_shell->set_surface_attribute(m_session->session(), m_surface, mir_surface_attrib_state, mirState);
1969+ DEBUG_MSG << "(" << unityapiMirStateToStr(state) << ")";
1970+ m_controller->requestState(m_window, state);
1971 }
1972
1973 void MirSurface::setLive(bool value)
1974@@ -546,69 +566,78 @@
1975
1976 bool MirSurface::visible() const
1977 {
1978- return m_surface->query(mir_surface_attrib_visibility) == mir_surface_visibility_exposed;
1979+ return m_visible;
1980 }
1981-
1982+#include <mir_toolkit/event.h>
1983 void MirSurface::mousePressEvent(QMouseEvent *event)
1984 {
1985 auto ev = EventBuilder::instance()->reconstructMirEvent(event);
1986- m_surface->consume(ev.get());
1987+ auto ev1 = reinterpret_cast<MirPointerEvent const*>(ev.get());
1988+ m_controller->deliverPointerEvent(m_window, ev1);
1989 event->accept();
1990 }
1991
1992 void MirSurface::mouseMoveEvent(QMouseEvent *event)
1993 {
1994 auto ev = EventBuilder::instance()->reconstructMirEvent(event);
1995- m_surface->consume(ev.get());
1996+ auto ev1 = reinterpret_cast<MirPointerEvent const*>(ev.get());
1997+ m_controller->deliverPointerEvent(m_window, ev1);
1998 event->accept();
1999 }
2000
2001 void MirSurface::mouseReleaseEvent(QMouseEvent *event)
2002 {
2003 auto ev = EventBuilder::instance()->reconstructMirEvent(event);
2004- m_surface->consume(ev.get());
2005+ auto ev1 = reinterpret_cast<MirPointerEvent const*>(ev.get());
2006+ m_controller->deliverPointerEvent(m_window, ev1);
2007 event->accept();
2008 }
2009
2010 void MirSurface::hoverEnterEvent(QHoverEvent *event)
2011 {
2012 auto ev = EventBuilder::instance()->reconstructMirEvent(event);
2013- m_surface->consume(ev.get());
2014+ auto ev1 = reinterpret_cast<MirPointerEvent const*>(ev.get());
2015+ m_controller->deliverPointerEvent(m_window, ev1);
2016 event->accept();
2017 }
2018
2019 void MirSurface::hoverLeaveEvent(QHoverEvent *event)
2020 {
2021 auto ev = EventBuilder::instance()->reconstructMirEvent(event);
2022- m_surface->consume(ev.get());
2023+ auto ev1 = reinterpret_cast<MirPointerEvent const*>(ev.get());
2024+ m_controller->deliverPointerEvent(m_window, ev1);
2025 event->accept();
2026 }
2027
2028 void MirSurface::hoverMoveEvent(QHoverEvent *event)
2029 {
2030 auto ev = EventBuilder::instance()->reconstructMirEvent(event);
2031- m_surface->consume(ev.get());
2032+ auto ev1 = reinterpret_cast<MirPointerEvent const*>(ev.get());
2033+ m_controller->deliverPointerEvent(m_window, ev1);
2034 event->accept();
2035 }
2036
2037 void MirSurface::wheelEvent(QWheelEvent *event)
2038 {
2039 auto ev = EventBuilder::instance()->makeMirEvent(event);
2040- m_surface->consume(ev.get());
2041+ auto ev1 = reinterpret_cast<MirPointerEvent const*>(ev.get());
2042+ m_controller->deliverPointerEvent(m_window, ev1);
2043 event->accept();
2044 }
2045
2046 void MirSurface::keyPressEvent(QKeyEvent *qtEvent)
2047 {
2048 auto ev = EventBuilder::instance()->makeMirEvent(qtEvent);
2049- m_surface->consume(ev.get());
2050+ auto ev1 = reinterpret_cast<MirKeyboardEvent const*>(ev.get());
2051+ m_controller->deliverKeyboardEvent(m_window, ev1);
2052 qtEvent->accept();
2053 }
2054
2055 void MirSurface::keyReleaseEvent(QKeyEvent *qtEvent)
2056 {
2057 auto ev = EventBuilder::instance()->makeMirEvent(qtEvent);
2058- m_surface->consume(ev.get());
2059+ auto ev1 = reinterpret_cast<MirKeyboardEvent const*>(ev.get());
2060+ m_controller->deliverKeyboardEvent(m_window, ev1);
2061 qtEvent->accept();
2062 }
2063
2064@@ -618,15 +647,16 @@
2065 ulong timestamp)
2066 {
2067 auto ev = EventBuilder::instance()->makeMirEvent(mods, touchPoints, touchPointStates, timestamp);
2068- m_surface->consume(ev.get());
2069+ auto ev1 = reinterpret_cast<MirTouchEvent const*>(ev.get());
2070+ m_controller->deliverTouchEvent(m_window, ev1);
2071 }
2072
2073 bool MirSurface::clientIsRunning() const
2074 {
2075 return (m_session &&
2076- (m_session->state() == Session::State::Running
2077- || m_session->state() == Session::State::Starting
2078- || m_session->state() == Session::State::Suspending))
2079+ (m_session->state() == SessionInterface::State::Running
2080+ || m_session->state() == SessionInterface::State::Starting
2081+ || m_session->state() == SessionInterface::State::Suspending))
2082 || !m_session;
2083 }
2084
2085@@ -654,39 +684,40 @@
2086 deleteLater();
2087 }
2088 }
2089- updateVisibility();
2090+ updateExposure();
2091 setViewActiveFocus(viewId, false);
2092 }
2093
2094-void MirSurface::setViewVisibility(qintptr viewId, bool visible)
2095+void MirSurface::setViewExposure(qintptr viewId, bool exposed)
2096 {
2097 if (!m_views.contains(viewId)) return;
2098
2099- m_views[viewId].visible = visible;
2100- updateVisibility();
2101+ m_views[viewId].exposed = exposed;
2102+ updateExposure();
2103 }
2104
2105-void MirSurface::updateVisibility()
2106+void MirSurface::updateExposure()
2107 {
2108- bool newVisible = false;
2109-
2110- if (m_oldEnoughToBeOccluded) {
2111- QHashIterator<qintptr, View> i(m_views);
2112- while (i.hasNext()) {
2113- i.next();
2114- newVisible |= i.value().visible;
2115- }
2116- } else {
2117- // Surface is too young to get occluded. Let it remain exposed for a bit to ensure that it displays
2118- // a properly formed UI on start up.
2119- newVisible = true;
2120- }
2121-
2122- if (newVisible != visible()) {
2123- DEBUG_MSG << "(" << newVisible << ")";
2124+ // Only update exposure after client has swapped a frame (aka surface is "ready"). MirAL only considers
2125+ // a surface visible after it has drawn something
2126+ if (!m_ready) {
2127+ return;
2128+ }
2129+
2130+ bool newExposed = false;
2131+ QHashIterator<qintptr, View> i(m_views);
2132+ while (i.hasNext()) {
2133+ i.next();
2134+ newExposed |= i.value().exposed;
2135+ }
2136+
2137+ const bool oldExposed = (m_surface->query(mir_surface_attrib_visibility) == mir_surface_visibility_exposed);
2138+
2139+ if (newExposed != oldExposed) {
2140+ DEBUG_MSG << "(" << newExposed << ")";
2141
2142 m_surface->configure(mir_surface_attrib_visibility,
2143- newVisible ? mir_surface_visibility_exposed : mir_surface_visibility_occluded);
2144+ newExposed ? mir_surface_visibility_exposed : mir_surface_visibility_occluded);
2145 }
2146 }
2147
2148@@ -777,15 +808,6 @@
2149 }
2150 }
2151
2152-void MirSurface::setScreen(QScreen *screen)
2153-{
2154- using namespace mir::geometry;
2155- // in Mir, this means moving the surface in Mir's scene to the matching display
2156- auto targetScreenTopLeftPx = screen->geometry().topLeft(); // * screen->devicePixelRatio(); GERRY?
2157- DEBUG_MSG << "moved to" << targetScreenTopLeftPx << "px";
2158- m_surface->move_to(Point{ X{targetScreenTopLeftPx.x()}, Y{targetScreenTopLeftPx.y()} });
2159-}
2160-
2161 bool MirSurface::inputAreaContains(const QPoint &point) const
2162 {
2163 bool result;
2164@@ -804,6 +826,30 @@
2165 return result;
2166 }
2167
2168+void MirSurface::updateState(Mir::State newState)
2169+{
2170+ if (newState == m_state) {
2171+ return;
2172+ }
2173+ DEBUG_MSG << "(" << unityapiMirStateToStr(newState) << ")";
2174+
2175+ m_state = newState;
2176+ Q_EMIT stateChanged(state());
2177+
2178+ // Mir determines visibility from the state, it may have changed
2179+ updateVisible();
2180+}
2181+
2182+void MirSurface::setReady()
2183+{
2184+ if (!m_ready) {
2185+ DEBUG_MSG << "()";
2186+ m_ready = true;
2187+ Q_EMIT ready();
2188+ updateExposure();
2189+ }
2190+}
2191+
2192 void MirSurface::setCursor(const QCursor &cursor)
2193 {
2194 DEBUG_MSG << "(" << qtCursorShapeToStr(cursor.shape()) << ")";
2195@@ -814,80 +860,32 @@
2196
2197 int MirSurface::minimumWidth() const
2198 {
2199- return m_minimumWidth;
2200+ return m_minWidth;
2201 }
2202
2203 int MirSurface::minimumHeight() const
2204 {
2205- return m_minimumHeight;
2206+ return m_minHeight;
2207 }
2208
2209 int MirSurface::maximumWidth() const
2210 {
2211- return m_maximumWidth;
2212+ return m_maxWidth;
2213 }
2214
2215 int MirSurface::maximumHeight() const
2216 {
2217- return m_maximumHeight;
2218+ return m_maxHeight;
2219 }
2220
2221 int MirSurface::widthIncrement() const
2222 {
2223- return m_widthIncrement;
2224+ return m_incWidth;
2225 }
2226
2227 int MirSurface::heightIncrement() const
2228 {
2229- return m_heightIncrement;
2230-}
2231-
2232-void MirSurface::setMinimumWidth(int value)
2233-{
2234- if (value != m_minimumWidth) {
2235- m_minimumWidth = value;
2236- Q_EMIT minimumWidthChanged(value);
2237- }
2238-}
2239-
2240-void MirSurface::setMinimumHeight(int value)
2241-{
2242- if (value != m_minimumHeight) {
2243- m_minimumHeight = value;
2244- Q_EMIT minimumHeightChanged(value);
2245- }
2246-}
2247-
2248-void MirSurface::setMaximumWidth(int value)
2249-{
2250- if (value != m_maximumWidth) {
2251- m_maximumWidth = value;
2252- Q_EMIT maximumWidthChanged(value);
2253- }
2254-}
2255-
2256-void MirSurface::setMaximumHeight(int value)
2257-{
2258- if (value != m_maximumHeight) {
2259- m_maximumHeight = value;
2260- Q_EMIT maximumHeightChanged(value);
2261- }
2262-}
2263-
2264-void MirSurface::setWidthIncrement(int value)
2265-{
2266- if (value != m_widthIncrement) {
2267- m_widthIncrement = value;
2268- Q_EMIT widthIncrementChanged(value);
2269- }
2270-}
2271-
2272-void MirSurface::setHeightIncrement(int value)
2273-{
2274- if (value != m_heightIncrement) {
2275- m_heightIncrement = value;
2276- Q_EMIT heightIncrementChanged(value);
2277- }
2278+ return m_incHeight;
2279 }
2280
2281 bool MirSurface::focused() const
2282@@ -905,16 +903,12 @@
2283 return m_surface->confine_pointer_state() == mir_pointer_confined_to_surface;
2284 }
2285
2286-void MirSurface::requestFocus()
2287-{
2288- DEBUG_MSG << "()";
2289- Q_EMIT focusRequested();
2290-}
2291-
2292-void MirSurface::raise()
2293-{
2294- DEBUG_MSG << "()";
2295- Q_EMIT raiseRequested();
2296+void MirSurface::activate()
2297+{
2298+ DEBUG_MSG << "()";
2299+ if (m_live) {
2300+ m_controller->activate(m_window);
2301+ }
2302 }
2303
2304 void MirSurface::onCloseTimedOut()
2305@@ -925,7 +919,9 @@
2306
2307 m_closingState = CloseOverdue;
2308
2309- m_session->session()->destroy_surface(m_surface);
2310+ if (m_live) {
2311+ m_controller->forceClose(m_window);
2312+ }
2313 }
2314
2315 void MirSurface::setCloseTimer(AbstractTimer *timer)
2316@@ -947,6 +943,11 @@
2317 }
2318 }
2319
2320+std::shared_ptr<SurfaceObserver> MirSurface::surfaceObserver() const
2321+{
2322+ return m_surfaceObserver;
2323+}
2324+
2325 void MirSurface::setInputBounds(const QRect &rect)
2326 {
2327 if (m_inputBounds != rect) {
2328@@ -955,3 +956,230 @@
2329 Q_EMIT inputBoundsChanged(m_inputBounds);
2330 }
2331 }
2332+
2333+QPoint MirSurface::requestedPosition() const
2334+{
2335+ return m_requestedPosition;
2336+}
2337+
2338+void MirSurface::setRequestedPosition(const QPoint &point)
2339+{
2340+ if (point != m_requestedPosition) {
2341+ m_requestedPosition = point;
2342+ Q_EMIT requestedPositionChanged(m_requestedPosition);
2343+
2344+ if (m_live) {
2345+ m_controller->move(m_window, m_requestedPosition);
2346+ }
2347+ }
2348+}
2349+
2350+void MirSurface::onMinimumWidthChanged(int minWidth)
2351+{
2352+ if (m_minWidth != minWidth)
2353+ {
2354+ m_minWidth = minWidth;
2355+ Q_EMIT minimumWidthChanged(minWidth);
2356+ }
2357+}
2358+
2359+void MirSurface::onMinimumHeightChanged(int minHeight)
2360+{
2361+ if (m_minHeight != minHeight)
2362+ {
2363+ m_minHeight = minHeight;
2364+ Q_EMIT minimumHeightChanged(minHeight);
2365+ }
2366+}
2367+
2368+void MirSurface::onMaximumWidthChanged(int maxWidth)
2369+{
2370+ if (m_maxWidth != maxWidth)
2371+ {
2372+ m_maxWidth = maxWidth;
2373+ Q_EMIT maximumWidthChanged(maxWidth);
2374+ }
2375+}
2376+
2377+void MirSurface::onMaximumHeightChanged(int maxHeight)
2378+{
2379+ if (m_maxHeight != maxHeight)
2380+ {
2381+ m_maxHeight = maxHeight;
2382+ Q_EMIT maximumHeightChanged(maxHeight);
2383+ }
2384+}
2385+
2386+void MirSurface::onWidthIncrementChanged(int incWidth)
2387+{
2388+ if (m_incWidth != incWidth)
2389+ {
2390+ m_incWidth = incWidth;
2391+ Q_EMIT widthIncrementChanged(incWidth);
2392+ }
2393+}
2394+
2395+void MirSurface::onHeightIncrementChanged(int incHeight)
2396+{
2397+ if (m_incHeight != incHeight)
2398+ {
2399+ m_incHeight = incHeight;
2400+ Q_EMIT heightIncrementChanged(incHeight);
2401+ }
2402+}
2403+
2404+void MirSurface::onNameChanged(const QString &name)
2405+{
2406+ if (m_name != name)
2407+ {
2408+ m_name = name;
2409+ Q_EMIT nameChanged(name);
2410+ }
2411+}
2412+
2413+MirSurface::SurfaceObserverImpl::SurfaceObserverImpl()
2414+ : m_listener(nullptr)
2415+ , m_framesPosted(false)
2416+{
2417+ m_cursorNameToShape["left_ptr"] = Qt::ArrowCursor;
2418+ m_cursorNameToShape["up_arrow"] = Qt::UpArrowCursor;
2419+ m_cursorNameToShape["cross"] = Qt::CrossCursor;
2420+ m_cursorNameToShape["watch"] = Qt::WaitCursor;
2421+ m_cursorNameToShape["xterm"] = Qt::IBeamCursor;
2422+ m_cursorNameToShape["size_ver"] = Qt::SizeVerCursor;
2423+ m_cursorNameToShape["size_hor"] = Qt::SizeHorCursor;
2424+ m_cursorNameToShape["size_bdiag"] = Qt::SizeBDiagCursor;
2425+ m_cursorNameToShape["size_fdiag"] = Qt::SizeFDiagCursor;
2426+ m_cursorNameToShape["size_all"] = Qt::SizeAllCursor;
2427+ m_cursorNameToShape["blank"] = Qt::BlankCursor;
2428+ m_cursorNameToShape["split_v"] = Qt::SplitVCursor;
2429+ m_cursorNameToShape["split_h"] = Qt::SplitHCursor;
2430+ m_cursorNameToShape["hand"] = Qt::PointingHandCursor;
2431+ m_cursorNameToShape["forbidden"] = Qt::ForbiddenCursor;
2432+ m_cursorNameToShape["whats_this"] = Qt::WhatsThisCursor;
2433+ m_cursorNameToShape["left_ptr_watch"] = Qt::BusyCursor;
2434+ m_cursorNameToShape["openhand"] = Qt::OpenHandCursor;
2435+ m_cursorNameToShape["closedhand"] = Qt::ClosedHandCursor;
2436+ m_cursorNameToShape["dnd-copy"] = Qt::DragCopyCursor;
2437+ m_cursorNameToShape["dnd-move"] = Qt::DragMoveCursor;
2438+ m_cursorNameToShape["dnd-link"] = Qt::DragLinkCursor;
2439+
2440+ // Used by Mir client API (mir_*_cursor_name strings)
2441+ m_cursorNameToShape["default"] = Qt::ArrowCursor;
2442+ m_cursorNameToShape["disabled"] = Qt::BlankCursor;
2443+ m_cursorNameToShape["arrow"] = Qt::ArrowCursor;
2444+ m_cursorNameToShape["busy"] = Qt::WaitCursor;
2445+ m_cursorNameToShape["caret"] = Qt::IBeamCursor;
2446+ m_cursorNameToShape["pointing-hand"] = Qt::PointingHandCursor;
2447+ m_cursorNameToShape["open-hand"] = Qt::OpenHandCursor;
2448+ m_cursorNameToShape["closed-hand"] = Qt::ClosedHandCursor;
2449+ m_cursorNameToShape["horizontal-resize"] = Qt::SizeHorCursor;
2450+ m_cursorNameToShape["vertical-resize"] = Qt::SizeVerCursor;
2451+ m_cursorNameToShape["diagonal-resize-bottom-to-top"] = Qt::SizeBDiagCursor;
2452+ m_cursorNameToShape["diagonal-resize-top_to_bottom"] = Qt::SizeFDiagCursor; // current string with typo
2453+ m_cursorNameToShape["diagonal-resize-top-to-bottom"] = Qt::SizeFDiagCursor; // how it will be when they fix it (if ever)
2454+ m_cursorNameToShape["omnidirectional-resize"] = Qt::SizeAllCursor;
2455+ m_cursorNameToShape["vsplit-resize"] = Qt::SplitVCursor;
2456+ m_cursorNameToShape["hsplit-resize"] = Qt::SplitHCursor;
2457+ m_cursorNameToShape["crosshair"] = Qt::CrossCursor;
2458+
2459+ qRegisterMetaType<MirShellChrome>("MirShellChrome");
2460+}
2461+
2462+MirSurface::SurfaceObserverImpl::~SurfaceObserverImpl()
2463+{
2464+}
2465+
2466+void MirSurface::SurfaceObserverImpl::setListener(QObject *listener)
2467+{
2468+ m_listener = listener;
2469+ if (m_framesPosted) {
2470+ Q_EMIT framesPosted();
2471+ }
2472+}
2473+
2474+void MirSurface::SurfaceObserverImpl::frame_posted(int /*frames_available*/, mir::geometry::Size const& /*size*/)
2475+{
2476+ m_framesPosted = true;
2477+ if (m_listener) {
2478+ Q_EMIT framesPosted();
2479+ }
2480+}
2481+
2482+void MirSurface::SurfaceObserverImpl::renamed(char const * name)
2483+{
2484+ Q_EMIT nameChanged(QString::fromUtf8(name));
2485+}
2486+
2487+void MirSurface::SurfaceObserverImpl::cursor_image_removed()
2488+{
2489+ Q_EMIT cursorChanged(QCursor());
2490+}
2491+
2492+#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 25, 0)
2493+void MirSurface::SurfaceObserverImpl::placed_relative(mir::geometry::Rectangle const& /*placement*/)
2494+{
2495+}
2496+#endif
2497+
2498+void MirSurface::SurfaceObserverImpl::attrib_changed(MirSurfaceAttrib attribute, int value)
2499+{
2500+ if (m_listener) {
2501+ Q_EMIT attributeChanged(attribute, value);
2502+ }
2503+}
2504+
2505+void MirSurface::SurfaceObserverImpl::resized_to(mir::geometry::Size const&size)
2506+{
2507+ Q_EMIT resized(QSize(size.width.as_int(), size.height.as_int()));
2508+}
2509+
2510+void MirSurface::SurfaceObserverImpl::cursor_image_set_to(const mir::graphics::CursorImage &cursorImage)
2511+{
2512+ QCursor qcursor = createQCursorFromMirCursorImage(cursorImage);
2513+ Q_EMIT cursorChanged(qcursor);
2514+}
2515+
2516+void MirSurface::SurfaceObserverImpl::keymap_changed(MirInputDeviceId, const std::string &, const std::string &layout,
2517+ const std::string &variant, const std::string &)
2518+{
2519+ Q_EMIT keymapChanged(QString::fromStdString(layout), QString::fromStdString(variant));
2520+}
2521+
2522+QCursor MirSurface::SurfaceObserverImpl::createQCursorFromMirCursorImage(const mir::graphics::CursorImage &cursorImage) {
2523+ if (cursorImage.as_argb_8888() == nullptr) {
2524+ // Must be a named cursor
2525+ auto namedCursor = dynamic_cast<const qtmir::NamedCursor*>(&cursorImage);
2526+ Q_ASSERT(namedCursor != nullptr);
2527+ if (namedCursor) {
2528+ // NB: If we need a named cursor not covered by Qt::CursorShape, we won't be able to
2529+ // used Qt's cursor API anymore for transmitting MirSurface's cursor image.
2530+
2531+ Qt::CursorShape cursorShape = Qt::ArrowCursor;
2532+ {
2533+ auto iterator = m_cursorNameToShape.constFind(namedCursor->name());
2534+ if (iterator == m_cursorNameToShape.constEnd()) {
2535+ qCWarning(QTMIR_SURFACES).nospace() << "SurfaceObserver: unrecognized cursor name "
2536+ << namedCursor->name();
2537+ } else {
2538+ cursorShape = iterator.value();
2539+ }
2540+ }
2541+ return QCursor(cursorShape);
2542+ } else {
2543+ // shouldn't happen
2544+ return QCursor();
2545+ }
2546+ } else {
2547+ QImage image((const uchar*)cursorImage.as_argb_8888(),
2548+ cursorImage.size().width.as_int(), cursorImage.size().height.as_int(), QImage::Format_ARGB32);
2549+
2550+ return QCursor(QPixmap::fromImage(image), cursorImage.hotspot().dx.as_int(), cursorImage.hotspot().dy.as_int());
2551+ }
2552+}
2553+
2554+void MirSurface::requestFocus()
2555+{
2556+ DEBUG_MSG << "()";
2557+ Q_EMIT focusRequested();
2558+}
2559
2560=== modified file 'src/modules/Unity/Application/mirsurface.h'
2561--- src/modules/Unity/Application/mirsurface.h 2016-10-11 20:50:50 +0000
2562+++ src/modules/Unity/Application/mirsurface.h 2016-12-01 11:46:42 +0000
2563@@ -22,45 +22,37 @@
2564
2565 // Qt
2566 #include <QCursor>
2567-#include <QElapsedTimer>
2568 #include <QMutex>
2569 #include <QPointer>
2570 #include <QRect>
2571 #include <QSharedPointer>
2572 #include <QWeakPointer>
2573 #include <QSet>
2574+#include <QTimer>
2575
2576 #include "mirbuffersgtexture.h"
2577-#include "session.h"
2578-
2579-// mirserver
2580-#include "creationhints.h"
2581+#include "windowcontrollerinterface.h"
2582+#include "windowmodelnotifier.h"
2583
2584 // mir
2585 #include <mir_toolkit/common.h>
2586
2587-namespace mir {
2588-namespace shell { class Shell; }
2589-namespace scene {class Surface; }
2590-}
2591
2592 class SurfaceObserver;
2593
2594 namespace qtmir {
2595
2596 class AbstractTimer;
2597+class SessionInterface;
2598
2599 class MirSurface : public MirSurfaceInterface
2600 {
2601 Q_OBJECT
2602
2603 public:
2604- MirSurface(std::shared_ptr<mir::scene::Surface> surface,
2605- const QString& persistentId,
2606- SessionInterface* session,
2607- mir::shell::Shell *shell,
2608- std::shared_ptr<SurfaceObserver> observer,
2609- const CreationHints &);
2610+ MirSurface(NewWindow windowInfo,
2611+ WindowControllerInterface *controller,
2612+ SessionInterface *session = nullptr);
2613 virtual ~MirSurface();
2614
2615 ////
2616@@ -74,10 +66,14 @@
2617
2618 QSize size() const override;
2619 void resize(int width, int height) override;
2620- void resize(const QSize &size) override { resize(size.width(), size.height()); }
2621+ Q_INVOKABLE void resize(const QSize &size) override { resize(size.width(), size.height()); }
2622+
2623+ QPoint position() const override;
2624+
2625+ QPoint requestedPosition() const override;
2626+ void setRequestedPosition(const QPoint &) override;
2627
2628 Mir::State state() const override;
2629- void setState(Mir::State qmlState) override;
2630
2631 bool live() const override;
2632
2633@@ -98,16 +94,15 @@
2634
2635 bool confinesMousePointer() const override;
2636
2637- Q_INVOKABLE void requestFocus() override;
2638+ Q_INVOKABLE void activate() override;
2639 Q_INVOKABLE void close() override;
2640- Q_INVOKABLE void raise() override;
2641
2642 ////
2643 // qtmir::MirSurfaceInterface
2644
2645 void setLive(bool value) override;
2646
2647- bool isFirstFrameDrawn() const override { return m_firstFrameDrawn; }
2648+ bool isReady() const override { return m_ready; }
2649
2650 void stopFrameDropper() override;
2651 void startFrameDropper() override;
2652@@ -116,7 +111,7 @@
2653
2654 void registerView(qintptr viewId) override;
2655 void unregisterView(qintptr viewId) override;
2656- void setViewVisibility(qintptr viewId, bool visible) override;
2657+ void setViewExposure(qintptr viewId, bool exposed) override;
2658
2659 // methods called from the rendering (scene graph) thread:
2660 QSharedPointer<QSGTexture> texture() override;
2661@@ -156,27 +151,31 @@
2662
2663 Mir::ShellChrome shellChrome() const override;
2664
2665- void setScreen(QScreen *screen) override;
2666-
2667 SessionInterface* session() override { return m_session.data(); }
2668
2669 bool inputAreaContains(const QPoint &) const override;
2670
2671+ void requestFocus() override;
2672+
2673 ////
2674 // Own API
2675+ void setPosition(const QPoint newPosition);
2676+ void updateState(Mir::State state);
2677+ void setReady();
2678+ miral::Window window() const { return m_window; }
2679
2680 // useful for tests
2681 void setCloseTimer(AbstractTimer *timer);
2682+ std::shared_ptr<SurfaceObserver> surfaceObserver() const;
2683
2684 public Q_SLOTS:
2685+ ////
2686+ // unity::shell::application::MirSurfaceInterface
2687+ void requestState(Mir::State qmlState) override;
2688+
2689+ ////
2690+ // qtmir::MirSurfaceInterface
2691 void onCompositorSwappedBuffers() override;
2692-
2693- void setMinimumWidth(int) override;
2694- void setMinimumHeight(int) override;
2695- void setMaximumWidth(int) override;
2696- void setMaximumHeight(int) override;
2697- void setWidthIncrement(int) override;
2698- void setHeightIncrement(int) override;
2699 void setShellChrome(Mir::ShellChrome shellChrome) override;
2700
2701 private Q_SLOTS:
2702@@ -192,15 +191,32 @@
2703 private:
2704 void syncSurfaceSizeWithItemSize();
2705 bool clientIsRunning() const;
2706- void updateVisibility();
2707+ void updateExposure();
2708 void applyKeymap();
2709 void updateActiveFocus();
2710-
2711- std::shared_ptr<mir::scene::Surface> m_surface;
2712+ void updateVisible();
2713+ void onNameChanged(const QString &name);
2714+ void onMinimumWidthChanged(int minWidth);
2715+ void onMinimumHeightChanged(int minHeight);
2716+ void onMaximumWidthChanged(int maxWidth);
2717+ void onMaximumHeightChanged(int maxHeight);
2718+ void onWidthIncrementChanged(int incWidth);
2719+ void onHeightIncrementChanged(int incHeight);
2720+
2721+ const miral::Window m_window;
2722+ const std::shared_ptr<ExtraWindowInfo> m_extraInfo;
2723+ QString m_name;
2724+ MirSurfaceType m_type;
2725+ int m_minWidth;
2726+ int m_minHeight;
2727+ int m_maxWidth;
2728+ int m_maxHeight;
2729+ int m_incWidth;
2730+ int m_incHeight;
2731+
2732+ const std::shared_ptr<mir::scene::Surface> m_surface; // keep copy of the Surface for lifecycle
2733 QPointer<SessionInterface> m_session;
2734- mir::shell::Shell *const m_shell;
2735- QString m_persistentId;
2736- bool m_firstFrameDrawn;
2737+ WindowControllerInterface *const m_controller;
2738
2739 //FIXME - have to save the state as Mir has no getter for it (bug:1357429)
2740 Mir::OrientationAngle m_orientationAngle;
2741@@ -214,31 +230,30 @@
2742 bool m_textureUpdated;
2743 unsigned int m_currentFrameNumber;
2744
2745+ bool m_ready{false};
2746+ bool m_visible;
2747 bool m_live;
2748 struct View {
2749- bool visible;
2750+ bool exposed;
2751 };
2752 QHash<qintptr, View> m_views;
2753
2754 QSet<qintptr> m_activelyFocusedViews;
2755 bool m_neverSetSurfaceFocus{true};
2756
2757- std::shared_ptr<SurfaceObserver> m_surfaceObserver;
2758+ class SurfaceObserverImpl;
2759+ std::shared_ptr<SurfaceObserverImpl> m_surfaceObserver;
2760
2761+ QPoint m_position;
2762+ QPoint m_requestedPosition;
2763 QSize m_size;
2764+ QSize m_pendingResize;
2765 QString m_keymap;
2766
2767 QCursor m_cursor;
2768+ Mir::State m_state; // FIXME: remove when Mir gains additional window states to match Mir::State
2769 Mir::ShellChrome m_shellChrome;
2770
2771- int m_minimumWidth{0};
2772- int m_minimumHeight{0};
2773- int m_maximumWidth{0};
2774- int m_maximumHeight{0};
2775- int m_widthIncrement{0};
2776- int m_heightIncrement{0};
2777- QSize m_pendingResize;
2778-
2779 QRect m_inputBounds;
2780
2781 bool m_focused{false};
2782@@ -250,11 +265,6 @@
2783 };
2784 ClosingState m_closingState{NotClosing};
2785 AbstractTimer *m_closeTimer{nullptr};
2786-
2787- // TODO: Make it configurable, exposing it as a QML property to shell.
2788- // In milliseconds.
2789- const int m_minimumAgeForOcclusion{10000};
2790- bool m_oldEnoughToBeOccluded{false};
2791 };
2792
2793 } // namespace qtmir
2794
2795=== modified file 'src/modules/Unity/Application/mirsurfaceinterface.h'
2796--- src/modules/Unity/Application/mirsurfaceinterface.h 2016-07-05 12:41:04 +0000
2797+++ src/modules/Unity/Application/mirsurfaceinterface.h 2016-12-01 11:46:42 +0000
2798@@ -24,6 +24,7 @@
2799
2800 // Qt
2801 #include <QCursor>
2802+#include <QPoint>
2803 #include <QSharedPointer>
2804 #include <QTouchEvent>
2805
2806@@ -44,7 +45,7 @@
2807
2808 virtual void setLive(bool value) = 0;
2809
2810- virtual bool isFirstFrameDrawn() const = 0;
2811+ virtual bool isReady() const = 0;
2812
2813 virtual void stopFrameDropper() = 0;
2814 virtual void startFrameDropper() = 0;
2815@@ -53,7 +54,7 @@
2816
2817 virtual void registerView(qintptr viewId) = 0;
2818 virtual void unregisterView(qintptr viewId) = 0;
2819- virtual void setViewVisibility(qintptr viewId, bool visible) = 0;
2820+ virtual void setViewExposure(qintptr viewId, bool exposed) = 0;
2821
2822 // methods called from the rendering (scene graph) thread:
2823 virtual QSharedPointer<QSGTexture> texture() = 0;
2824@@ -102,28 +103,21 @@
2825
2826 virtual QCursor cursor() const = 0;
2827
2828- virtual void setScreen(QScreen *screen) = 0;
2829-
2830 virtual SessionInterface* session() = 0;
2831
2832 virtual bool inputAreaContains(const QPoint &) const = 0;
2833
2834+ virtual void requestFocus() = 0;
2835+
2836 public Q_SLOTS:
2837 virtual void onCompositorSwappedBuffers() = 0;
2838
2839- virtual void setMinimumWidth(int) = 0;
2840- virtual void setMinimumHeight(int) = 0;
2841- virtual void setMaximumWidth(int) = 0;
2842- virtual void setMaximumHeight(int) = 0;
2843- virtual void setWidthIncrement(int) = 0;
2844- virtual void setHeightIncrement(int) = 0;
2845 virtual void setShellChrome(Mir::ShellChrome shellChrome) = 0;
2846
2847 Q_SIGNALS:
2848+ void ready();
2849 void cursorChanged(const QCursor &cursor);
2850 void raiseRequested();
2851- void closeRequested();
2852- void firstFrameDrawn();
2853 void framesPosted();
2854 void isBeingDisplayedChanged();
2855 void frameDropped();
2856
2857=== modified file 'src/modules/Unity/Application/mirsurfaceitem.cpp'
2858--- src/modules/Unity/Application/mirsurfaceitem.cpp 2016-07-15 15:38:04 +0000
2859+++ src/modules/Unity/Application/mirsurfaceitem.cpp 2016-12-01 11:46:42 +0000
2860@@ -18,7 +18,6 @@
2861 #include "application.h"
2862 #include "session.h"
2863 #include "mirsurfaceitem.h"
2864-#include "mirfocuscontroller.h"
2865 #include "logging.h"
2866 #include "tracepoints.h" // generated from tracepoints.tp
2867 #include "timestamp.h"
2868@@ -104,18 +103,10 @@
2869 connect(&m_updateMirSurfaceSizeTimer, &QTimer::timeout, this, &MirSurfaceItem::updateMirSurfaceSize);
2870
2871 connect(this, &QQuickItem::activeFocusChanged, this, &MirSurfaceItem::updateMirSurfaceActiveFocus);
2872- connect(this, &QQuickItem::visibleChanged, this, &MirSurfaceItem::updateMirSurfaceVisibility);
2873+ connect(this, &QQuickItem::visibleChanged, this, &MirSurfaceItem::updateMirSurfaceExposure);
2874 connect(this, &QQuickItem::windowChanged, this, &MirSurfaceItem::onWindowChanged);
2875 }
2876
2877-void MirSurfaceItem::componentComplete()
2878-{
2879- QQuickItem::componentComplete();
2880- if (window()) {
2881- updateScreen(window()->screen());
2882- }
2883-}
2884-
2885 MirSurfaceItem::~MirSurfaceItem()
2886 {
2887 qCDebug(QTMIR_SURFACES) << "MirSurfaceItem::~MirSurfaceItem - this=" << this;
2888@@ -492,13 +483,6 @@
2889 }
2890 }
2891
2892-void MirSurfaceItem::setSurfaceState(Mir::State state)
2893-{
2894- if (m_surface) {
2895- m_surface->setState(state);
2896- }
2897-}
2898-
2899 void MirSurfaceItem::scheduleMirSurfaceSizeUpdate()
2900 {
2901 if (!m_updateMirSurfaceSizeTimer.isActive()) {
2902@@ -519,13 +503,13 @@
2903 m_surface->resize(width, height);
2904 }
2905
2906-void MirSurfaceItem::updateMirSurfaceVisibility()
2907+void MirSurfaceItem::updateMirSurfaceExposure()
2908 {
2909 if (!m_surface || !m_surface->live()) {
2910 return;
2911 }
2912
2913- m_surface->setViewVisibility((qintptr)this, isVisible());
2914+ m_surface->setViewExposure((qintptr)this, isVisible());
2915 }
2916
2917 void MirSurfaceItem::updateMirSurfaceActiveFocus()
2918@@ -628,10 +612,7 @@
2919
2920 updateMirSurfaceSize();
2921 setImplicitSize(m_surface->size().width(), m_surface->size().height());
2922- updateMirSurfaceVisibility();
2923- if (window()) {
2924- updateScreen(window()->screen());
2925- }
2926+ updateMirSurfaceExposure();
2927
2928 // Qt::ArrowCursor is the default when no cursor has been explicitly set, so no point forwarding it.
2929 if (m_surface->cursor().shape() != Qt::ArrowCursor) {
2930@@ -672,16 +653,6 @@
2931 if (m_window) {
2932 connect(m_window, &QQuickWindow::frameSwapped, this, &MirSurfaceItem::onCompositorSwappedBuffers,
2933 Qt::DirectConnection);
2934-
2935- updateScreen(m_window->screen());
2936- connect(m_window, &QQuickWindow::screenChanged, this, &MirSurfaceItem::updateScreen);
2937- }
2938-}
2939-
2940-void MirSurfaceItem::updateScreen(QScreen *screen)
2941-{
2942- if (screen && m_surface) {
2943- m_surface->setScreen(screen);
2944 }
2945 }
2946
2947
2948=== modified file 'src/modules/Unity/Application/mirsurfaceitem.h'
2949--- src/modules/Unity/Application/mirsurfaceitem.h 2016-07-15 15:38:04 +0000
2950+++ src/modules/Unity/Application/mirsurfaceitem.h 2016-12-01 11:46:42 +0000
2951@@ -31,7 +31,6 @@
2952
2953 namespace qtmir {
2954
2955-class MirSurfaceManager;
2956 class QSGMirSurfaceNode;
2957 class MirTextureProvider;
2958
2959@@ -52,7 +51,6 @@
2960 Mir::ShellChrome shellChrome() const override;
2961
2962 Mir::State surfaceState() const override;
2963- void setSurfaceState(Mir::State) override;
2964
2965 Mir::OrientationAngle orientationAngle() const override;
2966 void setOrientationAngle(Mir::OrientationAngle angle) override;
2967@@ -109,7 +107,6 @@
2968
2969 QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override;
2970
2971- void componentComplete() override;
2972 void releaseResources() override;
2973
2974 private Q_SLOTS:
2975@@ -117,13 +114,12 @@
2976 void updateMirSurfaceSize();
2977
2978 void updateMirSurfaceActiveFocus();
2979- void updateMirSurfaceVisibility();
2980+ void updateMirSurfaceExposure();
2981
2982 void onActualSurfaceSizeChanged(QSize size);
2983 void onCompositorSwappedBuffers();
2984
2985 void onWindowChanged(QQuickWindow *window);
2986- void updateScreen(QScreen *screen);
2987
2988 private:
2989 void ensureTextureProvider();
2990
2991=== modified file 'src/modules/Unity/Application/mirsurfacelistmodel.cpp'
2992--- src/modules/Unity/Application/mirsurfacelistmodel.cpp 2016-07-15 15:38:04 +0000
2993+++ src/modules/Unity/Application/mirsurfacelistmodel.cpp 2016-12-01 11:46:42 +0000
2994@@ -77,7 +77,11 @@
2995
2996 void MirSurfaceListModel::connectSurface(MirSurfaceInterface *surface)
2997 {
2998- connect(surface, &MirSurfaceInterface::raiseRequested, this, [this, surface](){ this->raise(surface); });
2999+ connect(surface, &MirSurfaceInterface::focusedChanged, this, [this, surface](bool focused){
3000+ if (focused) {
3001+ this->raise(surface);
3002+ }
3003+ });
3004 connect(surface, &QObject::destroyed, this, [this, surface](){ this->removeSurface(surface); });
3005 }
3006
3007@@ -143,10 +147,12 @@
3008 for (int i = prependLast; i >= prependFirst; --i) {
3009 auto surface = surfaceList[i];
3010 m_surfaceList.prepend(surface);
3011- connect(surface, &MirSurfaceInterface::raiseRequested, this,
3012- [this, surface]()
3013+ connect(surface, &MirSurfaceInterface::focusedChanged, this,
3014+ [this, surface](bool focused)
3015 {
3016- this->raise(surface);
3017+ if (focused) {
3018+ this->raise(surface);
3019+ }
3020 });
3021 }
3022 endInsertRows();
3023
3024=== removed file 'src/modules/Unity/Application/mirsurfacemanager.cpp'
3025--- src/modules/Unity/Application/mirsurfacemanager.cpp 2016-08-30 12:24:51 +0000
3026+++ src/modules/Unity/Application/mirsurfacemanager.cpp 1970-01-01 00:00:00 +0000
3027@@ -1,188 +0,0 @@
3028-/*
3029- * Copyright (C) 2013-2016 Canonical, Ltd.
3030- *
3031- * This program is free software: you can redistribute it and/or modify it under
3032- * the terms of the GNU Lesser General Public License version 3, as published by
3033- * the Free Software Foundation.
3034- *
3035- * This program is distributed in the hope that it will be useful, but WITHOUT
3036- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
3037- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3038- * Lesser General Public License for more details.
3039- *
3040- * You should have received a copy of the GNU Lesser General Public License
3041- * along with this program. If not, see <http://www.gnu.org/licenses/>.
3042- */
3043-
3044-#include "mirsurfacemanager.h"
3045-
3046-// Qt
3047-#include <QGuiApplication>
3048-#include <QMutexLocker>
3049-
3050-// local
3051-#include "mirsurface.h"
3052-#include "sessionmanager.h"
3053-#include "application_manager.h"
3054-#include "tracepoints.h" // generated from tracepoints.tp
3055-
3056-// common
3057-#include <debughelpers.h>
3058-
3059-// QPA mirserver
3060-#include "nativeinterface.h"
3061-#include "sessionlistener.h"
3062-#include "logging.h"
3063-#include "creationhints.h"
3064-#include "mirserver.h"
3065-
3066-// mir
3067-#include <mir/scene/surface.h>
3068-#include <mir/shell/persistent_surface_store.h>
3069-
3070-
3071-namespace ms = mir::scene;
3072-namespace msh = mir::shell;
3073-
3074-namespace qtmir {
3075-
3076-MirSurfaceManager *MirSurfaceManager::instance = nullptr;
3077-
3078-
3079-void connectToSessionListener(MirSurfaceManager *manager, SessionListener *listener)
3080-{
3081- QObject::connect(listener, &SessionListener::sessionCreatedSurface,
3082- manager, &MirSurfaceManager::onSessionCreatedSurface);
3083- QObject::connect(listener, &SessionListener::sessionDestroyingSurface,
3084- manager, &MirSurfaceManager::onSessionDestroyingSurface);
3085-}
3086-
3087-MirSurfaceManager* MirSurfaceManager::singleton()
3088-{
3089- if (!instance) {
3090-
3091- NativeInterface *nativeInterface = dynamic_cast<NativeInterface*>(QGuiApplication::platformNativeInterface());
3092-
3093- if (!nativeInterface) {
3094- qCritical("ERROR: Unity.Application QML plugin requires use of the 'mirserver' QPA plugin");
3095- QGuiApplication::quit();
3096- return nullptr;
3097- }
3098-
3099- SessionListener *sessionListener = static_cast<SessionListener*>(nativeInterface->nativeResourceForIntegration("SessionListener"));
3100- mir::shell::Shell *shell = static_cast<mir::shell::Shell*>(nativeInterface->nativeResourceForIntegration("Shell"));
3101-
3102-
3103- instance = new MirSurfaceManager(shell,
3104- SessionManager::singleton(),
3105- nativeInterface->thePersistentSurfaceStore());
3106-
3107- connectToSessionListener(instance, sessionListener);
3108- }
3109- return instance;
3110-}
3111-
3112-MirSurfaceManager::MirSurfaceManager(
3113- mir::shell::Shell* shell,
3114- SessionManager* sessionManager,
3115- std::shared_ptr<msh::PersistentSurfaceStore> surfaceStore,
3116- QObject* parent)
3117- : QObject(parent)
3118- , m_shell(shell)
3119- , m_sessionManager(sessionManager)
3120- , m_surfaceStore(surfaceStore)
3121-{
3122- qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::MirSurfaceManager - this=" << this;
3123- setObjectName(QStringLiteral("qtmir::SurfaceManager"));
3124-}
3125-
3126-MirSurfaceManager::~MirSurfaceManager()
3127-{
3128- qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::~MirSurfaceManager - this=" << this;
3129-
3130- m_mirSurfaceToQmlSurfaceHash.clear();
3131-}
3132-
3133-void MirSurfaceManager::onSessionCreatedSurface(const mir::scene::Session *mirSession,
3134- const std::shared_ptr<mir::scene::Surface> &surface,
3135- const std::shared_ptr<SurfaceObserver> &observer,
3136- const qtmir::CreationHints &creationHints)
3137-{
3138- qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::onSessionCreatedSurface - mirSession=" << mirSession
3139- << "surface=" << surface.get() << "surface.name=" << surface->name().c_str()
3140- << "creationHints=" << creationHints.toString();
3141-
3142- SessionInterface* session = m_sessionManager->findSession(mirSession);
3143- auto qmlSurface = new MirSurface(surface,
3144- QString::fromStdString(m_surfaceStore->id_for_surface(surface).serialize_to_string()),
3145- session,
3146- m_shell,
3147- observer,
3148- creationHints);
3149- {
3150- QMutexLocker lock(&m_mutex);
3151- m_mirSurfaceToQmlSurfaceHash.insert(surface.get(), qmlSurface);
3152- }
3153-
3154- if (session)
3155- session->registerSurface(qmlSurface);
3156-
3157- if (qmlSurface->type() == Mir::InputMethodType) {
3158- m_inputMethodSurface = qmlSurface;
3159- Q_EMIT inputMethodSurfaceChanged();
3160- }
3161-
3162- // Only notify QML of surface creation once it has drawn its first frame.
3163- connect(qmlSurface, &MirSurfaceInterface::firstFrameDrawn, this, [=]() {
3164- tracepoint(qtmir, firstFrameDrawn);
3165- Q_EMIT surfaceCreated(qmlSurface);
3166- });
3167-
3168- // clean up after MirSurface is destroyed
3169- connect(qmlSurface, &QObject::destroyed, this, [&](QObject *obj) {
3170- auto qmlSurface = static_cast<MirSurfaceInterface*>(obj);
3171- {
3172- QMutexLocker lock(&m_mutex);
3173- m_mirSurfaceToQmlSurfaceHash.remove(m_mirSurfaceToQmlSurfaceHash.key(qmlSurface));
3174- }
3175-
3176- tracepoint(qtmir, surfaceDestroyed);
3177- });
3178- tracepoint(qtmir, surfaceCreated);
3179-}
3180-
3181-void MirSurfaceManager::onSessionDestroyingSurface(const mir::scene::Session *session,
3182- const std::shared_ptr<mir::scene::Surface> &surface)
3183-{
3184- qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::onSessionDestroyingSurface - session=" << session
3185- << "surface=" << surface.get() << "surface.name=" << surface->name().c_str();
3186-
3187- MirSurfaceInterface* qmlSurface = nullptr;
3188- {
3189- QMutexLocker lock(&m_mutex);
3190- auto it = m_mirSurfaceToQmlSurfaceHash.find(surface.get());
3191- if (it != m_mirSurfaceToQmlSurfaceHash.end()) {
3192- qmlSurface = it.value();
3193- m_mirSurfaceToQmlSurfaceHash.erase(it);
3194- } else {
3195- qCritical() << "MirSurfaceManager::onSessionDestroyingSurface: unable to find MirSurface corresponding"
3196- << "to surface=" << surface.get() << "surface.name=" << surface->name().c_str();
3197- return;
3198- }
3199- }
3200-
3201- if (qmlSurface->type() == Mir::InputMethodType) {
3202- m_inputMethodSurface = nullptr;
3203- Q_EMIT inputMethodSurfaceChanged();
3204- }
3205-
3206- qmlSurface->setLive(false);
3207- Q_EMIT surfaceDestroyed(qmlSurface);
3208-}
3209-
3210-MirSurfaceInterface* MirSurfaceManager::inputMethodSurface() const
3211-{
3212- return m_inputMethodSurface;
3213-}
3214-
3215-} // namespace qtmir
3216
3217=== removed file 'src/modules/Unity/Application/mirsurfacemanager.h'
3218--- src/modules/Unity/Application/mirsurfacemanager.h 2016-08-30 12:24:19 +0000
3219+++ src/modules/Unity/Application/mirsurfacemanager.h 1970-01-01 00:00:00 +0000
3220@@ -1,99 +0,0 @@
3221-/*
3222- * Copyright (C) 2013-2015 Canonical, Ltd.
3223- *
3224- * This program is free software: you can redistribute it and/or modify it under
3225- * the terms of the GNU Lesser General Public License version 3, as published by
3226- * the Free Software Foundation.
3227- *
3228- * This program is distributed in the hope that it will be useful, but WITHOUT
3229- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
3230- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3231- * Lesser General Public License for more details.
3232- *
3233- * You should have received a copy of the GNU Lesser General Public License
3234- * along with this program. If not, see <http://www.gnu.org/licenses/>.
3235- */
3236-
3237-#ifndef MIR_SURFACE_MANAGER_H
3238-#define MIR_SURFACE_MANAGER_H
3239-
3240-// std
3241-#include <memory>
3242-
3243-// Qt
3244-#include <QObject>
3245-#include <QHash>
3246-#include <QMutex>
3247-#include <QSharedPointer>
3248-
3249-// Mir
3250-#include <mir_toolkit/common.h>
3251-
3252-// mirserver qpa
3253-#include <creationhints.h>
3254-
3255-namespace mir {
3256- namespace scene {
3257- class Surface;
3258- class Session;
3259- class PromptSession;
3260- }
3261- namespace shell {
3262- class Shell;
3263- class PersistentSurfaceStore;
3264- }
3265-}
3266-
3267-class SurfaceObserver;
3268-
3269-namespace qtmir {
3270-
3271-class Application;
3272-class ApplicationManager;
3273-class MirSurfaceInterface;
3274-class SessionManager;
3275-
3276-class MirSurfaceManager : public QObject
3277-{
3278- Q_OBJECT
3279- Q_PROPERTY(MirSurfaceInterface* inputMethodSurface READ inputMethodSurface NOTIFY inputMethodSurfaceChanged)
3280-public:
3281- explicit MirSurfaceManager(
3282- mir::shell::Shell* shell,
3283- SessionManager* sessionManager,
3284- std::shared_ptr<mir::shell::PersistentSurfaceStore> surfaceStore,
3285- QObject* parent = nullptr
3286- );
3287- ~MirSurfaceManager();
3288-
3289- static MirSurfaceManager* singleton();
3290-
3291- MirSurfaceInterface* inputMethodSurface() const;
3292-
3293-Q_SIGNALS:
3294- void inputMethodSurfaceChanged();
3295- void surfaceCreated(MirSurfaceInterface* surface);
3296- void surfaceDestroyed(MirSurfaceInterface* surface);
3297-
3298-public Q_SLOTS:
3299- void onSessionCreatedSurface(const mir::scene::Session *,
3300- const std::shared_ptr<mir::scene::Surface> &,
3301- std::shared_ptr<SurfaceObserver> const&,
3302- const qtmir::CreationHints &);
3303- void onSessionDestroyingSurface(const mir::scene::Session *, const std::shared_ptr<mir::scene::Surface> &);
3304-
3305-protected:
3306- QHash<const mir::scene::Surface *, MirSurfaceInterface *> m_mirSurfaceToQmlSurfaceHash;
3307- QMutex m_mutex;
3308-
3309-private:
3310- mir::shell::Shell *const m_shell;
3311- SessionManager* m_sessionManager;
3312- std::shared_ptr<mir::shell::PersistentSurfaceStore> m_surfaceStore;
3313- static MirSurfaceManager *instance;
3314- MirSurfaceInterface* m_inputMethodSurface = nullptr;
3315-};
3316-
3317-} // namespace qtmir
3318-
3319-#endif // MIR_SURFACE_MANAGER_H
3320
3321=== modified file 'src/modules/Unity/Application/plugin.cpp'
3322--- src/modules/Unity/Application/plugin.cpp 2016-07-15 15:38:04 +0000
3323+++ src/modules/Unity/Application/plugin.cpp 2016-12-01 11:46:42 +0000
3324@@ -20,11 +20,11 @@
3325 // local
3326 #include "application.h"
3327 #include "application_manager.h"
3328-#include "mirfocuscontroller.h"
3329-#include "mirsurfacemanager.h"
3330 #include "mirsurfaceinterface.h"
3331 #include "mirsurfaceitem.h"
3332 #include "mirsurfacelistmodel.h"
3333+#include "windowmodel.h"
3334+#include "surfacemanager.h"
3335
3336 // platforms/mirserver
3337 #include <mirsingleton.h>
3338@@ -46,22 +46,9 @@
3339 return qtmir::ApplicationManager::singleton();
3340 }
3341
3342-QObject* surfaceManagerSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
3343- Q_UNUSED(engine);
3344- Q_UNUSED(scriptEngine);
3345- qCDebug(QTMIR_APPLICATIONS) << "surfaceManagerSingleton - engine=" << engine << "scriptEngine=" << scriptEngine;
3346-
3347- return qtmir::MirSurfaceManager::singleton();
3348-}
3349-
3350 QObject* mirSingleton(QQmlEngine* /*engine*/, QJSEngine* /*scriptEngine*/) {
3351 return qtmir::Mir::instance();
3352 }
3353-
3354-QObject* mirFocusControllerSingleton(QQmlEngine*, QJSEngine*)
3355-{
3356- return MirFocusController::instance();
3357-}
3358 } // anonymous namespace
3359
3360 class UnityApplicationPlugin : public QQmlExtensionPlugin {
3361@@ -77,6 +64,7 @@
3362 qRegisterMetaType<qtmir::Application*>("Application*");
3363 qRegisterMetaType<unity::shell::application::MirSurfaceInterface*>("MirSurfaceInterface*");
3364 qRegisterMetaType<unity::shell::application::MirSurfaceListInterface*>("unity::shell::application::MirSurfaceListInterface*");
3365+ qRegisterMetaType<unity::shell::application::SurfaceManagerInterface*>("unity::shell::application::SurfaceManagerInterface*");
3366 qRegisterMetaType<MirSurfaceAttrib>("MirSurfaceAttrib");
3367
3368 qmlRegisterUncreatableType<unity::shell::application::ApplicationManagerInterface>(
3369@@ -87,13 +75,13 @@
3370 uri, 0, 1, "ApplicationInfoInterface", "Abstract interface. Cannot be created in QML");
3371 qmlRegisterUncreatableType<qtmir::Application>(
3372 uri, 0, 1, "ApplicationInfo", "Application can't be instantiated");
3373- qmlRegisterSingletonType<qtmir::MirSurfaceManager>(
3374- uri, 0, 1, "SurfaceManager", surfaceManagerSingleton);
3375- qmlRegisterSingletonType<MirFocusController>(uri, 0, 1, "MirFocusController", mirFocusControllerSingleton);
3376 qmlRegisterUncreatableType<unity::shell::application::MirSurfaceInterface>(
3377 uri, 0, 1, "MirSurface", "MirSurface can't be instantiated from QML");
3378 qmlRegisterType<qtmir::MirSurfaceItem>(uri, 0, 1, "MirSurfaceItem");
3379 qmlRegisterSingletonType<qtmir::Mir>(uri, 0, 1, "Mir", mirSingleton);
3380+ qmlRegisterType<qtmir::SurfaceManager>(uri, 0, 1, "SurfaceManager");
3381+
3382+ qmlRegisterType<qtmir::WindowModel>(uri, 0, 1, "WindowModel");
3383 }
3384
3385 virtual void initializeEngine(QQmlEngine *engine, const char *uri)
3386
3387=== modified file 'src/modules/Unity/Application/session.cpp'
3388--- src/modules/Unity/Application/session.cpp 2016-09-22 15:58:26 +0000
3389+++ src/modules/Unity/Application/session.cpp 2016-12-01 11:46:42 +0000
3390@@ -19,16 +19,14 @@
3391 #include "debughelpers.h"
3392 #include "session.h"
3393 #include "mirsurfaceinterface.h"
3394-#include "mirsurfacemanager.h"
3395 #include "mirsurfaceitem.h"
3396+#include "promptsession.h"
3397
3398 // mirserver
3399 #include "logging.h"
3400
3401-// mir
3402-#include <mir/scene/session.h>
3403-#include <mir/scene/prompt_session.h>
3404-#include <mir/scene/prompt_session_manager.h>
3405+// miral
3406+#include <miral/application.h>
3407
3408 // Qt
3409 #include <QPainter>
3410@@ -66,7 +64,7 @@
3411 }
3412
3413 Session::Session(const std::shared_ptr<ms::Session>& session,
3414- const std::shared_ptr<ms::PromptSessionManager>& promptSessionManager,
3415+ const std::shared_ptr<PromptSessionManager>& promptSessionManager,
3416 QObject *parent)
3417 : SessionInterface(parent)
3418 , m_session(session)
3419@@ -121,7 +119,7 @@
3420
3421 QString Session::name() const
3422 {
3423- return QString::fromStdString(m_session->name());
3424+ return QString::fromStdString(miral::name_of(m_session));
3425 }
3426
3427 std::shared_ptr<ms::Session> Session::session() const
3428@@ -202,10 +200,10 @@
3429 DEBUG_MSG << "(surface=" << newSurface << ")";
3430
3431 // Only notify QML of surface creation once it has drawn its first frame.
3432- if (newSurface->isFirstFrameDrawn()) {
3433+ if (newSurface->isReady()) {
3434 prependSurface(newSurface);
3435 } else {
3436- connect(newSurface, &MirSurfaceInterface::firstFrameDrawn, this, [this, newSurface]()
3437+ connect(newSurface, &MirSurfaceInterface::ready, this, [this, newSurface]()
3438 {
3439 newSurface->disconnect(this);
3440 this->prependSurface(newSurface);
3441@@ -234,6 +232,10 @@
3442 this->removeSurface(newSurface);
3443 });
3444 connect(newSurface, &MirSurfaceInterface::focusRequested, this, &SessionInterface::focusRequested);
3445+ connect(newSurface, &MirSurfaceInterface::focusedChanged, this, [&](bool /*value*/) {
3446+ // TODO: May want to optimize that in the future.
3447+ Q_EMIT focusedChanged(focused());
3448+ });
3449
3450 m_surfaceList.prependSurface(newSurface);
3451 m_hadSurface = true;
3452@@ -289,11 +291,11 @@
3453 {
3454 DEBUG_MSG << " state=" << sessionStateToString(m_state);
3455 if (m_state == Running) {
3456- session()->set_lifecycle_state(mir_lifecycle_state_will_suspend);
3457+ miral::apply_lifecycle_state_to(session(), mir_lifecycle_state_will_suspend);
3458 m_suspendTimer->start();
3459
3460- foreachPromptSession([this](const std::shared_ptr<ms::PromptSession>& promptSession) {
3461- m_promptSessionManager->suspend_prompt_session(promptSession);
3462+ foreachPromptSession([this](const qtmir::PromptSession &promptSession) {
3463+ m_promptSessionManager->suspendPromptSession(promptSession);
3464 });
3465
3466 foreachChildSession([](SessionInterface* session) {
3467@@ -322,10 +324,10 @@
3468 }
3469 }
3470
3471- session()->set_lifecycle_state(mir_lifecycle_state_resumed);
3472+ miral::apply_lifecycle_state_to(session(), mir_lifecycle_state_resumed);
3473
3474- foreachPromptSession([this](const std::shared_ptr<ms::PromptSession>& promptSession) {
3475- m_promptSessionManager->resume_prompt_session(promptSession);
3476+ foreachPromptSession([this](const qtmir::PromptSession &promptSession) {
3477+ m_promptSessionManager->resumePromptSession(promptSession);
3478 });
3479
3480 foreachChildSession([](SessionInterface* session) {
3481@@ -453,16 +455,16 @@
3482 return m_children;
3483 }
3484
3485-void Session::appendPromptSession(const std::shared_ptr<ms::PromptSession>& promptSession)
3486+void Session::appendPromptSession(const qtmir::PromptSession &promptSession)
3487 {
3488- DEBUG_MSG << "(promptSession=" << (promptSession ? promptSession.get() : nullptr) << ")";
3489+ DEBUG_MSG << "(promptSession=" << promptSession.get() << ")";
3490
3491 m_promptSessions.append(promptSession);
3492 }
3493
3494-void Session::removePromptSession(const std::shared_ptr<ms::PromptSession>& promptSession)
3495+void Session::removePromptSession(const qtmir::PromptSession &promptSession)
3496 {
3497- DEBUG_MSG << "(promptSession=" << (promptSession ? promptSession.get() : nullptr) << ")";
3498+ DEBUG_MSG << "(promptSession=" << promptSession.get() << ")";
3499
3500 m_promptSessions.removeAll(promptSession);
3501 }
3502@@ -474,26 +476,26 @@
3503 static_cast<Session*>(child)->stopPromptSessions();
3504 }
3505
3506- QVector<std::shared_ptr<ms::PromptSession>> copy(m_promptSessions);
3507- QVectorIterator<std::shared_ptr<ms::PromptSession>> it(copy);
3508+ QVector<qtmir::PromptSession> copy(m_promptSessions);
3509+ QVectorIterator<qtmir::PromptSession> it(copy);
3510 for ( it.toBack(); it.hasPrevious(); ) {
3511- std::shared_ptr<ms::PromptSession> promptSession = it.previous();
3512+ qtmir::PromptSession promptSession = it.previous();
3513 DEBUG_MSG << " - promptSession=" << promptSession.get();
3514
3515- m_promptSessionManager->stop_prompt_session(promptSession);
3516+ m_promptSessionManager->stopPromptSession(promptSession);
3517 }
3518 }
3519
3520-std::shared_ptr<ms::PromptSession> Session::activePromptSession() const
3521+qtmir::PromptSession Session::activePromptSession() const
3522 {
3523 if (m_promptSessions.count() > 0)
3524 return m_promptSessions.back();
3525- return nullptr;
3526+ return {};
3527 }
3528
3529-void Session::foreachPromptSession(const std::function<void(const std::shared_ptr<ms::PromptSession>&)>& f) const
3530+void Session::foreachPromptSession(const std::function<void(const qtmir::PromptSession&)>& f) const
3531 {
3532- Q_FOREACH (std::shared_ptr<ms::PromptSession> promptSession, m_promptSessions) {
3533+ Q_FOREACH (qtmir::PromptSession promptSession, m_promptSessions) {
3534 f(promptSession);
3535 }
3536 }
3537@@ -516,6 +518,18 @@
3538 return m_hadSurface;
3539 }
3540
3541+bool Session::focused() const
3542+{
3543+ for (int i = 0; i < m_surfaceList.count(); ++i) {
3544+ auto surface = static_cast<const MirSurfaceInterface*>(m_surfaceList.get(i));
3545+ if (surface->focused()) {
3546+ return true;
3547+ }
3548+ }
3549+
3550+ return false;
3551+}
3552+
3553 bool Session::activeFocus() const
3554 {
3555 for (int i = 0; i < m_surfaceList.count(); ++i) {
3556@@ -530,7 +544,7 @@
3557
3558 pid_t Session::pid() const
3559 {
3560- return m_session->process_id();
3561+ return miral::pid_of(m_session);
3562 }
3563
3564 void Session::setSuspendTimer(AbstractTimer *timer)
3565
3566=== modified file 'src/modules/Unity/Application/session.h'
3567--- src/modules/Unity/Application/session.h 2016-07-15 15:38:04 +0000
3568+++ src/modules/Unity/Application/session.h 2016-12-01 11:46:42 +0000
3569@@ -23,19 +23,17 @@
3570 // local
3571 #include "session_interface.h"
3572 #include "mirsurfacelistmodel.h"
3573+#include "promptsessionmanager.h"
3574 #include "timer.h"
3575
3576 // Qt
3577 #include <QObject>
3578
3579-namespace mir {
3580- namespace scene {
3581- class PromptSessionManager;
3582- }
3583-}
3584
3585 namespace qtmir {
3586
3587+class PromptSessionManager;
3588+
3589 class Application;
3590
3591 class Session : public SessionInterface
3592@@ -43,7 +41,7 @@
3593 Q_OBJECT
3594 public:
3595 explicit Session(const std::shared_ptr<mir::scene::Session>& session,
3596- const std::shared_ptr<mir::scene::PromptSessionManager>& promptSessionManager,
3597+ const std::shared_ptr<PromptSessionManager>& promptSessionManager,
3598 QObject *parent = 0);
3599 virtual ~Session();
3600
3601@@ -66,6 +64,7 @@
3602 void stop() override;
3603 bool hadSurface() const override;
3604 bool hasClosingSurfaces() const override;
3605+ bool focused() const override;
3606
3607 bool activeFocus() const override;
3608
3609@@ -78,15 +77,15 @@
3610
3611 std::shared_ptr<mir::scene::Session> session() const override;
3612
3613- std::shared_ptr<mir::scene::PromptSession> activePromptSession() const override;
3614- void foreachPromptSession(const std::function<void(const std::shared_ptr<mir::scene::PromptSession>&)> &f) const override;
3615+ PromptSession activePromptSession() const override;
3616+ void foreachPromptSession(const std::function<void(const PromptSession&)> &f) const override;
3617
3618 SessionModel* childSessions() const override;
3619
3620 void setFullscreen(bool fullscreen) override;
3621 void setLive(const bool) override;
3622- void appendPromptSession(const std::shared_ptr<mir::scene::PromptSession>& session) override;
3623- void removePromptSession(const std::shared_ptr<mir::scene::PromptSession>& session) override;
3624+ void appendPromptSession(const PromptSession& session) override;
3625+ void removePromptSession(const PromptSession& session) override;
3626
3627 // useful for tests
3628 void setSuspendTimer(AbstractTimer *timer);
3629@@ -119,8 +118,8 @@
3630 State m_state;
3631 bool m_live;
3632 AbstractTimer* m_suspendTimer{nullptr};
3633- QVector<std::shared_ptr<mir::scene::PromptSession>> m_promptSessions;
3634- std::shared_ptr<mir::scene::PromptSessionManager> const m_promptSessionManager;
3635+ QVector<PromptSession> m_promptSessions;
3636+ std::shared_ptr<PromptSessionManager> const m_promptSessionManager;
3637 QList<MirSurfaceInterface*> m_closingSurfaces;
3638 bool m_hadSurface{false};
3639 };
3640
3641=== modified file 'src/modules/Unity/Application/session_interface.h'
3642--- src/modules/Unity/Application/session_interface.h 2016-07-15 15:38:04 +0000
3643+++ src/modules/Unity/Application/session_interface.h 2016-12-01 11:46:42 +0000
3644@@ -33,7 +33,6 @@
3645 namespace mir {
3646 namespace scene {
3647 class Session;
3648- class PromptSession;
3649 }
3650 }
3651
3652@@ -41,6 +40,7 @@
3653
3654 class MirSurfaceInterface;
3655 class MirSurfaceListModel;
3656+class PromptSession;
3657
3658 class SessionInterface : public QObject {
3659 Q_OBJECT
3660@@ -78,7 +78,7 @@
3661
3662 virtual std::shared_ptr<mir::scene::Session> session() const = 0;
3663
3664- // For MirSurface and MirSurfaceManager use
3665+ // For MirSurface use
3666
3667 virtual void registerSurface(MirSurfaceInterface* surface) = 0;
3668
3669@@ -91,6 +91,7 @@
3670 virtual void stop() = 0;
3671 virtual bool hadSurface() const = 0; // whether this session ever had any surface (currently or in the past)
3672 virtual bool hasClosingSurfaces() const = 0; // whether it has surfaces being forcibly closed
3673+ virtual bool focused() const = 0; // whether any surface in its list is focused()
3674
3675 // Whether any of its MirSurfaces has activeFocus()
3676 // See qtmir::MirSurfaceInterface::activeFocus
3677@@ -105,19 +106,20 @@
3678 virtual void removeChildSession(SessionInterface* session) = 0;
3679 virtual void foreachChildSession(const std::function<void(SessionInterface* session)>& f) const = 0;
3680
3681- virtual std::shared_ptr<mir::scene::PromptSession> activePromptSession() const = 0;
3682- virtual void foreachPromptSession(const std::function<void(const std::shared_ptr<mir::scene::PromptSession>&)>& f) const = 0;
3683+ virtual PromptSession activePromptSession() const = 0;
3684+ virtual void foreachPromptSession(const std::function<void(const PromptSession&)>& f) const = 0;
3685
3686 virtual void setFullscreen(bool fullscreen) = 0;
3687 virtual void setLive(const bool) = 0;
3688- virtual void appendPromptSession(const std::shared_ptr<mir::scene::PromptSession>& session) = 0;
3689- virtual void removePromptSession(const std::shared_ptr<mir::scene::PromptSession>& session) = 0;
3690+ virtual void appendPromptSession(const PromptSession& session) = 0;
3691+ virtual void removePromptSession(const PromptSession& session) = 0;
3692
3693 Q_SIGNALS:
3694 void applicationChanged(unity::shell::application::ApplicationInfoInterface* application);
3695 void stateChanged(State state);
3696 void fullscreenChanged(bool fullscreen);
3697 void liveChanged(bool live);
3698+ void focusedChanged(bool focused);
3699
3700 // Emitted when any surface in this session emits focusRequested()
3701 void focusRequested();
3702
3703=== modified file 'src/modules/Unity/Application/sessionmanager.cpp'
3704--- src/modules/Unity/Application/sessionmanager.cpp 2016-08-10 06:51:55 +0000
3705+++ src/modules/Unity/Application/sessionmanager.cpp 2016-12-01 11:46:42 +0000
3706@@ -23,28 +23,23 @@
3707 #include "sessionmanager.h"
3708
3709 // QPA mirserver
3710+#include "appnotifier.h"
3711+#include "logging.h"
3712 #include "nativeinterface.h"
3713-#include "sessionlistener.h"
3714-#include "logging.h"
3715 #include "promptsessionlistener.h"
3716-
3717-// mir
3718-#include <mir/scene/prompt_session.h>
3719-#include <mir/scene/prompt_session_manager.h>
3720-#include <mir/report_exception.h>
3721-
3722-namespace ms = mir::scene;
3723+#include "promptsession.h"
3724+
3725
3726 namespace qtmir {
3727
3728 SessionManager *SessionManager::the_session_manager = nullptr;
3729
3730
3731-void connectToSessionListener(SessionManager *manager, SessionListener *listener)
3732+void connectToAppNotifier(SessionManager *manager, AppNotifier *appNotifier)
3733 {
3734- QObject::connect(listener, &SessionListener::sessionStarting,
3735+ QObject::connect(appNotifier, &AppNotifier::appAdded,
3736 manager, &SessionManager::onSessionStarting);
3737- QObject::connect(listener, &SessionListener::sessionStopping,
3738+ QObject::connect(appNotifier, &AppNotifier::appRemoved,
3739 manager, &SessionManager::onSessionStopping);
3740 }
3741
3742@@ -61,7 +56,6 @@
3743 }
3744
3745 SessionManager* SessionManager::singleton()
3746-try
3747 {
3748 if (!the_session_manager) {
3749
3750@@ -73,27 +67,19 @@
3751 return nullptr;
3752 }
3753
3754- SessionListener *sessionListener = static_cast<SessionListener*>(nativeInterface->nativeResourceForIntegration("SessionListener"));
3755+ auto appNotifier = static_cast<AppNotifier*>(nativeInterface->nativeResourceForIntegration("AppNotifier"));
3756 PromptSessionListener *promptSessionListener = static_cast<PromptSessionListener*>(nativeInterface->nativeResourceForIntegration("PromptSessionListener"));
3757
3758 the_session_manager = new SessionManager(nativeInterface->thePromptSessionManager(), ApplicationManager::singleton());
3759
3760- connectToSessionListener(the_session_manager, sessionListener);
3761+ connectToAppNotifier(the_session_manager, appNotifier);
3762 connectToPromptSessionListener(the_session_manager, promptSessionListener);
3763 }
3764 return the_session_manager;
3765 }
3766-catch (...)
3767-{
3768- // We only call mir::report_exception() here to force linkage against libmirserver.
3769- // Unless we force this module to have a link dependency on libmirserver we get
3770- // several tests hanging during link loading. I wish I understood why. alan_g
3771- mir::report_exception();
3772- throw;
3773-}
3774
3775 SessionManager::SessionManager(
3776- const std::shared_ptr<mir::scene::PromptSessionManager>& promptSessionManager,
3777+ const std::shared_ptr<qtmir::PromptSessionManager>& promptSessionManager,
3778 ApplicationManager* applicationManager,
3779 QObject *parent)
3780 : SessionModel(parent)
3781@@ -120,10 +106,11 @@
3782 return nullptr;
3783 }
3784
3785-void SessionManager::onSessionStarting(std::shared_ptr<mir::scene::Session> const& session)
3786+void SessionManager::onSessionStarting(const miral::ApplicationInfo &appInfo)
3787 {
3788- qCDebug(QTMIR_SESSIONS) << "SessionManager::onSessionStarting - sessionName=" << session->name().c_str();
3789+ qCDebug(QTMIR_SESSIONS) << "SessionManager::onSessionStarting - sessionName=" << appInfo.name().c_str();
3790
3791+ const auto &session = appInfo.application();
3792 Session* qmlSession = new Session(session, m_promptSessionManager);
3793 insert(0, qmlSession);
3794
3795@@ -140,11 +127,11 @@
3796 Q_EMIT sessionStarting(qmlSession);
3797 }
3798
3799-void SessionManager::onSessionStopping(std::shared_ptr<mir::scene::Session> const& session)
3800+void SessionManager::onSessionStopping(const miral::ApplicationInfo &appInfo)
3801 {
3802- qCDebug(QTMIR_SESSIONS) << "SessionManager::onSessionStopping - sessionName=" << session->name().c_str();
3803+ qCDebug(QTMIR_SESSIONS) << "SessionManager::onSessionStopping - sessionName=" << appInfo.name().c_str();
3804
3805- SessionInterface* qmlSession = findSession(session.get());
3806+ SessionInterface* qmlSession = findSession(appInfo.application().get());
3807 if (!qmlSession) return;
3808
3809 remove(qmlSession);
3810@@ -153,11 +140,11 @@
3811 Q_EMIT sessionStopping(qmlSession);
3812 }
3813
3814-void SessionManager::onPromptSessionStarting(const std::shared_ptr<ms::PromptSession>& promptSession)
3815+void SessionManager::onPromptSessionStarting(const qtmir::PromptSession &promptSession)
3816 {
3817 qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptSessionStarting - promptSession=" << promptSession.get();
3818
3819- std::shared_ptr<mir::scene::Session> appSession = m_promptSessionManager->application_for(promptSession);
3820+ std::shared_ptr<mir::scene::Session> appSession = m_promptSessionManager->applicationFor(promptSession);
3821 SessionInterface *qmlAppSession = findSession(appSession.get());
3822 if (qmlAppSession) {
3823 m_mirPromptToSessionHash[promptSession.get()] = qmlAppSession;
3824@@ -167,7 +154,7 @@
3825 }
3826 }
3827
3828-void SessionManager::onPromptSessionStopping(const std::shared_ptr<ms::PromptSession>& promptSession)
3829+void SessionManager::onPromptSessionStopping(const qtmir::PromptSession &promptSession)
3830 {
3831 qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptSessionStopping - promptSession=" << promptSession.get();
3832
3833@@ -177,12 +164,12 @@
3834 m_mirPromptToSessionHash.remove(promptSession.get());
3835 }
3836
3837-void SessionManager::onPromptProviderAdded(const mir::scene::PromptSession *promptSession,
3838+void SessionManager::onPromptProviderAdded(const qtmir::PromptSession &promptSession,
3839 const std::shared_ptr<mir::scene::Session> &promptProvider)
3840 {
3841- qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderAdded - promptSession=" << promptSession << " promptProvider=" << promptProvider.get();
3842+ qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderAdded - promptSession=" << promptSession.get() << " promptProvider=" << promptProvider.get();
3843
3844- SessionInterface* qmlAppSession = m_mirPromptToSessionHash.value(promptSession, nullptr);
3845+ SessionInterface* qmlAppSession = m_mirPromptToSessionHash.value(promptSession.get(), nullptr);
3846 if (!qmlAppSession) {
3847 qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderAdded - could not find session item for app session";
3848 return;
3849@@ -197,10 +184,10 @@
3850 qmlAppSession->addChildSession(qmlPromptProvider);
3851 }
3852
3853-void SessionManager::onPromptProviderRemoved(const mir::scene::PromptSession *promptSession,
3854+void SessionManager::onPromptProviderRemoved(const qtmir::PromptSession &promptSession,
3855 const std::shared_ptr<mir::scene::Session> &promptProvider)
3856 {
3857- qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderRemoved - promptSession=" << promptSession << " promptProvider=" << promptProvider.get();
3858+ qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderRemoved - promptSession=" << promptSession.get() << " promptProvider=" << promptProvider.get();
3859
3860 SessionInterface* qmlPromptProvider = findSession(promptProvider.get());
3861 if (!qmlPromptProvider) {
3862
3863=== modified file 'src/modules/Unity/Application/sessionmanager.h'
3864--- src/modules/Unity/Application/sessionmanager.h 2016-08-10 06:51:37 +0000
3865+++ src/modules/Unity/Application/sessionmanager.h 2016-12-01 11:46:42 +0000
3866@@ -27,6 +27,9 @@
3867 // Mir
3868 #include <mir_toolkit/common.h>
3869
3870+// miral
3871+#include <miral/application_info.h>
3872+
3873 // local
3874 #include "session.h"
3875 #include "sessionmodel.h"
3876@@ -49,7 +52,7 @@
3877
3878 public:
3879 explicit SessionManager(
3880- const std::shared_ptr<mir::scene::PromptSessionManager>& promptSessionManager,
3881+ const std::shared_ptr<PromptSessionManager>& promptSessionManager,
3882 ApplicationManager* applicationManager,
3883 QObject *parent = 0
3884 );
3885@@ -64,18 +67,18 @@
3886 void sessionStopping(SessionInterface* session);
3887
3888 public Q_SLOTS:
3889- void onSessionStarting(std::shared_ptr<mir::scene::Session> const& session);
3890- void onSessionStopping(std::shared_ptr<mir::scene::Session> const& session);
3891+ void onSessionStarting(const miral::ApplicationInfo &appInfo);
3892+ void onSessionStopping(const miral::ApplicationInfo &appInfo);
3893
3894- void onPromptSessionStarting(const std::shared_ptr<mir::scene::PromptSession>& promptSession);
3895- void onPromptSessionStopping(const std::shared_ptr<mir::scene::PromptSession>& promptSession);
3896- void onPromptProviderAdded(const mir::scene::PromptSession *, const std::shared_ptr<mir::scene::Session> &);
3897- void onPromptProviderRemoved(const mir::scene::PromptSession *, const std::shared_ptr<mir::scene::Session> &);
3898+ void onPromptSessionStarting(const PromptSession& promptSession);
3899+ void onPromptSessionStopping(const PromptSession& promptSession);
3900+ void onPromptProviderAdded(const qtmir::PromptSession &promptSession, const std::shared_ptr<mir::scene::Session> &);
3901+ void onPromptProviderRemoved(const qtmir::PromptSession &promptSession, const std::shared_ptr<mir::scene::Session> &);
3902
3903 protected:
3904
3905 private:
3906- const std::shared_ptr<mir::scene::PromptSessionManager> m_promptSessionManager;
3907+ const std::shared_ptr<PromptSessionManager> m_promptSessionManager;
3908 ApplicationManager* m_applicationManager;
3909 static SessionManager *the_session_manager;
3910
3911
3912=== added file 'src/modules/Unity/Application/surfacemanager.cpp'
3913--- src/modules/Unity/Application/surfacemanager.cpp 1970-01-01 00:00:00 +0000
3914+++ src/modules/Unity/Application/surfacemanager.cpp 2016-12-01 11:46:42 +0000
3915@@ -0,0 +1,174 @@
3916+/*
3917+ * Copyright (C) 2016 Canonical, Ltd.
3918+ *
3919+ * This program is free software: you can redistribute it and/or modify it under
3920+ * the terms of the GNU Lesser General Public License version 3, as published by
3921+ * the Free Software Foundation.
3922+ *
3923+ * This program is distributed in the hope that it will be useful, but WITHOUT
3924+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
3925+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3926+ * Lesser General Public License for more details.
3927+ *
3928+ * You should have received a copy of the GNU Lesser General Public License
3929+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3930+ */
3931+
3932+#include "surfacemanager.h"
3933+
3934+#include "mirsurface.h"
3935+#include "sessionmanager.h"
3936+
3937+// mirserver
3938+#include "nativeinterface.h"
3939+
3940+// Qt
3941+#include <QGuiApplication>
3942+
3943+Q_LOGGING_CATEGORY(QTMIR_SURFACEMANAGER, "qtmir.surfacemanager", QtInfoMsg)
3944+
3945+#define DEBUG_MSG qCDebug(QTMIR_SURFACEMANAGER).nospace().noquote() << __func__
3946+
3947+using namespace qtmir;
3948+namespace unityapi = unity::shell::application;
3949+
3950+SurfaceManager::SurfaceManager(QObject *)
3951+{
3952+ DEBUG_MSG << "()";
3953+
3954+ auto nativeInterface = dynamic_cast<NativeInterface*>(QGuiApplication::platformNativeInterface());
3955+
3956+ if (!nativeInterface) {
3957+ qFatal("ERROR: Unity.Application QML plugin requires use of the 'mirserver' QPA plugin");
3958+ }
3959+
3960+ m_windowController = static_cast<WindowControllerInterface*>(nativeInterface->nativeResourceForIntegration("WindowController"));
3961+
3962+ auto windowModel = static_cast<WindowModelNotifier*>(nativeInterface->nativeResourceForIntegration("WindowModelNotifier"));
3963+ connectToWindowModelNotifier(windowModel);
3964+
3965+ m_sessionManager = SessionManager::singleton();
3966+}
3967+
3968+void SurfaceManager::connectToWindowModelNotifier(WindowModelNotifier *notifier)
3969+{
3970+ connect(notifier, &WindowModelNotifier::windowAdded, this, &SurfaceManager::onWindowAdded, Qt::QueuedConnection);
3971+ connect(notifier, &WindowModelNotifier::windowRemoved, this, &SurfaceManager::onWindowRemoved, Qt::QueuedConnection);
3972+ connect(notifier, &WindowModelNotifier::windowReady, this, &SurfaceManager::onWindowReady, Qt::QueuedConnection);
3973+ connect(notifier, &WindowModelNotifier::windowMoved, this, &SurfaceManager::onWindowMoved, Qt::QueuedConnection);
3974+ connect(notifier, &WindowModelNotifier::windowStateChanged, this, &SurfaceManager::onWindowStateChanged, Qt::QueuedConnection);
3975+ connect(notifier, &WindowModelNotifier::windowFocusChanged, this, &SurfaceManager::onWindowFocusChanged, Qt::QueuedConnection);
3976+ connect(notifier, &WindowModelNotifier::windowsRaised, this, &SurfaceManager::onWindowsRaised, Qt::QueuedConnection);
3977+ connect(notifier, &WindowModelNotifier::windowRequestedRaise, this, &SurfaceManager::onWindowsRequestedRaise, Qt::QueuedConnection);
3978+ connect(notifier, &WindowModelNotifier::modificationsStarted, this, &SurfaceManager::modificationsStarted, Qt::QueuedConnection);
3979+ connect(notifier, &WindowModelNotifier::modificationsEnded, this, &SurfaceManager::modificationsEnded, Qt::QueuedConnection);
3980+}
3981+
3982+void SurfaceManager::rememberMirSurface(MirSurface *surface)
3983+{
3984+ m_allSurfaces.append(surface);
3985+}
3986+
3987+void SurfaceManager::forgetMirSurface(const miral::Window &window)
3988+{
3989+ for (int i = 0; i < m_allSurfaces.count(); ++i) {
3990+ if (m_allSurfaces[i]->window() == window) {
3991+ m_allSurfaces.removeAt(i);
3992+ return;
3993+ }
3994+ }
3995+}
3996+void SurfaceManager::onWindowAdded(const NewWindow &window)
3997+{
3998+ auto mirSession = window.windowInfo.window().application();
3999+ SessionInterface* session = m_sessionManager->findSession(mirSession.get());
4000+
4001+ auto surface = new MirSurface(window, m_windowController, session);
4002+ rememberMirSurface(surface);
4003+
4004+ if (session)
4005+ session->registerSurface(surface);
4006+
4007+ Q_EMIT surfaceCreated(surface);
4008+}
4009+
4010+void SurfaceManager::onWindowRemoved(const miral::WindowInfo &windowInfo)
4011+{
4012+ MirSurface *surface = find(windowInfo);
4013+ forgetMirSurface(windowInfo.window());
4014+ surface->setLive(false);
4015+}
4016+
4017+MirSurface *SurfaceManager::find(const miral::WindowInfo &needle) const
4018+{
4019+ return find(needle.window());
4020+}
4021+
4022+MirSurface *SurfaceManager::find(const miral::Window &window) const
4023+{
4024+ Q_FOREACH(const auto surface, m_allSurfaces) {
4025+ if (surface->window() == window) {
4026+ return surface;
4027+ }
4028+ }
4029+ return nullptr;
4030+}
4031+
4032+void SurfaceManager::onWindowReady(const miral::WindowInfo &windowInfo)
4033+{
4034+ if (auto mirSurface = find(windowInfo)) {
4035+ mirSurface->setReady();
4036+ }
4037+}
4038+
4039+void SurfaceManager::onWindowMoved(const miral::WindowInfo &windowInfo, const QPoint topLeft)
4040+{
4041+ if (auto mirSurface = find(windowInfo)) {
4042+ mirSurface->setPosition(topLeft);
4043+ }
4044+}
4045+
4046+void SurfaceManager::onWindowFocusChanged(const miral::WindowInfo &windowInfo, bool focused)
4047+{
4048+ if (auto mirSurface = find(windowInfo)) {
4049+ mirSurface->setFocused(focused);
4050+ }
4051+}
4052+
4053+void SurfaceManager::onWindowStateChanged(const miral::WindowInfo &windowInfo, Mir::State state)
4054+{
4055+ if (auto mirSurface = find(windowInfo)) {
4056+ mirSurface->updateState(state);
4057+ }
4058+}
4059+
4060+void SurfaceManager::onWindowsRaised(const std::vector<miral::Window> &windows)
4061+{
4062+ // sad inefficiency when crossing API boundaries (from miral to qt)
4063+ const int raiseCount = windows.size();
4064+ QVector<unityapi::MirSurfaceInterface*> surfaces(raiseCount);
4065+ for (int i = 0; i < raiseCount; i++) {
4066+ auto mirSurface = find(windows[i]);
4067+ surfaces.append(mirSurface);
4068+ }
4069+ Q_EMIT surfacesRaised(surfaces);
4070+}
4071+
4072+void SurfaceManager::onWindowsRequestedRaise(const miral::WindowInfo &windowInfo)
4073+{
4074+ if (auto mirSurface = find(windowInfo)) {
4075+ mirSurface->requestFocus();
4076+ }
4077+}
4078+
4079+void SurfaceManager::raise(unityapi::MirSurfaceInterface *surface)
4080+{
4081+ auto qtmirSurface = static_cast<qtmir::MirSurface*>(surface);
4082+ m_windowController->raise(qtmirSurface->window());
4083+}
4084+
4085+void SurfaceManager::activate(unityapi::MirSurfaceInterface *surface)
4086+{
4087+ auto qtmirSurface = static_cast<qtmir::MirSurface*>(surface);
4088+ m_windowController->activate(qtmirSurface ? qtmirSurface->window() : miral::Window());
4089+}
4090
4091=== added file 'src/modules/Unity/Application/surfacemanager.h'
4092--- src/modules/Unity/Application/surfacemanager.h 1970-01-01 00:00:00 +0000
4093+++ src/modules/Unity/Application/surfacemanager.h 2016-12-01 11:46:42 +0000
4094@@ -0,0 +1,73 @@
4095+/*
4096+ * Copyright (C) 2016 Canonical, Ltd.
4097+ *
4098+ * This program is free software: you can redistribute it and/or modify it under
4099+ * the terms of the GNU Lesser General Public License version 3, as published by
4100+ * the Free Software Foundation.
4101+ *
4102+ * This program is distributed in the hope that it will be useful, but WITHOUT
4103+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
4104+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4105+ * Lesser General Public License for more details.
4106+ *
4107+ * You should have received a copy of the GNU Lesser General Public License
4108+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4109+ */
4110+
4111+#ifndef QTMIR_SURFACEMANAGER_H
4112+#define QTMIR_SURFACEMANAGER_H
4113+
4114+// common
4115+#include "windowmodelnotifier.h"
4116+
4117+// Unity API
4118+#include <unity/shell/application/SurfaceManagerInterface.h>
4119+
4120+#include <QVector>
4121+#include <QLoggingCategory>
4122+
4123+Q_DECLARE_LOGGING_CATEGORY(QTMIR_SURFACEMANAGER)
4124+
4125+namespace qtmir {
4126+
4127+class MirSurface;
4128+class SessionManager;
4129+class WindowControllerInterface;
4130+
4131+class SurfaceManager : public unity::shell::application::SurfaceManagerInterface
4132+{
4133+ Q_OBJECT
4134+
4135+public:
4136+ explicit SurfaceManager(QObject *parent = 0);
4137+ virtual ~SurfaceManager() {}
4138+
4139+ void raise(unity::shell::application::MirSurfaceInterface *surface) override;
4140+ void activate(unity::shell::application::MirSurfaceInterface *surface) override;
4141+
4142+private Q_SLOTS:
4143+ void onWindowAdded(const qtmir::NewWindow &windowInfo);
4144+ void onWindowRemoved(const miral::WindowInfo &windowInfo);
4145+ void onWindowReady(const miral::WindowInfo &windowInfo);
4146+ void onWindowMoved(const miral::WindowInfo &windowInfo, const QPoint topLeft);
4147+ void onWindowStateChanged(const miral::WindowInfo &windowInfo, Mir::State state);
4148+ void onWindowFocusChanged(const miral::WindowInfo &windowInfo, bool focused);
4149+ void onWindowsRaised(const std::vector<miral::Window> &windows);
4150+ void onWindowsRequestedRaise(const miral::WindowInfo &windowInfo);
4151+
4152+private:
4153+ void connectToWindowModelNotifier(WindowModelNotifier *notifier);
4154+ void rememberMirSurface(MirSurface *surface);
4155+ void forgetMirSurface(const miral::Window &window);
4156+ MirSurface* find(const miral::WindowInfo &needle) const;
4157+ MirSurface* find(const miral::Window &needle) const;
4158+
4159+ QVector<MirSurface*> m_allSurfaces;
4160+
4161+ WindowControllerInterface *m_windowController;
4162+ SessionManager* m_sessionManager;
4163+};
4164+
4165+} // namespace qtmir
4166+
4167+#endif // QTMIR_SURFACEMANAGER_H
4168
4169=== added file 'src/modules/Unity/Application/windowmodel.cpp'
4170--- src/modules/Unity/Application/windowmodel.cpp 1970-01-01 00:00:00 +0000
4171+++ src/modules/Unity/Application/windowmodel.cpp 2016-12-01 11:46:42 +0000
4172@@ -0,0 +1,235 @@
4173+/*
4174+ * Copyright (C) 2016 Canonical, Ltd.
4175+ *
4176+ * This program is free software: you can redistribute it and/or modify it under
4177+ * the terms of the GNU Lesser General Public License version 3, as published by
4178+ * the Free Software Foundation.
4179+ *
4180+ * This program is distributed in the hope that it will be useful, but WITHOUT
4181+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
4182+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4183+ * Lesser General Public License for more details.
4184+ *
4185+ * You should have received a copy of the GNU Lesser General Public License
4186+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4187+ */
4188+
4189+#include "windowmodel.h"
4190+
4191+#include "mirsurface.h"
4192+
4193+// mirserver
4194+#include "nativeinterface.h"
4195+
4196+// Qt
4197+#include <QGuiApplication>
4198+#include <QDebug>
4199+
4200+using namespace qtmir;
4201+
4202+WindowModel::WindowModel()
4203+{
4204+ auto nativeInterface = dynamic_cast<NativeInterface*>(QGuiApplication::platformNativeInterface());
4205+
4206+ if (!nativeInterface) {
4207+ qFatal("ERROR: Unity.Application QML plugin requires use of the 'mirserver' QPA plugin");
4208+ }
4209+
4210+ m_windowController = static_cast<WindowControllerInterface*>(nativeInterface->nativeResourceForIntegration("WindowController"));
4211+
4212+ auto windowModel = static_cast<WindowModelNotifier*>(nativeInterface->nativeResourceForIntegration("WindowModelNotifier"));
4213+ connectToWindowModelNotifier(windowModel);
4214+}
4215+
4216+WindowModel::WindowModel(WindowModelNotifier *notifier,
4217+ WindowControllerInterface *controller)
4218+ : m_windowController(controller)
4219+{
4220+ connectToWindowModelNotifier(notifier);
4221+}
4222+
4223+void WindowModel::connectToWindowModelNotifier(WindowModelNotifier *notifier)
4224+{
4225+ connect(notifier, &WindowModelNotifier::windowAdded, this, &WindowModel::onWindowAdded, Qt::QueuedConnection);
4226+ connect(notifier, &WindowModelNotifier::windowRemoved, this, &WindowModel::onWindowRemoved, Qt::QueuedConnection);
4227+ connect(notifier, &WindowModelNotifier::windowReady, this, &WindowModel::onWindowReady, Qt::QueuedConnection);
4228+ connect(notifier, &WindowModelNotifier::windowMoved, this, &WindowModel::onWindowMoved, Qt::QueuedConnection);
4229+ connect(notifier, &WindowModelNotifier::windowStateChanged, this, &WindowModel::onWindowStateChanged, Qt::QueuedConnection);
4230+ connect(notifier, &WindowModelNotifier::windowFocusChanged, this, &WindowModel::onWindowFocusChanged, Qt::QueuedConnection);
4231+ connect(notifier, &WindowModelNotifier::windowsRaised, this, &WindowModel::onWindowsRaised, Qt::QueuedConnection);
4232+}
4233+
4234+QHash<int, QByteArray> WindowModel::roleNames() const
4235+{
4236+ QHash<int, QByteArray> roleNames;
4237+ roleNames.insert(SurfaceRole, "surface");
4238+ return roleNames;
4239+}
4240+
4241+void WindowModel::onWindowAdded(const NewWindow &window)
4242+{
4243+ if (window.windowInfo.type() == mir_surface_type_inputmethod) {
4244+ addInputMethodWindow(window);
4245+ return;
4246+ }
4247+
4248+ const int index = m_windowModel.count();
4249+ beginInsertRows(QModelIndex(), index, index);
4250+ m_windowModel.append(new MirSurface(window, m_windowController));
4251+ endInsertRows();
4252+ Q_EMIT countChanged();
4253+}
4254+
4255+void WindowModel::onWindowRemoved(const miral::WindowInfo &windowInfo)
4256+{
4257+ if (windowInfo.type() == mir_surface_type_inputmethod) {
4258+ removeInputMethodWindow();
4259+ return;
4260+ }
4261+
4262+ const int index = findIndexOf(windowInfo.window());
4263+
4264+ beginRemoveRows(QModelIndex(), index, index);
4265+ m_windowModel.takeAt(index);
4266+ endRemoveRows();
4267+ Q_EMIT countChanged();
4268+}
4269+
4270+void WindowModel::onWindowReady(const miral::WindowInfo &windowInfo)
4271+{
4272+ if (auto mirSurface = find(windowInfo)) {
4273+ mirSurface->setReady();
4274+ }
4275+}
4276+
4277+void WindowModel::onWindowMoved(const miral::WindowInfo &windowInfo, const QPoint topLeft)
4278+{
4279+ if (auto mirSurface = find(windowInfo)) {
4280+ mirSurface->setPosition(topLeft);
4281+ }
4282+}
4283+
4284+void WindowModel::onWindowFocusChanged(const miral::WindowInfo &windowInfo, bool focused)
4285+{
4286+ if (auto mirSurface = find(windowInfo)) {
4287+ mirSurface->setFocused(focused);
4288+ }
4289+}
4290+
4291+void WindowModel::onWindowStateChanged(const miral::WindowInfo &windowInfo, Mir::State state)
4292+{
4293+ if (auto mirSurface = find(windowInfo)) {
4294+ mirSurface->updateState(state);
4295+ }
4296+}
4297+
4298+void WindowModel::addInputMethodWindow(const NewWindow &windowInfo)
4299+{
4300+ if (m_inputMethodSurface) {
4301+ qDebug("Multiple Input Method Surfaces created, removing the old one!");
4302+ delete m_inputMethodSurface;
4303+ }
4304+ m_inputMethodSurface = new MirSurface(windowInfo, m_windowController);
4305+ Q_EMIT inputMethodSurfaceChanged(m_inputMethodSurface);
4306+}
4307+
4308+void WindowModel::removeInputMethodWindow()
4309+{
4310+ if (m_inputMethodSurface) {
4311+ delete m_inputMethodSurface;
4312+ m_inputMethodSurface = nullptr;
4313+ Q_EMIT inputMethodSurfaceChanged(m_inputMethodSurface);
4314+ }
4315+}
4316+
4317+void WindowModel::onWindowsRaised(const std::vector<miral::Window> &windows)
4318+{
4319+ // Reminder: last item in the "windows" list should end up at the top of the model
4320+ const int modelCount = m_windowModel.count();
4321+ const int raiseCount = windows.size();
4322+
4323+ // Assumption: no NO-OPs are in this list - Qt will crash on endMoveRows() if you try NO-OPs!!!
4324+ // A NO-OP is if
4325+ // 1. "indices" is an empty list
4326+ // 2. "indices" of the form (..., modelCount - 2, modelCount - 1) which results in an unchanged list
4327+
4328+ // Precompute the list of indices of Windows/Surfaces to raise, including the offsets due to
4329+ // indices which have already been moved.
4330+ QVector<QPair<int /*from*/, int /*to*/>> moveList;
4331+
4332+ for (int i=raiseCount-1; i>=0; i--) {
4333+ int from = findIndexOf(windows[i]);
4334+ const int to = modelCount - raiseCount + i;
4335+
4336+ int moveCount = 0;
4337+ // how many list items under "index" have been moved so far, correct "from" to suit
4338+ for (int j=raiseCount-1; j>i; j--) {
4339+ if (findIndexOf(windows[j]) < from) {
4340+ moveCount++;
4341+ }
4342+ }
4343+ from -= moveCount;
4344+
4345+ if (from == to) {
4346+ // is NO-OP, would result in moving element to itself
4347+ } else {
4348+ moveList.prepend({from, to});
4349+ }
4350+ }
4351+
4352+ // Perform the moving, trusting the moveList is correct for each iteration.
4353+ QModelIndex parent;
4354+ for (int i=moveList.count()-1; i>=0; i--) {
4355+ const int from = moveList[i].first;
4356+ const int to = moveList[i].second;
4357+
4358+ beginMoveRows(parent, from, from, parent, to+1);
4359+#if QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
4360+ const auto &window = m_windowModel.takeAt(from);
4361+ m_windowModel.insert(to, window);
4362+#else
4363+ m_windowModel.move(from, to);
4364+#endif
4365+
4366+ endMoveRows();
4367+ }
4368+}
4369+
4370+int WindowModel::rowCount(const QModelIndex &/*parent*/) const
4371+{
4372+ return m_windowModel.count();
4373+}
4374+
4375+QVariant WindowModel::data(const QModelIndex &index, int role) const
4376+{
4377+ if (index.row() < 0 || index.row() >= m_windowModel.count())
4378+ return QVariant();
4379+
4380+ if (role == SurfaceRole) {
4381+ auto &surface = m_windowModel.at(index.row());
4382+ return QVariant::fromValue(surface);
4383+ } else {
4384+ return QVariant();
4385+ }
4386+}
4387+
4388+MirSurface *WindowModel::find(const miral::WindowInfo &needle) const
4389+{
4390+ auto window = needle.window();
4391+ Q_FOREACH(const auto mirSurface, m_windowModel) {
4392+ if (mirSurface->window() == window) {
4393+ return mirSurface;
4394+ }
4395+ }
4396+ return nullptr;
4397+}
4398+
4399+int WindowModel::findIndexOf(const miral::Window &needle) const
4400+{
4401+ for (int i=0; i<m_windowModel.count(); i++) {
4402+ if (m_windowModel[i]->window() == needle) {
4403+ return i;
4404+ }
4405+ }
4406+ return -1;
4407+}
4408
4409=== added file 'src/modules/Unity/Application/windowmodel.h'
4410--- src/modules/Unity/Application/windowmodel.h 1970-01-01 00:00:00 +0000
4411+++ src/modules/Unity/Application/windowmodel.h 2016-12-01 11:46:42 +0000
4412@@ -0,0 +1,83 @@
4413+/*
4414+ * Copyright (C) 2016 Canonical, Ltd.
4415+ *
4416+ * This program is free software: you can redistribute it and/or modify it under
4417+ * the terms of the GNU Lesser General Public License version 3, as published by
4418+ * the Free Software Foundation.
4419+ *
4420+ * This program is distributed in the hope that it will be useful, but WITHOUT
4421+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
4422+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4423+ * Lesser General Public License for more details.
4424+ *
4425+ * You should have received a copy of the GNU Lesser General Public License
4426+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4427+ */
4428+
4429+#ifndef WINDOWMODEL_H
4430+#define WINDOWMODEL_H
4431+
4432+#include <QAbstractListModel>
4433+
4434+#include "mirsurface.h"
4435+#include "windowmodelnotifier.h"
4436+
4437+namespace qtmir {
4438+
4439+class WindowControllerInterface;
4440+
4441+class WindowModel : public QAbstractListModel
4442+{
4443+ Q_OBJECT
4444+
4445+ Q_PROPERTY(int count READ count NOTIFY countChanged)
4446+
4447+ Q_PROPERTY(MirSurfaceInterface* inputMethodSurface READ inputMethodSurface NOTIFY inputMethodSurfaceChanged)
4448+
4449+public:
4450+ enum Roles {
4451+ SurfaceRole = Qt::UserRole
4452+ };
4453+
4454+ WindowModel();
4455+ explicit WindowModel(WindowModelNotifier *notifier,
4456+ WindowControllerInterface *controller); // For testing
4457+
4458+ // QAbstractItemModel methods
4459+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
4460+ QVariant data(const QModelIndex& index, int role) const override;
4461+
4462+ QHash<int, QByteArray> roleNames() const override;
4463+
4464+ int count() const { return rowCount(); }
4465+
4466+ MirSurface* inputMethodSurface() const { return m_inputMethodSurface; }
4467+
4468+Q_SIGNALS:
4469+ void countChanged();
4470+ void inputMethodSurfaceChanged(MirSurfaceInterface* inputMethodSurface);
4471+
4472+private Q_SLOTS:
4473+ void onWindowAdded(const qtmir::NewWindow &windowInfo);
4474+ void onWindowRemoved(const miral::WindowInfo &windowInfo);
4475+ void onWindowReady(const miral::WindowInfo &windowInfo);
4476+ void onWindowMoved(const miral::WindowInfo &windowInfo, const QPoint topLeft);
4477+ void onWindowStateChanged(const miral::WindowInfo &windowInfo, Mir::State state);
4478+ void onWindowFocusChanged(const miral::WindowInfo &windowInfo, bool focused);
4479+ void onWindowsRaised(const std::vector<miral::Window> &windows);
4480+
4481+private:
4482+ void connectToWindowModelNotifier(WindowModelNotifier *notifier);
4483+
4484+ void addInputMethodWindow(const NewWindow &windowInfo);
4485+ void removeInputMethodWindow();
4486+ MirSurface* find(const miral::WindowInfo &needle) const;
4487+ int findIndexOf(const miral::Window &needle) const;
4488+
4489+ QVector<MirSurface*> m_windowModel;
4490+ WindowControllerInterface *m_windowController;
4491+ MirSurface* m_inputMethodSurface{nullptr};
4492+};
4493+
4494+} // namespace qtmir
4495+#endif // WINDOWMODEL_H
4496
4497=== modified file 'src/modules/Unity/Screens/CMakeLists.txt'
4498--- src/modules/Unity/Screens/CMakeLists.txt 2016-06-06 18:12:07 +0000
4499+++ src/modules/Unity/Screens/CMakeLists.txt 2016-12-01 11:46:42 +0000
4500@@ -4,9 +4,9 @@
4501
4502 include_directories(
4503 SYSTEM
4504+ ${MIRCLIENT_INCLUDE_DIRS}
4505 ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
4506 ${Qt5Quick_INCLUDE_DIRS}
4507- ${MIRSERVER_INCLUDE_DIRS}
4508 )
4509
4510 set(SCREENSPLUGIN_SRC
4511
4512=== modified file 'src/modules/Unity/Screens/plugin.cpp'
4513--- src/modules/Unity/Screens/plugin.cpp 2016-04-29 15:41:00 +0000
4514+++ src/modules/Unity/Screens/plugin.cpp 2016-12-01 11:46:42 +0000
4515@@ -36,7 +36,7 @@
4516 qRegisterMetaType<QScreen*>("QScreen*");
4517
4518 qmlRegisterType<qtmir::Screens>(uri, 0, 1, "Screens");
4519- qRegisterMetaType<qtmir::Screens::FormFactor>("Screens::FormFactor");
4520+ qRegisterMetaType<qtmir::FormFactor>("qtmir::FormFactor");
4521
4522 qmlRegisterType<qtmir::QQuickScreenWindow>(uri, 0, 1, "ScreenWindow");
4523 }
4524
4525=== modified file 'src/modules/Unity/Screens/qquickscreenwindow.cpp'
4526--- src/modules/Unity/Screens/qquickscreenwindow.cpp 2016-06-06 19:25:20 +0000
4527+++ src/modules/Unity/Screens/qquickscreenwindow.cpp 2016-12-01 11:46:42 +0000
4528@@ -48,7 +48,7 @@
4529 QQuickScreenWindow::QQuickScreenWindow(QQuickWindow *parent)
4530 : QQuickWindow(parent)
4531 , m_scale(-1.0) // start with invalid initial state, fetch correct value on first invokation
4532- , m_formFactor(Screens::FormFactorUnknown)
4533+ , m_formFactor(FormFactorUnknown)
4534 {
4535 if (qGuiApp->platformName() == QLatin1String("mirserver")) {
4536 connect(qGuiApp->platformNativeInterface(), &QPlatformNativeInterface::windowPropertyChanged,
4537@@ -91,7 +91,7 @@
4538 return m_scale;
4539 }
4540
4541-bool QQuickScreenWindow::setScaleAndFormFactor(const float scale, const Screens::FormFactor formFactor)
4542+bool QQuickScreenWindow::setScaleAndFormFactor(const float scale, const FormFactor formFactor)
4543 {
4544 if (qFuzzyCompare(scale, m_scale) && formFactor == m_formFactor) {
4545 return true;
4546@@ -125,9 +125,9 @@
4547 return controller->setConfiguration(configs);
4548 }
4549
4550-Screens::FormFactor QQuickScreenWindow::formFactor()
4551+FormFactor QQuickScreenWindow::formFactor()
4552 {
4553- if (m_formFactor == Screens::FormFactorUnknown) {
4554+ if (m_formFactor == FormFactorUnknown) {
4555 m_formFactor = getFormFactorNativeProperty();
4556 }
4557 return m_formFactor;
4558@@ -173,7 +173,7 @@
4559 return scale;
4560 }
4561
4562-Screens::FormFactor QQuickScreenWindow::getFormFactorNativeProperty() const
4563+FormFactor QQuickScreenWindow::getFormFactorNativeProperty() const
4564 {
4565 QVariant formFactorVal = qGuiApp->platformNativeInterface()
4566 ->windowProperty(handle(), QStringLiteral("formFactor"));
4567@@ -181,5 +181,5 @@
4568 return m_formFactor;
4569 }
4570
4571- return static_cast<Screens::FormFactor>(formFactorVal.toInt());
4572+ return static_cast<FormFactor>(formFactorVal.toInt());
4573 }
4574
4575=== modified file 'src/modules/Unity/Screens/qquickscreenwindow.h'
4576--- src/modules/Unity/Screens/qquickscreenwindow.h 2016-01-28 23:32:53 +0000
4577+++ src/modules/Unity/Screens/qquickscreenwindow.h 2016-12-01 11:46:42 +0000
4578@@ -28,7 +28,7 @@
4579
4580 Q_PROPERTY(QScreen *screen READ screen WRITE setScreen NOTIFY screenChanged)
4581 Q_PROPERTY(float scale READ scale NOTIFY scaleChanged)
4582- Q_PROPERTY(Screens::FormFactor formFactor READ formFactor NOTIFY formFactorChanged)
4583+ Q_PROPERTY(FormFactor formFactor READ formFactor NOTIFY formFactorChanged)
4584
4585 public:
4586 explicit QQuickScreenWindow(QQuickWindow *parent = 0);
4587@@ -37,13 +37,13 @@
4588 void setScreen(QScreen *screen);
4589
4590 qreal scale();
4591- Screens::FormFactor formFactor();
4592- Q_INVOKABLE bool setScaleAndFormFactor(const float scale, const Screens::FormFactor formFactor);
4593+ FormFactor formFactor();
4594+ Q_INVOKABLE bool setScaleAndFormFactor(const float scale, const FormFactor formFactor);
4595
4596 Q_SIGNALS:
4597 void screenChanged(QScreen *screen);
4598 void scaleChanged(qreal scale);
4599- void formFactorChanged(Screens::FormFactor arg);
4600+ void formFactorChanged(FormFactor arg);
4601
4602 private Q_SLOTS:
4603 void nativePropertyChanged(QPlatformWindow *window, const QString &propertyName);
4604@@ -51,8 +51,8 @@
4605 private:
4606 float getScaleNativeProperty() const;
4607 float m_scale;
4608- Screens::FormFactor getFormFactorNativeProperty() const;
4609- Screens::FormFactor m_formFactor;
4610+ FormFactor getFormFactorNativeProperty() const;
4611+ FormFactor m_formFactor;
4612 };
4613
4614 } //namespace qtmir
4615
4616=== modified file 'src/modules/Unity/Screens/screens.cpp'
4617--- src/modules/Unity/Screens/screens.cpp 2016-04-29 15:41:00 +0000
4618+++ src/modules/Unity/Screens/screens.cpp 2016-12-01 11:46:42 +0000
4619@@ -62,7 +62,7 @@
4620 case OutputTypeRole: {
4621 auto screen = static_cast<Screen*>(m_screenList.at(index.row())->handle());
4622 if (screen) {
4623- return QVariant(static_cast<OutputTypes>(screen->outputType())); //FIXME: cheeky
4624+ return QVariant(screen->outputType());
4625 } else {
4626 return OutputTypes::Unknown;
4627 }
4628
4629=== modified file 'src/modules/Unity/Screens/screens.h'
4630--- src/modules/Unity/Screens/screens.h 2016-04-29 15:41:00 +0000
4631+++ src/modules/Unity/Screens/screens.h 2016-12-01 11:46:42 +0000
4632@@ -17,6 +17,8 @@
4633 #ifndef SCREENS_H
4634 #define SCREENS_H
4635
4636+#include "screentypes.h"
4637+
4638 #include <QAbstractListModel>
4639
4640 class QScreen;
4641@@ -39,33 +41,6 @@
4642 FormFactorRole,
4643 };
4644
4645- enum OutputTypes {
4646- Unknown,
4647- VGA,
4648- DVII,
4649- DVID,
4650- DVIA,
4651- Composite,
4652- SVideo,
4653- LVDS,
4654- Component,
4655- NinePinDIN,
4656- DisplayPort,
4657- HDMIA,
4658- HDMIB,
4659- TV,
4660- EDP
4661- };
4662-
4663- enum FormFactor {
4664- FormFactorUnknown,
4665- FormFactorPhone,
4666- FormFactorTablet,
4667- FormFactorMonitor,
4668- FormFactorTV,
4669- FormFactorProjector,
4670- };
4671-
4672 explicit Screens(QObject *parent = 0);
4673 virtual ~Screens() noexcept = default;
4674
4675@@ -91,6 +66,4 @@
4676
4677 } // namespace qtmir
4678
4679-Q_DECLARE_METATYPE(qtmir::Screens::FormFactor)
4680-
4681 #endif // SCREENS_H
4682
4683=== modified file 'src/platforms/mirserver/CMakeLists.txt'
4684--- src/platforms/mirserver/CMakeLists.txt 2016-09-08 22:46:57 +0000
4685+++ src/platforms/mirserver/CMakeLists.txt 2016-12-01 11:46:42 +0000
4686@@ -25,11 +25,11 @@
4687
4688 include_directories(
4689 ${CMAKE_SOURCE_DIR}/src/common
4690-
4691 )
4692
4693 include_directories(
4694- SYSTEM
4695+ SYSTEM
4696+ ${MIRAL_INCLUDE_DIRS}
4697 ${MIRCOMMON_INCLUDE_DIRS}
4698 ${MIRSERVER_INCLUDE_DIRS}
4699 ${MIRRENDERERGLDEV_INCLUDE_DIRS}
4700@@ -53,56 +53,70 @@
4701 # Needed to compile tracepoints in C99 mode.
4702 add_definitions(-DBYTE_ORDER=__BYTE_ORDER)
4703
4704-set(MIRSERVER_QPA_PLUGIN_SRC
4705- ${CMAKE_SOURCE_DIR}/src/common/debughelpers.cpp
4706+# These files will compile without mirserver-dev
4707+add_library(qpa-mirserver-nomirserver OBJECT
4708 ${CMAKE_SOURCE_DIR}/src/common/timestamp.cpp
4709- cursor.cpp
4710- eventbuilder.cpp
4711 logging.cpp
4712+ plugin.cpp
4713+ shelluuid.cpp
4714+ ubuntutheme.cpp
4715+ clipboard.cpp
4716+ openglcontextfactory.cpp openglcontextfactory.h
4717 mircursorimages.cpp
4718 mirdisplayconfigurationpolicy.cpp
4719- mirwindowmanager.cpp
4720 mirsingleton.cpp
4721+ sessionauthorizer.cpp
4722+ promptsessionlistener.cpp
4723+ mirserverstatuslistener.cpp
4724+ screenscontroller.cpp
4725+ nativeinterface.cpp
4726+ qtcompositor.cpp
4727+ services.cpp
4728+ windowcontroller.cpp
4729+ windowmanagementpolicy.cpp
4730+ mirserverhooks.cpp mirserverhooks.h
4731+ setqtcompositor.cpp setqtcompositor.h
4732+ tracepoints.c
4733+# We need to run moc on these headers
4734+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/Mir.h
4735+ ${CMAKE_SOURCE_DIR}/src/common/appnotifier.h
4736+ ${CMAKE_SOURCE_DIR}/src/common/windowcontrollerinterface.h
4737+ ${CMAKE_SOURCE_DIR}/src/common/windowmodelnotifier.h
4738+)
4739+set_source_files_properties(tracepoints.c PROPERTIES COMPILE_FLAGS "${CMAKE_CFLAGS} -fPIC")
4740+
4741+include_directories(SYSTEM ${MIRSERVER_INCLUDE_DIRS})
4742+
4743+set(MIRSERVER_QPA_PLUGIN_SRC
4744+ ${CMAKE_SOURCE_DIR}/src/common/debughelpers.cpp
4745+ cursor.cpp
4746+ eventbuilder.cpp
4747 qteventfeeder.cpp
4748- plugin.cpp
4749 qmirserver.cpp
4750 qmirserver_p.cpp
4751- sessionauthorizer.cpp
4752- sessionlistener.cpp
4753- shelluuid.cpp
4754 surfaceobserver.cpp
4755- promptsessionlistener.cpp
4756- mirserver.cpp
4757- mirserverstatuslistener.cpp
4758 screen.cpp
4759 screenwindow.cpp
4760- screenscontroller.cpp
4761 screensmodel.cpp
4762 mirserverintegration.cpp
4763 miropenglcontext.cpp
4764- nativeinterface.cpp
4765 offscreensurface.cpp
4766- qtcompositor.cpp
4767- services.cpp
4768- ubuntutheme.cpp
4769- clipboard.cpp
4770- creationhints.cpp
4771- tracepoints.c
4772+ promptsessionmanager.cpp promptsessionmanager.h promptsession.h
4773 # We need to run moc on these headers
4774- ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/Mir.h
4775 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirMousePointerInterface.h
4776- )
4777+)
4778
4779 add_library(qpa-mirserver SHARED
4780 ${MIRSERVER_QPA_PLUGIN_SRC}
4781+ $<TARGET_OBJECTS:qpa-mirserver-nomirserver>
4782 )
4783
4784 target_link_libraries(
4785 qpa-mirserver
4786 Qt5PlatformSupport
4787
4788+ ${MIRAL_LDFLAGS}
4789 ${MIRSERVER_LDFLAGS}
4790- ${MIRCLIENT_LDFLAGS}
4791 ${URL_DISPATCHER_LDFLAGS}
4792 ${EGL_LDFLAGS}
4793 ${GL_LIBRARIES}
4794
4795=== removed file 'src/platforms/mirserver/creationhints.cpp'
4796--- src/platforms/mirserver/creationhints.cpp 2016-06-06 19:25:20 +0000
4797+++ src/platforms/mirserver/creationhints.cpp 1970-01-01 00:00:00 +0000
4798@@ -1,67 +0,0 @@
4799-/*
4800- * Copyright (C) 2016 Canonical, Ltd.
4801- *
4802- * This program is free software: you can redistribute it and/or modify it under
4803- * the terms of the GNU Lesser General Public License version 3, as published by
4804- * the Free Software Foundation.
4805- *
4806- * This program is distributed in the hope that it will be useful, but WITHOUT
4807- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
4808- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4809- * Lesser General Public License for more details.
4810- *
4811- * You should have received a copy of the GNU Lesser General Public License
4812- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4813- */
4814-
4815-#include <mir/scene/surface_creation_parameters.h>
4816-
4817-#include "creationhints.h"
4818-
4819-using namespace qtmir;
4820-
4821-inline const char* shellChromeToString(Mir::ShellChrome chrome) {
4822- switch (chrome) {
4823- case Mir::ShellChrome::NormalChrome:
4824- return "normal";
4825- case Mir::ShellChrome::LowChrome:
4826- return "low";
4827- }
4828- return "unknown";
4829-}
4830-
4831-CreationHints::CreationHints(const mir::scene::SurfaceCreationParameters &params)
4832-{
4833- minWidth = params.min_width.is_set() ? params.min_width.value().as_int() : 0;
4834- maxWidth = params.max_width.is_set() ? params.max_width.value().as_int() : 0;
4835-
4836- minHeight = params.min_height.is_set() ? params.min_height.value().as_int() : 0;
4837- maxHeight = params.max_height.is_set() ? params.max_height.value().as_int() : 0;
4838-
4839- widthIncrement = params.width_inc.is_set() ? params.width_inc.value().as_int() : 0;
4840- heightIncrement = params.height_inc.is_set() ? params.height_inc.value().as_int() : 0;
4841-
4842- if (params.shell_chrome.is_set()) {
4843- switch (params.shell_chrome.value()) {
4844- case mir_shell_chrome_normal:
4845- default:
4846- shellChrome = Mir::ShellChrome::NormalChrome;
4847- break;
4848- case mir_shell_chrome_low:
4849- shellChrome = Mir::ShellChrome::LowChrome;
4850- break;
4851- }
4852- }
4853-}
4854-
4855-QString CreationHints::toString() const
4856-{
4857- return QStringLiteral("CreationHints(minW=%1,minH=%2,maxW=%3,maxH=%4,wIncr=%5,hInc=%6,shellChrome=%7)")
4858- .arg(minWidth)
4859- .arg(minHeight)
4860- .arg(maxWidth)
4861- .arg(maxHeight)
4862- .arg(widthIncrement)
4863- .arg(heightIncrement)
4864- .arg(shellChromeToString(shellChrome));
4865-}
4866
4867=== removed file 'src/platforms/mirserver/creationhints.h'
4868--- src/platforms/mirserver/creationhints.h 2016-06-06 19:25:20 +0000
4869+++ src/platforms/mirserver/creationhints.h 1970-01-01 00:00:00 +0000
4870@@ -1,56 +0,0 @@
4871-/*
4872- * Copyright (C) 2016 Canonical, Ltd.
4873- *
4874- * This program is free software: you can redistribute it and/or modify it under
4875- * the terms of the GNU Lesser General Public License version 3, as published by
4876- * the Free Software Foundation.
4877- *
4878- * This program is distributed in the hope that it will be useful, but WITHOUT
4879- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
4880- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4881- * Lesser General Public License for more details.
4882- *
4883- * You should have received a copy of the GNU Lesser General Public License
4884- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4885- */
4886-
4887-#ifndef QTMIR_CREATIONHINTS_H
4888-#define QTMIR_CREATIONHINTS_H
4889-
4890-#include <QMetaType>
4891-#include <QString>
4892-
4893-#include <unity/shell/application/Mir.h>
4894-
4895-namespace mir {
4896- namespace scene {
4897- struct SurfaceCreationParameters;
4898- }
4899-}
4900-
4901-namespace qtmir {
4902-
4903-class CreationHints {
4904-public:
4905- CreationHints() {}
4906- CreationHints(const mir::scene::SurfaceCreationParameters&);
4907-
4908- QString toString() const;
4909-
4910- int minWidth{0};
4911- int maxWidth{0};
4912-
4913- int minHeight{0};
4914- int maxHeight{0};
4915-
4916- int widthIncrement{0};
4917- int heightIncrement{0};
4918-
4919- Mir::ShellChrome shellChrome{Mir::ShellChrome::NormalChrome};
4920-};
4921-
4922-} // namespace qtmir
4923-
4924-Q_DECLARE_METATYPE(qtmir::CreationHints)
4925-
4926-#endif // QTMIR_CREATIONHINTS_H
4927
4928=== modified file 'src/platforms/mirserver/cursor.cpp'
4929--- src/platforms/mirserver/cursor.cpp 2016-08-08 13:10:40 +0000
4930+++ src/platforms/mirserver/cursor.cpp 2016-12-01 11:46:42 +0000
4931@@ -69,7 +69,7 @@
4932 // just different from the previous custom cursor name, which is enough to trigger a change in the cursor
4933 // source image URL in the QML side which on is turn makes QML request the new cursor image.
4934 static quint8 serialNumber = 1;
4935- m_qtCursorName = QStringLiteral("custom%1").arg(serialNumber++);
4936+ m_qtCursorName = QString("custom%1").arg(serialNumber++);
4937 m_mousePointer->setCustomCursor(*windowCursor);
4938 }
4939 } else {
4940
4941=== modified file 'src/platforms/mirserver/customscreenconfiguration.h'
4942--- src/platforms/mirserver/customscreenconfiguration.h 2016-01-11 14:29:06 +0000
4943+++ src/platforms/mirserver/customscreenconfiguration.h 2016-12-01 11:46:42 +0000
4944@@ -20,11 +20,13 @@
4945 #include <QPoint>
4946 #include <QVector>
4947
4948-#include <mir/graphics/display_configuration.h>
4949+#include "screentypes.h"
4950+#include <mir_toolkit/common.h>
4951+
4952
4953 struct CustomScreenConfiguration
4954 {
4955- mir::graphics::DisplayConfigurationOutputId id;
4956+ qtmir::OutputId id;
4957
4958 QPoint topLeft;
4959 uint32_t currentModeIndex;
4960
4961=== modified file 'src/platforms/mirserver/mirdisplayconfigurationpolicy.cpp'
4962--- src/platforms/mirserver/mirdisplayconfigurationpolicy.cpp 2016-04-29 15:41:00 +0000
4963+++ src/platforms/mirserver/mirdisplayconfigurationpolicy.cpp 2016-12-01 11:46:42 +0000
4964@@ -16,8 +16,10 @@
4965
4966 #include "mirdisplayconfigurationpolicy.h"
4967
4968+#include <mir/graphics/display_configuration_policy.h>
4969 #include <mir/graphics/display_configuration.h>
4970 #include <mir/geometry/point.h>
4971+#include <mir/server.h>
4972
4973 #include <qglobal.h>
4974 #include <QByteArray>
4975@@ -28,6 +30,18 @@
4976 #define DEFAULT_GRID_UNIT_PX 8
4977
4978 namespace {
4979+class MirDisplayConfigurationPolicy : public mir::graphics::DisplayConfigurationPolicy
4980+{
4981+public:
4982+ MirDisplayConfigurationPolicy(const std::shared_ptr<mir::graphics::DisplayConfigurationPolicy> &wrapped);
4983+
4984+ void apply_to(mir::graphics::DisplayConfiguration &conf) override;
4985+
4986+private:
4987+ const std::shared_ptr<mir::graphics::DisplayConfigurationPolicy> m_wrapped;
4988+ float m_defaultScale;
4989+};
4990+
4991 static float getenvFloat(const char* name, float defaultValue)
4992 {
4993 QByteArray stringValue = qgetenv(name);
4994@@ -35,7 +49,6 @@
4995 float value = stringValue.toFloat(&ok);
4996 return ok ? value : defaultValue;
4997 }
4998-} //namespace
4999
5000 MirDisplayConfigurationPolicy::MirDisplayConfigurationPolicy(
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches