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

Proposed by Daniel d'Andrada on 2016-11-03
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 continuous-integration Needs Fixing on 2016-12-01
Mir development team 2016-11-03 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.
572. By Daniel d'Andrada on 2016-11-03

Bump miral version dependency

573. By Daniel d'Andrada on 2016-11-04

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

574. By Daniel d'Andrada on 2016-11-04

Clean up debug messages

575. By Daniel d'Andrada on 2016-11-04

Fix MirSurface::setReady()

576. By Daniel d'Andrada on 2016-11-07

Let TopLevelWindowModel unset the surface

Otherwise it will mess up with TopLevelWindowModel logic.

577. By Daniel d'Andrada on 2016-11-07

Fix package build

578. By Daniel d'Andrada on 2016-11-09

Fix memory leak when removing an application

579. By Gerry Boland on 2016-11-09

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

580. By Gerry Boland on 2016-11-16

Fix handling of command line arguments

581. By Daniel d'Andrada on 2016-11-17

Move TopLevelWindowModel out of qtmir. Export a SurfaceManager instead

582. By Daniel d'Andrada on 2016-11-24

MirSurface::activate()

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

583. By Daniel d'Andrada on 2016-11-25

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

+ Update mirSurfaceTypeToStr

584. By Daniel d'Andrada on 2016-12-01

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

585. By Daniel d'Andrada on 2016-12-01

Fix order of entries in debian/changelog

586. By Daniel d'Andrada on 2016-12-05

Add missing license header

587. By Daniel d'Andrada on 2016-12-07

findApplicationWithSurface is const

588. By Daniel d'Andrada on 2016-12-13

Mir 0.25 compat (merging upcoming trunk)

589. By Daniel d'Andrada on 2016-12-13

Bump dependency version of other mir packages

590. By Daniel d'Andrada on 2016-12-16

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