Merge lp:~aacid/qtmir/make_sure_surface_not_null into lp:qtmir

Proposed by Albert Astals Cid
Status: Superseded
Proposed branch: lp:~aacid/qtmir/make_sure_surface_not_null
Merge into: lp:qtmir
Diff against target: 1210 lines (+785/-131)
19 files modified
src/modules/Unity/Application/CMakeLists.txt (+0/-2)
src/modules/Unity/Application/mirbuffersgtexture.cpp (+4/-17)
src/modules/Unity/Application/mirbuffersgtexture.h (+2/-2)
src/modules/Unity/Application/mirsurface.cpp (+0/-14)
src/modules/Unity/Application/mirsurface.h (+0/-1)
src/modules/Unity/Application/sessionmanager.cpp (+4/-0)
src/modules/Unity/Application/sessionmanager.h (+3/-2)
src/modules/Unity/Application/surfacemanager.cpp (+36/-29)
src/modules/Unity/Application/surfacemanager.h (+8/-3)
src/platforms/mirserver/CMakeLists.txt (+1/-0)
src/platforms/mirserver/mirbuffer.cpp (+70/-0)
src/platforms/mirserver/mirbuffer.h (+48/-0)
tests/framework/CMakeLists.txt (+2/-0)
tests/framework/mock_session_manager.h (+33/-0)
tests/framework/mock_window_controller.h (+43/-0)
tests/modules/CMakeLists.txt (+2/-1)
tests/modules/SurfaceManager/CMakeLists.txt (+40/-0)
tests/modules/SurfaceManager/surface_manager_test.cpp (+489/-0)
tests/modules/WindowManager/mirsurface_test.cpp (+0/-60)
To merge this branch: bzr merge lp:~aacid/qtmir/make_sure_surface_not_null
Reviewer Review Type Date Requested Status
Unity8 CI Bot (community) continuous-integration Needs Fixing
Daniel d'Andrada (community) Approve
Review via email: mp+318744@code.launchpad.net

This proposal has been superseded by a proposal from 2017-03-10.

Commit message

Check for find() result not being null before using it

We do it in onWindowReady, onWindowMoved, onWindowFocusChanged, etc so no reason to not do it in onWindowRemoved

Description of the change

 * Are there any related MPs required for this MP to build/function as expected?
No

 * Did you perform an exploratory manual test run of your code change and any related functionality?
N/A

 * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A

To post a comment you must log in.
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

Ok

review: Approve
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:609
https://unity8-jenkins.ubuntu.com/job/lp-qtmir-ci/544/
Executed test runs:
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build/4281/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/4309
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4143
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4143/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4143
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4143/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4143/console
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4143/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4143
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4143/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4143
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4143/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4143
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4143/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-qtmir-ci/544/rebuild

review: Needs Fixing (continuous-integration)
613. By Alan Griffiths

Simplify and remove dead code

614. By Alan Griffiths

Put const where "we" like it

615. By Alan Griffiths

Move const to the left

616. By Alan Griffiths

merge :parent

620. By Gerry Boland

Small SurfaceManager Test improvements

621. By Gerry Boland

Remove tests for the old delete-self behaviour of MirSurface

622. By Gerry Boland

Stop MirSurface deleting itself, ensure SurfaceManager alone manages MirSurface lifetimes

This fixes bugs where a MirSurface would call deleteLater on itself, but SurfaceManager would have no idea and keep a pointer to that MirSurface in its internal list.

Instead SurfaceManager listens for signals from MirSurface and decides when to delete it.

623. By Gerry Boland

Cleanup: no need to pass MirSurface out in isBeingDisplayedChanged signal

624. By Gerry Boland

Make self-triggered MirSurface deletion happen later, makes code more robust

625. By Gerry Boland

Remnant of bad rebase, delete SessionManager reference

626. By Albert Astals Cid

Check for find() result not being null before using it

We do it in onWindowReady, onWindowMoved, onWindowFocusChanged, etc so no reason to not do it in onWindowRemoved

627. By Albert Astals Cid

Merge

628. By Albert Astals Cid

Wrong merge

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/modules/Unity/Application/CMakeLists.txt'
--- src/modules/Unity/Application/CMakeLists.txt 2017-02-08 12:19:14 +0000
+++ src/modules/Unity/Application/CMakeLists.txt 2017-03-10 12:23:14 +0000
@@ -74,8 +74,6 @@
74# Frig for files that still rely on mirserver-dev74# Frig for files that still rely on mirserver-dev
75string(REPLACE ";" " -I" QTMIR_ADD_MIRSERVER "-I ${MIRSERVER_INCLUDE_DIRS}")75string(REPLACE ";" " -I" QTMIR_ADD_MIRSERVER "-I ${MIRSERVER_INCLUDE_DIRS}")
76set_source_files_properties(mirsurface.cpp PROPERTIES COMPILE_FLAGS "${CMAKE_CXXFLAGS} ${QTMIR_ADD_MIRSERVER}")76set_source_files_properties(mirsurface.cpp PROPERTIES COMPILE_FLAGS "${CMAKE_CXXFLAGS} ${QTMIR_ADD_MIRSERVER}")
77set_source_files_properties(mirbuffersgtexture.cpp PROPERTIES COMPILE_FLAGS "${CMAKE_CXXFLAGS} ${QTMIR_ADD_MIRSERVER}")
78set_source_files_properties(surfacemanager.cpp PROPERTIES COMPILE_FLAGS "${CMAKE_CXXFLAGS} ${QTMIR_ADD_MIRSERVER}")
7977
80target_link_libraries(78target_link_libraries(
81 unityapplicationplugin79 unityapplicationplugin
8280
=== modified file 'src/modules/Unity/Application/mirbuffersgtexture.cpp'
--- src/modules/Unity/Application/mirbuffersgtexture.cpp 2015-12-14 09:05:06 +0000
+++ src/modules/Unity/Application/mirbuffersgtexture.cpp 2017-03-10 12:23:14 +0000
@@ -17,12 +17,9 @@
17#include "mirbuffersgtexture.h"17#include "mirbuffersgtexture.h"
1818
19// Mir19// Mir
20#include <mir/graphics/buffer.h>
21#include <mir/geometry/size.h>20#include <mir/geometry/size.h>
22#include <mir/renderer/gl/texture_source.h>
2321
24namespace mg = mir::geometry;22namespace mg = mir::geometry;
25namespace mrg = mir::renderer::gl;
2623
27MirBufferSGTexture::MirBufferSGTexture()24MirBufferSGTexture::MirBufferSGTexture()
28 : QSGTexture()25 : QSGTexture()
@@ -54,14 +51,14 @@
54void MirBufferSGTexture::setBuffer(const std::shared_ptr<mir::graphics::Buffer>& buffer)51void MirBufferSGTexture::setBuffer(const std::shared_ptr<mir::graphics::Buffer>& buffer)
55{52{
56 m_mirBuffer = buffer;53 m_mirBuffer = buffer;
57 mg::Size size = buffer->size();54 mg::Size size = m_mirBuffer.size();
58 m_height = size.height.as_int();55 m_height = size.height.as_int();
59 m_width = size.width.as_int();56 m_width = size.width.as_int();
60}57}
6158
62bool MirBufferSGTexture::hasBuffer() const59bool MirBufferSGTexture::hasBuffer() const
63{60{
64 return !!m_mirBuffer;61 return m_mirBuffer.hasBuffer();
65}62}
6663
67int MirBufferSGTexture::textureId() const64int MirBufferSGTexture::textureId() const
@@ -76,12 +73,7 @@
7673
77bool MirBufferSGTexture::hasAlphaChannel() const74bool MirBufferSGTexture::hasAlphaChannel() const
78{75{
79 if (hasBuffer()) {76 return m_mirBuffer.hasAlphaChannel();
80 return m_mirBuffer->pixel_format() == mir_pixel_format_abgr_8888
81 || m_mirBuffer->pixel_format() == mir_pixel_format_argb_8888;
82 } else {
83 return false;
84 }
85}77}
8678
87void MirBufferSGTexture::bind()79void MirBufferSGTexture::bind()
@@ -90,10 +82,5 @@
90 glBindTexture(GL_TEXTURE_2D, m_textureId);82 glBindTexture(GL_TEXTURE_2D, m_textureId);
91 updateBindOptions(true/* force */);83 updateBindOptions(true/* force */);
9284
93 auto const texture_source =85 m_mirBuffer.glBindToTexture();
94 dynamic_cast<mrg::TextureSource*>(m_mirBuffer->native_buffer_base());
95 if (!texture_source)
96 throw std::logic_error("Buffer does not support GL rendering");
97
98 texture_source->gl_bind_to_texture();
99}86}
10087
=== modified file 'src/modules/Unity/Application/mirbuffersgtexture.h'
--- src/modules/Unity/Application/mirbuffersgtexture.h 2015-10-28 13:45:07 +0000
+++ src/modules/Unity/Application/mirbuffersgtexture.h 2017-03-10 12:23:14 +0000
@@ -17,7 +17,7 @@
17#ifndef MIRBUFFERSGTEXTURE_H17#ifndef MIRBUFFERSGTEXTURE_H
18#define MIRBUFFERSGTEXTURE_H18#define MIRBUFFERSGTEXTURE_H
1919
20#include <memory>20#include "mirbuffer.h"
2121
22#include <QSGTexture>22#include <QSGTexture>
2323
@@ -44,7 +44,7 @@
44 void bind() override;44 void bind() override;
4545
46private:46private:
47 std::shared_ptr<mir::graphics::Buffer> m_mirBuffer;47 qtmir::MirBuffer m_mirBuffer;
48 int m_width;48 int m_width;
49 int m_height;49 int m_height;
50 GLuint m_textureId;50 GLuint m_textureId;
5151
=== modified file 'src/modules/Unity/Application/mirsurface.cpp'
--- src/modules/Unity/Application/mirsurface.cpp 2017-02-09 11:01:37 +0000
+++ src/modules/Unity/Application/mirsurface.cpp 2017-03-10 12:23:14 +0000
@@ -169,7 +169,6 @@
169 connect(m_surfaceObserver.get(), &SurfaceObserver::confinesMousePointerChanged, this, &MirSurface::confinesMousePointerChanged);169 connect(m_surfaceObserver.get(), &SurfaceObserver::confinesMousePointerChanged, this, &MirSurface::confinesMousePointerChanged);
170 m_surfaceObserver->setListener(this);170 m_surfaceObserver->setListener(this);
171171
172 //connect(session, &QObject::destroyed, this, &MirSurface::onSessionDestroyed); // TODO try using Shared pointer for lifecycle
173 connect(session, &SessionInterface::stateChanged, this, [this]() {172 connect(session, &SessionInterface::stateChanged, this, [this]() {
174 if (clientIsRunning() && m_pendingResize.isValid()) {173 if (clientIsRunning() && m_pendingResize.isValid()) {
175 resize(m_pendingResize.width(), m_pendingResize.height());174 resize(m_pendingResize.width(), m_pendingResize.height());
@@ -585,9 +584,6 @@
585 DEBUG_MSG << "(" << value << ")";584 DEBUG_MSG << "(" << value << ")";
586 m_live = value;585 m_live = value;
587 Q_EMIT liveChanged(value);586 Q_EMIT liveChanged(value);
588 if (m_views.isEmpty() && !m_live) {
589 deleteLater();
590 }
591 }587 }
592}588}
593589
@@ -712,9 +708,6 @@
712 DEBUG_MSG << "(" << viewId << ")" << " after=" << m_views.count() << " live=" << m_live;708 DEBUG_MSG << "(" << viewId << ")" << " after=" << m_views.count() << " live=" << m_live;
713 if (m_views.count() == 0) {709 if (m_views.count() == 0) {
714 Q_EMIT isBeingDisplayedChanged();710 Q_EMIT isBeingDisplayedChanged();
715 if (m_session.isNull() || !m_live) {
716 deleteLater();
717 }
718 }711 }
719 updateExposure();712 updateExposure();
720 setViewActiveFocus(viewId, false);713 setViewActiveFocus(viewId, false);
@@ -759,13 +752,6 @@
759 return m_currentFrameNumber;752 return m_currentFrameNumber;
760}753}
761754
762void MirSurface::onSessionDestroyed()
763{
764 if (m_views.isEmpty()) {
765 deleteLater();
766 }
767}
768
769void MirSurface::emitSizeChanged()755void MirSurface::emitSizeChanged()
770{756{
771 Q_EMIT sizeChanged(m_size);757 Q_EMIT sizeChanged(m_size);
772758
=== modified file 'src/modules/Unity/Application/mirsurface.h'
--- src/modules/Unity/Application/mirsurface.h 2017-02-02 09:17:48 +0000
+++ src/modules/Unity/Application/mirsurface.h 2017-03-10 12:23:14 +0000
@@ -188,7 +188,6 @@
188 void dropPendingBuffer();188 void dropPendingBuffer();
189 void onAttributeChanged(const MirWindowAttrib, const int);189 void onAttributeChanged(const MirWindowAttrib, const int);
190 void onFramesPostedObserved();190 void onFramesPostedObserved();
191 void onSessionDestroyed();
192 void emitSizeChanged();191 void emitSizeChanged();
193 void setCursor(const QCursor &cursor);192 void setCursor(const QCursor &cursor);
194 void onCloseTimedOut();193 void onCloseTimedOut();
195194
=== modified file 'src/modules/Unity/Application/sessionmanager.cpp'
--- src/modules/Unity/Application/sessionmanager.cpp 2016-11-03 20:17:46 +0000
+++ src/modules/Unity/Application/sessionmanager.cpp 2017-03-10 12:23:14 +0000
@@ -90,6 +90,10 @@
90 setObjectName(QStringLiteral("qtmir::SessionManager"));90 setObjectName(QStringLiteral("qtmir::SessionManager"));
91}91}
9292
93SessionManager::SessionManager() // for test use only
94 : m_applicationManager(nullptr)
95{}
96
93SessionManager::~SessionManager()97SessionManager::~SessionManager()
94{98{
95 qCDebug(QTMIR_SESSIONS) << "SessionManager::~SessionManager - this=" << this;99 qCDebug(QTMIR_SESSIONS) << "SessionManager::~SessionManager - this=" << this;
96100
=== modified file 'src/modules/Unity/Application/sessionmanager.h'
--- src/modules/Unity/Application/sessionmanager.h 2016-11-03 20:17:46 +0000
+++ src/modules/Unity/Application/sessionmanager.h 2017-03-10 12:23:14 +0000
@@ -56,11 +56,11 @@
56 ApplicationManager* applicationManager,56 ApplicationManager* applicationManager,
57 QObject *parent = 057 QObject *parent = 0
58 );58 );
59 ~SessionManager();59 virtual ~SessionManager();
6060
61 static SessionManager* singleton();61 static SessionManager* singleton();
6262
63 SessionInterface *findSession(const mir::scene::Session* session) const;63 virtual SessionInterface *findSession(const mir::scene::Session* session) const;
6464
65Q_SIGNALS:65Q_SIGNALS:
66 void sessionStarting(SessionInterface* session);66 void sessionStarting(SessionInterface* session);
@@ -76,6 +76,7 @@
76 void onPromptProviderRemoved(const qtmir::PromptSession &promptSession, const std::shared_ptr<mir::scene::Session> &);76 void onPromptProviderRemoved(const qtmir::PromptSession &promptSession, const std::shared_ptr<mir::scene::Session> &);
7777
78protected:78protected:
79 SessionManager(); // for test purposes only
7980
80private:81private:
81 const std::shared_ptr<PromptSessionManager> m_promptSessionManager;82 const std::shared_ptr<PromptSessionManager> m_promptSessionManager;
8283
=== modified file 'src/modules/Unity/Application/surfacemanager.cpp'
--- src/modules/Unity/Application/surfacemanager.cpp 2017-02-15 13:21:07 +0000
+++ src/modules/Unity/Application/surfacemanager.cpp 2017-03-10 12:23:14 +0000
@@ -27,9 +27,6 @@
27#include <debughelpers.h>27#include <debughelpers.h>
28#include <mirqtconversion.h>28#include <mirqtconversion.h>
2929
30// Mir
31#include <mir/scene/surface.h>
32
33// Qt30// Qt
34#include <QGuiApplication>31#include <QGuiApplication>
3532
@@ -41,7 +38,8 @@
41using namespace qtmir;38using namespace qtmir;
42namespace unityapi = unity::shell::application;39namespace unityapi = unity::shell::application;
4340
44SurfaceManager::SurfaceManager(QObject *)41
42SurfaceManager::SurfaceManager()
45{43{
46 DEBUG_MSG << "()";44 DEBUG_MSG << "()";
4745
@@ -59,6 +57,16 @@
59 m_sessionManager = SessionManager::singleton();57 m_sessionManager = SessionManager::singleton();
60}58}
6159
60SurfaceManager::SurfaceManager(WindowControllerInterface *windowController,
61 WindowModelNotifier *windowModel,
62 SessionManager *sessionManager)
63 : m_windowController(windowController)
64 , m_sessionManager(sessionManager)
65{
66 DEBUG_MSG << "()";
67 connectToWindowModelNotifier(windowModel);
68}
69
62void SurfaceManager::connectToWindowModelNotifier(WindowModelNotifier *notifier)70void SurfaceManager::connectToWindowModelNotifier(WindowModelNotifier *notifier)
63{71{
64 connect(notifier, &WindowModelNotifier::windowAdded, this, &SurfaceManager::onWindowAdded, Qt::QueuedConnection);72 connect(notifier, &WindowModelNotifier::windowAdded, this, &SurfaceManager::onWindowAdded, Qt::QueuedConnection);
@@ -90,27 +98,32 @@
9098
91void SurfaceManager::onWindowAdded(const NewWindow &window)99void SurfaceManager::onWindowAdded(const NewWindow &window)
92{100{
101 const auto &windowInfo = window.windowInfo;
93 {102 {
94 std::shared_ptr<mir::scene::Surface> surface = window.surface;103 DEBUG_MSG << " mir::scene::Surface[type=" << mirSurfaceTypeToStr(windowInfo.type())
95 DEBUG_MSG << " mir::scene::Surface[type=" << mirSurfaceTypeToStr(surface->type())104 << ",parent=" << (void*)(std::shared_ptr<mir::scene::Surface>{windowInfo.parent()}.get())
96 << ",parent=" << (void*)(surface->parent().get())105 << ",state=" << mirSurfaceStateToStr(windowInfo.state())
97 << ",state=" << mirSurfaceStateToStr(surface->state())106 << ",top_left=" << toQPoint(windowInfo.window().top_left())
98 << ",top_left=" << toQPoint(surface->top_left())
99 << "]";107 << "]";
100 }108 }
101109
102 auto mirSession = window.windowInfo.window().application();110 auto mirSession = windowInfo.window().application();
111
103 SessionInterface* session = m_sessionManager->findSession(mirSession.get());112 SessionInterface* session = m_sessionManager->findSession(mirSession.get());
104113
105 MirSurface *parentSurface;114 const auto parentSurface = find(windowInfo.parent());
106 {115 const auto surface = new MirSurface(window, m_windowController, session, parentSurface);
107 std::shared_ptr<mir::scene::Surface> surface = window.windowInfo.window();
108 parentSurface = find(surface->parent());
109 }
110
111 auto surface = new MirSurface(window, m_windowController, session, parentSurface);
112 rememberMirSurface(surface);116 rememberMirSurface(surface);
113117
118 connect(surface, &MirSurface::isBeingDisplayedChanged, this, [this, surface]() {
119 if ((!surface->live() || !surface->session())
120 && !surface->isBeingDisplayed()) {
121 forgetMirSurface(static_cast<MirSurface*>(surface)->window());
122 surface->deleteLater(); // don't delete immediately, slot may be directly connected
123 tracepoint(qtmir, surfaceDestroyed);
124 }
125 });
126
114 if (parentSurface) {127 if (parentSurface) {
115 static_cast<MirSurfaceListModel*>(parentSurface->childSurfaceList())->prependSurface(surface);128 static_cast<MirSurfaceListModel*>(parentSurface->childSurfaceList())->prependSurface(surface);
116 }129 }
@@ -126,8 +139,12 @@
126{139{
127 MirSurface *surface = find(windowInfo);140 MirSurface *surface = find(windowInfo);
128 forgetMirSurface(windowInfo.window());141 forgetMirSurface(windowInfo.window());
129 surface->setLive(false);142 if (surface && surface->isBeingDisplayed()) {
130 tracepoint(qtmir, surfaceDestroyed);143 surface->setLive(false);
144 } else {
145 delete surface;
146 tracepoint(qtmir, surfaceDestroyed);
147 }
131}148}
132149
133MirSurface *SurfaceManager::find(const miral::WindowInfo &needle) const150MirSurface *SurfaceManager::find(const miral::WindowInfo &needle) const
@@ -145,16 +162,6 @@
145 return nullptr;162 return nullptr;
146}163}
147164
148MirSurface *SurfaceManager::find(const std::shared_ptr<mir::scene::Surface> &needle) const
149{
150 Q_FOREACH(const auto surface, m_allSurfaces) {
151 if (surface->window() == needle) {
152 return surface;
153 }
154 }
155 return nullptr;
156}
157
158void SurfaceManager::onWindowReady(const miral::WindowInfo &windowInfo)165void SurfaceManager::onWindowReady(const miral::WindowInfo &windowInfo)
159{166{
160 if (auto mirSurface = find(windowInfo)) {167 if (auto mirSurface = find(windowInfo)) {
161168
=== modified file 'src/modules/Unity/Application/surfacemanager.h'
--- src/modules/Unity/Application/surfacemanager.h 2017-02-02 09:17:48 +0000
+++ src/modules/Unity/Application/surfacemanager.h 2017-03-10 12:23:14 +0000
@@ -39,12 +39,19 @@
39 Q_OBJECT39 Q_OBJECT
4040
41public:41public:
42 explicit SurfaceManager(QObject *parent = 0);42 explicit SurfaceManager();
43 virtual ~SurfaceManager() {}43 virtual ~SurfaceManager() {}
4444
45 void raise(unity::shell::application::MirSurfaceInterface *surface) override;45 void raise(unity::shell::application::MirSurfaceInterface *surface) override;
46 void activate(unity::shell::application::MirSurfaceInterface *surface) override;46 void activate(unity::shell::application::MirSurfaceInterface *surface) override;
4747
48protected:
49 // for testing purposes
50 SurfaceManager(WindowControllerInterface *windowController,
51 WindowModelNotifier *windowModel,
52 SessionManager *sessionManager);
53 MirSurface* find(const miral::WindowInfo &needle) const;
54
48private Q_SLOTS:55private Q_SLOTS:
49 void onWindowAdded(const qtmir::NewWindow &windowInfo);56 void onWindowAdded(const qtmir::NewWindow &windowInfo);
50 void onWindowRemoved(const miral::WindowInfo &windowInfo);57 void onWindowRemoved(const miral::WindowInfo &windowInfo);
@@ -59,9 +66,7 @@
59 void connectToWindowModelNotifier(WindowModelNotifier *notifier);66 void connectToWindowModelNotifier(WindowModelNotifier *notifier);
60 void rememberMirSurface(MirSurface *surface);67 void rememberMirSurface(MirSurface *surface);
61 void forgetMirSurface(const miral::Window &window);68 void forgetMirSurface(const miral::Window &window);
62 MirSurface* find(const miral::WindowInfo &needle) const;
63 MirSurface* find(const miral::Window &needle) const;69 MirSurface* find(const miral::Window &needle) const;
64 MirSurface* find(const std::shared_ptr<mir::scene::Surface> &needle) const;
6570
66 QVector<MirSurface*> m_allSurfaces;71 QVector<MirSurface*> m_allSurfaces;
6772
6873
=== modified file 'src/platforms/mirserver/CMakeLists.txt'
--- src/platforms/mirserver/CMakeLists.txt 2017-02-15 13:21:50 +0000
+++ src/platforms/mirserver/CMakeLists.txt 2017-03-10 12:23:14 +0000
@@ -88,6 +88,7 @@
88 setqtcompositor.cpp setqtcompositor.h88 setqtcompositor.cpp setqtcompositor.h
89 eventdispatch.cpp eventdispatch.h89 eventdispatch.cpp eventdispatch.h
90 promptsessionmanager.cpp promptsessionmanager.h promptsession.h90 promptsessionmanager.cpp promptsessionmanager.h promptsession.h
91 mirbuffer.cpp mirbuffer.h
91)92)
9293
93# These files get entangled by automoc so they need to go together. And some depend on mirserver-dev94# These files get entangled by automoc so they need to go together. And some depend on mirserver-dev
9495
=== added file 'src/platforms/mirserver/mirbuffer.cpp'
--- src/platforms/mirserver/mirbuffer.cpp 1970-01-01 00:00:00 +0000
+++ src/platforms/mirserver/mirbuffer.cpp 2017-03-10 12:23:14 +0000
@@ -0,0 +1,70 @@
1/*
2 * Copyright © 2017 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "mirbuffer.h"
18
19#include <mir/graphics/buffer.h>
20#include <mir/renderer/gl/texture_source.h>
21
22#include <stdexcept>
23
24qtmir::MirBuffer::MirBuffer() = default;
25qtmir::MirBuffer::~MirBuffer() = default;
26qtmir::MirBuffer::MirBuffer(std::shared_ptr<mir::graphics::Buffer> const &buffer) :
27 m_mirBuffer(buffer)
28{
29}
30
31qtmir::MirBuffer& qtmir::MirBuffer::operator=(std::shared_ptr<mir::graphics::Buffer> const &buffer)
32{
33 m_mirBuffer = buffer;
34 return *this;
35}
36
37bool qtmir::MirBuffer::hasBuffer() const
38{
39 return !!m_mirBuffer;
40}
41
42bool qtmir::MirBuffer::hasAlphaChannel() const
43{
44 return hasBuffer() &&
45 (m_mirBuffer->pixel_format() == mir_pixel_format_abgr_8888
46 || m_mirBuffer->pixel_format() == mir_pixel_format_argb_8888);
47}
48
49mir::geometry::Size qtmir::MirBuffer::size() const
50{
51 return m_mirBuffer->size();
52}
53
54void qtmir::MirBuffer::reset()
55{
56 m_mirBuffer.reset();
57}
58
59void qtmir::MirBuffer::glBindToTexture()
60{
61 namespace mrg = mir::renderer::gl;
62
63 auto const texture_source =
64 dynamic_cast<mrg::TextureSource*>(m_mirBuffer->native_buffer_base());
65 if (!texture_source)
66 throw std::logic_error("Buffer does not support GL rendering");
67
68 texture_source->gl_bind_to_texture();
69}
70
071
=== added file 'src/platforms/mirserver/mirbuffer.h'
--- src/platforms/mirserver/mirbuffer.h 1970-01-01 00:00:00 +0000
+++ src/platforms/mirserver/mirbuffer.h 2017-03-10 12:23:14 +0000
@@ -0,0 +1,48 @@
1/*
2 * Copyright © 2017 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef QTMIR_MIR_BUFFER_H
18#define QTMIR_MIR_BUFFER_H
19
20#include <mir/geometry/size.h>
21
22#include <memory>
23
24namespace mir { namespace graphics { class Buffer; }}
25
26namespace qtmir
27{
28class MirBuffer
29{
30public:
31 MirBuffer();
32 ~MirBuffer();
33 explicit MirBuffer(std::shared_ptr<mir::graphics::Buffer> const &buffer);
34 MirBuffer& operator=(std::shared_ptr<mir::graphics::Buffer> const &buffer);
35
36 bool hasBuffer() const;
37 bool hasAlphaChannel() const;
38 mir::geometry::Size size() const;
39
40 void reset();
41 void glBindToTexture();
42
43private:
44 std::shared_ptr<mir::graphics::Buffer> m_mirBuffer;
45};
46}
47
48#endif //QTMIR_MIR_BUFFER_H
049
=== modified file 'tests/framework/CMakeLists.txt'
--- tests/framework/CMakeLists.txt 2016-12-02 16:22:45 +0000
+++ tests/framework/CMakeLists.txt 2017-03-10 12:23:14 +0000
@@ -46,6 +46,8 @@
46target_link_libraries(46target_link_libraries(
47 qtmir-test-framework-static47 qtmir-test-framework-static
4848
49 unityapplicationplugin
50
49 ${GTEST_BOTH_LIBRARIES}51 ${GTEST_BOTH_LIBRARIES}
50 ${GMOCK_LIBRARIES}52 ${GMOCK_LIBRARIES}
51)53)
5254
=== added file 'tests/framework/mock_session_manager.h'
--- tests/framework/mock_session_manager.h 1970-01-01 00:00:00 +0000
+++ tests/framework/mock_session_manager.h 2017-03-10 12:23:14 +0000
@@ -0,0 +1,33 @@
1/*
2 * Copyright (C) 2017 Canonical, Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License version 3, as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10 * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef MOCK_SESSION_MANAGER_H
18#define MOCK_SESSION_MANAGER_H
19
20#include <Unity/Application/sessionmanager.h>
21
22#include <gmock/gmock.h>
23
24namespace qtmir {
25
26struct MockSessionManager : public qtmir::SessionManager
27{
28 MOCK_CONST_METHOD1(findSession, qtmir::SessionInterface*(const mir::scene::Session*));
29};
30
31} // namespace qtmir
32
33#endif // MOCK_SESSION_MANAGER_H
034
=== added file 'tests/framework/mock_window_controller.h'
--- tests/framework/mock_window_controller.h 1970-01-01 00:00:00 +0000
+++ tests/framework/mock_window_controller.h 2017-03-10 12:23:14 +0000
@@ -0,0 +1,43 @@
1/*
2 * Copyright (C) 2017 Canonical, Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License version 3, as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10 * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef MOCK_WINDOW_CONTROLLER_H
18#define MOCK_WINDOW_CONTROLLER_H
19
20#include "windowcontrollerinterface.h"
21
22#include <gmock/gmock.h>
23
24class MockWindowController : public qtmir::WindowControllerInterface
25{
26public:
27 MOCK_METHOD1(activate, void(const miral::Window &));
28 MOCK_METHOD1(raise, void(const miral::Window &));
29
30 MOCK_METHOD2(resize, void(const miral::Window &, const QSize &));
31 MOCK_METHOD2(move, void(const miral::Window &, const QPoint &));
32
33 MOCK_METHOD1(requestClose, void(const miral::Window &));
34 MOCK_METHOD1(forceClose, void(const miral::Window &));
35
36 MOCK_METHOD2(requestState, void(const miral::Window &, const Mir::State));
37
38 MOCK_METHOD2(deliverKeyboardEvent, void(const miral::Window &, const MirKeyboardEvent *));
39 MOCK_METHOD2(deliverTouchEvent, void(const miral::Window &, const MirTouchEvent *));
40 MOCK_METHOD2(deliverPointerEvent, void(const miral::Window &, const MirPointerEvent *));
41};
42
43#endif // MOCK_WINDOW_CONTROLLER_H
044
=== modified file 'tests/modules/CMakeLists.txt'
--- tests/modules/CMakeLists.txt 2016-11-03 20:17:46 +0000
+++ tests/modules/CMakeLists.txt 2017-03-10 12:23:14 +0000
@@ -1,6 +1,7 @@
1add_subdirectory(Application)1add_subdirectory(Application)
2add_subdirectory(ApplicationManager)2add_subdirectory(ApplicationManager)
3add_subdirectory(General)3add_subdirectory(General)
4add_subdirectory(SessionManager)
4add_subdirectory(SharedWakelock)5add_subdirectory(SharedWakelock)
5add_subdirectory(SessionManager)6add_subdirectory(SurfaceManager)
6add_subdirectory(WindowManager)7add_subdirectory(WindowManager)
78
=== added directory 'tests/modules/SurfaceManager'
=== added file 'tests/modules/SurfaceManager/CMakeLists.txt'
--- tests/modules/SurfaceManager/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ tests/modules/SurfaceManager/CMakeLists.txt 2017-03-10 12:23:14 +0000
@@ -0,0 +1,40 @@
1set(
2 SURFACE_MANAGER_TEST_SOURCES
3 surface_manager_test.cpp
4 ${CMAKE_SOURCE_DIR}/src/common/debughelpers.cpp
5)
6
7include_directories(
8 ${CMAKE_SOURCE_DIR}/src/common
9 ${CMAKE_SOURCE_DIR}/src/platforms/mirserver
10 ${CMAKE_SOURCE_DIR}/src/modules
11 ${CMAKE_SOURCE_DIR}/tests/framework
12)
13
14include_directories(
15 SYSTEM
16 ${APPLICATION_API_INCLUDE_DIRS}
17 ${MIRAL_INCLUDE_DIRS}
18 ${MIRTEST_INCLUDE_DIRS}
19)
20
21add_executable(surfacemanager_test ${SURFACE_MANAGER_TEST_SOURCES})
22
23add_dependencies(surfacemanager_test qtmir-test-framework-static)
24
25target_link_libraries(
26 surfacemanager_test
27
28 unityapplicationplugin
29
30 Qt5::Test
31
32 -L${CMAKE_BINARY_DIR}/tests/framework
33 qtmir-test-framework-static
34
35 ${MIRTEST_LDFLAGS}
36 ${GTEST_BOTH_LIBRARIES}
37 ${GMOCK_LIBRARIES}
38)
39
40add_test(SurfaceManager, surfacemanager_test)
041
=== added file 'tests/modules/SurfaceManager/surface_manager_test.cpp'
--- tests/modules/SurfaceManager/surface_manager_test.cpp 1970-01-01 00:00:00 +0000
+++ tests/modules/SurfaceManager/surface_manager_test.cpp 2017-03-10 12:23:14 +0000
@@ -0,0 +1,489 @@
1/*
2 * Copyright (C) 2017 Canonical, Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License version 3, as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10 * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <QLoggingCategory>
18#include <QSignalSpy>
19
20// the test subject
21#include <Unity/Application/surfacemanager.h>
22#include <Unity/Application/mirsurface.h>
23
24// miral
25#include <miral/window.h>
26#include <miral/window_info.h>
27
28// mirtest
29#include <mir/test/doubles/stub_session.h>
30#include <mir/test/doubles/stub_surface.h>
31
32// local
33#include "qtmir_test.h"
34#include "fake_session.h"
35#include "mock_session_manager.h"
36#include "mock_window_controller.h"
37
38using namespace qtmir;
39using StubSurface = mir::test::doubles::StubSurface;
40using StubSession = mir::test::doubles::StubSession;
41
42struct TestableSurfaceManager : public SurfaceManager
43{
44 // just exports the test-only protected constructor
45 TestableSurfaceManager(WindowControllerInterface *windowController,
46 WindowModelNotifier *windowModel,
47 SessionManager *sessionManager)
48 : SurfaceManager(windowController, windowModel, sessionManager) {}
49
50 MirSurface* find(const miral::WindowInfo &needle) const
51 {
52 return SurfaceManager::find(needle);
53 }
54};
55
56class SurfaceManagerTests : public ::testing::Test
57{
58public:
59 SurfaceManagerTests()
60 {
61 // We don't want the logging spam cluttering the test results
62 QLoggingCategory::setFilterRules(QStringLiteral("qtmir.*=false"));
63
64 qRegisterMetaType<unity::shell::application::MirSurfaceInterface*>();
65 qRegisterMetaType<QVector<unity::shell::application::MirSurfaceInterface*>>();
66 }
67
68 testing::NiceMock<MockSessionManager> sessionManager;
69 testing::NiceMock<MockWindowController> wmController;
70 WindowModelNotifier wmNotifier;
71 QScopedPointer<TestableSurfaceManager> surfaceManager;
72 QScopedPointer<QCoreApplication> qtApp; // need to spin event loop for queued connections
73
74 // Needed to create miral::WindowInfo
75 const std::shared_ptr<StubSession> stubSession{std::make_shared<StubSession>()};
76 const std::shared_ptr<StubSurface> stubSurface{std::make_shared<StubSurface>()};
77 const miral::Window window{stubSession, stubSurface};
78 const ms::SurfaceCreationParameters spec;
79 const miral::WindowInfo windowInfo{window, spec};
80 FakeSession fakeSession;
81
82protected:
83 void SetUp() override
84 {
85 int argc = 0;
86 char* argv[0];
87 qtApp.reset(new QCoreApplication(argc, argv));
88
89 using namespace ::testing;
90 ON_CALL(sessionManager,findSession(_))
91 .WillByDefault(Return(&fakeSession));
92
93 surfaceManager.reset(new TestableSurfaceManager(&wmController,
94 &wmNotifier, &sessionManager));
95 }
96};
97
98/*
99 * Test if MirAL notifies that a window was created, SurfaceManager emits the surfaceCreated
100 * signal
101 */
102TEST_F(SurfaceManagerTests, miralWindowCreationCausesSignalEmission)
103{
104 QSignalSpy newMirSurfaceSpy(surfaceManager.data(), &SurfaceManager::surfaceCreated);
105
106 // Test
107 Q_EMIT wmNotifier.windowAdded(windowInfo);
108 qtApp->sendPostedEvents();
109
110 // Check result
111 EXPECT_EQ(1, newMirSurfaceSpy.count());
112}
113
114
115/*
116 * Test if MirAL notifies that a window was created, SurfaceManager emits the surfaceCreated
117 * signal with a corresponding MirSurface
118 */
119TEST_F(SurfaceManagerTests, miralWindowCreationCausesMirSurfaceCreation)
120{
121 QSignalSpy newMirSurfaceSpy(surfaceManager.data(), &SurfaceManager::surfaceCreated);
122
123 // Test
124 Q_EMIT wmNotifier.windowAdded(windowInfo);
125 qtApp->sendPostedEvents();
126
127 // Check result
128 auto mirSurface = qvariant_cast<MirSurface*>(newMirSurfaceSpy.takeFirst().at(0));
129 ASSERT_TRUE(mirSurface);
130 EXPECT_EQ(window, mirSurface->window());
131}
132
133/*
134 * Test if MirAL notifies that a window was created, SurfaceManager adds the corresponding
135 * MirSurface to its internal list
136 */
137TEST_F(SurfaceManagerTests, miralWindowCreationAddsMirSurfaceToItsInternalList)
138{
139 // Test
140 Q_EMIT wmNotifier.windowAdded(windowInfo);
141 qtApp->sendPostedEvents();
142
143 // Check result
144 auto mirSurface = surfaceManager->find(windowInfo);
145 ASSERT_TRUE(mirSurface);
146 EXPECT_EQ(window, mirSurface->window());
147}
148
149/*
150 * Test SurfaceManager creates a MirSurface with a Session associated
151 */
152TEST_F(SurfaceManagerTests, createdMirSurfaceHasSessionSet)
153{
154 // Setup
155 using namespace ::testing;
156 EXPECT_CALL(sessionManager,findSession(_))
157 .WillOnce(Return(&fakeSession));
158
159 // Test
160 Q_EMIT wmNotifier.windowAdded(windowInfo);
161 qtApp->sendPostedEvents();
162
163 // Check result
164 auto mirSurface = surfaceManager->find(windowInfo);
165 ASSERT_TRUE(mirSurface);
166 EXPECT_EQ(&fakeSession, mirSurface->session());
167}
168
169/*
170 * Test when MirAL creates a surface with a parent, SurfaceManager correctly associates
171 * the parent MirSurface to the MirSurface
172 */
173TEST_F(SurfaceManagerTests, parentedMiralWindowGeneratesMirSurfaceWithCorrectParent)
174{
175 // Setup
176 miral::Window parentWindow(stubSession, stubSurface);
177 miral::Window childWindow(stubSession, stubSurface);
178 miral::WindowInfo parentWindowInfo(parentWindow, spec);
179 miral::WindowInfo childWindowInfo(childWindow, spec);
180 childWindowInfo.parent(parentWindow);
181
182 // Test
183 Q_EMIT wmNotifier.windowAdded(parentWindowInfo);
184 Q_EMIT wmNotifier.windowAdded(childWindowInfo);
185 qtApp->sendPostedEvents();
186
187 // Check result
188 auto childMirSurface = surfaceManager->find(childWindowInfo);
189 auto parentMirSurface = surfaceManager->find(parentWindowInfo);
190 ASSERT_TRUE(childMirSurface);
191 ASSERT_TRUE(parentMirSurface);
192
193 EXPECT_EQ(parentMirSurface, childMirSurface->parentSurface());
194}
195
196/*
197 * Test when MirAL creates a surface with a parent, SurfaceManager correctly associates
198 * the child MirSurface to the parent MirSurface
199 */
200TEST_F(SurfaceManagerTests, miralWindowWithChildHasMirSurfaceWithCorrectChild)
201{
202 // Setup
203 miral::Window parentWindow(stubSession, stubSurface);
204 miral::Window childWindow(stubSession, stubSurface);
205 miral::WindowInfo parentWindowInfo(parentWindow, spec);
206 miral::WindowInfo childWindowInfo(childWindow, spec);
207 childWindowInfo.parent(parentWindow);
208
209 // Test
210 Q_EMIT wmNotifier.windowAdded(parentWindowInfo);
211 Q_EMIT wmNotifier.windowAdded(childWindowInfo);
212 qtApp->sendPostedEvents();
213
214 // Check result
215 auto childMirSurface = surfaceManager->find(childWindowInfo);
216 auto parentMirSurface = surfaceManager->find(parentWindowInfo);
217 ASSERT_TRUE(childMirSurface);
218 ASSERT_TRUE(parentMirSurface);
219
220 ASSERT_EQ(1, parentMirSurface->childSurfaceList()->count());
221 EXPECT_EQ(childMirSurface, parentMirSurface->childSurfaceList()->first());
222}
223
224/*
225 * Test if MirAL notifies that a window is ready, SurfaceManager updates the corresponding
226 * MirSurface causing it to emit a ready() signal
227 */
228TEST_F(SurfaceManagerTests, miralWindowReadyUpdatesMirSurfaceState)
229{
230 // Setup: add window and get corresponding MirSurface
231 Q_EMIT wmNotifier.windowAdded(windowInfo);
232 qtApp->sendPostedEvents();
233 auto mirSurface = surfaceManager->find(windowInfo);
234 ASSERT_TRUE(mirSurface);
235
236 QSignalSpy mirSurfaceReadySpy(mirSurface, &MirSurface::ready);
237
238 // Test
239 Q_EMIT wmNotifier.windowReady(windowInfo);
240 qtApp->sendPostedEvents();
241
242 // Check result
243 EXPECT_EQ(1, mirSurfaceReadySpy.count());
244}
245
246/*
247 * Test if MirAL notifies that a window is moved, SurfaceManager updates the corresponding
248 * MirSurface position
249 */
250TEST_F(SurfaceManagerTests, miralWindowMoveUpdatesMirSurfacePosition)
251{
252 QPoint newPosition(222,333);
253
254 // Setup: add window and get corresponding MirSurface
255 Q_EMIT wmNotifier.windowAdded(windowInfo);
256 qtApp->sendPostedEvents();
257 auto mirSurface = surfaceManager->find(windowInfo);
258 ASSERT_TRUE(mirSurface);
259
260 QSignalSpy mirSurfacePositionSpy(mirSurface, &MirSurface::positionChanged);
261
262 // Test
263 Q_EMIT wmNotifier.windowMoved(windowInfo, newPosition);
264 qtApp->sendPostedEvents();
265
266 // Check result
267 EXPECT_EQ(1, mirSurfacePositionSpy.count());
268 EXPECT_EQ(mirSurface->position(), newPosition);
269}
270
271/*
272 * Test if MirAL notifies that a window's focus state changes, SurfaceManager updates the corresponding
273 * MirSurface focus state
274 */
275TEST_F(SurfaceManagerTests, miralWindowFocusChangeUpdatesMirSurfaceFocus)
276{
277 // Setup: add window and get corresponding MirSurface
278 Q_EMIT wmNotifier.windowAdded(windowInfo);
279 qtApp->sendPostedEvents();
280 auto mirSurface = surfaceManager->find(windowInfo);
281 ASSERT_TRUE(mirSurface);
282 ASSERT_FALSE(mirSurface->focused()); // false must be the initial state
283
284 QSignalSpy mirSurfaceFocusSpy(mirSurface, &MirSurface::focusedChanged);
285
286 // Test
287 Q_EMIT wmNotifier.windowFocusChanged(windowInfo, true);
288 qtApp->sendPostedEvents();
289
290 // Check result
291 EXPECT_EQ(1, mirSurfaceFocusSpy.count());
292 EXPECT_EQ(mirSurface->focused(), true);
293}
294
295/*
296 * Test if MirAL notifies that a window's state changes, SurfaceManager updates the corresponding
297 * MirSurface state (just testing a single state, see no value in testing all possible states here)
298 */
299TEST_F(SurfaceManagerTests, miralWindowStateChangeUpdatesMirSurfaceState)
300{
301 auto newState = Mir::FullscreenState;
302
303 // Setup: add window and get corresponding MirSurface
304 Q_EMIT wmNotifier.windowAdded(windowInfo);
305 qtApp->sendPostedEvents();
306 auto mirSurface = surfaceManager->find(windowInfo);
307 ASSERT_TRUE(mirSurface);
308
309 QSignalSpy mirSurfaceStateSpy(mirSurface, &MirSurface::stateChanged);
310
311 // Test
312 Q_EMIT wmNotifier.windowStateChanged(windowInfo, newState);
313 qtApp->sendPostedEvents();
314
315 // Check result
316 EXPECT_EQ(1, mirSurfaceStateSpy.count());
317 EXPECT_EQ(mirSurface->state(), newState);
318}
319
320/*
321 * Test when miral raises a list of surfaces, the raise signal is fired by SurfaceManager with
322 * a list of MirSurfaces in the matching order
323 */
324TEST_F(SurfaceManagerTests, miralsRaiseWindowListTransformedToVectorOfMirSurfaces)
325{
326 // Setup
327 miral::Window window1(stubSession, stubSurface);
328 miral::Window window2(stubSession, stubSurface);
329 miral::WindowInfo windowInfo1(window1, spec);
330 miral::WindowInfo windowInfo2(window2, spec);
331
332 // Setup: add 2 windows and get their MirSurfaces
333 Q_EMIT wmNotifier.windowAdded(windowInfo1);
334 Q_EMIT wmNotifier.windowAdded(windowInfo2);
335 qtApp->sendPostedEvents();
336 auto mirSurface1 = surfaceManager->find(windowInfo1);
337 auto mirSurface2 = surfaceManager->find(windowInfo2);
338 ASSERT_TRUE(mirSurface1);
339 ASSERT_TRUE(mirSurface2);
340
341 QSignalSpy mirSurfacesRaisedSpy(surfaceManager.data(), &SurfaceManager::surfacesRaised);
342
343 // Test
344 std::vector<miral::Window> raiseWindowList{window2, window1};
345 Q_EMIT wmNotifier.windowsRaised(raiseWindowList);
346 qtApp->sendPostedEvents();
347
348 // Check results
349 ASSERT_EQ(1, mirSurfacesRaisedSpy.count());
350 auto raiseMirSurfaceList = qvariant_cast<QVector<unity::shell::application::MirSurfaceInterface*>>(
351 mirSurfacesRaisedSpy.takeFirst().at(0)); // first argument of signal
352 ASSERT_EQ(2, raiseMirSurfaceList.count());
353 EXPECT_EQ(mirSurface1, raiseMirSurfaceList.at(1));
354 EXPECT_EQ(mirSurface2, raiseMirSurfaceList.at(0));
355}
356
357/*
358 * Test focus requests fire focusRequested signal of the MirSurface
359 */
360TEST_F(SurfaceManagerTests, focusRequestCausesMirSurfaceToFireFocusRequestedSignal)
361{
362 // Setup: add window and get corresponding MirSurface
363 Q_EMIT wmNotifier.windowAdded(windowInfo);
364 qtApp->sendPostedEvents();
365 auto mirSurface = surfaceManager->find(windowInfo);
366 ASSERT_TRUE(mirSurface);
367
368 QSignalSpy mirSurfaceFocusRequestedSpy(mirSurface, &MirSurface::focusRequested);
369
370 // Test
371 Q_EMIT wmNotifier.windowRequestedRaise(windowInfo);
372 qtApp->sendPostedEvents();
373
374 // Check result
375 EXPECT_EQ(1, mirSurfaceFocusRequestedSpy.count());
376}
377
378/*
379 * If MirAL notifies that a window was removed, and its corresponding MirSurface is not
380 * being displayed, test that SurfaceManager removes the corresponding MirSurface from
381 * its internal list and deletes the MirSurface
382 */
383TEST_F(SurfaceManagerTests, miralWindowRemovedDeletesSurfaceManagerInternalEntryAndMirSurface)
384{
385 // Setup: add window and get corresponding MirSurface
386 Q_EMIT wmNotifier.windowAdded(windowInfo);
387 qtApp->sendPostedEvents();
388 auto mirSurface = surfaceManager->find(windowInfo);
389 ASSERT_TRUE(mirSurface);
390
391 QSignalSpy mirSurfaceDestroyedSpy(mirSurface, &QObject::destroyed);
392
393 // Test
394 Q_EMIT wmNotifier.windowRemoved(windowInfo);
395 qtApp->sendPostedEvents();
396
397 // Check result
398 ASSERT_EQ(2, mirSurfaceDestroyedSpy.count()); //FIXME - should be 1
399 EXPECT_FALSE(surfaceManager->find(windowInfo));
400}
401
402/*
403 * If MirAL notifies that a window was removed, and its corresponding MirSurface *is*
404 * being displayed, test that SurfaceManager removes the corresponding MirSurface from
405 * its internal list but does *not* delete the MirSurface, but sets it as not "live"
406 */
407TEST_F(SurfaceManagerTests, miralWindowRemovedDeletesSurfaceManagerInternalEntryButNotMirSurface)
408{
409 // Setup: add window and get corresponding MirSurface
410 Q_EMIT wmNotifier.windowAdded(windowInfo);
411 qtApp->sendPostedEvents();
412 auto mirSurface = surfaceManager->find(windowInfo);
413 ASSERT_TRUE(mirSurface);
414
415 QSignalSpy mirSurfaceDestroyedSpy(mirSurface, &QObject::destroyed);
416
417 mirSurface->registerView(1);
418
419 // Test
420 Q_EMIT wmNotifier.windowRemoved(windowInfo);
421 qtApp->sendPostedEvents();
422
423 // Check result
424 ASSERT_EQ(0, mirSurfaceDestroyedSpy.count());
425 EXPECT_FALSE(surfaceManager->find(windowInfo));
426 EXPECT_FALSE(mirSurface->live());
427}
428
429/*
430 * If MirAL notifies that a window was removed, and its corresponding MirSurface *is*
431 * being displayed, SurfaceManager does *not* delete the MirSurface. Later when that
432 * MirSurface is not being displayed any more, SurfaceManager should delete it.
433 */
434TEST_F(SurfaceManagerTests, miralWindowRemovedSurfaceManagerDeletesMirSurfaceWhenItDoneWith)
435{
436 int viewId = 99;
437
438 // Setup: add window and get corresponding MirSurface
439 Q_EMIT wmNotifier.windowAdded(windowInfo);
440 qtApp->sendPostedEvents();
441 auto mirSurface = surfaceManager->find(windowInfo);
442 ASSERT_TRUE(mirSurface);
443
444 QSignalSpy mirSurfaceDestroyedSpy(mirSurface, &QObject::destroyed);
445
446 // Setup: indicate MirSurface is being displayed
447 mirSurface->registerView(viewId);
448
449 // Setup: notify that window removed
450 Q_EMIT wmNotifier.windowRemoved(windowInfo);
451 qtApp->sendPostedEvents();
452
453 // Test
454 mirSurface->unregisterView(viewId);
455 // MirSurface is deleteLater()ed by SurfaceManager, so need to spin event loop.
456 // But DeferredDelete is special: likes to be called out specifically or it won't come out
457 qtApp->sendPostedEvents(mirSurface, QEvent::DeferredDelete);
458 qtApp->sendPostedEvents();
459
460 // Check result
461 ASSERT_EQ(2, mirSurfaceDestroyedSpy.count()); //FIXME - should be 1
462}
463
464/*
465 * Test that if a MirSurface is live, and stops being displayed, SurfaceManager does *not*
466 * delete the MirSurface.
467 */
468TEST_F(SurfaceManagerTests, surfaceManagerDoesNotDeleteLiveMirSurfaceWhenStopsBeingDisplayed)
469{
470 int viewId = 99;
471
472 // Setup: add window and get corresponding MirSurface
473 Q_EMIT wmNotifier.windowAdded(windowInfo);
474 qtApp->sendPostedEvents();
475 auto mirSurface = surfaceManager->find(windowInfo);
476 ASSERT_TRUE(mirSurface);
477 ASSERT_TRUE(mirSurface->live());
478
479 QSignalSpy mirSurfaceDestroyedSpy(mirSurface, &QObject::destroyed);
480
481 // Setup: indicate MirSurface is being displayed
482 mirSurface->registerView(viewId);
483
484 // Test
485 mirSurface->unregisterView(viewId);
486
487 // Check result
488 ASSERT_EQ(0, mirSurfaceDestroyedSpy.count());
489}
0490
=== modified file 'tests/modules/WindowManager/mirsurface_test.cpp'
--- tests/modules/WindowManager/mirsurface_test.cpp 2017-02-02 09:29:46 +0000
+++ tests/modules/WindowManager/mirsurface_test.cpp 2017-03-10 12:23:14 +0000
@@ -110,66 +110,6 @@
110 ASSERT_TRUE(spyFrameDropped.count() > 0);110 ASSERT_TRUE(spyFrameDropped.count() > 0);
111}111}
112112
113
114TEST_F(MirSurfaceTest, DeleteMirSurfaceOnLastNonLiveUnregisterView)
115{
116 int argc = 0;
117 char* argv[0];
118 QCoreApplication qtApp(argc, argv); // app for deleteLater event
119
120 miral::Window mockWindow(stubSession, stubSurface);
121 ms::SurfaceCreationParameters spec;
122 miral::WindowInfo mockWindowInfo(mockWindow, spec);
123
124 auto surface = new MirSurface(mockWindowInfo, nullptr); // lives on the heap, as it will delete itself
125
126 bool surfaceDeleted = false;
127 QObject::connect(surface, &QObject::destroyed, [&surfaceDeleted](){ surfaceDeleted = true; });
128
129 qintptr view1 = (qintptr)1;
130 qintptr view2 = (qintptr)2;
131
132 surface->registerView(view1);
133 surface->registerView(view2);
134 surface->setLive(false);
135 EXPECT_FALSE(surfaceDeleted);
136
137 surface->unregisterView(view1);
138 surface->unregisterView(view2);
139
140 QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
141 EXPECT_TRUE(surfaceDeleted);
142}
143
144
145TEST_F(MirSurfaceTest, DISABLED_DoNotDeleteMirSurfaceOnLastLiveUnregisterView)
146{
147 int argc = 0;
148 char* argv[0];
149 QCoreApplication qtApp(argc, argv); // app for deleteLater event
150
151 miral::Window mockWindow(stubSession, stubSurface);
152 ms::SurfaceCreationParameters spec;
153 miral::WindowInfo mockWindowInfo(mockWindow, spec);
154
155 auto surface = new MirSurface(mockWindowInfo, nullptr); // lives on the heap, as it may delete itself
156
157 bool surfaceDeleted = false;
158 QObject::connect(surface, &QObject::destroyed, [&surfaceDeleted](){ surfaceDeleted = true; });
159
160 qintptr view1 = (qintptr)1;
161 qintptr view2 = (qintptr)2;
162
163 surface->registerView(view1);
164 surface->registerView(view2);
165
166 surface->unregisterView(view1);
167 surface->unregisterView(view2);
168
169 QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
170 EXPECT_FALSE(surfaceDeleted);
171}
172
173/*113/*
174 * Test that MirSurface.visible is recalculated after the client swaps the first frame.114 * Test that MirSurface.visible is recalculated after the client swaps the first frame.
175 * A surface is not considered visible unless it has a non-hidden & non-minimized state, and115 * A surface is not considered visible unless it has a non-hidden & non-minimized state, and

Subscribers

People subscribed via source and target branches