Merge lp:~alan-griffiths/qtmir/WindowControllerInterface-isVisible into lp:~unity-team/qtmir/miral-qt-integration

Proposed by Alan Griffiths on 2016-11-07
Status: Superseded
Proposed branch: lp:~alan-griffiths/qtmir/WindowControllerInterface-isVisible
Merge into: lp:~unity-team/qtmir/miral-qt-integration
Diff against target: 243 lines (+57/-24)
12 files modified
CMakeLists.txt (+0/-4)
debian/changelog (+14/-3)
src/common/windowcontrollerinterface.h (+2/-0)
src/modules/Unity/Application/application_manager.cpp (+2/-3)
src/modules/Unity/Application/application_manager.h (+1/-6)
src/modules/Unity/Application/mirsurface.cpp (+18/-5)
src/platforms/mirserver/windowcontroller.cpp (+5/-0)
src/platforms/mirserver/windowcontroller.h (+2/-0)
src/platforms/mirserver/windowmanagementpolicy.cpp (+5/-0)
src/platforms/mirserver/windowmanagementpolicy.h (+1/-0)
tests/framework/stub_windowcontroller.h (+1/-0)
tests/modules/WindowManager/windowmodel_test.cpp (+6/-3)
To merge this branch: bzr merge lp:~alan-griffiths/qtmir/WindowControllerInterface-isVisible
Reviewer Review Type Date Requested Status
Daniel d'Andrada (community) 2016-11-07 Needs Fixing on 2016-11-09
Review via email: mp+310184@code.launchpad.net

This proposal has been superseded by a proposal from 2017-01-05.

Commit Message

Implement WindowControllerInterface::isVisible(const miral::Window &window)

To post a comment you must log in.
Daniel d'Andrada (dandrader) wrote :

I don't get why we need the try{}catch{} in MirSurface::updateVisible()

review: Needs Information
Alan Griffiths (alan-griffiths) wrote :

> I don't get why we need the try{}catch{} in MirSurface::updateVisible()

The m_surface member is an awkward hack that extends the life of a ms:Surface object beyond the time it is known to MirAL and Mir. (I hope, eventually, to make this unnecessary.)

This lifetime extension makes it difficult to detect a race between a surface closing (as far as the rest of the system is concerned) and MirSurface::updateVisible() being called.

The only convenient point at which to detect this race is in miral::BasicWindowManager::info_for() which throws out_of_range{}. The try...catch detects this, asserts that the cause is m_surface extending the lifetime and suppresses the "error".

One scenario I've found to reliably reproduce this problem is:

qml-demo-shell --startup gnome-terminal

and then close the terminal through the file menu

Daniel d'Andrada (dandrader) wrote :

ok

review: Abstain
Daniel d'Andrada (dandrader) wrote :

This would leave the code in a inconsistent state. We update MirSurface::visible when state changes but MirSurface::visible itself is defined by an opaque function from an external controller. So no guarantees that controller::isVisible indeed changes when surface state changes and, most importantly, *only* when surface state changes.

If controller::isVisible changes due to thins other than surface state changes, this MirSurface::visible won't get update and will, therefore, be broken.

I think this change should be accompanied by a notification miral::WindowInfo::visible changes from miral.

Which makes me think that, while the miral notification doesn't come up in the API, we either drop the "&& m_surface->visible()" from updateVisible or also track changes to it if possible (which I think it's not)

review: Needs Fixing
Alan Griffiths (alan-griffiths) wrote :

> This would leave the code in a inconsistent state. We update
> MirSurface::visible when state changes but MirSurface::visible itself is
> defined by an opaque function from an external controller. So no guarantees
> that controller::isVisible indeed changes when surface state changes and, most
> importantly, *only* when surface state changes.

This MP does not effect any of that.

> If controller::isVisible changes due to thins other than surface state
> changes, this MirSurface::visible won't get update and will, therefore, be
> broken.
>
> I think this change should be accompanied by a notification
> miral::WindowInfo::visible changes from miral.
>
> Which makes me think that, while the miral notification doesn't come up in the
> API, we either drop the "&& m_surface->visible()" from updateVisible or also
> track changes to it if possible (which I think it's not)

That would change the meaning of MirSurface::visible - I don't know enough of the purpose of this property to know if that's a good idea.

570. By Gerry Boland on 2016-11-23

Fix FTBFS due to new googletest framework release (1.8)

- needed to update the gmock-fixes.h to add Unwrap() support
- small signed/unsigned comparison fix flagged by GTest

Approved by: Daniel d'Andrada

571. By Gerry Boland on 2016-11-23

Revert Lttng test-crash workaround from rev 557

Approved by: Daniel d'Andrada, Unity8 CI Bot

572. By Jonas G. Drange on 2016-11-23

relax auth of clients to allow USS to set base mir display config

Approved by: Gerry Boland

573. By Albert Astals Cid on 2016-11-23

Build with Qt 5.7 (LP: #1642608, #1642954)

Approved by: Gerry Boland, Unity8 CI Bot

574. By CI Train Bot Account on 2016-11-23

Releasing 0.5.0+17.04.20161123.3-0ubuntu1

575. By Brandon Schaefer on 2016-12-03

Mir 0.25 compat

576. By CI Train Bot Account on 2016-12-03

Releasing 0.5.0+17.04.20161203-0ubuntu1

577. By CI Train Bot Account on 2016-12-16

First release using MirAL

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

Get rid of the ApplicationManager::Factory class

It's useless

Approved by: Gerry Boland, Unity8 CI Bot

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

Enable tests in Xenial

This workaround was needed only for the glib version present in Vivid

Approved by: Gerry Boland, Unity8 CI Bot

580. By CI Train Bot Account on 2016-12-16

Releasing 0.5.1+17.04.20161216-0ubuntu1

581. By Łukasz Zemczak on 2016-12-22

No-change rebuild against latest miral.

582. By Alan Griffiths on 2017-01-05

  Implement WindowControllerInterface::isVisible(const miral::Window &window)

583. By Alan Griffiths on 2017-01-05

  Another null check

584. By Alan Griffiths on 2017-01-05

  Nasty hack because of existing nasty hack

585. By Alan Griffiths on 2017-01-05

  Put const in the Qt place

586. By Alan Griffiths on 2017-01-05

  Don't use the standard library when Qt has an alternative

587. By Alan Griffiths on 2017-01-05

  Use StubWindowModelController in tests where nullptr won't do

Unmerged revisions

587. By Alan Griffiths on 2017-01-05

  Use StubWindowModelController in tests where nullptr won't do

586. By Alan Griffiths on 2017-01-05

  Don't use the standard library when Qt has an alternative

585. By Alan Griffiths on 2017-01-05

  Put const in the Qt place

584. By Alan Griffiths on 2017-01-05

  Nasty hack because of existing nasty hack

583. By Alan Griffiths on 2017-01-05

  Another null check

582. By Alan Griffiths on 2017-01-05

  Implement WindowControllerInterface::isVisible(const miral::Window &window)

581. By Łukasz Zemczak on 2016-12-22

No-change rebuild against latest miral.

580. By CI Train Bot Account on 2016-12-16

Releasing 0.5.1+17.04.20161216-0ubuntu1

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

Enable tests in Xenial

This workaround was needed only for the glib version present in Vivid

Approved by: Gerry Boland, Unity8 CI Bot

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

Get rid of the ApplicationManager::Factory class

It's useless

Approved by: Gerry Boland, Unity8 CI Bot

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-12-13 15:31:26 +0000
3+++ CMakeLists.txt 2017-01-05 10:18:12 +0000
4@@ -166,10 +166,6 @@
5 # Tests
6 if (NO_TESTS)
7 message(STATUS "Tests disabled")
8-# glibc on Vivid+Overlay has a bug which causes LTTng-enabled tests to hang. It is hard to get the glibc version
9-# in cmake, so it is easier to check for the LTTng on V+O and gate on that instead.
10-elseif (LTTNG_VERSION VERSION_EQUAL 2.7.1)
11- message(STATUS "Tests disabled due to bug with glibc causing lttng to hang (lp:1618201)")
12 else()
13 include(CTest)
14 enable_testing()
15
16=== modified file 'debian/changelog'
17--- debian/changelog 2016-12-13 15:31:26 +0000
18+++ debian/changelog 2017-01-05 10:18:12 +0000
19@@ -1,8 +1,19 @@
20-qtmir (0.5.1) UNRELEASED; urgency=medium
21-
22+qtmir (0.5.1+17.04.20161216-0ubuntu2) zesty; urgency=medium
23+
24+ * No-change rebuild against latest miral.
25+
26+ -- Ĺukasz 'sil2100' Zemczak <lukasz.zemczak@ubuntu.com> Wed, 21 Dec 2016 10:07:36 +0100
27+
28+qtmir (0.5.1+17.04.20161216-0ubuntu1) zesty; urgency=medium
29+
30+ [ Gerry Boland ]
31 * First release using MirAL
32
33- -- Gerry Boland <gerry.boland@canonical.com> Fri, 14 Oct 2016 16:51:26 +0100
34+ [ Daniel d'Andrada ]
35+ * Get rid of the ApplicationManager::Factory class
36+ * Enable tests in Xenial
37+
38+ -- Daniel d'Andrada <daniel.dandrada@canonical.com> Fri, 16 Dec 2016 08:25:00 +0000
39
40 qtmir (0.5.0+17.04.20161203-0ubuntu1) zesty; urgency=medium
41
42
43=== modified file 'src/common/windowcontrollerinterface.h'
44--- src/common/windowcontrollerinterface.h 2016-11-03 20:17:46 +0000
45+++ src/common/windowcontrollerinterface.h 2017-01-05 10:18:12 +0000
46@@ -48,6 +48,8 @@
47
48 virtual void requestState(const miral::Window &window, const Mir::State state) = 0;
49
50+ virtual bool isVisible(const miral::Window &window) = 0;
51+
52 virtual void deliverKeyboardEvent(const miral::Window &window, const MirKeyboardEvent *event) = 0;
53 virtual void deliverTouchEvent (const miral::Window &window, const MirTouchEvent *event) = 0;
54 virtual void deliverPointerEvent (const miral::Window &window, const MirPointerEvent *event) = 0;
55
56=== modified file 'src/modules/Unity/Application/application_manager.cpp'
57--- src/modules/Unity/Application/application_manager.cpp 2016-12-07 11:17:13 +0000
58+++ src/modules/Unity/Application/application_manager.cpp 2017-01-05 10:18:12 +0000
59@@ -97,7 +97,7 @@
60
61 } // namespace
62
63-ApplicationManager* ApplicationManager::Factory::Factory::create()
64+ApplicationManager* ApplicationManager::create()
65 {
66 NativeInterface *nativeInterface = dynamic_cast<NativeInterface*>(QGuiApplication::platformNativeInterface());
67
68@@ -150,8 +150,7 @@
69 {
70 static ApplicationManager* instance;
71 if (!instance) {
72- Factory appFactory;
73- instance = appFactory.create();
74+ instance = create();
75 }
76 return instance;
77 }
78
79=== modified file 'src/modules/Unity/Application/application_manager.h'
80--- src/modules/Unity/Application/application_manager.h 2016-12-07 11:17:13 +0000
81+++ src/modules/Unity/Application/application_manager.h 2017-01-05 10:18:12 +0000
82@@ -63,12 +63,7 @@
83 Q_PROPERTY(bool empty READ isEmpty NOTIFY emptyChanged)
84
85 public:
86- class Factory
87- {
88- public:
89- ApplicationManager* create();
90- };
91-
92+ static ApplicationManager* create();
93 static ApplicationManager* singleton();
94
95 explicit ApplicationManager(
96
97=== modified file 'src/modules/Unity/Application/mirsurface.cpp'
98--- src/modules/Unity/Application/mirsurface.cpp 2016-11-25 15:23:36 +0000
99+++ src/modules/Unity/Application/mirsurface.cpp 2017-01-05 10:18:12 +0000
100@@ -427,11 +427,24 @@
101
102 void MirSurface::updateVisible()
103 {
104- const bool visible = !(m_state == Mir::HiddenState || m_state == Mir::MinimizedState) && m_surface->visible();
105-
106- if (m_visible != visible) {
107- m_visible = visible;
108- Q_EMIT visibleChanged(visible);
109+ try
110+ {
111+ const bool visible = m_controller->isVisible(m_window);
112+
113+ if (m_visible != visible) {
114+ m_visible = visible;
115+ Q_EMIT visibleChanged(visible);
116+ }
117+ }
118+ catch (const std::out_of_range &)
119+ {
120+ // MirAL can not know we hold ownership of the underlying surface and may have forgotten it
121+ Q_ASSERT(m_surface.unique());
122+
123+ if (m_visible) {
124+ m_visible = false;
125+ Q_EMIT visibleChanged(false);
126+ }
127 }
128 }
129
130
131=== modified file 'src/platforms/mirserver/windowcontroller.cpp'
132--- src/platforms/mirserver/windowcontroller.cpp 2016-11-03 20:17:46 +0000
133+++ src/platforms/mirserver/windowcontroller.cpp 2017-01-05 10:18:12 +0000
134@@ -76,6 +76,11 @@
135 }
136 }
137
138+bool WindowController::isVisible(const miral::Window &window)
139+{
140+ return m_policy && m_policy->isVisible(window);
141+}
142+
143 void WindowController::deliverKeyboardEvent(const miral::Window &window, const MirKeyboardEvent *event)
144 {
145 if (m_policy) {
146
147=== modified file 'src/platforms/mirserver/windowcontroller.h'
148--- src/platforms/mirserver/windowcontroller.h 2016-11-03 20:17:46 +0000
149+++ src/platforms/mirserver/windowcontroller.h 2017-01-05 10:18:12 +0000
150@@ -39,6 +39,8 @@
151
152 void requestState(const miral::Window &window, const Mir::State state) override;
153
154+ bool isVisible(const miral::Window &window) override;
155+
156 void deliverKeyboardEvent(const miral::Window &window, const MirKeyboardEvent *event) override;
157 void deliverTouchEvent (const miral::Window &window, const MirTouchEvent *event) override;
158 void deliverPointerEvent (const miral::Window &window, const MirPointerEvent *event) override;
159
160=== modified file 'src/platforms/mirserver/windowmanagementpolicy.cpp'
161--- src/platforms/mirserver/windowmanagementpolicy.cpp 2016-11-22 18:01:11 +0000
162+++ src/platforms/mirserver/windowmanagementpolicy.cpp 2017-01-05 10:18:12 +0000
163@@ -333,3 +333,8 @@
164 });
165 }
166 }
167+
168+bool WindowManagementPolicy::isVisible(const miral::Window &window)
169+{
170+ return window && m_tools.info_for(window).is_visible();
171+}
172
173=== modified file 'src/platforms/mirserver/windowmanagementpolicy.h'
174--- src/platforms/mirserver/windowmanagementpolicy.h 2016-11-03 20:17:46 +0000
175+++ src/platforms/mirserver/windowmanagementpolicy.h 2017-01-05 10:18:12 +0000
176@@ -80,6 +80,7 @@
177 void move (const miral::Window &window, const Point topLeft);
178 void raise(const miral::Window &window);
179 void requestState(const miral::Window &window, const Mir::State state);
180+ bool isVisible(const miral::Window &window);
181
182 void ask_client_to_close(const miral::Window &window);
183 void forceClose(const miral::Window &window);
184
185=== modified file 'tests/framework/stub_windowcontroller.h'
186--- tests/framework/stub_windowcontroller.h 2016-11-03 20:17:46 +0000
187+++ tests/framework/stub_windowcontroller.h 2017-01-05 10:18:12 +0000
188@@ -33,6 +33,7 @@
189 void forceClose(const miral::Window &/*window*/) override { return; }
190
191 void requestState(const miral::Window &/*window*/, const Mir::State /*state*/) override { return; }
192+ bool isVisible(const miral::Window &) override { return false; }
193
194 void deliverKeyboardEvent(const miral::Window &/*window*/, const MirKeyboardEvent */*event*/) override { return; }
195 void deliverTouchEvent (const miral::Window &/*window*/, const MirTouchEvent */*event*/) override { return; }
196
197=== modified file 'tests/modules/WindowManager/windowmodel_test.cpp'
198--- tests/modules/WindowManager/windowmodel_test.cpp 2016-11-03 20:17:46 +0000
199+++ tests/modules/WindowManager/windowmodel_test.cpp 2017-01-05 10:18:12 +0000
200@@ -25,6 +25,7 @@
201 #include "Unity/Application/mirsurface.h"
202 #include "Unity/Application/windowmodel.h"
203
204+#include "stub_windowcontroller.h"
205 #include <mir/test/doubles/stub_surface.h>
206 #include <mir/test/doubles/stub_session.h>
207
208@@ -123,6 +124,8 @@
209 const std::shared_ptr<StubSession> stubSession{std::make_shared<StubSession>()};
210 const std::shared_ptr<SizedStubSurface> stubSurface{std::make_shared<SizedStubSurface>()};
211 QCoreApplication *qtApp;
212+
213+ StubWindowModelController controller;
214 };
215
216 /*
217@@ -688,7 +691,7 @@
218 TEST_F(WindowModelTest, WindowReadyCausesMirSurfaceToEmitReadySignal)
219 {
220 WindowModelNotifier notifier;
221- WindowModel model(&notifier, nullptr); // no need for controller in this testcase
222+ WindowModel model(&notifier, &controller);
223
224 auto newWindow = createNewWindow();
225 notifier.windowAdded(newWindow);
226@@ -745,7 +748,7 @@
227 auto const& param = GetParam();
228
229 WindowModelNotifier notifier;
230- WindowModel model(&notifier, nullptr); // no need for controller in this testcase
231+ WindowModel model(&notifier, &controller);
232
233 auto newWindow = createNewWindowWithState(Mir::UnknownState);
234 notifier.windowAdded(newWindow);
235@@ -766,7 +769,7 @@
236 auto const& param = GetParam();
237
238 WindowModelNotifier notifier;
239- WindowModel model(&notifier, nullptr); // no need for controller in this testcase
240+ WindowModel model(&notifier, &controller);
241
242 auto newWindow = createNewWindowWithState(Mir::UnknownState);
243 notifier.windowAdded(newWindow);

Subscribers

People subscribed via source and target branches