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
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2016-12-13 15:31:26 +0000
+++ CMakeLists.txt 2017-01-05 10:18:12 +0000
@@ -166,10 +166,6 @@
166# Tests166# Tests
167if (NO_TESTS)167if (NO_TESTS)
168 message(STATUS "Tests disabled")168 message(STATUS "Tests disabled")
169# glibc on Vivid+Overlay has a bug which causes LTTng-enabled tests to hang. It is hard to get the glibc version
170# in cmake, so it is easier to check for the LTTng on V+O and gate on that instead.
171elseif (LTTNG_VERSION VERSION_EQUAL 2.7.1)
172 message(STATUS "Tests disabled due to bug with glibc causing lttng to hang (lp:1618201)")
173else()169else()
174 include(CTest)170 include(CTest)
175 enable_testing()171 enable_testing()
176172
=== modified file 'debian/changelog'
--- debian/changelog 2016-12-13 15:31:26 +0000
+++ debian/changelog 2017-01-05 10:18:12 +0000
@@ -1,8 +1,19 @@
1qtmir (0.5.1) UNRELEASED; urgency=medium1qtmir (0.5.1+17.04.20161216-0ubuntu2) zesty; urgency=medium
22
3 * No-change rebuild against latest miral.
4
5 -- Ĺukasz 'sil2100' Zemczak <lukasz.zemczak@ubuntu.com> Wed, 21 Dec 2016 10:07:36 +0100
6
7qtmir (0.5.1+17.04.20161216-0ubuntu1) zesty; urgency=medium
8
9 [ Gerry Boland ]
3 * First release using MirAL10 * First release using MirAL
411
5 -- Gerry Boland <gerry.boland@canonical.com> Fri, 14 Oct 2016 16:51:26 +010012 [ Daniel d'Andrada ]
13 * Get rid of the ApplicationManager::Factory class
14 * Enable tests in Xenial
15
16 -- Daniel d'Andrada <daniel.dandrada@canonical.com> Fri, 16 Dec 2016 08:25:00 +0000
617
7qtmir (0.5.0+17.04.20161203-0ubuntu1) zesty; urgency=medium18qtmir (0.5.0+17.04.20161203-0ubuntu1) zesty; urgency=medium
819
920
=== modified file 'src/common/windowcontrollerinterface.h'
--- src/common/windowcontrollerinterface.h 2016-11-03 20:17:46 +0000
+++ src/common/windowcontrollerinterface.h 2017-01-05 10:18:12 +0000
@@ -48,6 +48,8 @@
4848
49 virtual void requestState(const miral::Window &window, const Mir::State state) = 0;49 virtual void requestState(const miral::Window &window, const Mir::State state) = 0;
5050
51 virtual bool isVisible(const miral::Window &window) = 0;
52
51 virtual void deliverKeyboardEvent(const miral::Window &window, const MirKeyboardEvent *event) = 0;53 virtual void deliverKeyboardEvent(const miral::Window &window, const MirKeyboardEvent *event) = 0;
52 virtual void deliverTouchEvent (const miral::Window &window, const MirTouchEvent *event) = 0;54 virtual void deliverTouchEvent (const miral::Window &window, const MirTouchEvent *event) = 0;
53 virtual void deliverPointerEvent (const miral::Window &window, const MirPointerEvent *event) = 0;55 virtual void deliverPointerEvent (const miral::Window &window, const MirPointerEvent *event) = 0;
5456
=== modified file 'src/modules/Unity/Application/application_manager.cpp'
--- src/modules/Unity/Application/application_manager.cpp 2016-12-07 11:17:13 +0000
+++ src/modules/Unity/Application/application_manager.cpp 2017-01-05 10:18:12 +0000
@@ -97,7 +97,7 @@
9797
98} // namespace98} // namespace
9999
100ApplicationManager* ApplicationManager::Factory::Factory::create()100ApplicationManager* ApplicationManager::create()
101{101{
102 NativeInterface *nativeInterface = dynamic_cast<NativeInterface*>(QGuiApplication::platformNativeInterface());102 NativeInterface *nativeInterface = dynamic_cast<NativeInterface*>(QGuiApplication::platformNativeInterface());
103103
@@ -150,8 +150,7 @@
150{150{
151 static ApplicationManager* instance;151 static ApplicationManager* instance;
152 if (!instance) {152 if (!instance) {
153 Factory appFactory;153 instance = create();
154 instance = appFactory.create();
155 }154 }
156 return instance;155 return instance;
157}156}
158157
=== modified file 'src/modules/Unity/Application/application_manager.h'
--- src/modules/Unity/Application/application_manager.h 2016-12-07 11:17:13 +0000
+++ src/modules/Unity/Application/application_manager.h 2017-01-05 10:18:12 +0000
@@ -63,12 +63,7 @@
63 Q_PROPERTY(bool empty READ isEmpty NOTIFY emptyChanged)63 Q_PROPERTY(bool empty READ isEmpty NOTIFY emptyChanged)
6464
65public:65public:
66 class Factory66 static ApplicationManager* create();
67 {
68 public:
69 ApplicationManager* create();
70 };
71
72 static ApplicationManager* singleton();67 static ApplicationManager* singleton();
7368
74 explicit ApplicationManager(69 explicit ApplicationManager(
7570
=== modified file 'src/modules/Unity/Application/mirsurface.cpp'
--- src/modules/Unity/Application/mirsurface.cpp 2016-11-25 15:23:36 +0000
+++ src/modules/Unity/Application/mirsurface.cpp 2017-01-05 10:18:12 +0000
@@ -427,11 +427,24 @@
427427
428void MirSurface::updateVisible()428void MirSurface::updateVisible()
429{429{
430 const bool visible = !(m_state == Mir::HiddenState || m_state == Mir::MinimizedState) && m_surface->visible();430 try
431431 {
432 if (m_visible != visible) {432 const bool visible = m_controller->isVisible(m_window);
433 m_visible = visible;433
434 Q_EMIT visibleChanged(visible);434 if (m_visible != visible) {
435 m_visible = visible;
436 Q_EMIT visibleChanged(visible);
437 }
438 }
439 catch (const std::out_of_range &)
440 {
441 // MirAL can not know we hold ownership of the underlying surface and may have forgotten it
442 Q_ASSERT(m_surface.unique());
443
444 if (m_visible) {
445 m_visible = false;
446 Q_EMIT visibleChanged(false);
447 }
435 }448 }
436}449}
437450
438451
=== modified file 'src/platforms/mirserver/windowcontroller.cpp'
--- src/platforms/mirserver/windowcontroller.cpp 2016-11-03 20:17:46 +0000
+++ src/platforms/mirserver/windowcontroller.cpp 2017-01-05 10:18:12 +0000
@@ -76,6 +76,11 @@
76 }76 }
77}77}
7878
79bool WindowController::isVisible(const miral::Window &window)
80{
81 return m_policy && m_policy->isVisible(window);
82}
83
79void WindowController::deliverKeyboardEvent(const miral::Window &window, const MirKeyboardEvent *event)84void WindowController::deliverKeyboardEvent(const miral::Window &window, const MirKeyboardEvent *event)
80{85{
81 if (m_policy) {86 if (m_policy) {
8287
=== modified file 'src/platforms/mirserver/windowcontroller.h'
--- src/platforms/mirserver/windowcontroller.h 2016-11-03 20:17:46 +0000
+++ src/platforms/mirserver/windowcontroller.h 2017-01-05 10:18:12 +0000
@@ -39,6 +39,8 @@
3939
40 void requestState(const miral::Window &window, const Mir::State state) override;40 void requestState(const miral::Window &window, const Mir::State state) override;
4141
42 bool isVisible(const miral::Window &window) override;
43
42 void deliverKeyboardEvent(const miral::Window &window, const MirKeyboardEvent *event) override;44 void deliverKeyboardEvent(const miral::Window &window, const MirKeyboardEvent *event) override;
43 void deliverTouchEvent (const miral::Window &window, const MirTouchEvent *event) override;45 void deliverTouchEvent (const miral::Window &window, const MirTouchEvent *event) override;
44 void deliverPointerEvent (const miral::Window &window, const MirPointerEvent *event) override;46 void deliverPointerEvent (const miral::Window &window, const MirPointerEvent *event) override;
4547
=== modified file 'src/platforms/mirserver/windowmanagementpolicy.cpp'
--- src/platforms/mirserver/windowmanagementpolicy.cpp 2016-11-22 18:01:11 +0000
+++ src/platforms/mirserver/windowmanagementpolicy.cpp 2017-01-05 10:18:12 +0000
@@ -333,3 +333,8 @@
333 });333 });
334 }334 }
335}335}
336
337bool WindowManagementPolicy::isVisible(const miral::Window &window)
338{
339 return window && m_tools.info_for(window).is_visible();
340}
336341
=== modified file 'src/platforms/mirserver/windowmanagementpolicy.h'
--- src/platforms/mirserver/windowmanagementpolicy.h 2016-11-03 20:17:46 +0000
+++ src/platforms/mirserver/windowmanagementpolicy.h 2017-01-05 10:18:12 +0000
@@ -80,6 +80,7 @@
80 void move (const miral::Window &window, const Point topLeft);80 void move (const miral::Window &window, const Point topLeft);
81 void raise(const miral::Window &window);81 void raise(const miral::Window &window);
82 void requestState(const miral::Window &window, const Mir::State state);82 void requestState(const miral::Window &window, const Mir::State state);
83 bool isVisible(const miral::Window &window);
8384
84 void ask_client_to_close(const miral::Window &window);85 void ask_client_to_close(const miral::Window &window);
85 void forceClose(const miral::Window &window);86 void forceClose(const miral::Window &window);
8687
=== modified file 'tests/framework/stub_windowcontroller.h'
--- tests/framework/stub_windowcontroller.h 2016-11-03 20:17:46 +0000
+++ tests/framework/stub_windowcontroller.h 2017-01-05 10:18:12 +0000
@@ -33,6 +33,7 @@
33 void forceClose(const miral::Window &/*window*/) override { return; }33 void forceClose(const miral::Window &/*window*/) override { return; }
3434
35 void requestState(const miral::Window &/*window*/, const Mir::State /*state*/) override { return; }35 void requestState(const miral::Window &/*window*/, const Mir::State /*state*/) override { return; }
36 bool isVisible(const miral::Window &) override { return false; }
3637
37 void deliverKeyboardEvent(const miral::Window &/*window*/, const MirKeyboardEvent */*event*/) override { return; }38 void deliverKeyboardEvent(const miral::Window &/*window*/, const MirKeyboardEvent */*event*/) override { return; }
38 void deliverTouchEvent (const miral::Window &/*window*/, const MirTouchEvent */*event*/) override { return; }39 void deliverTouchEvent (const miral::Window &/*window*/, const MirTouchEvent */*event*/) override { return; }
3940
=== modified file 'tests/modules/WindowManager/windowmodel_test.cpp'
--- tests/modules/WindowManager/windowmodel_test.cpp 2016-11-03 20:17:46 +0000
+++ tests/modules/WindowManager/windowmodel_test.cpp 2017-01-05 10:18:12 +0000
@@ -25,6 +25,7 @@
25#include "Unity/Application/mirsurface.h"25#include "Unity/Application/mirsurface.h"
26#include "Unity/Application/windowmodel.h"26#include "Unity/Application/windowmodel.h"
2727
28#include "stub_windowcontroller.h"
28#include <mir/test/doubles/stub_surface.h>29#include <mir/test/doubles/stub_surface.h>
29#include <mir/test/doubles/stub_session.h>30#include <mir/test/doubles/stub_session.h>
3031
@@ -123,6 +124,8 @@
123 const std::shared_ptr<StubSession> stubSession{std::make_shared<StubSession>()};124 const std::shared_ptr<StubSession> stubSession{std::make_shared<StubSession>()};
124 const std::shared_ptr<SizedStubSurface> stubSurface{std::make_shared<SizedStubSurface>()};125 const std::shared_ptr<SizedStubSurface> stubSurface{std::make_shared<SizedStubSurface>()};
125 QCoreApplication *qtApp;126 QCoreApplication *qtApp;
127
128 StubWindowModelController controller;
126};129};
127130
128/*131/*
@@ -688,7 +691,7 @@
688TEST_F(WindowModelTest, WindowReadyCausesMirSurfaceToEmitReadySignal)691TEST_F(WindowModelTest, WindowReadyCausesMirSurfaceToEmitReadySignal)
689{692{
690 WindowModelNotifier notifier;693 WindowModelNotifier notifier;
691 WindowModel model(&notifier, nullptr); // no need for controller in this testcase694 WindowModel model(&notifier, &controller);
692695
693 auto newWindow = createNewWindow();696 auto newWindow = createNewWindow();
694 notifier.windowAdded(newWindow);697 notifier.windowAdded(newWindow);
@@ -745,7 +748,7 @@
745 auto const& param = GetParam();748 auto const& param = GetParam();
746749
747 WindowModelNotifier notifier;750 WindowModelNotifier notifier;
748 WindowModel model(&notifier, nullptr); // no need for controller in this testcase751 WindowModel model(&notifier, &controller);
749752
750 auto newWindow = createNewWindowWithState(Mir::UnknownState);753 auto newWindow = createNewWindowWithState(Mir::UnknownState);
751 notifier.windowAdded(newWindow);754 notifier.windowAdded(newWindow);
@@ -766,7 +769,7 @@
766 auto const& param = GetParam();769 auto const& param = GetParam();
767770
768 WindowModelNotifier notifier;771 WindowModelNotifier notifier;
769 WindowModel model(&notifier, nullptr); // no need for controller in this testcase772 WindowModel model(&notifier, &controller);
770773
771 auto newWindow = createNewWindowWithState(Mir::UnknownState);774 auto newWindow = createNewWindowWithState(Mir::UnknownState);
772 notifier.windowAdded(newWindow);775 notifier.windowAdded(newWindow);

Subscribers

People subscribed via source and target branches