Merge lp:~gerboland/miral/add-interactivity-to-WM into lp:miral

Proposed by Gerry Boland
Status: Merged
Merged at revision: 271
Proposed branch: lp:~gerboland/miral/add-interactivity-to-WM
Merge into: lp:miral
Diff against target: 2067 lines (+752/-431)
22 files modified
miral-qt/demos/qml-demo-shell/windowModel.qml (+104/-25)
miral-qt/src/common/windowcontrollerinterface.h (+53/-0)
miral-qt/src/common/windowmodelinterface.h (+36/-30)
miral-qt/src/modules/Unity/Application/mirsurface.cpp (+152/-124)
miral-qt/src/modules/Unity/Application/mirsurface.h (+12/-30)
miral-qt/src/modules/Unity/Application/mirsurfaceinterface.h (+1/-7)
miral-qt/src/modules/Unity/Application/mirsurfacemanager.cpp (+54/-54)
miral-qt/src/modules/Unity/Application/windowmodel.cpp (+43/-29)
miral-qt/src/modules/Unity/Application/windowmodel.h (+9/-2)
miral-qt/src/platforms/mirserver/CMakeLists.txt (+2/-0)
miral-qt/src/platforms/mirserver/mirserver.cpp (+3/-4)
miral-qt/src/platforms/mirserver/mirserver.h (+4/-2)
miral-qt/src/platforms/mirserver/qmirserver.cpp (+2/-2)
miral-qt/src/platforms/mirserver/windowcontroller.cpp (+85/-0)
miral-qt/src/platforms/mirserver/windowcontroller.h (+51/-0)
miral-qt/src/platforms/mirserver/windowmanagementpolicy.cpp (+48/-20)
miral-qt/src/platforms/mirserver/windowmanagementpolicy.h (+13/-8)
miral-qt/src/platforms/mirserver/windowmodel.cpp (+10/-26)
miral-qt/tests/framework/fake_mirsurface.cpp (+6/-4)
miral-qt/tests/framework/fake_mirsurface.h (+5/-10)
miral-qt/tests/modules/SurfaceManager/CMakeLists.txt (+3/-1)
miral-qt/tests/modules/SurfaceManager/mirsurface_test.cpp (+56/-53)
To merge this branch: bzr merge lp:~gerboland/miral/add-interactivity-to-WM
Reviewer Review Type Date Requested Status
Alan Griffiths Approve
Review via email: mp+302531@code.launchpad.net

Commit message

[miral-qt] Refactor out MirSurfaceManager and replace with qtmir::WindowModel. Add WindowController which enables window move & resize.

- MirSurfaceManager managed lifetimes of MirSurfaces. With MirAL, this responsibility must move to the WindowModel. Will fully remove MirSurfaceManager in a later MP (commented out for now).
- WindowController allows shell to control the window manager
- MirSurface refactored to wrap miral::WindowInfo which has nearly all the info it needs, and given access to the WindowController.
- redid the signal/slot interface between mirserver::WindowModel and qtmir::WindowModel to reduce the amount of traffic and better reflect the miral API.
- mir::shell::Shell no longer exported in the top-level MirServer class.

To post a comment you must log in.
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

With Vivid+Overlay/clang I need:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function"
Q_DECLARE_OPERATORS_FOR_FLAGS(DirtyStates)
#pragma clang diagnostic pop

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

/home/alan/display_server/miral/miral-qt/tests/modules/Application/application_test.cpp:287:35: error: allocating an object of abstract class type 'qtmir::FakeMirSurface'
    FakeMirSurface *surface = new FakeMirSurface;
                                  ^
/home/alan/display_server/miral/miral-qt/src/modules/Unity/Application/mirsurfaceinterface.h:52:18: note: unimplemented pure virtual method 'requestPosition' in 'FakeMirSurface'
    virtual void requestPosition(const QPoint newPosition) = 0;
                 ^
/home/alan/display_server/miral/miral-qt/src/modules/Unity/Application/mirsurfaceinterface.h:121:18: note: unimplemented pure virtual method 'setShellChrome' in 'FakeMirSurface'
    virtual void setShellChrome(Mir::ShellChrome shellChrome) = 0;
                 ^

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Possibly not new with this MP, but after starting "qml-demo-shell --x11-displays 648x480" and running mir_demo_client_egltriangle to try move/resize the server crashed when I closed the client.

Revision history for this message
Gerry Boland (gerboland) wrote :

That's what I get for leaving NO_TESTS=1 set!

I've made whatever tests that should be workable compile - they fail still. Other tests I've not updated until the functionality they rely on has been restored.

On your crash find, I cannot reproduce it here. Could you grab me a backtrace?

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Crash seems fairly consistent. If it matters, this is g++/yakkety:

Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00007fdbe02508fb in qtmir::MirSurface::updateTexture (this=0x55d46b5f13a0)
    at /home/alan/display_server/miral0/miral-qt/src/modules/Unity/Application/mirsurface.cpp:406
406 auto renderables = window->generate_renderables(userId);
[Current thread is 1 (Thread 0x7fdbce4d5700 (LWP 9694))]
(gdb) bt
#0 0x00007fdbe02508fb in qtmir::MirSurface::updateTexture (this=0x55d46b5f13a0)
    at /home/alan/display_server/miral0/miral-qt/src/modules/Unity/Application/mirsurface.cpp:406
#1 0x00007fdbe025bf81 in qtmir::MirSurfaceItem::updatePaintNode (
    this=0x55d46b418ac0, oldNode=0x7fdbc4569bd0)
    at /home/alan/display_server/miral0/miral-qt/src/modules/Unity/Application/mirsurfaceitem.cpp:226
#2 0x00007fdc011132c8 in QQuickWindowPrivate::updateDirtyNode(QQuickItem*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Quick.so.5
#3 0x00007fdc01113b3b in QQuickWindowPrivate::updateDirtyNodes() ()
   from /usr/lib/x86_64-linux-gnu/libQt5Quick.so.5
#4 0x00007fdc01113cb0 in QQuickWindowPrivate::syncSceneGraph() ()
   from /usr/lib/x86_64-linux-gnu/libQt5Quick.so.5
#5 0x00007fdc010e4d53 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Quick.so.5
#6 0x00007fdc010e5f95 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Quick.so.5
#7 0x00007fdc010eb07c in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Quick.so.5
#8 0x00007fdc001d77be in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#9 0x00007fdbff2ab70a in start_thread (arg=0x7fdbce4d5700) at pthread_create.c:333
#10 0x00007fdbff8d06ad in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

On balance I think it better to land this "wiring" than to try to perfect it first.

~~~~

+#include "miral/window_info.h"

Once MirAL supports everything we need we intend to separate the Qt use of MirAL from the project. So I'd be inclined to use <> includes for miral headers.

~~~~

I see this a few times: "static_cast<std::shared_ptr<mir::scene::Surface>>(m_windowInfo.window);" but I don't see why you use the cast operator. Ideally we don't want Qt to use mir::xxx::Yyy, so is this just a tag to review later?

review: Approve
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> With Vivid+Overlay/clang I need:
>
> #pragma clang diagnostic push
> #pragma clang diagnostic ignored "-Wunused-function"
> Q_DECLARE_OPERATORS_FOR_FLAGS(DirtyStates)
> #pragma clang diagnostic pop

Oh g++ errors on these. We need something like:

#if defined(__clang__)

review: Needs Fixing
266. By Gerry Boland

ifdef the clang workaround

Revision history for this message
Gerry Boland (gerboland) wrote :

Done. Your g++/clang++ are more fussy than mine on xenial!

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-function"
+Q_DECLARE_OPERATORS_FOR_FLAGS(DirtyStates)
+#pragma clang diagnostic pop
+#endif

Do you really mean we only need Q_DECLARE_OPERATORS_FOR_FLAGS() with clang? Maybe we just don't need it?

review: Needs Fixing
267. By Gerry Boland

The | operator for QFlags not actually needed - yet! Remove, add back only when I need it

Revision history for this message
Gerry Boland (gerboland) wrote :

> +#if defined(__clang__)
> +#pragma clang diagnostic push
> +#pragma clang diagnostic ignored "-Wunused-function"
> +Q_DECLARE_OPERATORS_FOR_FLAGS(DirtyStates)
> +#pragma clang diagnostic pop
> +#endif
>
> Do you really mean we only need Q_DECLARE_OPERATORS_FOR_FLAGS() with clang?
> Maybe we just don't need it?

Quite right, it's not needed until I start combining flags with the | operator. I've removed it entirely

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

There's an orphaned comment but WTF

review: Approve
268. By Gerry Boland

remove defunkt comment

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'miral-qt/demos/qml-demo-shell/windowModel.qml'
2--- miral-qt/demos/qml-demo-shell/windowModel.qml 2016-07-27 12:37:01 +0000
3+++ miral-qt/demos/qml-demo-shell/windowModel.qml 2016-08-12 12:04:26 +0000
4@@ -2,37 +2,116 @@
5 import Unity.Application 0.1
6
7 FocusScope {
8+ id: root
9 focus: true
10
11 WindowModel {
12 id: windowModel;
13 }
14
15- Repeater {
16- anchors.fill: parent
17- model: windowModel
18-
19- delegate: MirSurfaceItem {
20- id: surfaceItem
21- surface: model.surface
22- consumesInput: true // QUESTION: why is this non-default?
23- x: surface.position.x
24- y: surface.position.y
25- width: surface.size.width
26- height: surface.size.height
27- focus: surface.focused
28-
29- Rectangle {
30- anchors { top: parent.bottom; right: parent.right }
31- width: childrenRect.width
32- height: childrenRect.height
33- color: surface.focused ? "red" : "lightsteelblue"
34- opacity: 0.8
35- Text {
36- text: surface.position.x + "," + surface.position.y + " " + surface.size.width + "x" + surface.size.height
37- font.pixelSize: 10
38- }
39- }
40+ Item {
41+ id: windowViewContainer
42+ anchors.fill: parent
43+
44+ Repeater {
45+ model: windowModel
46+
47+ delegate: MirSurfaceItem {
48+ id: surfaceItem
49+ surface: model.surface
50+ consumesInput: true // QUESTION: why is this non-default?
51+ x: surface.position.x
52+ y: surface.position.y
53+ width: surface.size.width
54+ height: surface.size.height
55+ focus: surface.focused
56+
57+ Rectangle {
58+ anchors { top: parent.bottom; right: parent.right }
59+ width: childrenRect.width
60+ height: childrenRect.height
61+ color: surface.focused ? "red" : "lightsteelblue"
62+ opacity: 0.8
63+ Text {
64+ text: surface.position.x + "," + surface.position.y + " " + surface.size.width + "x" + surface.size.height
65+ font.pixelSize: 10
66+ }
67+ }
68+ }
69+ }
70+ }
71+
72+ Button {
73+ anchors { right: parent.right; bottom: parent.bottom }
74+ height: 30
75+ width: 80
76+ text: "Quit"
77+ onClicked: Qt.quit()
78+ }
79+
80+ Text {
81+ anchors { left: parent.left; bottom: parent.bottom }
82+ text: "Move window: Ctrl+click\n
83+Resize window: Ctrl+Right click"
84+ }
85+
86+ MouseArea {
87+ anchors.fill: parent
88+ acceptedButtons: Qt.LeftButton | Qt.RightButton
89+ property variant window: null
90+ property int initialWindowXPosition
91+ property int initialWindowYPosition
92+ property int initialWindowWidth
93+ property int initialWindowHeight
94+ property int initialMouseXPosition
95+ property int initialMouseYPosition
96+ property var action
97+
98+ function moveWindowBy(window, delta) {
99+ window.surface.requestPosition(Qt.point(initialWindowXPosition + delta.x,
100+ initialWindowYPosition + delta.y))
101+ }
102+ function resizeWindowBy(window, delta) {
103+ window.surface.resize(Qt.size(initialWindowWidth + delta.x,
104+ initialWindowHeight + delta.y))
105+ }
106+
107+ onPressed: {
108+ if (mouse.modifiers & Qt.ControlModifier) {
109+ window = windowViewContainer.childAt(mouse.x, mouse.y)
110+ if (!window) return;
111+
112+ if (mouse.button == Qt.LeftButton) {
113+ initialWindowXPosition = window.surface.position.x
114+ initialWindowYPosition = window.surface.position.y
115+ action = moveWindowBy
116+ } else if (mouse.button == Qt.RightButton) {
117+ initialWindowHeight = window.surface.size.height
118+ initialWindowWidth = window.surface.size.width
119+ action = resizeWindowBy
120+ }
121+ initialMouseXPosition = mouse.x
122+ initialMouseYPosition = mouse.y
123+ } else {
124+ mouse.accepted = false
125+ }
126+ }
127+
128+ onPositionChanged: {
129+ if (!window) {
130+ mouse.accepted = false
131+ return
132+ }
133+ action(window, Qt.point(mouse.x - initialMouseXPosition, mouse.y - initialMouseYPosition))
134+ }
135+
136+ onReleased: {
137+ if (!window) {
138+ mouse.accepted = false
139+ return
140+ }
141+ action(window, Qt.point(mouse.x - initialMouseXPosition, mouse.y - initialMouseYPosition))
142+ window = null;
143 }
144 }
145 }
146
147=== added file 'miral-qt/src/common/windowcontrollerinterface.h'
148--- miral-qt/src/common/windowcontrollerinterface.h 1970-01-01 00:00:00 +0000
149+++ miral-qt/src/common/windowcontrollerinterface.h 2016-08-12 12:04:26 +0000
150@@ -0,0 +1,53 @@
151+/*
152+ * Copyright (C) 2016 Canonical, Ltd.
153+ *
154+ * This program is free software: you can redistribute it and/or modify it under
155+ * the terms of the GNU Lesser General Public License version 3, as published by
156+ * the Free Software Foundation.
157+ *
158+ * This program is distributed in the hope that it will be useful, but WITHOUT
159+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
160+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
161+ * Lesser General Public License for more details.
162+ *
163+ * You should have received a copy of the GNU Lesser General Public License
164+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
165+ */
166+
167+#ifndef WINDOWCONTROLLERINTERFACE_H
168+#define WINDOWCONTROLLERINTERFACE_H
169+
170+#include "miral/window.h"
171+
172+#include "mir_toolkit/event.h"
173+
174+#include <QPoint>
175+#include <QSize>
176+
177+namespace qtmir {
178+
179+class MirSurface;
180+
181+class WindowControllerInterface {
182+public:
183+ WindowControllerInterface() = default;
184+ virtual ~WindowControllerInterface() = default;
185+
186+ // focus() asks Mir to bring particular window to the front and recommend to shell that it be focused
187+ virtual void focus (const miral::Window &window) = 0;
188+ // setActiveFocus() is how shell notifies Mir/application that a window actually has input focus
189+ virtual void setActiveFocus(const miral::Window &window, const bool activeFocus) = 0;
190+
191+ virtual void resize(const miral::Window &window, const QSize &size) = 0;
192+ virtual void move (const miral::Window &window, const QPoint &topLeft) = 0;
193+
194+ virtual void setState(const miral::Window &window, const MirSurfaceState state) = 0;
195+
196+ virtual void deliverKeyboardEvent(const miral::Window &window, const MirKeyboardEvent *event) = 0;
197+ virtual void deliverTouchEvent (const miral::Window &window, const MirTouchEvent *event) = 0;
198+ virtual void deliverPointerEvent (const miral::Window &window, const MirPointerEvent *event) = 0;
199+};
200+
201+} // namespace qtmir
202+
203+#endif // WINDOWCONTROLLERINTERFACE_H
204
205=== modified file 'miral-qt/src/common/windowmodelinterface.h'
206--- miral-qt/src/common/windowmodelinterface.h 2016-07-27 17:41:48 +0000
207+++ miral-qt/src/common/windowmodelinterface.h 2016-08-12 12:04:26 +0000
208@@ -22,35 +22,39 @@
209 #include <QPoint>
210 #include <QVector>
211
212-#include <mir/scene/surface.h>
213+#include "miral/window_info.h"
214
215 namespace qtmir {
216
217-// miral::WindowInfo contains all the metadata the WindowManager{,Policy} needs. However the
218-// WindowModel only needs a read-only subset of this data, which is what the struct is for.
219-struct WindowInfo {
220- QSize size;
221- QPoint position;
222- bool focused;
223- const std::shared_ptr<mir::scene::Surface> surface;
224-
225- enum class DirtyStates {
226- Size = 1,
227- Position = 2,
228- Focus = 4
229- };
230-};
231-
232-// We assign each Window with an index which corresponds to the position it has in the window stack.
233-struct NumberedWindow {
234- unsigned int index;
235- WindowInfo windowInfo;
236-};
237-
238-struct DirtiedWindow {
239- unsigned int index;
240- WindowInfo windowInfo;
241- WindowInfo::DirtyStates dirtyWindowInfo;
242+// miral::WindowInfo missing a default constructor, needed by MOC. Need to wrap it instead
243+class WindowInfo {
244+public:
245+ WindowInfo() = default;
246+ WindowInfo(const miral::WindowInfo &windowInfo)
247+ : window(windowInfo.window())
248+ , name(windowInfo.name())
249+ , type(windowInfo.type())
250+ , state(windowInfo.state())
251+ , restoreRect(windowInfo.restore_rect())
252+ , parent(windowInfo.parent())
253+ , children(windowInfo.children())
254+ , minWidth(windowInfo.min_width())
255+ , minHeight(windowInfo.min_height())
256+ , maxWidth(windowInfo.max_width())
257+ , maxHeight(windowInfo.max_height())
258+ {}
259+
260+ miral::Window window;
261+ mir::optional_value<std::string> name;
262+ MirSurfaceType type;
263+ MirSurfaceState state;
264+ mir::geometry::Rectangle restoreRect;
265+ miral::Window parent;
266+ std::vector<miral::Window> children;
267+ mir::geometry::Width minWidth;
268+ mir::geometry::Height minHeight;
269+ mir::geometry::Width maxWidth;
270+ mir::geometry::Height maxHeight;
271 };
272
273
274@@ -62,9 +66,12 @@
275 virtual ~WindowModelInterface() = default;
276
277 Q_SIGNALS:
278- void windowAdded(const qtmir::NumberedWindow);
279+ void windowAdded(const qtmir::WindowInfo, const unsigned int index);
280 void windowRemoved(const unsigned int index);
281- void windowChanged(const qtmir::DirtiedWindow);
282+ void windowMoved(const QPoint topLeft, const unsigned int index);
283+ void windowResized(const QSize size, const unsigned int index);
284+ void windowFocused(const unsigned int index);
285+ void windowInfoChanged(const qtmir::WindowInfo, const unsigned int index);
286
287 private:
288 Q_DISABLE_COPY(WindowModelInterface)
289@@ -72,7 +79,6 @@
290
291 } // namespace qtmir
292
293-Q_DECLARE_METATYPE(qtmir::NumberedWindow)
294-Q_DECLARE_METATYPE(qtmir::DirtiedWindow)
295+Q_DECLARE_METATYPE(qtmir::WindowInfo)
296
297 #endif // WINDOWMODELINTERFACE_H
298
299=== modified file 'miral-qt/src/modules/Unity/Application/mirsurface.cpp'
300--- miral-qt/src/modules/Unity/Application/mirsurface.cpp 2016-07-27 12:42:21 +0000
301+++ miral-qt/src/modules/Unity/Application/mirsurface.cpp 2016-08-12 12:04:26 +0000
302@@ -177,34 +177,38 @@
303 return ev;
304 }
305
306+enum class DirtyState {
307+ Clean = 0,
308+ Name = 1 << 1,
309+ Type = 1 << 2,
310+ State = 1 << 3,
311+ RestoreRect = 1 << 4,
312+ Children = 1 << 5,
313+ MinSize = 1 << 6,
314+ MaxSize = 1 << 7,
315+};
316+Q_DECLARE_FLAGS(DirtyStates, DirtyState)
317+
318 } // namespace {
319
320-MirSurface::MirSurface(std::shared_ptr<mir::scene::Surface> surface,
321- SessionInterface* session,
322- mir::shell::Shell* shell,
323- std::shared_ptr<SurfaceObserver> observer,
324- const CreationHints &creationHints)
325+MirSurface::MirSurface(WindowInfo windowInfo,
326+ WindowControllerInterface* controller,
327+ std::shared_ptr<SurfaceObserver> observer)
328 : MirSurfaceInterface()
329- , m_surface(surface)
330- , m_session(session)
331- , m_shell(shell)
332+ , m_windowInfo(windowInfo)
333+ , m_controller(controller)
334 , m_firstFrameDrawn(false)
335 , m_orientationAngle(Mir::Angle0)
336 , m_textureUpdated(false)
337 , m_currentFrameNumber(0)
338 , m_live(true)
339+ , m_position(toQPoint(windowInfo.window.top_left()))
340+ , m_size(toQSize(windowInfo.window.size()))
341 , m_shellChrome(Mir::NormalChrome)
342 {
343 DEBUG_MSG << "()";
344
345- m_position = toQPoint(surface->top_left());
346- m_minimumWidth = creationHints.minWidth;
347- m_minimumHeight = creationHints.minHeight;
348- m_maximumWidth = creationHints.maxWidth;
349- m_maximumHeight = creationHints.maxHeight;
350- m_widthIncrement = creationHints.widthIncrement;
351- m_heightIncrement = creationHints.heightIncrement;
352- m_shellChrome = creationHints.shellChrome;
353+ //m_shellChrome = creationHints.shellChrome; TODO - where will this come from now?
354
355 m_surfaceObserver = observer;
356 if (observer) {
357@@ -212,12 +216,6 @@
358 connect(observer.get(), &SurfaceObserver::attributeChanged, this, &MirSurface::onAttributeChanged);
359 connect(observer.get(), &SurfaceObserver::nameChanged, this, &MirSurface::nameChanged);
360 connect(observer.get(), &SurfaceObserver::cursorChanged, this, &MirSurface::setCursor);
361- connect(observer.get(), &SurfaceObserver::minimumWidthChanged, this, &MirSurface::setMinimumWidth);
362- connect(observer.get(), &SurfaceObserver::minimumHeightChanged, this, &MirSurface::setMinimumHeight);
363- connect(observer.get(), &SurfaceObserver::maximumWidthChanged, this, &MirSurface::setMaximumWidth);
364- connect(observer.get(), &SurfaceObserver::maximumHeightChanged, this, &MirSurface::setMaximumHeight);
365- connect(observer.get(), &SurfaceObserver::widthIncrementChanged, this, &MirSurface::setWidthIncrement);
366- connect(observer.get(), &SurfaceObserver::heightIncrementChanged, this, &MirSurface::setHeightIncrement);
367 connect(observer.get(), &SurfaceObserver::shellChromeChanged, this, [&](MirShellChrome shell_chrome) {
368 setShellChrome(static_cast<Mir::ShellChrome>(shell_chrome));
369 });
370@@ -225,7 +223,7 @@
371 observer->setListener(this);
372 }
373
374- connect(session, &QObject::destroyed, this, &MirSurface::onSessionDestroyed);
375+ //connect(session, &QObject::destroyed, this, &MirSurface::onSessionDestroyed); // TODO try using Shared pointer for lifecycle
376
377 connect(&m_frameDropperTimer, &QTimer::timeout,
378 this, &MirSurface::dropPendingBuffer);
379@@ -256,7 +254,8 @@
380 Q_ASSERT(m_views.isEmpty());
381
382 QMutexLocker locker(&m_mutex);
383- m_surface->remove_observer(m_surfaceObserver);
384+// auto const &window = static_cast<std::shared_ptr<mir::scene::Surface>>(m_windowInfo.window);
385+// window->remove_observer(m_surfaceObserver); // FIXME - window null at this stage!
386
387 delete m_closeTimer;
388
389@@ -298,7 +297,7 @@
390
391 Mir::Type MirSurface::type() const
392 {
393- switch (m_surface->type()) {
394+ switch (m_windowInfo.type) {
395 case mir_surface_type_normal:
396 return Mir::NormalType;
397
398@@ -337,7 +336,8 @@
399
400 const void* const userId = (void*)123; // TODO: Multimonitor support
401
402- int framesPending = m_surface->buffers_ready_for_compositor(userId);
403+ auto const &window = static_cast<std::shared_ptr<mir::scene::Surface>>(m_windowInfo.window);
404+ int framesPending = window->buffers_ready_for_compositor(userId);
405 if (framesPending > 0) {
406 m_textureUpdated = false;
407
408@@ -398,10 +398,11 @@
409 }
410
411 const void* const userId = (void*)123;
412- auto renderables = m_surface->generate_renderables(userId);
413+ auto const &window = static_cast<std::shared_ptr<mir::scene::Surface>>(m_windowInfo.window);
414+ auto renderables = window->generate_renderables(userId);
415
416 if (renderables.size() > 0 &&
417- (m_surface->buffers_ready_for_compositor(userId) > 0 || !texture->hasBuffer())
418+ (window->buffers_ready_for_compositor(userId) > 0 || !texture->hasBuffer())
419 ) {
420 // Avoid holding two buffers for the compositor at the same time. Thus free the current
421 // before acquiring the next
422@@ -409,7 +410,7 @@
423 texture->setBuffer(renderables[0]->buffer());
424 ++m_currentFrameNumber;
425
426- if (texture->textureSize() != m_size) {
427+ if (texture->textureSize() != size()) {
428 m_size = texture->textureSize();
429 QMetaObject::invokeMethod(this, "emitSizeChanged", Qt::QueuedConnection);
430 }
431@@ -417,7 +418,7 @@
432 m_textureUpdated = true;
433 }
434
435- if (m_surface->buffers_ready_for_compositor(userId) > 0) {
436+ if (window->buffers_ready_for_compositor(userId) > 0) {
437 // restart the frame dropper to give MirSurfaceItems enough time to render the next frame.
438 // queued since the timer lives in a different thread
439 QMetaObject::invokeMethod(&m_frameDropperTimer, "start", Qt::QueuedConnection);
440@@ -436,7 +437,8 @@
441 {
442 QMutexLocker locker(&m_mutex);
443 const void* const userId = (void*)123;
444- return m_surface->buffers_ready_for_compositor(userId);
445+ auto const &window = static_cast<std::shared_ptr<mir::scene::Surface>>(m_windowInfo.window);
446+ return window->buffers_ready_for_compositor(userId);
447 }
448
449 void MirSurface::setFocused(bool value)
450@@ -479,10 +481,10 @@
451
452 if (m_activelyFocusedViews.isEmpty()) {
453 DEBUG_MSG << "() unfocused";
454- m_shell->set_surface_attribute(m_session->session(), m_surface, mir_surface_attrib_focus, mir_surface_unfocused);
455+ m_controller->setActiveFocus(m_windowInfo.window, false);
456 } else {
457 DEBUG_MSG << "() focused";
458- m_shell->set_surface_attribute(m_session->session(), m_surface, mir_surface_attrib_focus, mir_surface_focused);
459+ m_controller->setActiveFocus(m_windowInfo.window, true);
460 }
461
462 m_neverSetSurfaceFocus = false;
463@@ -500,22 +502,21 @@
464 Q_EMIT closeRequested();
465 m_closeTimer->start();
466
467- if (m_surface) {
468- m_surface->request_client_surface_close();
469+ if (m_windowInfo.window) {
470+ auto const &window = static_cast<std::shared_ptr<mir::scene::Surface>>(m_windowInfo.window);
471+ window->request_client_surface_close();
472 }
473 }
474
475 void MirSurface::resize(int width, int height)
476 {
477- int mirWidth = m_surface->size().width.as_int();
478- int mirHeight = m_surface->size().height.as_int();
479+ auto const &window = m_windowInfo.window;
480
481- bool mirSizeIsDifferent = width != mirWidth || height != mirHeight;
482+ bool mirSizeIsDifferent = width != m_size.width() || height != m_size.height();
483
484 if (clientIsRunning() && mirSizeIsDifferent) {
485- mir::geometry::Size newMirSize(width, height);
486- m_surface->resize(newMirSize);
487- DEBUG_MSG << " old (" << mirWidth << "," << mirHeight << ")"
488+ m_controller->resize(window, QSize(width, height));
489+ DEBUG_MSG << " old (" << m_size.width() << "," << m_size.height() << ")"
490 << ", new (" << width << "," << height << ")";
491 }
492 }
493@@ -525,6 +526,27 @@
494 return m_position;
495 }
496
497+void MirSurface::setPosition(const QPoint newPosition)
498+{
499+ if (m_position != newPosition) {
500+ m_position = newPosition;
501+ Q_EMIT positionChanged(newPosition);
502+ }
503+}
504+
505+void MirSurface::requestPosition(const QPoint newPosition)
506+{
507+ m_controller->move(m_windowInfo.window, newPosition);
508+}
509+
510+void MirSurface::setSize(const QSize newSize)
511+{
512+ if (m_size != newSize) {
513+ m_size = newSize;
514+ Q_EMIT sizeChanged(newSize);
515+ }
516+}
517+
518 QSize MirSurface::size() const
519 {
520 return m_size;
521@@ -532,7 +554,7 @@
522
523 Mir::State MirSurface::state() const
524 {
525- switch (m_surface->state()) {
526+ switch (m_windowInfo.state) {
527 case mir_surface_state_unknown:
528 return Mir::UnknownState;
529 case mir_surface_state_restored:
530@@ -587,8 +609,9 @@
531 return;
532 }
533
534- if (m_surface) {
535- m_surface->set_orientation(mirOrientation);
536+ if (m_windowInfo.window) {
537+ auto const &window = static_cast<std::shared_ptr<mir::scene::Surface>>(m_windowInfo.window);
538+ window->set_orientation(mirOrientation);
539 }
540
541 Q_EMIT orientationAngleChanged(angle);
542@@ -596,12 +619,15 @@
543
544 QString MirSurface::name() const
545 {
546- return QString::fromStdString(m_surface->name());
547+ if (!m_windowInfo.name.is_set()) {
548+ return QStringLiteral();
549+ }
550+ return QString::fromStdString(m_windowInfo.name.value());
551 }
552
553 void MirSurface::setState(Mir::State qmlState)
554 {
555- int mirState;
556+ MirSurfaceState mirState;
557
558 switch (qmlState) {
559 default:
560@@ -638,7 +664,7 @@
561 break;
562 }
563
564- m_shell->set_surface_attribute(m_session->session(), m_surface, mir_surface_attrib_state, mirState);
565+ m_controller->setState(m_windowInfo.window, mirState);
566 }
567
568 void MirSurface::setLive(bool value)
569@@ -660,69 +686,79 @@
570
571 bool MirSurface::visible() const
572 {
573- return m_surface->query(mir_surface_attrib_visibility) == mir_surface_visibility_exposed;
574+ //return m_windowInfo->query(mir_surface_attrib_visibility) == mir_surface_visibility_exposed;
575+ return true; //FIXME
576 }
577-
578+#include <mir_toolkit/event.h>
579 void MirSurface::mousePressEvent(QMouseEvent *event)
580 {
581 auto ev = makeMirEvent(event, mir_pointer_action_button_down);
582- m_surface->consume(ev.get());
583+ auto ev1 = reinterpret_cast<MirPointerEvent const*>(ev.get());
584+ m_controller->deliverPointerEvent(m_windowInfo.window, ev1);
585 event->accept();
586 }
587
588 void MirSurface::mouseMoveEvent(QMouseEvent *event)
589 {
590 auto ev = makeMirEvent(event, mir_pointer_action_motion);
591- m_surface->consume(ev.get());
592+ auto ev1 = reinterpret_cast<MirPointerEvent const*>(ev.get());
593+ m_controller->deliverPointerEvent(m_windowInfo.window, ev1);
594 event->accept();
595 }
596
597 void MirSurface::mouseReleaseEvent(QMouseEvent *event)
598 {
599 auto ev = makeMirEvent(event, mir_pointer_action_button_up);
600- m_surface->consume(ev.get());
601+ auto ev1 = reinterpret_cast<MirPointerEvent const*>(ev.get());
602+ m_controller->deliverPointerEvent(m_windowInfo.window, ev1);
603 event->accept();
604 }
605
606 void MirSurface::hoverEnterEvent(QHoverEvent *event)
607 {
608 auto ev = makeMirEvent(event, mir_pointer_action_enter);
609- m_surface->consume(ev.get());
610+ auto ev1 = reinterpret_cast<MirPointerEvent const*>(ev.get());
611+ m_controller->deliverPointerEvent(m_windowInfo.window, ev1);
612 event->accept();
613 }
614
615 void MirSurface::hoverLeaveEvent(QHoverEvent *event)
616 {
617 auto ev = makeMirEvent(event, mir_pointer_action_leave);
618- m_surface->consume(ev.get());
619+ auto ev1 = reinterpret_cast<MirPointerEvent const*>(ev.get());
620+ m_controller->deliverPointerEvent(m_windowInfo.window, ev1);
621 event->accept();
622 }
623
624 void MirSurface::hoverMoveEvent(QHoverEvent *event)
625 {
626 auto ev = makeMirEvent(event, mir_pointer_action_motion);
627- m_surface->consume(ev.get());
628+ auto ev1 = reinterpret_cast<MirPointerEvent const*>(ev.get());
629+ m_controller->deliverPointerEvent(m_windowInfo.window, ev1);
630 event->accept();
631 }
632
633 void MirSurface::wheelEvent(QWheelEvent *event)
634 {
635 auto ev = makeMirEvent(event);
636- m_surface->consume(ev.get());
637+ auto ev1 = reinterpret_cast<MirPointerEvent const*>(ev.get());
638+ m_controller->deliverPointerEvent(m_windowInfo.window, ev1);
639 event->accept();
640 }
641
642 void MirSurface::keyPressEvent(QKeyEvent *qtEvent)
643 {
644 auto ev = makeMirEvent(qtEvent);
645- m_surface->consume(ev.get());
646+ auto ev1 = reinterpret_cast<MirKeyboardEvent const*>(ev.get());
647+ m_controller->deliverKeyboardEvent(m_windowInfo.window, ev1);
648 qtEvent->accept();
649 }
650
651 void MirSurface::keyReleaseEvent(QKeyEvent *qtEvent)
652 {
653 auto ev = makeMirEvent(qtEvent);
654- m_surface->consume(ev.get());
655+ auto ev1 = reinterpret_cast<MirKeyboardEvent const*>(ev.get());
656+ m_controller->deliverKeyboardEvent(m_windowInfo.window, ev1);
657 qtEvent->accept();
658 }
659
660@@ -732,7 +768,8 @@
661 ulong timestamp)
662 {
663 auto ev = makeMirEvent(mods, touchPoints, touchPointStates, timestamp);
664- m_surface->consume(ev.get());
665+ auto ev1 = reinterpret_cast<MirTouchEvent const*>(ev.get());
666+ m_controller->deliverTouchEvent(m_windowInfo.window, ev1);
667 }
668
669 bool MirSurface::clientIsRunning() const
670@@ -865,7 +902,9 @@
671 return;
672 }
673
674- m_surface->set_keymap(MirInputDeviceId(), "", layout.toStdString(), variant.toStdString(), "");
675+ auto const &window = static_cast<std::shared_ptr<mir::scene::Surface>>(m_windowInfo.window);
676+
677+ window->set_keymap(MirInputDeviceId(), "", layout.toStdString(), variant.toStdString(), "");
678 }
679
680 QCursor MirSurface::cursor() const
681@@ -905,6 +944,52 @@
682 return result;
683 }
684
685+void MirSurface::updateWindowInfo(const WindowInfo &windowInfo)
686+{
687+ qDebug() << "MirSurface::updateWindowInfo";
688+ // Need to compare the new windowInfo instance with the existing one to figure out what changed
689+ DirtyStates dirt = DirtyState::Clean;
690+
691+ if (windowInfo.name != m_windowInfo.name) {
692+ dirt &= DirtyState::Name; qDebug("Name changed");
693+ }
694+ if (windowInfo.type != m_windowInfo.type) {
695+ dirt &= DirtyState::Type; qDebug("Type changed");
696+ }
697+ if (windowInfo.state != m_windowInfo.state) {
698+ dirt &= DirtyState::State; qDebug("State changed");
699+ }
700+ if (windowInfo.restoreRect != m_windowInfo.restoreRect) {
701+ dirt &= DirtyState::RestoreRect; qDebug("RestoreRect changed");
702+ }
703+ if (windowInfo.children != m_windowInfo.children) {
704+ dirt &= DirtyState::Children; qDebug("Children changed");
705+ }
706+ if (windowInfo.minWidth != m_windowInfo.minWidth
707+ && windowInfo.minHeight != m_windowInfo.minHeight) {
708+ dirt &= DirtyState::MinSize; qDebug("MinSize changed");
709+ }
710+ if (windowInfo.maxWidth != m_windowInfo.maxWidth
711+ && windowInfo.maxHeight != m_windowInfo.maxHeight) {
712+ dirt &= DirtyState::MaxSize; qDebug("MaxHeight changed");
713+ }
714+
715+ if (dirt | DirtyState::Clean) {
716+ return;
717+ }
718+ m_windowInfo = windowInfo;
719+
720+ if (dirt | DirtyState::Name) {
721+ Q_EMIT nameChanged(name());
722+ }
723+ if (dirt | DirtyState::Type) {
724+ Q_EMIT typeChanged(type());
725+ }
726+ if (dirt | DirtyState::State) {
727+ Q_EMIT stateChanged(state());
728+ }
729+}
730+
731 void MirSurface::setCursor(const QCursor &cursor)
732 {
733 DEBUG_MSG << "(" << qtCursorShapeToStr(cursor.shape()) << ")";
734@@ -915,80 +1000,32 @@
735
736 int MirSurface::minimumWidth() const
737 {
738- return m_minimumWidth;
739+ return m_windowInfo.minWidth.as_int();
740 }
741
742 int MirSurface::minimumHeight() const
743 {
744- return m_minimumHeight;
745+ return m_windowInfo.minHeight.as_int();
746 }
747
748 int MirSurface::maximumWidth() const
749 {
750- return m_maximumWidth;
751+ return m_windowInfo.maxWidth.as_int();
752 }
753
754 int MirSurface::maximumHeight() const
755 {
756- return m_maximumHeight;
757+ return m_windowInfo.maxHeight.as_int();
758 }
759
760 int MirSurface::widthIncrement() const
761 {
762- return m_widthIncrement;
763+ return 0; //TODO
764 }
765
766 int MirSurface::heightIncrement() const
767 {
768- return m_heightIncrement;
769-}
770-
771-void MirSurface::setMinimumWidth(int value)
772-{
773- if (value != m_minimumWidth) {
774- m_minimumWidth = value;
775- Q_EMIT minimumWidthChanged(value);
776- }
777-}
778-
779-void MirSurface::setMinimumHeight(int value)
780-{
781- if (value != m_minimumHeight) {
782- m_minimumHeight = value;
783- Q_EMIT minimumHeightChanged(value);
784- }
785-}
786-
787-void MirSurface::setMaximumWidth(int value)
788-{
789- if (value != m_maximumWidth) {
790- m_maximumWidth = value;
791- Q_EMIT maximumWidthChanged(value);
792- }
793-}
794-
795-void MirSurface::setMaximumHeight(int value)
796-{
797- if (value != m_maximumHeight) {
798- m_maximumHeight = value;
799- Q_EMIT maximumHeightChanged(value);
800- }
801-}
802-
803-void MirSurface::setWidthIncrement(int value)
804-{
805- if (value != m_widthIncrement) {
806- m_widthIncrement = value;
807- Q_EMIT widthIncrementChanged(value);
808- }
809-}
810-
811-void MirSurface::setHeightIncrement(int value)
812-{
813- if (value != m_heightIncrement) {
814- m_heightIncrement = value;
815- Q_EMIT heightIncrementChanged(value);
816- }
817+ return 0; //TODO
818 }
819
820 bool MirSurface::focused() const
821@@ -1021,16 +1058,7 @@
822
823 m_closingState = CloseOverdue;
824
825- m_session->session()->destroy_surface(m_surface);
826-}
827-
828-void MirSurface::setPosition(const QPoint newPosition)
829-{
830- if (m_position == newPosition) {
831- return;
832- }
833- m_position = newPosition;
834- Q_EMIT positionChanged(m_position);
835+ //m_session->session()->destroy_surface(m_windowInfo); TODO use WindowManagerTools::ask_client_to_close(window)
836 }
837
838 void MirSurface::setCloseTimer(AbstractTimer *timer)
839
840=== modified file 'miral-qt/src/modules/Unity/Application/mirsurface.h'
841--- miral-qt/src/modules/Unity/Application/mirsurface.h 2016-07-27 12:05:20 +0000
842+++ miral-qt/src/modules/Unity/Application/mirsurface.h 2016-08-12 12:04:26 +0000
843@@ -31,17 +31,11 @@
844
845 #include "mirbuffersgtexture.h"
846 #include "session.h"
847-
848-// mirserver
849-#include "creationhints.h"
850-
851+#include "windowcontrollerinterface.h"
852+#include "windowmodelinterface.h"
853 // mir
854 #include <mir_toolkit/common.h>
855
856-namespace mir {
857-namespace shell { class Shell; }
858-namespace scene {class Surface; }
859-}
860
861 class SurfaceObserver;
862
863@@ -54,11 +48,9 @@
864 Q_OBJECT
865
866 public:
867- MirSurface(std::shared_ptr<mir::scene::Surface> surface,
868- SessionInterface* session,
869- mir::shell::Shell *shell,
870- std::shared_ptr<SurfaceObserver> observer,
871- const CreationHints &);
872+ MirSurface(WindowInfo windowInfo,
873+ WindowControllerInterface *controller,
874+ std::shared_ptr<SurfaceObserver> observer);
875 virtual ~MirSurface();
876
877 ////
878@@ -70,10 +62,10 @@
879
880 QSize size() const override;
881 void resize(int width, int height) override;
882- void resize(const QSize &size) override { resize(size.width(), size.height()); }
883+ Q_INVOKABLE void resize(const QSize &size) override { resize(size.width(), size.height()); }
884
885 QPoint position() const override;
886- void setPosition(const QPoint newPosition) override;
887+ Q_INVOKABLE void requestPosition(const QPoint newPosition) override;
888
889 Mir::State state() const override;
890 void setState(Mir::State qmlState) override;
891@@ -159,6 +151,9 @@
892
893 ////
894 // Own API
895+ void setPosition(const QPoint newPosition);
896+ void setSize(const QSize newSize);
897+ void updateWindowInfo(const WindowInfo &windowInfo);
898
899 // useful for tests
900 void setCloseTimer(AbstractTimer *timer);
901@@ -166,12 +161,6 @@
902 public Q_SLOTS:
903 void onCompositorSwappedBuffers() override;
904
905- void setMinimumWidth(int) override;
906- void setMinimumHeight(int) override;
907- void setMaximumWidth(int) override;
908- void setMaximumHeight(int) override;
909- void setWidthIncrement(int) override;
910- void setHeightIncrement(int) override;
911 void setShellChrome(Mir::ShellChrome shellChrome) override;
912
913 private Q_SLOTS:
914@@ -191,9 +180,9 @@
915 void applyKeymap();
916 void updateActiveFocus();
917
918- std::shared_ptr<mir::scene::Surface> m_surface;
919+ WindowInfo m_windowInfo;
920 QPointer<SessionInterface> m_session;
921- mir::shell::Shell *const m_shell;
922+ WindowControllerInterface *const m_controller;
923 bool m_firstFrameDrawn;
924
925 //FIXME - have to save the state as Mir has no getter for it (bug:1357429)
926@@ -226,13 +215,6 @@
927 QCursor m_cursor;
928 Mir::ShellChrome m_shellChrome;
929
930- int m_minimumWidth{0};
931- int m_minimumHeight{0};
932- int m_maximumWidth{0};
933- int m_maximumHeight{0};
934- int m_widthIncrement{0};
935- int m_heightIncrement{0};
936-
937 QRect m_inputBounds;
938
939 bool m_focused{false};
940
941=== modified file 'miral-qt/src/modules/Unity/Application/mirsurfaceinterface.h'
942--- miral-qt/src/modules/Unity/Application/mirsurfaceinterface.h 2016-07-27 12:05:20 +0000
943+++ miral-qt/src/modules/Unity/Application/mirsurfaceinterface.h 2016-08-12 12:04:26 +0000
944@@ -49,7 +49,7 @@
945 virtual ~MirSurfaceInterface() {}
946
947 virtual QPoint position() const = 0;
948- virtual void setPosition(const QPoint newPosition) = 0;
949+ virtual void requestPosition(const QPoint newPosition) = 0;
950
951 virtual void setLive(bool value) = 0;
952
953@@ -118,12 +118,6 @@
954 public Q_SLOTS:
955 virtual void onCompositorSwappedBuffers() = 0;
956
957- virtual void setMinimumWidth(int) = 0;
958- virtual void setMinimumHeight(int) = 0;
959- virtual void setMaximumWidth(int) = 0;
960- virtual void setMaximumHeight(int) = 0;
961- virtual void setWidthIncrement(int) = 0;
962- virtual void setHeightIncrement(int) = 0;
963 virtual void setShellChrome(Mir::ShellChrome shellChrome) = 0;
964
965 Q_SIGNALS:
966
967=== modified file 'miral-qt/src/modules/Unity/Application/mirsurfacemanager.cpp'
968--- miral-qt/src/modules/Unity/Application/mirsurfacemanager.cpp 2016-06-01 22:06:51 +0000
969+++ miral-qt/src/modules/Unity/Application/mirsurfacemanager.cpp 2016-08-12 12:04:26 +0000
970@@ -97,45 +97,45 @@
971
972 void MirSurfaceManager::onSessionCreatedSurface(const mir::scene::Session *mirSession,
973 const std::shared_ptr<mir::scene::Surface> &surface,
974- const std::shared_ptr<SurfaceObserver> &observer,
975+ const std::shared_ptr<SurfaceObserver> &/*observer*/,
976 qtmir::CreationHints creationHints)
977 {
978 qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::onSessionCreatedSurface - mirSession=" << mirSession
979 << "surface=" << surface.get() << "surface.name=" << surface->name().c_str()
980 << "creationHints=" << creationHints.toString();
981
982- SessionInterface* session = m_sessionManager->findSession(mirSession);
983- auto qmlSurface = new MirSurface(surface, session, m_shell, observer, creationHints);
984- {
985- QMutexLocker lock(&m_mutex);
986- m_mirSurfaceToQmlSurfaceHash.insert(surface.get(), qmlSurface);
987- }
988-
989- if (session)
990- session->registerSurface(qmlSurface);
991-
992- if (qmlSurface->type() == Mir::InputMethodType) {
993- m_inputMethodSurface = qmlSurface;
994- Q_EMIT inputMethodSurfaceChanged();
995- }
996-
997- // Only notify QML of surface creation once it has drawn its first frame.
998- connect(qmlSurface, &MirSurfaceInterface::firstFrameDrawn, this, [=]() {
999- tracepoint(qtmir, firstFrameDrawn);
1000- Q_EMIT surfaceCreated(qmlSurface);
1001- });
1002-
1003- // clean up after MirSurface is destroyed
1004- connect(qmlSurface, &QObject::destroyed, this, [&](QObject *obj) {
1005- auto qmlSurface = static_cast<MirSurfaceInterface*>(obj);
1006- {
1007- QMutexLocker lock(&m_mutex);
1008- m_mirSurfaceToQmlSurfaceHash.remove(m_mirSurfaceToQmlSurfaceHash.key(qmlSurface));
1009- }
1010-
1011- tracepoint(qtmir, surfaceDestroyed);
1012- });
1013- tracepoint(qtmir, surfaceCreated);
1014+// SessionInterface* session = m_sessionManager->findSession(mirSession);
1015+// auto qmlSurface = new MirSurface(surface, session, m_shell, observer, creationHints);
1016+// {
1017+// QMutexLocker lock(&m_mutex);
1018+// m_mirSurfaceToQmlSurfaceHash.insert(surface.get(), qmlSurface);
1019+// }
1020+
1021+// if (session)
1022+// session->registerSurface(qmlSurface);
1023+
1024+// if (qmlSurface->type() == Mir::InputMethodType) {
1025+// m_inputMethodSurface = qmlSurface;
1026+// Q_EMIT inputMethodSurfaceChanged();
1027+// }
1028+
1029+// // Only notify QML of surface creation once it has drawn its first frame.
1030+// connect(qmlSurface, &MirSurfaceInterface::firstFrameDrawn, this, [=]() {
1031+// tracepoint(qtmir, firstFrameDrawn);
1032+// Q_EMIT surfaceCreated(qmlSurface);
1033+// });
1034+
1035+// // clean up after MirSurface is destroyed
1036+// connect(qmlSurface, &QObject::destroyed, this, [&](QObject *obj) {
1037+// auto qmlSurface = static_cast<MirSurfaceInterface*>(obj);
1038+// {
1039+// QMutexLocker lock(&m_mutex);
1040+// m_mirSurfaceToQmlSurfaceHash.remove(m_mirSurfaceToQmlSurfaceHash.key(qmlSurface));
1041+// }
1042+
1043+// tracepoint(qtmir, surfaceDestroyed);
1044+// });
1045+// tracepoint(qtmir, surfaceCreated);
1046 }
1047
1048 void MirSurfaceManager::onSessionDestroyingSurface(const mir::scene::Session *session,
1049@@ -144,27 +144,27 @@
1050 qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::onSessionDestroyingSurface - session=" << session
1051 << "surface=" << surface.get() << "surface.name=" << surface->name().c_str();
1052
1053- MirSurfaceInterface* qmlSurface = nullptr;
1054- {
1055- QMutexLocker lock(&m_mutex);
1056- auto it = m_mirSurfaceToQmlSurfaceHash.find(surface.get());
1057- if (it != m_mirSurfaceToQmlSurfaceHash.end()) {
1058- qmlSurface = it.value();
1059- m_mirSurfaceToQmlSurfaceHash.erase(it);
1060- } else {
1061- qCritical() << "MirSurfaceManager::onSessionDestroyingSurface: unable to find MirSurface corresponding"
1062- << "to surface=" << surface.get() << "surface.name=" << surface->name().c_str();
1063- return;
1064- }
1065- }
1066-
1067- if (qmlSurface->type() == Mir::InputMethodType) {
1068- m_inputMethodSurface = nullptr;
1069- Q_EMIT inputMethodSurfaceChanged();
1070- }
1071-
1072- qmlSurface->setLive(false);
1073- Q_EMIT surfaceDestroyed(qmlSurface);
1074+// MirSurfaceInterface* qmlSurface = nullptr;
1075+// {
1076+// QMutexLocker lock(&m_mutex);
1077+// auto it = m_mirSurfaceToQmlSurfaceHash.find(surface.get());
1078+// if (it != m_mirSurfaceToQmlSurfaceHash.end()) {
1079+// qmlSurface = it.value();
1080+// m_mirSurfaceToQmlSurfaceHash.erase(it);
1081+// } else {
1082+// qCritical() << "MirSurfaceManager::onSessionDestroyingSurface: unable to find MirSurface corresponding"
1083+// << "to surface=" << surface.get() << "surface.name=" << surface->name().c_str();
1084+// return;
1085+// }
1086+// }
1087+
1088+// if (qmlSurface->type() == Mir::InputMethodType) {
1089+// m_inputMethodSurface = nullptr;
1090+// Q_EMIT inputMethodSurfaceChanged();
1091+// }
1092+
1093+// qmlSurface->setLive(false);
1094+// Q_EMIT surfaceDestroyed(qmlSurface);
1095 }
1096
1097 MirSurfaceInterface* MirSurfaceManager::inputMethodSurface() const
1098
1099=== modified file 'miral-qt/src/modules/Unity/Application/windowmodel.cpp'
1100--- miral-qt/src/modules/Unity/Application/windowmodel.cpp 2016-07-27 12:05:20 +0000
1101+++ miral-qt/src/modules/Unity/Application/windowmodel.cpp 2016-08-12 12:04:26 +0000
1102@@ -31,8 +31,8 @@
1103 using namespace qtmir;
1104
1105 WindowModel::WindowModel()
1106+ : m_focusedWindow(nullptr)
1107 {
1108-
1109 auto nativeInterface = dynamic_cast<NativeInterface*>(QGuiApplication::platformNativeInterface());
1110
1111 if (!nativeInterface) {
1112@@ -40,10 +40,14 @@
1113 }
1114
1115 auto windowModel = static_cast<WindowModelInterface*>(nativeInterface->nativeResourceForIntegration("WindowModel"));
1116+ m_windowController = static_cast<WindowControllerInterface*>(nativeInterface->nativeResourceForIntegration("WindowController"));
1117
1118- connect(windowModel, &WindowModelInterface::windowAdded, this, &WindowModel::onWindowAdded);
1119- connect(windowModel, &WindowModelInterface::windowRemoved, this, &WindowModel::onWindowRemoved);
1120- connect(windowModel, &WindowModelInterface::windowChanged, this, &WindowModel::onWindowChanged);
1121+ connect(windowModel, &WindowModelInterface::windowAdded, this, &WindowModel::onWindowAdded);
1122+ connect(windowModel, &WindowModelInterface::windowRemoved, this, &WindowModel::onWindowRemoved);
1123+ connect(windowModel, &WindowModelInterface::windowMoved, this, &WindowModel::onWindowMoved);
1124+ connect(windowModel, &WindowModelInterface::windowResized, this, &WindowModel::onWindowResized);
1125+ connect(windowModel, &WindowModelInterface::windowFocused, this, &WindowModel::onWindowFocused);
1126+ connect(windowModel, &WindowModelInterface::windowInfoChanged, this, &WindowModel::onWindowInfoChanged);
1127 }
1128
1129 QHash<int, QByteArray> WindowModel::roleNames() const
1130@@ -53,17 +57,18 @@
1131 return roleNames;
1132 }
1133
1134-void WindowModel::onWindowAdded(const NumberedWindow window)
1135+void WindowModel::onWindowAdded(const WindowInfo windowInfo, const unsigned int index)
1136 {
1137- qDebug() << "Window Added!" << window.index;
1138+ qDebug() << "Window Added!" << index;
1139 std::shared_ptr<SurfaceObserver> surfaceObserver = std::make_shared<SurfaceObserver>();
1140- const auto &surface = window.windowInfo.surface;
1141+
1142+ const auto &surface = static_cast<std::shared_ptr<mir::scene::Surface>>(windowInfo.window);
1143 SurfaceObserver::registerObserverForSurface(surfaceObserver.get(), surface.get());
1144 surface->add_observer(surfaceObserver);
1145
1146- auto mirSurface = new MirSurface(surface, nullptr, nullptr, surfaceObserver, CreationHints());
1147- beginInsertRows(QModelIndex(), window.index, window.index);
1148- m_windowModel.insert(window.index, mirSurface);
1149+ auto mirSurface = new MirSurface(windowInfo, m_windowController, surfaceObserver);
1150+ beginInsertRows(QModelIndex(), index, index);
1151+ m_windowModel.insert(index, mirSurface);
1152 endInsertRows();
1153 Q_EMIT countChanged();
1154 }
1155@@ -77,25 +82,34 @@
1156 Q_EMIT countChanged();
1157 }
1158
1159-void WindowModel::onWindowChanged(const DirtiedWindow window)
1160-{
1161- qDebug() << "Window Change!" << window.index;
1162- auto mirSurface = m_windowModel.value(window.index);
1163-
1164- switch(window.dirtyWindowInfo) {
1165- case WindowInfo::DirtyStates::Size: {
1166- qDebug() << "size";
1167- // Do nothing yet, it gets new size from swapped buffer for now
1168- }
1169- case WindowInfo::DirtyStates::Position:
1170- qDebug() << "position";
1171- mirSurface->setPosition(window.windowInfo.position);
1172- case WindowInfo::DirtyStates::Focus:
1173- qDebug() << "focus";
1174- mirSurface->setFocused(window.windowInfo.focused);
1175- }
1176-
1177- QModelIndex row = index(window.index);
1178+void WindowModel::onWindowMoved(const QPoint topLeft, const unsigned int index)
1179+{
1180+ auto mirSurface = static_cast<MirSurface *>(m_windowModel.value(index));
1181+ mirSurface->setPosition(topLeft);
1182+}
1183+
1184+void WindowModel::onWindowResized(const QSize size, const unsigned int index)
1185+{
1186+ auto mirSurface = static_cast<MirSurface *>(m_windowModel.value(index));
1187+ mirSurface->setSize(size);
1188+}
1189+
1190+void WindowModel::onWindowFocused(const unsigned int index)
1191+{
1192+ auto mirSurface = static_cast<MirSurface *>(m_windowModel.value(index));
1193+ if (m_focusedWindow && m_focusedWindow != mirSurface) {
1194+ m_focusedWindow->setFocused(false);
1195+ }
1196+ mirSurface->setFocused(true);
1197+ m_focusedWindow = mirSurface;
1198+}
1199+
1200+void WindowModel::onWindowInfoChanged(const WindowInfo windowInfo, const unsigned int pos)
1201+{
1202+ auto mirSurface = static_cast<MirSurface *>(m_windowModel.value(pos));
1203+ mirSurface->updateWindowInfo(windowInfo);
1204+
1205+ QModelIndex row = index(pos);
1206 Q_EMIT dataChanged(row, row, QVector<int>() << SurfaceRole);
1207 }
1208
1209
1210=== modified file 'miral-qt/src/modules/Unity/Application/windowmodel.h'
1211--- miral-qt/src/modules/Unity/Application/windowmodel.h 2016-07-27 11:48:55 +0000
1212+++ miral-qt/src/modules/Unity/Application/windowmodel.h 2016-08-12 12:04:26 +0000
1213@@ -24,6 +24,8 @@
1214
1215 namespace qtmir {
1216
1217+class WindowControllerInterface;
1218+
1219 class WindowModel : public QAbstractListModel
1220 {
1221 Q_OBJECT
1222@@ -49,12 +51,17 @@
1223 void countChanged();
1224
1225 private Q_SLOTS:
1226- void onWindowAdded(const NumberedWindow);
1227+ void onWindowAdded(const WindowInfo windowInfo, const unsigned int index);
1228 void onWindowRemoved(const unsigned int index);
1229- void onWindowChanged(const DirtiedWindow);
1230+ void onWindowMoved(const QPoint topLeft, const unsigned int index);
1231+ void onWindowResized(const QSize size, const unsigned int index);
1232+ void onWindowFocused(const unsigned int index);
1233+ void onWindowInfoChanged(const WindowInfo windowInfo, const unsigned int index);
1234
1235 private:
1236 QVector<MirSurfaceInterface *> m_windowModel;
1237+ WindowControllerInterface *m_windowController;
1238+ MirSurfaceInterface* m_focusedWindow;
1239 };
1240
1241 } // namespace qtmir
1242
1243=== modified file 'miral-qt/src/platforms/mirserver/CMakeLists.txt'
1244--- miral-qt/src/platforms/mirserver/CMakeLists.txt 2016-07-28 13:37:17 +0000
1245+++ miral-qt/src/platforms/mirserver/CMakeLists.txt 2016-08-12 12:04:26 +0000
1246@@ -79,12 +79,14 @@
1247 ubuntutheme.cpp
1248 clipboard.cpp
1249 creationhints.cpp
1250+ windowcontroller.cpp
1251 windowmanagementpolicy.cpp
1252 windowmodel.cpp
1253 tracepoints.c
1254 # We need to run moc on these headers
1255 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/Mir.h
1256 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirMousePointerInterface.h
1257+ ${MIRAL_QT_SOURCE_DIR}/src/common/windowcontrollerinterface.h
1258 ${MIRAL_QT_SOURCE_DIR}/src/common/windowmodelinterface.h
1259 )
1260
1261
1262=== modified file 'miral-qt/src/platforms/mirserver/mirserver.cpp'
1263--- miral-qt/src/platforms/mirserver/mirserver.cpp 2016-07-28 13:37:17 +0000
1264+++ miral-qt/src/platforms/mirserver/mirserver.cpp 2016-08-12 12:04:26 +0000
1265@@ -192,7 +192,7 @@
1266
1267 UsingQtMirWindowManager::UsingQtMirWindowManager(const QSharedPointer<ScreensModel> &model)
1268 : m_screensModel(model)
1269- , m_policy(miral::set_window_managment_policy<WindowManagementPolicy>(m_windowModel, m_screensModel))
1270+ , m_policy(miral::set_window_managment_policy<WindowManagementPolicy>(m_windowModel, m_windowController, m_screensModel))
1271 {
1272 }
1273
1274@@ -206,10 +206,9 @@
1275 return &m_windowModel;
1276 }
1277
1278-mir::shell::Shell *MirServer::shell()
1279+qtmir::WindowControllerInterface *UsingQtMirWindowManager::windowController()
1280 {
1281- std::weak_ptr<mir::shell::Shell> m_shell = the_shell();
1282- return m_shell.lock().get();
1283+ return &m_windowController;
1284 }
1285
1286 QSharedPointer<ScreensModel> MirServer::screensModel() const
1287
1288=== modified file 'miral-qt/src/platforms/mirserver/mirserver.h'
1289--- miral-qt/src/platforms/mirserver/mirserver.h 2016-07-28 13:37:17 +0000
1290+++ miral-qt/src/platforms/mirserver/mirserver.h 2016-08-12 12:04:26 +0000
1291@@ -22,6 +22,7 @@
1292 #include <mir/server.h>
1293 #include "miral/set_window_managment_policy.h"
1294 #include "windowmodel.h"
1295+#include "windowcontroller.h"
1296
1297 class QtEventFeeder;
1298 class MirDisplayConfigurationPolicy;
1299@@ -70,10 +71,12 @@
1300 UsingQtMirWindowManager(const QSharedPointer<ScreensModel> &model);
1301 void operator()(mir::Server& server);
1302 qtmir::WindowModelInterface *windowModel();
1303+ qtmir::WindowControllerInterface *windowController();
1304
1305 private:
1306 const QSharedPointer<ScreensModel> &m_screensModel;
1307 miral::SetWindowManagmentPolicy m_policy;
1308+ qtmir::WindowController m_windowController;
1309 qtmir::WindowModel m_windowModel;
1310 };
1311
1312@@ -92,7 +95,6 @@
1313
1314 Q_PROPERTY(SessionAuthorizer* sessionAuthorizer READ sessionAuthorizer CONSTANT)
1315 Q_PROPERTY(SessionListener* sessionListener READ sessionListener CONSTANT)
1316- Q_PROPERTY(mir::shell::Shell* shell READ shell CONSTANT)
1317 Q_PROPERTY(PromptSessionListener* promptSessionListener READ promptSessionListener CONSTANT)
1318
1319 public:
1320@@ -115,7 +117,7 @@
1321 using UsingQtMirSessionListener::sessionListener;
1322 using UsingQtMirPromptSessionListener::promptSessionListener;
1323 using UsingQtMirWindowManager::windowModel;
1324- mir::shell::Shell *shell();
1325+ using UsingQtMirWindowManager::windowController;
1326
1327 QSharedPointer<ScreensModel> screensModel() const;
1328
1329
1330=== modified file 'miral-qt/src/platforms/mirserver/qmirserver.cpp'
1331--- miral-qt/src/platforms/mirserver/qmirserver.cpp 2016-07-28 13:37:17 +0000
1332+++ miral-qt/src/platforms/mirserver/qmirserver.cpp 2016-08-12 12:04:26 +0000
1333@@ -113,12 +113,12 @@
1334 if (d->server) {
1335 if (resource == "SessionAuthorizer")
1336 result = d->server->sessionAuthorizer();
1337- else if (resource == "Shell")
1338- result = d->server->shell();
1339 else if (resource == "SessionListener")
1340 result = d->server->sessionListener();
1341 else if (resource == "PromptSessionListener")
1342 result = d->server->promptSessionListener();
1343+ else if (resource == "WindowController")
1344+ result = d->server->windowController();
1345 else if (resource == "WindowModel")
1346 result = d->server->windowModel();
1347 else if (resource == "ScreensController")
1348
1349=== added file 'miral-qt/src/platforms/mirserver/windowcontroller.cpp'
1350--- miral-qt/src/platforms/mirserver/windowcontroller.cpp 1970-01-01 00:00:00 +0000
1351+++ miral-qt/src/platforms/mirserver/windowcontroller.cpp 2016-08-12 12:04:26 +0000
1352@@ -0,0 +1,85 @@
1353+/*
1354+ * Copyright (C) 2016 Canonical, Ltd.
1355+ *
1356+ * This program is free software: you can redistribute it and/or modify it under
1357+ * the terms of the GNU Lesser General Public License version 3, as published by
1358+ * the Free Software Foundation.
1359+ *
1360+ * This program is distributed in the hope that it will be useful, but WITHOUT
1361+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1362+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1363+ * Lesser General Public License for more details.
1364+ *
1365+ * You should have received a copy of the GNU Lesser General Public License
1366+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1367+ */
1368+
1369+#include "windowcontroller.h"
1370+
1371+#include "windowmanagementpolicy.h"
1372+#include "mirqtconversion.h"
1373+
1374+using namespace qtmir;
1375+
1376+
1377+WindowController::WindowController()
1378+ : m_policy(nullptr)
1379+{
1380+}
1381+
1382+void WindowController::focus(const miral::Window &window)
1383+{
1384+ if (m_policy) {
1385+ m_policy->focus(window);
1386+ }
1387+}
1388+
1389+void WindowController::resize(const miral::Window &window, const QSize &size)
1390+{
1391+ if (m_policy) {
1392+ m_policy->resize(window, toMirSize(size));
1393+ }
1394+}
1395+
1396+void WindowController::move(const miral::Window &window, const QPoint &topLeft)
1397+{
1398+ if (m_policy) {
1399+ m_policy->move(window, toMirPoint(topLeft));
1400+ }
1401+}
1402+
1403+void WindowController::setActiveFocus(const miral::Window &/*window*/, const bool /*activeFocus*/)
1404+{
1405+
1406+}
1407+
1408+void WindowController::setState(const miral::Window &/*window*/, const MirSurfaceState /*state*/)
1409+{
1410+
1411+}
1412+
1413+void WindowController::deliverKeyboardEvent(const miral::Window &window, const MirKeyboardEvent *event)
1414+{
1415+ if (m_policy) {
1416+ m_policy->deliver_keyboard_event(event, window);
1417+ }
1418+}
1419+
1420+void WindowController::deliverTouchEvent(const miral::Window &window, const MirTouchEvent *event)
1421+{
1422+ if (m_policy) {
1423+ m_policy->deliver_touch_event(event, window);
1424+ }
1425+}
1426+
1427+void WindowController::deliverPointerEvent(const miral::Window &window, const MirPointerEvent *event)
1428+{
1429+ if (m_policy) {
1430+ m_policy->deliver_pointer_event(event, window);
1431+ }
1432+}
1433+
1434+void WindowController::setPolicy(WindowManagementPolicy * const policy)
1435+{
1436+ m_policy = policy;
1437+}
1438
1439=== added file 'miral-qt/src/platforms/mirserver/windowcontroller.h'
1440--- miral-qt/src/platforms/mirserver/windowcontroller.h 1970-01-01 00:00:00 +0000
1441+++ miral-qt/src/platforms/mirserver/windowcontroller.h 2016-08-12 12:04:26 +0000
1442@@ -0,0 +1,51 @@
1443+/*
1444+ * Copyright (C) 2016 Canonical, Ltd.
1445+ *
1446+ * This program is free software: you can redistribute it and/or modify it under
1447+ * the terms of the GNU Lesser General Public License version 3, as published by
1448+ * the Free Software Foundation.
1449+ *
1450+ * This program is distributed in the hope that it will be useful, but WITHOUT
1451+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1452+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1453+ * Lesser General Public License for more details.
1454+ *
1455+ * You should have received a copy of the GNU Lesser General Public License
1456+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1457+ */
1458+
1459+#ifndef WINDOWCONTROLLER_H
1460+#define WINDOWCONTROLLER_H
1461+
1462+#include "windowcontrollerinterface.h"
1463+
1464+class WindowManagementPolicy;
1465+
1466+namespace qtmir {
1467+
1468+class WindowController : public WindowControllerInterface
1469+{
1470+public:
1471+ WindowController();
1472+ virtual ~WindowController() = default;
1473+
1474+ void focus (const miral::Window &window) override;
1475+ void resize(const miral::Window &window, const QSize &size) override;
1476+ void move (const miral::Window &window, const QPoint &topLeft) override;
1477+
1478+ void setActiveFocus(const miral::Window &window, const bool activeFocus) override;
1479+ void setState(const miral::Window &window, const MirSurfaceState state) override;
1480+
1481+ void deliverKeyboardEvent(const miral::Window &window, const MirKeyboardEvent *event) override;
1482+ void deliverTouchEvent (const miral::Window &window, const MirTouchEvent *event) override;
1483+ void deliverPointerEvent (const miral::Window &window, const MirPointerEvent *event) override;
1484+
1485+ void setPolicy(WindowManagementPolicy *policy);
1486+
1487+protected:
1488+ WindowManagementPolicy *m_policy;
1489+};
1490+
1491+} // namespace qtmir
1492+
1493+#endif // WINDOWCONTROLLER_H
1494
1495=== modified file 'miral-qt/src/platforms/mirserver/windowmanagementpolicy.cpp'
1496--- miral-qt/src/platforms/mirserver/windowmanagementpolicy.cpp 2016-08-10 11:48:02 +0000
1497+++ miral-qt/src/platforms/mirserver/windowmanagementpolicy.cpp 2016-08-12 12:04:26 +0000
1498@@ -26,12 +26,14 @@
1499
1500 WindowManagementPolicy::WindowManagementPolicy(const miral::WindowManagerTools &tools,
1501 qtmir::WindowModel &windowModel,
1502+ qtmir::WindowController &windowController,
1503 const QSharedPointer<ScreensModel> screensModel)
1504 : CanonicalWindowManagerPolicy(tools)
1505 , m_tools(tools)
1506 , m_windowModel(windowModel)
1507 , m_eventFeeder(new QtEventFeeder(screensModel))
1508 {
1509+ windowController.setPolicy(this);
1510 }
1511
1512 /* Following are hooks to allow custom policy be imposed */
1513@@ -46,7 +48,7 @@
1514
1515 void WindowManagementPolicy::handle_window_ready(miral::WindowInfo &windowInfo)
1516 {
1517- qDebug("Window ready");
1518+ qDebug("Window Ready");
1519 m_tools.select_active_window(windowInfo.window());
1520 }
1521
1522@@ -85,6 +87,7 @@
1523
1524 void WindowManagementPolicy::advise_new_window(const miral::WindowInfo &windowInfo)
1525 {
1526+ // TODO: attach surface observer here
1527 m_windowModel.addWindow(windowInfo);
1528 }
1529
1530@@ -115,13 +118,13 @@
1531
1532 void WindowManagementPolicy::advise_move_to(const miral::WindowInfo &windowInfo, Point topLeft)
1533 {
1534- qDebug("Window move");
1535+ qDebug("Window Moved to (%d, %d)", topLeft.x.as_int(), topLeft.y.as_int());
1536 m_windowModel.moveWindow(windowInfo, topLeft);
1537 }
1538
1539 void WindowManagementPolicy::advise_resize(const miral::WindowInfo &windowInfo, const Size &newSize)
1540 {
1541- qDebug("Window Resize");
1542+ qDebug("Window Resized to %dx%d", newSize.width.as_int(), newSize.height.as_int());
1543 m_windowModel.resizeWindow(windowInfo, newSize);
1544 }
1545
1546@@ -147,35 +150,60 @@
1547
1548 /* Following methods all called from the Qt GUI thread to deliver events to clients */
1549 void WindowManagementPolicy::deliver_keyboard_event(const MirKeyboardEvent *event,
1550- const std::shared_ptr<mir::scene::Surface> &surface)
1551+ const miral::Window &window)
1552 {
1553- m_tools.invoke_under_lock([&surface, this]() {
1554- auto windowInfo = m_tools.info_for(surface);
1555- m_tools.select_active_window(windowInfo.window());
1556+ m_tools.invoke_under_lock([&window, this]() {
1557+ m_tools.select_active_window(window);
1558 });
1559 auto e = reinterpret_cast<MirEvent const*>(event); // naughty
1560- surface->consume(e);
1561+
1562+ if (auto surface = std::weak_ptr<mir::scene::Surface>(window).lock()) {
1563+ surface->consume(e);
1564+ }
1565 }
1566
1567 void WindowManagementPolicy::deliver_touch_event(const MirTouchEvent *event,
1568- const std::shared_ptr<mir::scene::Surface> &surface)
1569+ const miral::Window &window)
1570 {
1571- m_tools.invoke_under_lock([&surface, this]() {
1572- auto windowInfo = m_tools.info_for(surface);
1573- m_tools.select_active_window(windowInfo.window());
1574+ m_tools.invoke_under_lock([&window, this]() {
1575+ m_tools.select_active_window(window);
1576 });
1577 auto e = reinterpret_cast<MirEvent const*>(event); // naughty
1578- surface->consume(e);
1579+
1580+ if (auto surface = std::weak_ptr<mir::scene::Surface>(window).lock()) {
1581+ surface->consume(e);
1582+ }
1583 }
1584
1585 void WindowManagementPolicy::deliver_pointer_event(const MirPointerEvent *event,
1586- const std::shared_ptr<mir::scene::Surface> &surface)
1587+ const miral::Window &window)
1588 {
1589- m_tools.invoke_under_lock([&surface, this]() {
1590- auto windowInfo = m_tools.info_for(surface);
1591- m_tools.select_active_window(windowInfo.window());
1592+ m_tools.invoke_under_lock([&window, this]() {
1593+ m_tools.select_active_window(window);
1594 });
1595 auto e = reinterpret_cast<MirEvent const*>(event); // naughty
1596- surface->consume(e);
1597-}
1598-
1599+
1600+ if (auto surface = std::weak_ptr<mir::scene::Surface>(window).lock()) {
1601+ surface->consume(e);
1602+ }
1603+}
1604+
1605+/* Methods to allow Shell to request changes to the window stack */
1606+void WindowManagementPolicy::focus(const miral::Window &window)
1607+{
1608+ m_tools.select_active_window(window);
1609+}
1610+
1611+void WindowManagementPolicy::resize(const miral::Window &window, const Size size)
1612+{
1613+ miral::WindowSpecification modifications;
1614+ modifications.size() = size;
1615+ m_tools.modify_window(m_tools.info_for(window), modifications);
1616+}
1617+
1618+void WindowManagementPolicy::move(const miral::Window &window, const Point topLeft)
1619+{
1620+ miral::WindowSpecification modifications;
1621+ modifications.top_left() = topLeft;
1622+ m_tools.modify_window(m_tools.info_for(window), modifications);
1623+}
1624
1625=== modified file 'miral-qt/src/platforms/mirserver/windowmanagementpolicy.h'
1626--- miral-qt/src/platforms/mirserver/windowmanagementpolicy.h 2016-08-10 11:48:02 +0000
1627+++ miral-qt/src/platforms/mirserver/windowmanagementpolicy.h 2016-08-12 12:04:26 +0000
1628@@ -20,9 +20,9 @@
1629 #include "miral/canonical_window_manager.h"
1630
1631 #include "qteventfeeder.h"
1632+#include "windowcontroller.h"
1633 #include "windowmodel.h"
1634
1635-#include <QObject>
1636 #include <QScopedPointer>
1637 #include <QSize>
1638
1639@@ -30,11 +30,12 @@
1640
1641 class ScreensModel;
1642
1643-class WindowManagementPolicy : public QObject, public miral::CanonicalWindowManagerPolicy
1644+class WindowManagementPolicy : public miral::CanonicalWindowManagerPolicy
1645 {
1646 public:
1647 WindowManagementPolicy(const miral::WindowManagerTools &tools,
1648 qtmir::WindowModel &windowModel,
1649+ qtmir::WindowController &windowController,
1650 const QSharedPointer<ScreensModel> screensModel);
1651
1652 // From WindowManagementPolicy
1653@@ -65,12 +66,16 @@
1654 void advise_move_to(const miral::WindowInfo &windowInfo, Point topLeft) override;
1655 void advise_resize(const miral::WindowInfo &info, const Size &newSize) override;
1656 void advise_delete_window(const miral::WindowInfo &windowInfo) override;
1657- void advise_raise(std::vector<miral::Window> const& windows) override;
1658-
1659- // Exposing some tools
1660- void deliver_keyboard_event(const MirKeyboardEvent *event, const std::shared_ptr<mir::scene::Surface> &surface);
1661- void deliver_touch_event(const MirTouchEvent *event, const std::shared_ptr<mir::scene::Surface> &surface);
1662- void deliver_pointer_event(const MirPointerEvent *event, const std::shared_ptr<mir::scene::Surface> &surface);
1663+ void advise_raise(const std::vector<miral::Window> &windows) override;
1664+
1665+ // Methods for consumption by WindowControllerInterface
1666+ void deliver_keyboard_event(const MirKeyboardEvent *event, const miral::Window &window);
1667+ void deliver_touch_event (const MirTouchEvent *event, const miral::Window &window);
1668+ void deliver_pointer_event (const MirPointerEvent *event, const miral::Window &window);
1669+
1670+ void focus (const miral::Window &window);
1671+ void resize(const miral::Window &window, const Size size);
1672+ void move (const miral::Window &window, const Point topLeft);
1673
1674 Q_SIGNALS:
1675
1676
1677=== modified file 'miral-qt/src/platforms/mirserver/windowmodel.cpp'
1678--- miral-qt/src/platforms/mirserver/windowmodel.cpp 2016-08-05 09:54:43 +0000
1679+++ miral-qt/src/platforms/mirserver/windowmodel.cpp 2016-08-12 12:04:26 +0000
1680@@ -32,8 +32,7 @@
1681 WindowModel::WindowModel()
1682 {
1683 qDebug("WindowModel::WindowModel");
1684- qRegisterMetaType<qtmir::NumberedWindow>();
1685- qRegisterMetaType<qtmir::DirtiedWindow>();
1686+ qRegisterMetaType<qtmir::WindowInfo>();
1687 }
1688
1689 WindowModel::~WindowModel()
1690@@ -47,12 +46,7 @@
1691 auto stackPosition = static_cast<unsigned int>(m_windowStack.count());
1692 m_windowStack.push_back(windowInfo.window()); // ASSUMPTION: Mir should tell us where in stack
1693
1694- QSize size = toQSize(windowInfo.window().size());
1695- QPoint position = toQPoint(windowInfo.window().top_left());
1696-
1697- WindowInfo info{ size, position, false, windowInfo.window() };
1698- NumberedWindow window{ stackPosition, info };
1699- Q_EMIT windowAdded(window);
1700+ Q_EMIT windowAdded(windowInfo, stackPosition);
1701 }
1702
1703 void WindowModel::removeWindow(const miral::WindowInfo &windowInfo)
1704@@ -76,13 +70,11 @@
1705 return;
1706 }
1707 auto upos = static_cast<unsigned int>(pos);
1708- m_focusedWindowIndex = upos;
1709- QSize size = toQSize(windowInfo.window().size());
1710- QPoint position = toQPoint(windowInfo.window().top_left());
1711
1712- WindowInfo info{ size, position, focus, windowInfo.window() };
1713- DirtiedWindow window{ upos, info, WindowInfo::DirtyStates::Focus};
1714- Q_EMIT windowChanged(window);
1715+ if (focus && m_focusedWindowIndex != upos) {
1716+ m_focusedWindowIndex = upos;
1717+ Q_EMIT windowFocused(upos);
1718+ }
1719 }
1720
1721 void WindowModel::moveWindow(const miral::WindowInfo &windowInfo, mir::geometry::Point topLeft)
1722@@ -93,13 +85,9 @@
1723 return;
1724 }
1725 auto upos = static_cast<unsigned int>(pos);
1726- const bool focused = (m_focusedWindowIndex == upos);
1727- QSize size = toQSize(windowInfo.window().size());
1728- QPoint position = toQPoint(topLeft);
1729
1730- WindowInfo info{ size, position, focused, windowInfo.window() };
1731- DirtiedWindow window{ upos, info, WindowInfo::DirtyStates::Position};
1732- Q_EMIT windowChanged(window);
1733+ // Note: windowInfo.window() is in the state before the move
1734+ Q_EMIT windowMoved(toQPoint(topLeft), upos);
1735 }
1736
1737 void WindowModel::resizeWindow(const miral::WindowInfo &windowInfo, mir::geometry::Size newSize)
1738@@ -110,13 +98,9 @@
1739 return;
1740 }
1741 auto upos = static_cast<unsigned int>(pos);
1742- const bool focused = (m_focusedWindowIndex == upos);
1743- QSize size = toQSize(newSize);
1744- QPoint position = toQPoint(windowInfo.window().top_left());
1745
1746- WindowInfo info{ size, position, focused, windowInfo.window() };
1747- DirtiedWindow window{ upos, info, WindowInfo::DirtyStates::Size};
1748- Q_EMIT windowChanged(window);
1749+ // Note: windowInfo.window() is in the state before the resize
1750+ Q_EMIT windowResized(toQSize(newSize), upos);
1751 }
1752
1753 void WindowModel::raiseWindows(const std::vector<miral::Window> &/*windows*/)
1754
1755=== modified file 'miral-qt/tests/framework/fake_mirsurface.cpp'
1756--- miral-qt/tests/framework/fake_mirsurface.cpp 2016-07-27 12:05:20 +0000
1757+++ miral-qt/tests/framework/fake_mirsurface.cpp 2016-08-12 12:04:26 +0000
1758@@ -58,11 +58,11 @@
1759
1760 QPoint FakeMirSurface::position() const { return m_position; }
1761
1762-void FakeMirSurface::setPosition(const QPoint position)
1763+void FakeMirSurface::requestPosition(const QPoint newPosition)
1764 {
1765- if (m_position != position) {
1766- m_position = position;
1767- Q_EMIT positionChanged(position);
1768+ if (m_position != newPosition) {
1769+ m_position = newPosition;
1770+ Q_EMIT positionChanged(newPosition);
1771 }
1772 }
1773
1774@@ -192,6 +192,8 @@
1775
1776 void FakeMirSurface::onCompositorSwappedBuffers() {}
1777
1778+void FakeMirSurface::setShellChrome(Mir::ShellChrome /*shellChrome*/) {}
1779+
1780 void FakeMirSurface::drawFirstFrame()
1781 {
1782 if (!m_isFirstFrameDrawn) {
1783
1784=== modified file 'miral-qt/tests/framework/fake_mirsurface.h'
1785--- miral-qt/tests/framework/fake_mirsurface.h 2016-07-27 12:05:20 +0000
1786+++ miral-qt/tests/framework/fake_mirsurface.h 2016-08-12 12:04:26 +0000
1787@@ -54,8 +54,6 @@
1788 Mir::Type type() const override;
1789 QString name() const override;
1790 QSize size() const override;
1791- QPoint position() const override;
1792- void setPosition(const QPoint position) override;
1793 void resize(int width, int height) override;
1794 void resize(const QSize &size) override;
1795 Mir::State state() const override;
1796@@ -93,6 +91,9 @@
1797 ////
1798 // qtmir.MirSurfaceInterface
1799
1800+ QPoint position() const override;
1801+ void requestPosition(const QPoint newPosition) override;
1802+
1803 bool isFirstFrameDrawn() const override;
1804 void stopFrameDropper() override;
1805 void startFrameDropper() override;
1806@@ -112,7 +113,7 @@
1807
1808 void setFocused(bool focus) override;
1809
1810- void setViewActiveFocus(qintptr, bool) override {};
1811+ void setViewActiveFocus(qintptr, bool) override {}
1812 bool activeFocus() const override { return false; }
1813
1814 void mousePressEvent(QMouseEvent *) override;
1815@@ -141,13 +142,7 @@
1816 public Q_SLOTS:
1817 void onCompositorSwappedBuffers() override;
1818
1819- void setMinimumWidth(int) {}
1820- void setMinimumHeight(int) {}
1821- void setMaximumWidth(int) {}
1822- void setMaximumHeight(int) {}
1823- void setWidthIncrement(int) {}
1824- void setHeightIncrement(int) {}
1825- void setShellChrome(Mir::ShellChrome) override {}
1826+ void setShellChrome(Mir::ShellChrome shellChrome) override;
1827
1828 ////
1829 // Test API from now on
1830
1831=== modified file 'miral-qt/tests/modules/SurfaceManager/CMakeLists.txt'
1832--- miral-qt/tests/modules/SurfaceManager/CMakeLists.txt 2016-06-07 20:32:04 +0000
1833+++ miral-qt/tests/modules/SurfaceManager/CMakeLists.txt 2016-08-12 12:04:26 +0000
1834@@ -1,14 +1,16 @@
1835 set(
1836 MIR_SURFACE_MANAGER_TEST_SOURCES
1837- mirsurfaceitem_test.cpp
1838+# mirsurfaceitem_test.cpp #FIXME - reinstate these tests when functionality there
1839 mirsurface_test.cpp
1840 ${MIRAL_QT_SOURCE_DIR}/src/common/debughelpers.cpp
1841 )
1842
1843 include_directories(
1844+ ${MIRAL_QT_SOURCE_DIR}/src/common
1845 ${MIRAL_QT_SOURCE_DIR}/src/modules
1846 ${MIRAL_QT_SOURCE_DIR}/src/platforms/mirserver
1847 ${MIRAL_QT_SOURCE_DIR}/tests/framework
1848+ ${CMAKE_SOURCE_DIR}/include/miral #FIXME
1849 ${MIRSERVER_INCLUDE_DIRS}
1850 ${Qt5Quick_PRIVATE_INCLUDE_DIRS}
1851 )
1852
1853=== modified file 'miral-qt/tests/modules/SurfaceManager/mirsurface_test.cpp'
1854--- miral-qt/tests/modules/SurfaceManager/mirsurface_test.cpp 2016-06-07 20:32:04 +0000
1855+++ miral-qt/tests/modules/SurfaceManager/mirsurface_test.cpp 2016-08-12 12:04:26 +0000
1856@@ -24,22 +24,24 @@
1857 #include <QTest>
1858 #include <QSignalSpy>
1859
1860+// src/common
1861+#include "windowmodelinterface.h"
1862+
1863 // the test subject
1864 #include <Unity/Application/mirsurface.h>
1865
1866 #include <Unity/Application/timer.h>
1867
1868 // tests/framework
1869-#include <fake_session.h>
1870 #include <mock_mir_session.h>
1871-#include <mock_shell.h>
1872 #include <mock_surface.h>
1873
1874 // tests/modules/common
1875 #include <surfaceobserver.h>
1876
1877-// mirserver
1878-#include <creationhints.h>
1879+// miral
1880+#include "window.h"
1881+#include "window_info.h"
1882
1883 using namespace qtmir;
1884
1885@@ -54,8 +56,6 @@
1886 // We don't want the logging spam cluttering the test results
1887 QLoggingCategory::setFilterRules(QStringLiteral("qtmir.surfaces=false"));
1888 }
1889-
1890- NiceMock<mir::shell::MockShell> m_mockShell;
1891 };
1892
1893 TEST_F(MirSurfaceTest, UpdateTextureBeforeDraw)
1894@@ -64,22 +64,23 @@
1895 char* argv[0];
1896 QCoreApplication qtApp(argc, argv); // app for deleteLater event
1897
1898- auto fakeSession = new FakeSession();
1899+ auto const fakeSession = std::make_shared<ms::MockSession>();
1900 auto mockSurface = std::make_shared<NiceMock<ms::MockSurface>>();
1901+ miral::Window mockWindow(fakeSession, mockSurface);
1902+ miral::WindowInfo mockWindowInfo(mockWindow, {});
1903+ QScopedPointer<WindowInfo> windowInfo(new WindowInfo(mockWindowInfo));
1904+
1905 auto surfaceObserver = std::make_shared<SurfaceObserver>();
1906
1907 EXPECT_CALL(*mockSurface.get(),buffers_ready_for_compositor(_))
1908 .WillRepeatedly(Return(1));
1909
1910- MirSurface *surface = new MirSurface(mockSurface, fakeSession, &m_mockShell, surfaceObserver, CreationHints());
1911+ MirSurface surface(mockWindowInfo, nullptr, surfaceObserver);
1912 surfaceObserver->frame_posted(1, mir::geometry::Size{1,1});
1913
1914- QSignalSpy spyFrameDropped(surface, SIGNAL(frameDropped()));
1915+ QSignalSpy spyFrameDropped(&surface, SIGNAL(frameDropped()));
1916 QTest::qWait(300);
1917 ASSERT_TRUE(spyFrameDropped.count() > 0);
1918-
1919- delete fakeSession;
1920- delete surface;
1921 }
1922
1923
1924@@ -89,28 +90,31 @@
1925 char* argv[0];
1926 QCoreApplication qtApp(argc, argv); // app for deleteLater event
1927
1928- auto fakeSession = new FakeSession();
1929+ auto const fakeSession = std::make_shared<NiceMock<ms::MockSession>>();
1930 auto mockSurface = std::make_shared<NiceMock<ms::MockSurface>>();
1931-
1932- MirSurface *surface = new MirSurface(mockSurface, fakeSession, &m_mockShell, nullptr, CreationHints());
1933+ miral::Window mockWindow(fakeSession, mockSurface);
1934+ miral::WindowInfo mockWindowInfo(mockWindow, {});
1935+ QScopedPointer<WindowInfo> windowInfo(new WindowInfo(mockWindowInfo));
1936+ auto surfaceObserver = std::make_shared<SurfaceObserver>();
1937+
1938+ MirSurface surface(mockWindowInfo, nullptr, surfaceObserver);
1939+
1940 bool surfaceDeleted = false;
1941- QObject::connect(surface, &QObject::destroyed, surface, [&surfaceDeleted](){ surfaceDeleted = true; });
1942+ QObject::connect(&surface, &QObject::destroyed, &surface, [&surfaceDeleted](){ surfaceDeleted = true; });
1943
1944 qintptr view1 = (qintptr)1;
1945 qintptr view2 = (qintptr)2;
1946
1947- surface->registerView(view1);
1948- surface->registerView(view2);
1949- surface->setLive(false);
1950+ surface.registerView(view1);
1951+ surface.registerView(view2);
1952+ surface.setLive(false);
1953 EXPECT_FALSE(surfaceDeleted);
1954
1955- surface->unregisterView(view1);
1956- surface->unregisterView(view2);
1957+ surface.unregisterView(view1);
1958+ surface.unregisterView(view2);
1959
1960 QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
1961 EXPECT_TRUE(surfaceDeleted);
1962-
1963- delete fakeSession;
1964 }
1965
1966
1967@@ -120,62 +124,63 @@
1968 char* argv[0];
1969 QCoreApplication qtApp(argc, argv); // app for deleteLater event
1970
1971- auto fakeSession = new FakeSession();
1972+ auto const fakeSession = std::make_shared<ms::MockSession>();
1973 auto mockSurface = std::make_shared<NiceMock<ms::MockSurface>>();
1974-
1975- MirSurface *surface = new MirSurface(mockSurface, fakeSession, &m_mockShell, nullptr, CreationHints());
1976+ miral::Window mockWindow(fakeSession, mockSurface);
1977+ miral::WindowInfo mockWindowInfo(mockWindow, {});
1978+ QScopedPointer<WindowInfo> windowInfo(new WindowInfo(mockWindowInfo));
1979+ auto surfaceObserver = std::make_shared<SurfaceObserver>();
1980+
1981+ MirSurface surface(mockWindowInfo, nullptr, surfaceObserver);
1982+
1983 bool surfaceDeleted = false;
1984- QObject::connect(surface, &QObject::destroyed, surface, [&surfaceDeleted](){ surfaceDeleted = true; });
1985+ QObject::connect(&surface, &QObject::destroyed, &surface, [&surfaceDeleted](){ surfaceDeleted = true; });
1986
1987 qintptr view1 = (qintptr)1;
1988 qintptr view2 = (qintptr)2;
1989
1990- surface->registerView(view1);
1991- surface->registerView(view2);
1992+ surface.registerView(view1);
1993+ surface.registerView(view2);
1994
1995- surface->unregisterView(view1);
1996- surface->unregisterView(view2);
1997+ surface.unregisterView(view1);
1998+ surface.unregisterView(view2);
1999
2000 QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
2001 EXPECT_FALSE(surfaceDeleted);
2002-
2003- delete fakeSession;
2004- delete surface;
2005 }
2006
2007 /*
2008 * Test that a surface whose client fails to comply with a close request will eventually get destroyed.
2009 */
2010-TEST_F(MirSurfaceTest, failedSurfaceCloseEventualyDestroysSurface)
2011+TEST_F(MirSurfaceTest, failedSurfaceCloseEventuallyDestroysSurface)
2012 {
2013- const pid_t pid = 1234;
2014- const char appId[] = "test-app";
2015-
2016 int argc = 0;
2017 char* argv[0];
2018 QCoreApplication qtApp(argc, argv); // app for deleteLater event
2019
2020- auto fakeSession = new FakeSession();
2021- auto mirSession = std::make_shared<mir::scene::MockSession>(appId, pid);
2022- fakeSession->setSession(mirSession);
2023-
2024+ auto const mockSession = std::make_shared<NiceMock<ms::MockSession>>();
2025 auto mockSurface = std::make_shared<NiceMock<ms::MockSurface>>();
2026-
2027- MirSurface *surface = new MirSurface(mockSurface, fakeSession, &m_mockShell, nullptr, CreationHints());
2028+ miral::Window mockWindow(mockSession, mockSurface);
2029+ miral::WindowInfo mockWindowInfo(mockWindow, {});
2030+ QScopedPointer<WindowInfo> windowInfo(new WindowInfo(mockWindowInfo));
2031+ auto surfaceObserver = std::make_shared<SurfaceObserver>();
2032+
2033+ MirSurface surface(mockWindowInfo, nullptr, surfaceObserver);
2034+
2035 bool surfaceDeleted = false;
2036- QObject::connect(surface, &QObject::destroyed, surface, [&surfaceDeleted](){ surfaceDeleted = true; });
2037+ QObject::connect(&surface, &QObject::destroyed, &surface, [&surfaceDeleted](){ surfaceDeleted = true; });
2038
2039 QSharedPointer<FakeTimeSource> fakeTimeSource(new FakeTimeSource);
2040 QPointer<FakeTimer> fakeTimer(new FakeTimer(fakeTimeSource));
2041- surface->setCloseTimer(fakeTimer.data()); // surface takes ownership of the timer
2042+ surface.setCloseTimer(fakeTimer.data()); // surface takes ownership of the timer
2043
2044 qintptr view = (qintptr)1;
2045- surface->registerView(view);
2046+ surface.registerView(view);
2047
2048- EXPECT_CALL(*mirSession.get(), destroy_surface(An<const std::weak_ptr<mir::scene::Surface> &>()))
2049+ EXPECT_CALL(*mockSession.get(), destroy_surface(An<const std::weak_ptr<ms::Surface> &>()))
2050 .Times(1);
2051
2052- surface->close();
2053+ surface.close();
2054
2055 if (fakeTimer->isRunning()) {
2056 // Simulate that closeTimer has timed out.
2057@@ -184,8 +189,6 @@
2058 }
2059
2060 // clean up
2061- surface->setLive(false);
2062- surface->unregisterView(view);
2063- delete surface;
2064- delete fakeSession;
2065+ surface.setLive(false);
2066+ surface.unregisterView(view);
2067 }

Subscribers

People subscribed via source and target branches