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

Proposed by Alan Griffiths
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) Needs Fixing
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.
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

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

review: Needs Information
Revision history for this message
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

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

ok

review: Abstain
Revision history for this message
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
Revision history for this message
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

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

Revert Lttng test-crash workaround from rev 557

Approved by: Daniel d'Andrada, Unity8 CI Bot

572. By Jonas G. Drange

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

Approved by: Gerry Boland

573. By Albert Astals Cid

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

Approved by: Gerry Boland, Unity8 CI Bot

574. By CI Train Bot Account

Releasing 0.5.0+17.04.20161123.3-0ubuntu1

575. By Brandon Schaefer

Mir 0.25 compat

576. By CI Train Bot Account

Releasing 0.5.0+17.04.20161203-0ubuntu1

577. By CI Train Bot Account

First release using MirAL

578. By Daniel d'Andrada

Get rid of the ApplicationManager::Factory class

It's useless

Approved by: Gerry Boland, Unity8 CI Bot

579. By Daniel d'Andrada

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

Releasing 0.5.1+17.04.20161216-0ubuntu1

581. By Łukasz Zemczak

No-change rebuild against latest miral.

582. By Alan Griffiths

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

583. By Alan Griffiths

  Another null check

584. By Alan Griffiths

  Nasty hack because of existing nasty hack

585. By Alan Griffiths

  Put const in the Qt place

586. By Alan Griffiths

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

587. By Alan Griffiths

  Use StubWindowModelController in tests where nullptr won't do

Unmerged revisions

587. By Alan Griffiths

  Use StubWindowModelController in tests where nullptr won't do

586. By Alan Griffiths

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

585. By Alan Griffiths

  Put const in the Qt place

584. By Alan Griffiths

  Nasty hack because of existing nasty hack

583. By Alan Griffiths

  Another null check

582. By Alan Griffiths

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

581. By Łukasz Zemczak

No-change rebuild against latest miral.

580. By CI Train Bot Account

Releasing 0.5.1+17.04.20161216-0ubuntu1

579. By Daniel d'Andrada

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

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