Merge lp:~aacid/qtmir/make_sure_surface_not_null into lp:qtmir
- make_sure_surface_not_null
- Merge into trunk
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 |
Related bugs: |
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, onWindowFocusCh
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
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:609
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
- 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 isBeingDisplaye
dChanged 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, onWindowFocusCh
anged, 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
1 | === modified file 'src/modules/Unity/Application/CMakeLists.txt' | |||
2 | --- src/modules/Unity/Application/CMakeLists.txt 2017-02-08 12:19:14 +0000 | |||
3 | +++ src/modules/Unity/Application/CMakeLists.txt 2017-03-10 12:23:14 +0000 | |||
4 | @@ -74,8 +74,6 @@ | |||
5 | 74 | # Frig for files that still rely on mirserver-dev | 74 | # Frig for files that still rely on mirserver-dev |
6 | 75 | string(REPLACE ";" " -I" QTMIR_ADD_MIRSERVER "-I ${MIRSERVER_INCLUDE_DIRS}") | 75 | string(REPLACE ";" " -I" QTMIR_ADD_MIRSERVER "-I ${MIRSERVER_INCLUDE_DIRS}") |
7 | 76 | set_source_files_properties(mirsurface.cpp PROPERTIES COMPILE_FLAGS "${CMAKE_CXXFLAGS} ${QTMIR_ADD_MIRSERVER}") | 76 | set_source_files_properties(mirsurface.cpp PROPERTIES COMPILE_FLAGS "${CMAKE_CXXFLAGS} ${QTMIR_ADD_MIRSERVER}") |
8 | 77 | set_source_files_properties(mirbuffersgtexture.cpp PROPERTIES COMPILE_FLAGS "${CMAKE_CXXFLAGS} ${QTMIR_ADD_MIRSERVER}") | ||
9 | 78 | set_source_files_properties(surfacemanager.cpp PROPERTIES COMPILE_FLAGS "${CMAKE_CXXFLAGS} ${QTMIR_ADD_MIRSERVER}") | ||
10 | 79 | 77 | ||
11 | 80 | target_link_libraries( | 78 | target_link_libraries( |
12 | 81 | unityapplicationplugin | 79 | unityapplicationplugin |
13 | 82 | 80 | ||
14 | === modified file 'src/modules/Unity/Application/mirbuffersgtexture.cpp' | |||
15 | --- src/modules/Unity/Application/mirbuffersgtexture.cpp 2015-12-14 09:05:06 +0000 | |||
16 | +++ src/modules/Unity/Application/mirbuffersgtexture.cpp 2017-03-10 12:23:14 +0000 | |||
17 | @@ -17,12 +17,9 @@ | |||
18 | 17 | #include "mirbuffersgtexture.h" | 17 | #include "mirbuffersgtexture.h" |
19 | 18 | 18 | ||
20 | 19 | // Mir | 19 | // Mir |
21 | 20 | #include <mir/graphics/buffer.h> | ||
22 | 21 | #include <mir/geometry/size.h> | 20 | #include <mir/geometry/size.h> |
23 | 22 | #include <mir/renderer/gl/texture_source.h> | ||
24 | 23 | 21 | ||
25 | 24 | namespace mg = mir::geometry; | 22 | namespace mg = mir::geometry; |
26 | 25 | namespace mrg = mir::renderer::gl; | ||
27 | 26 | 23 | ||
28 | 27 | MirBufferSGTexture::MirBufferSGTexture() | 24 | MirBufferSGTexture::MirBufferSGTexture() |
29 | 28 | : QSGTexture() | 25 | : QSGTexture() |
30 | @@ -54,14 +51,14 @@ | |||
31 | 54 | void MirBufferSGTexture::setBuffer(const std::shared_ptr<mir::graphics::Buffer>& buffer) | 51 | void MirBufferSGTexture::setBuffer(const std::shared_ptr<mir::graphics::Buffer>& buffer) |
32 | 55 | { | 52 | { |
33 | 56 | m_mirBuffer = buffer; | 53 | m_mirBuffer = buffer; |
35 | 57 | mg::Size size = buffer->size(); | 54 | mg::Size size = m_mirBuffer.size(); |
36 | 58 | m_height = size.height.as_int(); | 55 | m_height = size.height.as_int(); |
37 | 59 | m_width = size.width.as_int(); | 56 | m_width = size.width.as_int(); |
38 | 60 | } | 57 | } |
39 | 61 | 58 | ||
40 | 62 | bool MirBufferSGTexture::hasBuffer() const | 59 | bool MirBufferSGTexture::hasBuffer() const |
41 | 63 | { | 60 | { |
43 | 64 | return !!m_mirBuffer; | 61 | return m_mirBuffer.hasBuffer(); |
44 | 65 | } | 62 | } |
45 | 66 | 63 | ||
46 | 67 | int MirBufferSGTexture::textureId() const | 64 | int MirBufferSGTexture::textureId() const |
47 | @@ -76,12 +73,7 @@ | |||
48 | 76 | 73 | ||
49 | 77 | bool MirBufferSGTexture::hasAlphaChannel() const | 74 | bool MirBufferSGTexture::hasAlphaChannel() const |
50 | 78 | { | 75 | { |
57 | 79 | if (hasBuffer()) { | 76 | return m_mirBuffer.hasAlphaChannel(); |
52 | 80 | return m_mirBuffer->pixel_format() == mir_pixel_format_abgr_8888 | ||
53 | 81 | || m_mirBuffer->pixel_format() == mir_pixel_format_argb_8888; | ||
54 | 82 | } else { | ||
55 | 83 | return false; | ||
56 | 84 | } | ||
58 | 85 | } | 77 | } |
59 | 86 | 78 | ||
60 | 87 | void MirBufferSGTexture::bind() | 79 | void MirBufferSGTexture::bind() |
61 | @@ -90,10 +82,5 @@ | |||
62 | 90 | glBindTexture(GL_TEXTURE_2D, m_textureId); | 82 | glBindTexture(GL_TEXTURE_2D, m_textureId); |
63 | 91 | updateBindOptions(true/* force */); | 83 | updateBindOptions(true/* force */); |
64 | 92 | 84 | ||
71 | 93 | auto const texture_source = | 85 | m_mirBuffer.glBindToTexture(); |
66 | 94 | dynamic_cast<mrg::TextureSource*>(m_mirBuffer->native_buffer_base()); | ||
67 | 95 | if (!texture_source) | ||
68 | 96 | throw std::logic_error("Buffer does not support GL rendering"); | ||
69 | 97 | |||
70 | 98 | texture_source->gl_bind_to_texture(); | ||
72 | 99 | } | 86 | } |
73 | 100 | 87 | ||
74 | === modified file 'src/modules/Unity/Application/mirbuffersgtexture.h' | |||
75 | --- src/modules/Unity/Application/mirbuffersgtexture.h 2015-10-28 13:45:07 +0000 | |||
76 | +++ src/modules/Unity/Application/mirbuffersgtexture.h 2017-03-10 12:23:14 +0000 | |||
77 | @@ -17,7 +17,7 @@ | |||
78 | 17 | #ifndef MIRBUFFERSGTEXTURE_H | 17 | #ifndef MIRBUFFERSGTEXTURE_H |
79 | 18 | #define MIRBUFFERSGTEXTURE_H | 18 | #define MIRBUFFERSGTEXTURE_H |
80 | 19 | 19 | ||
82 | 20 | #include <memory> | 20 | #include "mirbuffer.h" |
83 | 21 | 21 | ||
84 | 22 | #include <QSGTexture> | 22 | #include <QSGTexture> |
85 | 23 | 23 | ||
86 | @@ -44,7 +44,7 @@ | |||
87 | 44 | void bind() override; | 44 | void bind() override; |
88 | 45 | 45 | ||
89 | 46 | private: | 46 | private: |
91 | 47 | std::shared_ptr<mir::graphics::Buffer> m_mirBuffer; | 47 | qtmir::MirBuffer m_mirBuffer; |
92 | 48 | int m_width; | 48 | int m_width; |
93 | 49 | int m_height; | 49 | int m_height; |
94 | 50 | GLuint m_textureId; | 50 | GLuint m_textureId; |
95 | 51 | 51 | ||
96 | === modified file 'src/modules/Unity/Application/mirsurface.cpp' | |||
97 | --- src/modules/Unity/Application/mirsurface.cpp 2017-02-09 11:01:37 +0000 | |||
98 | +++ src/modules/Unity/Application/mirsurface.cpp 2017-03-10 12:23:14 +0000 | |||
99 | @@ -169,7 +169,6 @@ | |||
100 | 169 | connect(m_surfaceObserver.get(), &SurfaceObserver::confinesMousePointerChanged, this, &MirSurface::confinesMousePointerChanged); | 169 | connect(m_surfaceObserver.get(), &SurfaceObserver::confinesMousePointerChanged, this, &MirSurface::confinesMousePointerChanged); |
101 | 170 | m_surfaceObserver->setListener(this); | 170 | m_surfaceObserver->setListener(this); |
102 | 171 | 171 | ||
103 | 172 | //connect(session, &QObject::destroyed, this, &MirSurface::onSessionDestroyed); // TODO try using Shared pointer for lifecycle | ||
104 | 173 | connect(session, &SessionInterface::stateChanged, this, [this]() { | 172 | connect(session, &SessionInterface::stateChanged, this, [this]() { |
105 | 174 | if (clientIsRunning() && m_pendingResize.isValid()) { | 173 | if (clientIsRunning() && m_pendingResize.isValid()) { |
106 | 175 | resize(m_pendingResize.width(), m_pendingResize.height()); | 174 | resize(m_pendingResize.width(), m_pendingResize.height()); |
107 | @@ -585,9 +584,6 @@ | |||
108 | 585 | DEBUG_MSG << "(" << value << ")"; | 584 | DEBUG_MSG << "(" << value << ")"; |
109 | 586 | m_live = value; | 585 | m_live = value; |
110 | 587 | Q_EMIT liveChanged(value); | 586 | Q_EMIT liveChanged(value); |
111 | 588 | if (m_views.isEmpty() && !m_live) { | ||
112 | 589 | deleteLater(); | ||
113 | 590 | } | ||
114 | 591 | } | 587 | } |
115 | 592 | } | 588 | } |
116 | 593 | 589 | ||
117 | @@ -712,9 +708,6 @@ | |||
118 | 712 | DEBUG_MSG << "(" << viewId << ")" << " after=" << m_views.count() << " live=" << m_live; | 708 | DEBUG_MSG << "(" << viewId << ")" << " after=" << m_views.count() << " live=" << m_live; |
119 | 713 | if (m_views.count() == 0) { | 709 | if (m_views.count() == 0) { |
120 | 714 | Q_EMIT isBeingDisplayedChanged(); | 710 | Q_EMIT isBeingDisplayedChanged(); |
121 | 715 | if (m_session.isNull() || !m_live) { | ||
122 | 716 | deleteLater(); | ||
123 | 717 | } | ||
124 | 718 | } | 711 | } |
125 | 719 | updateExposure(); | 712 | updateExposure(); |
126 | 720 | setViewActiveFocus(viewId, false); | 713 | setViewActiveFocus(viewId, false); |
127 | @@ -759,13 +752,6 @@ | |||
128 | 759 | return m_currentFrameNumber; | 752 | return m_currentFrameNumber; |
129 | 760 | } | 753 | } |
130 | 761 | 754 | ||
131 | 762 | void MirSurface::onSessionDestroyed() | ||
132 | 763 | { | ||
133 | 764 | if (m_views.isEmpty()) { | ||
134 | 765 | deleteLater(); | ||
135 | 766 | } | ||
136 | 767 | } | ||
137 | 768 | |||
138 | 769 | void MirSurface::emitSizeChanged() | 755 | void MirSurface::emitSizeChanged() |
139 | 770 | { | 756 | { |
140 | 771 | Q_EMIT sizeChanged(m_size); | 757 | Q_EMIT sizeChanged(m_size); |
141 | 772 | 758 | ||
142 | === modified file 'src/modules/Unity/Application/mirsurface.h' | |||
143 | --- src/modules/Unity/Application/mirsurface.h 2017-02-02 09:17:48 +0000 | |||
144 | +++ src/modules/Unity/Application/mirsurface.h 2017-03-10 12:23:14 +0000 | |||
145 | @@ -188,7 +188,6 @@ | |||
146 | 188 | void dropPendingBuffer(); | 188 | void dropPendingBuffer(); |
147 | 189 | void onAttributeChanged(const MirWindowAttrib, const int); | 189 | void onAttributeChanged(const MirWindowAttrib, const int); |
148 | 190 | void onFramesPostedObserved(); | 190 | void onFramesPostedObserved(); |
149 | 191 | void onSessionDestroyed(); | ||
150 | 192 | void emitSizeChanged(); | 191 | void emitSizeChanged(); |
151 | 193 | void setCursor(const QCursor &cursor); | 192 | void setCursor(const QCursor &cursor); |
152 | 194 | void onCloseTimedOut(); | 193 | void onCloseTimedOut(); |
153 | 195 | 194 | ||
154 | === modified file 'src/modules/Unity/Application/sessionmanager.cpp' | |||
155 | --- src/modules/Unity/Application/sessionmanager.cpp 2016-11-03 20:17:46 +0000 | |||
156 | +++ src/modules/Unity/Application/sessionmanager.cpp 2017-03-10 12:23:14 +0000 | |||
157 | @@ -90,6 +90,10 @@ | |||
158 | 90 | setObjectName(QStringLiteral("qtmir::SessionManager")); | 90 | setObjectName(QStringLiteral("qtmir::SessionManager")); |
159 | 91 | } | 91 | } |
160 | 92 | 92 | ||
161 | 93 | SessionManager::SessionManager() // for test use only | ||
162 | 94 | : m_applicationManager(nullptr) | ||
163 | 95 | {} | ||
164 | 96 | |||
165 | 93 | SessionManager::~SessionManager() | 97 | SessionManager::~SessionManager() |
166 | 94 | { | 98 | { |
167 | 95 | qCDebug(QTMIR_SESSIONS) << "SessionManager::~SessionManager - this=" << this; | 99 | qCDebug(QTMIR_SESSIONS) << "SessionManager::~SessionManager - this=" << this; |
168 | 96 | 100 | ||
169 | === modified file 'src/modules/Unity/Application/sessionmanager.h' | |||
170 | --- src/modules/Unity/Application/sessionmanager.h 2016-11-03 20:17:46 +0000 | |||
171 | +++ src/modules/Unity/Application/sessionmanager.h 2017-03-10 12:23:14 +0000 | |||
172 | @@ -56,11 +56,11 @@ | |||
173 | 56 | ApplicationManager* applicationManager, | 56 | ApplicationManager* applicationManager, |
174 | 57 | QObject *parent = 0 | 57 | QObject *parent = 0 |
175 | 58 | ); | 58 | ); |
177 | 59 | ~SessionManager(); | 59 | virtual ~SessionManager(); |
178 | 60 | 60 | ||
179 | 61 | static SessionManager* singleton(); | 61 | static SessionManager* singleton(); |
180 | 62 | 62 | ||
182 | 63 | SessionInterface *findSession(const mir::scene::Session* session) const; | 63 | virtual SessionInterface *findSession(const mir::scene::Session* session) const; |
183 | 64 | 64 | ||
184 | 65 | Q_SIGNALS: | 65 | Q_SIGNALS: |
185 | 66 | void sessionStarting(SessionInterface* session); | 66 | void sessionStarting(SessionInterface* session); |
186 | @@ -76,6 +76,7 @@ | |||
187 | 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> &); |
188 | 77 | 77 | ||
189 | 78 | protected: | 78 | protected: |
190 | 79 | SessionManager(); // for test purposes only | ||
191 | 79 | 80 | ||
192 | 80 | private: | 81 | private: |
193 | 81 | const std::shared_ptr<PromptSessionManager> m_promptSessionManager; | 82 | const std::shared_ptr<PromptSessionManager> m_promptSessionManager; |
194 | 82 | 83 | ||
195 | === modified file 'src/modules/Unity/Application/surfacemanager.cpp' | |||
196 | --- src/modules/Unity/Application/surfacemanager.cpp 2017-02-15 13:21:07 +0000 | |||
197 | +++ src/modules/Unity/Application/surfacemanager.cpp 2017-03-10 12:23:14 +0000 | |||
198 | @@ -27,9 +27,6 @@ | |||
199 | 27 | #include <debughelpers.h> | 27 | #include <debughelpers.h> |
200 | 28 | #include <mirqtconversion.h> | 28 | #include <mirqtconversion.h> |
201 | 29 | 29 | ||
202 | 30 | // Mir | ||
203 | 31 | #include <mir/scene/surface.h> | ||
204 | 32 | |||
205 | 33 | // Qt | 30 | // Qt |
206 | 34 | #include <QGuiApplication> | 31 | #include <QGuiApplication> |
207 | 35 | 32 | ||
208 | @@ -41,7 +38,8 @@ | |||
209 | 41 | using namespace qtmir; | 38 | using namespace qtmir; |
210 | 42 | namespace unityapi = unity::shell::application; | 39 | namespace unityapi = unity::shell::application; |
211 | 43 | 40 | ||
213 | 44 | SurfaceManager::SurfaceManager(QObject *) | 41 | |
214 | 42 | SurfaceManager::SurfaceManager() | ||
215 | 45 | { | 43 | { |
216 | 46 | DEBUG_MSG << "()"; | 44 | DEBUG_MSG << "()"; |
217 | 47 | 45 | ||
218 | @@ -59,6 +57,16 @@ | |||
219 | 59 | m_sessionManager = SessionManager::singleton(); | 57 | m_sessionManager = SessionManager::singleton(); |
220 | 60 | } | 58 | } |
221 | 61 | 59 | ||
222 | 60 | SurfaceManager::SurfaceManager(WindowControllerInterface *windowController, | ||
223 | 61 | WindowModelNotifier *windowModel, | ||
224 | 62 | SessionManager *sessionManager) | ||
225 | 63 | : m_windowController(windowController) | ||
226 | 64 | , m_sessionManager(sessionManager) | ||
227 | 65 | { | ||
228 | 66 | DEBUG_MSG << "()"; | ||
229 | 67 | connectToWindowModelNotifier(windowModel); | ||
230 | 68 | } | ||
231 | 69 | |||
232 | 62 | void SurfaceManager::connectToWindowModelNotifier(WindowModelNotifier *notifier) | 70 | void SurfaceManager::connectToWindowModelNotifier(WindowModelNotifier *notifier) |
233 | 63 | { | 71 | { |
234 | 64 | connect(notifier, &WindowModelNotifier::windowAdded, this, &SurfaceManager::onWindowAdded, Qt::QueuedConnection); | 72 | connect(notifier, &WindowModelNotifier::windowAdded, this, &SurfaceManager::onWindowAdded, Qt::QueuedConnection); |
235 | @@ -90,27 +98,32 @@ | |||
236 | 90 | 98 | ||
237 | 91 | void SurfaceManager::onWindowAdded(const NewWindow &window) | 99 | void SurfaceManager::onWindowAdded(const NewWindow &window) |
238 | 92 | { | 100 | { |
239 | 101 | const auto &windowInfo = window.windowInfo; | ||
240 | 93 | { | 102 | { |
246 | 94 | std::shared_ptr<mir::scene::Surface> surface = window.surface; | 103 | DEBUG_MSG << " mir::scene::Surface[type=" << mirSurfaceTypeToStr(windowInfo.type()) |
247 | 95 | DEBUG_MSG << " mir::scene::Surface[type=" << mirSurfaceTypeToStr(surface->type()) | 104 | << ",parent=" << (void*)(std::shared_ptr<mir::scene::Surface>{windowInfo.parent()}.get()) |
248 | 96 | << ",parent=" << (void*)(surface->parent().get()) | 105 | << ",state=" << mirSurfaceStateToStr(windowInfo.state()) |
249 | 97 | << ",state=" << mirSurfaceStateToStr(surface->state()) | 106 | << ",top_left=" << toQPoint(windowInfo.window().top_left()) |
245 | 98 | << ",top_left=" << toQPoint(surface->top_left()) | ||
250 | 99 | << "]"; | 107 | << "]"; |
251 | 100 | } | 108 | } |
252 | 101 | 109 | ||
254 | 102 | auto mirSession = window.windowInfo.window().application(); | 110 | auto mirSession = windowInfo.window().application(); |
255 | 111 | |||
256 | 103 | SessionInterface* session = m_sessionManager->findSession(mirSession.get()); | 112 | SessionInterface* session = m_sessionManager->findSession(mirSession.get()); |
257 | 104 | 113 | ||
265 | 105 | MirSurface *parentSurface; | 114 | const auto parentSurface = find(windowInfo.parent()); |
266 | 106 | { | 115 | const auto surface = new MirSurface(window, m_windowController, session, parentSurface); |
260 | 107 | std::shared_ptr<mir::scene::Surface> surface = window.windowInfo.window(); | ||
261 | 108 | parentSurface = find(surface->parent()); | ||
262 | 109 | } | ||
263 | 110 | |||
264 | 111 | auto surface = new MirSurface(window, m_windowController, session, parentSurface); | ||
267 | 112 | rememberMirSurface(surface); | 116 | rememberMirSurface(surface); |
268 | 113 | 117 | ||
269 | 118 | connect(surface, &MirSurface::isBeingDisplayedChanged, this, [this, surface]() { | ||
270 | 119 | if ((!surface->live() || !surface->session()) | ||
271 | 120 | && !surface->isBeingDisplayed()) { | ||
272 | 121 | forgetMirSurface(static_cast<MirSurface*>(surface)->window()); | ||
273 | 122 | surface->deleteLater(); // don't delete immediately, slot may be directly connected | ||
274 | 123 | tracepoint(qtmir, surfaceDestroyed); | ||
275 | 124 | } | ||
276 | 125 | }); | ||
277 | 126 | |||
278 | 114 | if (parentSurface) { | 127 | if (parentSurface) { |
279 | 115 | static_cast<MirSurfaceListModel*>(parentSurface->childSurfaceList())->prependSurface(surface); | 128 | static_cast<MirSurfaceListModel*>(parentSurface->childSurfaceList())->prependSurface(surface); |
280 | 116 | } | 129 | } |
281 | @@ -126,8 +139,12 @@ | |||
282 | 126 | { | 139 | { |
283 | 127 | MirSurface *surface = find(windowInfo); | 140 | MirSurface *surface = find(windowInfo); |
284 | 128 | forgetMirSurface(windowInfo.window()); | 141 | forgetMirSurface(windowInfo.window()); |
287 | 129 | surface->setLive(false); | 142 | if (surface && surface->isBeingDisplayed()) { |
288 | 130 | tracepoint(qtmir, surfaceDestroyed); | 143 | surface->setLive(false); |
289 | 144 | } else { | ||
290 | 145 | delete surface; | ||
291 | 146 | tracepoint(qtmir, surfaceDestroyed); | ||
292 | 147 | } | ||
293 | 131 | } | 148 | } |
294 | 132 | 149 | ||
295 | 133 | MirSurface *SurfaceManager::find(const miral::WindowInfo &needle) const | 150 | MirSurface *SurfaceManager::find(const miral::WindowInfo &needle) const |
296 | @@ -145,16 +162,6 @@ | |||
297 | 145 | return nullptr; | 162 | return nullptr; |
298 | 146 | } | 163 | } |
299 | 147 | 164 | ||
300 | 148 | MirSurface *SurfaceManager::find(const std::shared_ptr<mir::scene::Surface> &needle) const | ||
301 | 149 | { | ||
302 | 150 | Q_FOREACH(const auto surface, m_allSurfaces) { | ||
303 | 151 | if (surface->window() == needle) { | ||
304 | 152 | return surface; | ||
305 | 153 | } | ||
306 | 154 | } | ||
307 | 155 | return nullptr; | ||
308 | 156 | } | ||
309 | 157 | |||
310 | 158 | void SurfaceManager::onWindowReady(const miral::WindowInfo &windowInfo) | 165 | void SurfaceManager::onWindowReady(const miral::WindowInfo &windowInfo) |
311 | 159 | { | 166 | { |
312 | 160 | if (auto mirSurface = find(windowInfo)) { | 167 | if (auto mirSurface = find(windowInfo)) { |
313 | 161 | 168 | ||
314 | === modified file 'src/modules/Unity/Application/surfacemanager.h' | |||
315 | --- src/modules/Unity/Application/surfacemanager.h 2017-02-02 09:17:48 +0000 | |||
316 | +++ src/modules/Unity/Application/surfacemanager.h 2017-03-10 12:23:14 +0000 | |||
317 | @@ -39,12 +39,19 @@ | |||
318 | 39 | Q_OBJECT | 39 | Q_OBJECT |
319 | 40 | 40 | ||
320 | 41 | public: | 41 | public: |
322 | 42 | explicit SurfaceManager(QObject *parent = 0); | 42 | explicit SurfaceManager(); |
323 | 43 | virtual ~SurfaceManager() {} | 43 | virtual ~SurfaceManager() {} |
324 | 44 | 44 | ||
325 | 45 | void raise(unity::shell::application::MirSurfaceInterface *surface) override; | 45 | void raise(unity::shell::application::MirSurfaceInterface *surface) override; |
326 | 46 | void activate(unity::shell::application::MirSurfaceInterface *surface) override; | 46 | void activate(unity::shell::application::MirSurfaceInterface *surface) override; |
327 | 47 | 47 | ||
328 | 48 | protected: | ||
329 | 49 | // for testing purposes | ||
330 | 50 | SurfaceManager(WindowControllerInterface *windowController, | ||
331 | 51 | WindowModelNotifier *windowModel, | ||
332 | 52 | SessionManager *sessionManager); | ||
333 | 53 | MirSurface* find(const miral::WindowInfo &needle) const; | ||
334 | 54 | |||
335 | 48 | private Q_SLOTS: | 55 | private Q_SLOTS: |
336 | 49 | void onWindowAdded(const qtmir::NewWindow &windowInfo); | 56 | void onWindowAdded(const qtmir::NewWindow &windowInfo); |
337 | 50 | void onWindowRemoved(const miral::WindowInfo &windowInfo); | 57 | void onWindowRemoved(const miral::WindowInfo &windowInfo); |
338 | @@ -59,9 +66,7 @@ | |||
339 | 59 | void connectToWindowModelNotifier(WindowModelNotifier *notifier); | 66 | void connectToWindowModelNotifier(WindowModelNotifier *notifier); |
340 | 60 | void rememberMirSurface(MirSurface *surface); | 67 | void rememberMirSurface(MirSurface *surface); |
341 | 61 | void forgetMirSurface(const miral::Window &window); | 68 | void forgetMirSurface(const miral::Window &window); |
342 | 62 | MirSurface* find(const miral::WindowInfo &needle) const; | ||
343 | 63 | MirSurface* find(const miral::Window &needle) const; | 69 | MirSurface* find(const miral::Window &needle) const; |
344 | 64 | MirSurface* find(const std::shared_ptr<mir::scene::Surface> &needle) const; | ||
345 | 65 | 70 | ||
346 | 66 | QVector<MirSurface*> m_allSurfaces; | 71 | QVector<MirSurface*> m_allSurfaces; |
347 | 67 | 72 | ||
348 | 68 | 73 | ||
349 | === modified file 'src/platforms/mirserver/CMakeLists.txt' | |||
350 | --- src/platforms/mirserver/CMakeLists.txt 2017-02-15 13:21:50 +0000 | |||
351 | +++ src/platforms/mirserver/CMakeLists.txt 2017-03-10 12:23:14 +0000 | |||
352 | @@ -88,6 +88,7 @@ | |||
353 | 88 | setqtcompositor.cpp setqtcompositor.h | 88 | setqtcompositor.cpp setqtcompositor.h |
354 | 89 | eventdispatch.cpp eventdispatch.h | 89 | eventdispatch.cpp eventdispatch.h |
355 | 90 | promptsessionmanager.cpp promptsessionmanager.h promptsession.h | 90 | promptsessionmanager.cpp promptsessionmanager.h promptsession.h |
356 | 91 | mirbuffer.cpp mirbuffer.h | ||
357 | 91 | ) | 92 | ) |
358 | 92 | 93 | ||
359 | 93 | # These files get entangled by automoc so they need to go together. And some depend on mirserver-dev | 94 | # These files get entangled by automoc so they need to go together. And some depend on mirserver-dev |
360 | 94 | 95 | ||
361 | === added file 'src/platforms/mirserver/mirbuffer.cpp' | |||
362 | --- src/platforms/mirserver/mirbuffer.cpp 1970-01-01 00:00:00 +0000 | |||
363 | +++ src/platforms/mirserver/mirbuffer.cpp 2017-03-10 12:23:14 +0000 | |||
364 | @@ -0,0 +1,70 @@ | |||
365 | 1 | /* | ||
366 | 2 | * Copyright © 2017 Canonical Ltd. | ||
367 | 3 | * | ||
368 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
369 | 5 | * under the terms of the GNU General Public License version 3, | ||
370 | 6 | * as published by the Free Software Foundation. | ||
371 | 7 | * | ||
372 | 8 | * This program is distributed in the hope that it will be useful, | ||
373 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
374 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
375 | 11 | * GNU General Public License for more details. | ||
376 | 12 | * | ||
377 | 13 | * You should have received a copy of the GNU General Public License | ||
378 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
379 | 15 | */ | ||
380 | 16 | |||
381 | 17 | #include "mirbuffer.h" | ||
382 | 18 | |||
383 | 19 | #include <mir/graphics/buffer.h> | ||
384 | 20 | #include <mir/renderer/gl/texture_source.h> | ||
385 | 21 | |||
386 | 22 | #include <stdexcept> | ||
387 | 23 | |||
388 | 24 | qtmir::MirBuffer::MirBuffer() = default; | ||
389 | 25 | qtmir::MirBuffer::~MirBuffer() = default; | ||
390 | 26 | qtmir::MirBuffer::MirBuffer(std::shared_ptr<mir::graphics::Buffer> const &buffer) : | ||
391 | 27 | m_mirBuffer(buffer) | ||
392 | 28 | { | ||
393 | 29 | } | ||
394 | 30 | |||
395 | 31 | qtmir::MirBuffer& qtmir::MirBuffer::operator=(std::shared_ptr<mir::graphics::Buffer> const &buffer) | ||
396 | 32 | { | ||
397 | 33 | m_mirBuffer = buffer; | ||
398 | 34 | return *this; | ||
399 | 35 | } | ||
400 | 36 | |||
401 | 37 | bool qtmir::MirBuffer::hasBuffer() const | ||
402 | 38 | { | ||
403 | 39 | return !!m_mirBuffer; | ||
404 | 40 | } | ||
405 | 41 | |||
406 | 42 | bool qtmir::MirBuffer::hasAlphaChannel() const | ||
407 | 43 | { | ||
408 | 44 | return hasBuffer() && | ||
409 | 45 | (m_mirBuffer->pixel_format() == mir_pixel_format_abgr_8888 | ||
410 | 46 | || m_mirBuffer->pixel_format() == mir_pixel_format_argb_8888); | ||
411 | 47 | } | ||
412 | 48 | |||
413 | 49 | mir::geometry::Size qtmir::MirBuffer::size() const | ||
414 | 50 | { | ||
415 | 51 | return m_mirBuffer->size(); | ||
416 | 52 | } | ||
417 | 53 | |||
418 | 54 | void qtmir::MirBuffer::reset() | ||
419 | 55 | { | ||
420 | 56 | m_mirBuffer.reset(); | ||
421 | 57 | } | ||
422 | 58 | |||
423 | 59 | void qtmir::MirBuffer::glBindToTexture() | ||
424 | 60 | { | ||
425 | 61 | namespace mrg = mir::renderer::gl; | ||
426 | 62 | |||
427 | 63 | auto const texture_source = | ||
428 | 64 | dynamic_cast<mrg::TextureSource*>(m_mirBuffer->native_buffer_base()); | ||
429 | 65 | if (!texture_source) | ||
430 | 66 | throw std::logic_error("Buffer does not support GL rendering"); | ||
431 | 67 | |||
432 | 68 | texture_source->gl_bind_to_texture(); | ||
433 | 69 | } | ||
434 | 70 | |||
435 | 0 | 71 | ||
436 | === added file 'src/platforms/mirserver/mirbuffer.h' | |||
437 | --- src/platforms/mirserver/mirbuffer.h 1970-01-01 00:00:00 +0000 | |||
438 | +++ src/platforms/mirserver/mirbuffer.h 2017-03-10 12:23:14 +0000 | |||
439 | @@ -0,0 +1,48 @@ | |||
440 | 1 | /* | ||
441 | 2 | * Copyright © 2017 Canonical Ltd. | ||
442 | 3 | * | ||
443 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
444 | 5 | * under the terms of the GNU General Public License version 3, | ||
445 | 6 | * as published by the Free Software Foundation. | ||
446 | 7 | * | ||
447 | 8 | * This program is distributed in the hope that it will be useful, | ||
448 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
449 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
450 | 11 | * GNU General Public License for more details. | ||
451 | 12 | * | ||
452 | 13 | * You should have received a copy of the GNU General Public License | ||
453 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
454 | 15 | */ | ||
455 | 16 | |||
456 | 17 | #ifndef QTMIR_MIR_BUFFER_H | ||
457 | 18 | #define QTMIR_MIR_BUFFER_H | ||
458 | 19 | |||
459 | 20 | #include <mir/geometry/size.h> | ||
460 | 21 | |||
461 | 22 | #include <memory> | ||
462 | 23 | |||
463 | 24 | namespace mir { namespace graphics { class Buffer; }} | ||
464 | 25 | |||
465 | 26 | namespace qtmir | ||
466 | 27 | { | ||
467 | 28 | class MirBuffer | ||
468 | 29 | { | ||
469 | 30 | public: | ||
470 | 31 | MirBuffer(); | ||
471 | 32 | ~MirBuffer(); | ||
472 | 33 | explicit MirBuffer(std::shared_ptr<mir::graphics::Buffer> const &buffer); | ||
473 | 34 | MirBuffer& operator=(std::shared_ptr<mir::graphics::Buffer> const &buffer); | ||
474 | 35 | |||
475 | 36 | bool hasBuffer() const; | ||
476 | 37 | bool hasAlphaChannel() const; | ||
477 | 38 | mir::geometry::Size size() const; | ||
478 | 39 | |||
479 | 40 | void reset(); | ||
480 | 41 | void glBindToTexture(); | ||
481 | 42 | |||
482 | 43 | private: | ||
483 | 44 | std::shared_ptr<mir::graphics::Buffer> m_mirBuffer; | ||
484 | 45 | }; | ||
485 | 46 | } | ||
486 | 47 | |||
487 | 48 | #endif //QTMIR_MIR_BUFFER_H | ||
488 | 0 | 49 | ||
489 | === modified file 'tests/framework/CMakeLists.txt' | |||
490 | --- tests/framework/CMakeLists.txt 2016-12-02 16:22:45 +0000 | |||
491 | +++ tests/framework/CMakeLists.txt 2017-03-10 12:23:14 +0000 | |||
492 | @@ -46,6 +46,8 @@ | |||
493 | 46 | target_link_libraries( | 46 | target_link_libraries( |
494 | 47 | qtmir-test-framework-static | 47 | qtmir-test-framework-static |
495 | 48 | 48 | ||
496 | 49 | unityapplicationplugin | ||
497 | 50 | |||
498 | 49 | ${GTEST_BOTH_LIBRARIES} | 51 | ${GTEST_BOTH_LIBRARIES} |
499 | 50 | ${GMOCK_LIBRARIES} | 52 | ${GMOCK_LIBRARIES} |
500 | 51 | ) | 53 | ) |
501 | 52 | 54 | ||
502 | === added file 'tests/framework/mock_session_manager.h' | |||
503 | --- tests/framework/mock_session_manager.h 1970-01-01 00:00:00 +0000 | |||
504 | +++ tests/framework/mock_session_manager.h 2017-03-10 12:23:14 +0000 | |||
505 | @@ -0,0 +1,33 @@ | |||
506 | 1 | /* | ||
507 | 2 | * Copyright (C) 2017 Canonical, Ltd. | ||
508 | 3 | * | ||
509 | 4 | * This program is free software: you can redistribute it and/or modify it under | ||
510 | 5 | * the terms of the GNU Lesser General Public License version 3, as published by | ||
511 | 6 | * the Free Software Foundation. | ||
512 | 7 | * | ||
513 | 8 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
514 | 9 | * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, | ||
515 | 10 | * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
516 | 11 | * Lesser General Public License for more details. | ||
517 | 12 | * | ||
518 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
519 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
520 | 15 | */ | ||
521 | 16 | |||
522 | 17 | #ifndef MOCK_SESSION_MANAGER_H | ||
523 | 18 | #define MOCK_SESSION_MANAGER_H | ||
524 | 19 | |||
525 | 20 | #include <Unity/Application/sessionmanager.h> | ||
526 | 21 | |||
527 | 22 | #include <gmock/gmock.h> | ||
528 | 23 | |||
529 | 24 | namespace qtmir { | ||
530 | 25 | |||
531 | 26 | struct MockSessionManager : public qtmir::SessionManager | ||
532 | 27 | { | ||
533 | 28 | MOCK_CONST_METHOD1(findSession, qtmir::SessionInterface*(const mir::scene::Session*)); | ||
534 | 29 | }; | ||
535 | 30 | |||
536 | 31 | } // namespace qtmir | ||
537 | 32 | |||
538 | 33 | #endif // MOCK_SESSION_MANAGER_H | ||
539 | 0 | 34 | ||
540 | === added file 'tests/framework/mock_window_controller.h' | |||
541 | --- tests/framework/mock_window_controller.h 1970-01-01 00:00:00 +0000 | |||
542 | +++ tests/framework/mock_window_controller.h 2017-03-10 12:23:14 +0000 | |||
543 | @@ -0,0 +1,43 @@ | |||
544 | 1 | /* | ||
545 | 2 | * Copyright (C) 2017 Canonical, Ltd. | ||
546 | 3 | * | ||
547 | 4 | * This program is free software: you can redistribute it and/or modify it under | ||
548 | 5 | * the terms of the GNU Lesser General Public License version 3, as published by | ||
549 | 6 | * the Free Software Foundation. | ||
550 | 7 | * | ||
551 | 8 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
552 | 9 | * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, | ||
553 | 10 | * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
554 | 11 | * Lesser General Public License for more details. | ||
555 | 12 | * | ||
556 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
557 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
558 | 15 | */ | ||
559 | 16 | |||
560 | 17 | #ifndef MOCK_WINDOW_CONTROLLER_H | ||
561 | 18 | #define MOCK_WINDOW_CONTROLLER_H | ||
562 | 19 | |||
563 | 20 | #include "windowcontrollerinterface.h" | ||
564 | 21 | |||
565 | 22 | #include <gmock/gmock.h> | ||
566 | 23 | |||
567 | 24 | class MockWindowController : public qtmir::WindowControllerInterface | ||
568 | 25 | { | ||
569 | 26 | public: | ||
570 | 27 | MOCK_METHOD1(activate, void(const miral::Window &)); | ||
571 | 28 | MOCK_METHOD1(raise, void(const miral::Window &)); | ||
572 | 29 | |||
573 | 30 | MOCK_METHOD2(resize, void(const miral::Window &, const QSize &)); | ||
574 | 31 | MOCK_METHOD2(move, void(const miral::Window &, const QPoint &)); | ||
575 | 32 | |||
576 | 33 | MOCK_METHOD1(requestClose, void(const miral::Window &)); | ||
577 | 34 | MOCK_METHOD1(forceClose, void(const miral::Window &)); | ||
578 | 35 | |||
579 | 36 | MOCK_METHOD2(requestState, void(const miral::Window &, const Mir::State)); | ||
580 | 37 | |||
581 | 38 | MOCK_METHOD2(deliverKeyboardEvent, void(const miral::Window &, const MirKeyboardEvent *)); | ||
582 | 39 | MOCK_METHOD2(deliverTouchEvent, void(const miral::Window &, const MirTouchEvent *)); | ||
583 | 40 | MOCK_METHOD2(deliverPointerEvent, void(const miral::Window &, const MirPointerEvent *)); | ||
584 | 41 | }; | ||
585 | 42 | |||
586 | 43 | #endif // MOCK_WINDOW_CONTROLLER_H | ||
587 | 0 | 44 | ||
588 | === modified file 'tests/modules/CMakeLists.txt' | |||
589 | --- tests/modules/CMakeLists.txt 2016-11-03 20:17:46 +0000 | |||
590 | +++ tests/modules/CMakeLists.txt 2017-03-10 12:23:14 +0000 | |||
591 | @@ -1,6 +1,7 @@ | |||
592 | 1 | add_subdirectory(Application) | 1 | add_subdirectory(Application) |
593 | 2 | add_subdirectory(ApplicationManager) | 2 | add_subdirectory(ApplicationManager) |
594 | 3 | add_subdirectory(General) | 3 | add_subdirectory(General) |
595 | 4 | add_subdirectory(SessionManager) | ||
596 | 4 | add_subdirectory(SharedWakelock) | 5 | add_subdirectory(SharedWakelock) |
598 | 5 | add_subdirectory(SessionManager) | 6 | add_subdirectory(SurfaceManager) |
599 | 6 | add_subdirectory(WindowManager) | 7 | add_subdirectory(WindowManager) |
600 | 7 | 8 | ||
601 | === added directory 'tests/modules/SurfaceManager' | |||
602 | === added file 'tests/modules/SurfaceManager/CMakeLists.txt' | |||
603 | --- tests/modules/SurfaceManager/CMakeLists.txt 1970-01-01 00:00:00 +0000 | |||
604 | +++ tests/modules/SurfaceManager/CMakeLists.txt 2017-03-10 12:23:14 +0000 | |||
605 | @@ -0,0 +1,40 @@ | |||
606 | 1 | set( | ||
607 | 2 | SURFACE_MANAGER_TEST_SOURCES | ||
608 | 3 | surface_manager_test.cpp | ||
609 | 4 | ${CMAKE_SOURCE_DIR}/src/common/debughelpers.cpp | ||
610 | 5 | ) | ||
611 | 6 | |||
612 | 7 | include_directories( | ||
613 | 8 | ${CMAKE_SOURCE_DIR}/src/common | ||
614 | 9 | ${CMAKE_SOURCE_DIR}/src/platforms/mirserver | ||
615 | 10 | ${CMAKE_SOURCE_DIR}/src/modules | ||
616 | 11 | ${CMAKE_SOURCE_DIR}/tests/framework | ||
617 | 12 | ) | ||
618 | 13 | |||
619 | 14 | include_directories( | ||
620 | 15 | SYSTEM | ||
621 | 16 | ${APPLICATION_API_INCLUDE_DIRS} | ||
622 | 17 | ${MIRAL_INCLUDE_DIRS} | ||
623 | 18 | ${MIRTEST_INCLUDE_DIRS} | ||
624 | 19 | ) | ||
625 | 20 | |||
626 | 21 | add_executable(surfacemanager_test ${SURFACE_MANAGER_TEST_SOURCES}) | ||
627 | 22 | |||
628 | 23 | add_dependencies(surfacemanager_test qtmir-test-framework-static) | ||
629 | 24 | |||
630 | 25 | target_link_libraries( | ||
631 | 26 | surfacemanager_test | ||
632 | 27 | |||
633 | 28 | unityapplicationplugin | ||
634 | 29 | |||
635 | 30 | Qt5::Test | ||
636 | 31 | |||
637 | 32 | -L${CMAKE_BINARY_DIR}/tests/framework | ||
638 | 33 | qtmir-test-framework-static | ||
639 | 34 | |||
640 | 35 | ${MIRTEST_LDFLAGS} | ||
641 | 36 | ${GTEST_BOTH_LIBRARIES} | ||
642 | 37 | ${GMOCK_LIBRARIES} | ||
643 | 38 | ) | ||
644 | 39 | |||
645 | 40 | add_test(SurfaceManager, surfacemanager_test) | ||
646 | 0 | 41 | ||
647 | === added file 'tests/modules/SurfaceManager/surface_manager_test.cpp' | |||
648 | --- tests/modules/SurfaceManager/surface_manager_test.cpp 1970-01-01 00:00:00 +0000 | |||
649 | +++ tests/modules/SurfaceManager/surface_manager_test.cpp 2017-03-10 12:23:14 +0000 | |||
650 | @@ -0,0 +1,489 @@ | |||
651 | 1 | /* | ||
652 | 2 | * Copyright (C) 2017 Canonical, Ltd. | ||
653 | 3 | * | ||
654 | 4 | * This program is free software: you can redistribute it and/or modify it under | ||
655 | 5 | * the terms of the GNU Lesser General Public License version 3, as published by | ||
656 | 6 | * the Free Software Foundation. | ||
657 | 7 | * | ||
658 | 8 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
659 | 9 | * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, | ||
660 | 10 | * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
661 | 11 | * Lesser General Public License for more details. | ||
662 | 12 | * | ||
663 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
664 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
665 | 15 | */ | ||
666 | 16 | |||
667 | 17 | #include <QLoggingCategory> | ||
668 | 18 | #include <QSignalSpy> | ||
669 | 19 | |||
670 | 20 | // the test subject | ||
671 | 21 | #include <Unity/Application/surfacemanager.h> | ||
672 | 22 | #include <Unity/Application/mirsurface.h> | ||
673 | 23 | |||
674 | 24 | // miral | ||
675 | 25 | #include <miral/window.h> | ||
676 | 26 | #include <miral/window_info.h> | ||
677 | 27 | |||
678 | 28 | // mirtest | ||
679 | 29 | #include <mir/test/doubles/stub_session.h> | ||
680 | 30 | #include <mir/test/doubles/stub_surface.h> | ||
681 | 31 | |||
682 | 32 | // local | ||
683 | 33 | #include "qtmir_test.h" | ||
684 | 34 | #include "fake_session.h" | ||
685 | 35 | #include "mock_session_manager.h" | ||
686 | 36 | #include "mock_window_controller.h" | ||
687 | 37 | |||
688 | 38 | using namespace qtmir; | ||
689 | 39 | using StubSurface = mir::test::doubles::StubSurface; | ||
690 | 40 | using StubSession = mir::test::doubles::StubSession; | ||
691 | 41 | |||
692 | 42 | struct TestableSurfaceManager : public SurfaceManager | ||
693 | 43 | { | ||
694 | 44 | // just exports the test-only protected constructor | ||
695 | 45 | TestableSurfaceManager(WindowControllerInterface *windowController, | ||
696 | 46 | WindowModelNotifier *windowModel, | ||
697 | 47 | SessionManager *sessionManager) | ||
698 | 48 | : SurfaceManager(windowController, windowModel, sessionManager) {} | ||
699 | 49 | |||
700 | 50 | MirSurface* find(const miral::WindowInfo &needle) const | ||
701 | 51 | { | ||
702 | 52 | return SurfaceManager::find(needle); | ||
703 | 53 | } | ||
704 | 54 | }; | ||
705 | 55 | |||
706 | 56 | class SurfaceManagerTests : public ::testing::Test | ||
707 | 57 | { | ||
708 | 58 | public: | ||
709 | 59 | SurfaceManagerTests() | ||
710 | 60 | { | ||
711 | 61 | // We don't want the logging spam cluttering the test results | ||
712 | 62 | QLoggingCategory::setFilterRules(QStringLiteral("qtmir.*=false")); | ||
713 | 63 | |||
714 | 64 | qRegisterMetaType<unity::shell::application::MirSurfaceInterface*>(); | ||
715 | 65 | qRegisterMetaType<QVector<unity::shell::application::MirSurfaceInterface*>>(); | ||
716 | 66 | } | ||
717 | 67 | |||
718 | 68 | testing::NiceMock<MockSessionManager> sessionManager; | ||
719 | 69 | testing::NiceMock<MockWindowController> wmController; | ||
720 | 70 | WindowModelNotifier wmNotifier; | ||
721 | 71 | QScopedPointer<TestableSurfaceManager> surfaceManager; | ||
722 | 72 | QScopedPointer<QCoreApplication> qtApp; // need to spin event loop for queued connections | ||
723 | 73 | |||
724 | 74 | // Needed to create miral::WindowInfo | ||
725 | 75 | const std::shared_ptr<StubSession> stubSession{std::make_shared<StubSession>()}; | ||
726 | 76 | const std::shared_ptr<StubSurface> stubSurface{std::make_shared<StubSurface>()}; | ||
727 | 77 | const miral::Window window{stubSession, stubSurface}; | ||
728 | 78 | const ms::SurfaceCreationParameters spec; | ||
729 | 79 | const miral::WindowInfo windowInfo{window, spec}; | ||
730 | 80 | FakeSession fakeSession; | ||
731 | 81 | |||
732 | 82 | protected: | ||
733 | 83 | void SetUp() override | ||
734 | 84 | { | ||
735 | 85 | int argc = 0; | ||
736 | 86 | char* argv[0]; | ||
737 | 87 | qtApp.reset(new QCoreApplication(argc, argv)); | ||
738 | 88 | |||
739 | 89 | using namespace ::testing; | ||
740 | 90 | ON_CALL(sessionManager,findSession(_)) | ||
741 | 91 | .WillByDefault(Return(&fakeSession)); | ||
742 | 92 | |||
743 | 93 | surfaceManager.reset(new TestableSurfaceManager(&wmController, | ||
744 | 94 | &wmNotifier, &sessionManager)); | ||
745 | 95 | } | ||
746 | 96 | }; | ||
747 | 97 | |||
748 | 98 | /* | ||
749 | 99 | * Test if MirAL notifies that a window was created, SurfaceManager emits the surfaceCreated | ||
750 | 100 | * signal | ||
751 | 101 | */ | ||
752 | 102 | TEST_F(SurfaceManagerTests, miralWindowCreationCausesSignalEmission) | ||
753 | 103 | { | ||
754 | 104 | QSignalSpy newMirSurfaceSpy(surfaceManager.data(), &SurfaceManager::surfaceCreated); | ||
755 | 105 | |||
756 | 106 | // Test | ||
757 | 107 | Q_EMIT wmNotifier.windowAdded(windowInfo); | ||
758 | 108 | qtApp->sendPostedEvents(); | ||
759 | 109 | |||
760 | 110 | // Check result | ||
761 | 111 | EXPECT_EQ(1, newMirSurfaceSpy.count()); | ||
762 | 112 | } | ||
763 | 113 | |||
764 | 114 | |||
765 | 115 | /* | ||
766 | 116 | * Test if MirAL notifies that a window was created, SurfaceManager emits the surfaceCreated | ||
767 | 117 | * signal with a corresponding MirSurface | ||
768 | 118 | */ | ||
769 | 119 | TEST_F(SurfaceManagerTests, miralWindowCreationCausesMirSurfaceCreation) | ||
770 | 120 | { | ||
771 | 121 | QSignalSpy newMirSurfaceSpy(surfaceManager.data(), &SurfaceManager::surfaceCreated); | ||
772 | 122 | |||
773 | 123 | // Test | ||
774 | 124 | Q_EMIT wmNotifier.windowAdded(windowInfo); | ||
775 | 125 | qtApp->sendPostedEvents(); | ||
776 | 126 | |||
777 | 127 | // Check result | ||
778 | 128 | auto mirSurface = qvariant_cast<MirSurface*>(newMirSurfaceSpy.takeFirst().at(0)); | ||
779 | 129 | ASSERT_TRUE(mirSurface); | ||
780 | 130 | EXPECT_EQ(window, mirSurface->window()); | ||
781 | 131 | } | ||
782 | 132 | |||
783 | 133 | /* | ||
784 | 134 | * Test if MirAL notifies that a window was created, SurfaceManager adds the corresponding | ||
785 | 135 | * MirSurface to its internal list | ||
786 | 136 | */ | ||
787 | 137 | TEST_F(SurfaceManagerTests, miralWindowCreationAddsMirSurfaceToItsInternalList) | ||
788 | 138 | { | ||
789 | 139 | // Test | ||
790 | 140 | Q_EMIT wmNotifier.windowAdded(windowInfo); | ||
791 | 141 | qtApp->sendPostedEvents(); | ||
792 | 142 | |||
793 | 143 | // Check result | ||
794 | 144 | auto mirSurface = surfaceManager->find(windowInfo); | ||
795 | 145 | ASSERT_TRUE(mirSurface); | ||
796 | 146 | EXPECT_EQ(window, mirSurface->window()); | ||
797 | 147 | } | ||
798 | 148 | |||
799 | 149 | /* | ||
800 | 150 | * Test SurfaceManager creates a MirSurface with a Session associated | ||
801 | 151 | */ | ||
802 | 152 | TEST_F(SurfaceManagerTests, createdMirSurfaceHasSessionSet) | ||
803 | 153 | { | ||
804 | 154 | // Setup | ||
805 | 155 | using namespace ::testing; | ||
806 | 156 | EXPECT_CALL(sessionManager,findSession(_)) | ||
807 | 157 | .WillOnce(Return(&fakeSession)); | ||
808 | 158 | |||
809 | 159 | // Test | ||
810 | 160 | Q_EMIT wmNotifier.windowAdded(windowInfo); | ||
811 | 161 | qtApp->sendPostedEvents(); | ||
812 | 162 | |||
813 | 163 | // Check result | ||
814 | 164 | auto mirSurface = surfaceManager->find(windowInfo); | ||
815 | 165 | ASSERT_TRUE(mirSurface); | ||
816 | 166 | EXPECT_EQ(&fakeSession, mirSurface->session()); | ||
817 | 167 | } | ||
818 | 168 | |||
819 | 169 | /* | ||
820 | 170 | * Test when MirAL creates a surface with a parent, SurfaceManager correctly associates | ||
821 | 171 | * the parent MirSurface to the MirSurface | ||
822 | 172 | */ | ||
823 | 173 | TEST_F(SurfaceManagerTests, parentedMiralWindowGeneratesMirSurfaceWithCorrectParent) | ||
824 | 174 | { | ||
825 | 175 | // Setup | ||
826 | 176 | miral::Window parentWindow(stubSession, stubSurface); | ||
827 | 177 | miral::Window childWindow(stubSession, stubSurface); | ||
828 | 178 | miral::WindowInfo parentWindowInfo(parentWindow, spec); | ||
829 | 179 | miral::WindowInfo childWindowInfo(childWindow, spec); | ||
830 | 180 | childWindowInfo.parent(parentWindow); | ||
831 | 181 | |||
832 | 182 | // Test | ||
833 | 183 | Q_EMIT wmNotifier.windowAdded(parentWindowInfo); | ||
834 | 184 | Q_EMIT wmNotifier.windowAdded(childWindowInfo); | ||
835 | 185 | qtApp->sendPostedEvents(); | ||
836 | 186 | |||
837 | 187 | // Check result | ||
838 | 188 | auto childMirSurface = surfaceManager->find(childWindowInfo); | ||
839 | 189 | auto parentMirSurface = surfaceManager->find(parentWindowInfo); | ||
840 | 190 | ASSERT_TRUE(childMirSurface); | ||
841 | 191 | ASSERT_TRUE(parentMirSurface); | ||
842 | 192 | |||
843 | 193 | EXPECT_EQ(parentMirSurface, childMirSurface->parentSurface()); | ||
844 | 194 | } | ||
845 | 195 | |||
846 | 196 | /* | ||
847 | 197 | * Test when MirAL creates a surface with a parent, SurfaceManager correctly associates | ||
848 | 198 | * the child MirSurface to the parent MirSurface | ||
849 | 199 | */ | ||
850 | 200 | TEST_F(SurfaceManagerTests, miralWindowWithChildHasMirSurfaceWithCorrectChild) | ||
851 | 201 | { | ||
852 | 202 | // Setup | ||
853 | 203 | miral::Window parentWindow(stubSession, stubSurface); | ||
854 | 204 | miral::Window childWindow(stubSession, stubSurface); | ||
855 | 205 | miral::WindowInfo parentWindowInfo(parentWindow, spec); | ||
856 | 206 | miral::WindowInfo childWindowInfo(childWindow, spec); | ||
857 | 207 | childWindowInfo.parent(parentWindow); | ||
858 | 208 | |||
859 | 209 | // Test | ||
860 | 210 | Q_EMIT wmNotifier.windowAdded(parentWindowInfo); | ||
861 | 211 | Q_EMIT wmNotifier.windowAdded(childWindowInfo); | ||
862 | 212 | qtApp->sendPostedEvents(); | ||
863 | 213 | |||
864 | 214 | // Check result | ||
865 | 215 | auto childMirSurface = surfaceManager->find(childWindowInfo); | ||
866 | 216 | auto parentMirSurface = surfaceManager->find(parentWindowInfo); | ||
867 | 217 | ASSERT_TRUE(childMirSurface); | ||
868 | 218 | ASSERT_TRUE(parentMirSurface); | ||
869 | 219 | |||
870 | 220 | ASSERT_EQ(1, parentMirSurface->childSurfaceList()->count()); | ||
871 | 221 | EXPECT_EQ(childMirSurface, parentMirSurface->childSurfaceList()->first()); | ||
872 | 222 | } | ||
873 | 223 | |||
874 | 224 | /* | ||
875 | 225 | * Test if MirAL notifies that a window is ready, SurfaceManager updates the corresponding | ||
876 | 226 | * MirSurface causing it to emit a ready() signal | ||
877 | 227 | */ | ||
878 | 228 | TEST_F(SurfaceManagerTests, miralWindowReadyUpdatesMirSurfaceState) | ||
879 | 229 | { | ||
880 | 230 | // Setup: add window and get corresponding MirSurface | ||
881 | 231 | Q_EMIT wmNotifier.windowAdded(windowInfo); | ||
882 | 232 | qtApp->sendPostedEvents(); | ||
883 | 233 | auto mirSurface = surfaceManager->find(windowInfo); | ||
884 | 234 | ASSERT_TRUE(mirSurface); | ||
885 | 235 | |||
886 | 236 | QSignalSpy mirSurfaceReadySpy(mirSurface, &MirSurface::ready); | ||
887 | 237 | |||
888 | 238 | // Test | ||
889 | 239 | Q_EMIT wmNotifier.windowReady(windowInfo); | ||
890 | 240 | qtApp->sendPostedEvents(); | ||
891 | 241 | |||
892 | 242 | // Check result | ||
893 | 243 | EXPECT_EQ(1, mirSurfaceReadySpy.count()); | ||
894 | 244 | } | ||
895 | 245 | |||
896 | 246 | /* | ||
897 | 247 | * Test if MirAL notifies that a window is moved, SurfaceManager updates the corresponding | ||
898 | 248 | * MirSurface position | ||
899 | 249 | */ | ||
900 | 250 | TEST_F(SurfaceManagerTests, miralWindowMoveUpdatesMirSurfacePosition) | ||
901 | 251 | { | ||
902 | 252 | QPoint newPosition(222,333); | ||
903 | 253 | |||
904 | 254 | // Setup: add window and get corresponding MirSurface | ||
905 | 255 | Q_EMIT wmNotifier.windowAdded(windowInfo); | ||
906 | 256 | qtApp->sendPostedEvents(); | ||
907 | 257 | auto mirSurface = surfaceManager->find(windowInfo); | ||
908 | 258 | ASSERT_TRUE(mirSurface); | ||
909 | 259 | |||
910 | 260 | QSignalSpy mirSurfacePositionSpy(mirSurface, &MirSurface::positionChanged); | ||
911 | 261 | |||
912 | 262 | // Test | ||
913 | 263 | Q_EMIT wmNotifier.windowMoved(windowInfo, newPosition); | ||
914 | 264 | qtApp->sendPostedEvents(); | ||
915 | 265 | |||
916 | 266 | // Check result | ||
917 | 267 | EXPECT_EQ(1, mirSurfacePositionSpy.count()); | ||
918 | 268 | EXPECT_EQ(mirSurface->position(), newPosition); | ||
919 | 269 | } | ||
920 | 270 | |||
921 | 271 | /* | ||
922 | 272 | * Test if MirAL notifies that a window's focus state changes, SurfaceManager updates the corresponding | ||
923 | 273 | * MirSurface focus state | ||
924 | 274 | */ | ||
925 | 275 | TEST_F(SurfaceManagerTests, miralWindowFocusChangeUpdatesMirSurfaceFocus) | ||
926 | 276 | { | ||
927 | 277 | // Setup: add window and get corresponding MirSurface | ||
928 | 278 | Q_EMIT wmNotifier.windowAdded(windowInfo); | ||
929 | 279 | qtApp->sendPostedEvents(); | ||
930 | 280 | auto mirSurface = surfaceManager->find(windowInfo); | ||
931 | 281 | ASSERT_TRUE(mirSurface); | ||
932 | 282 | ASSERT_FALSE(mirSurface->focused()); // false must be the initial state | ||
933 | 283 | |||
934 | 284 | QSignalSpy mirSurfaceFocusSpy(mirSurface, &MirSurface::focusedChanged); | ||
935 | 285 | |||
936 | 286 | // Test | ||
937 | 287 | Q_EMIT wmNotifier.windowFocusChanged(windowInfo, true); | ||
938 | 288 | qtApp->sendPostedEvents(); | ||
939 | 289 | |||
940 | 290 | // Check result | ||
941 | 291 | EXPECT_EQ(1, mirSurfaceFocusSpy.count()); | ||
942 | 292 | EXPECT_EQ(mirSurface->focused(), true); | ||
943 | 293 | } | ||
944 | 294 | |||
945 | 295 | /* | ||
946 | 296 | * Test if MirAL notifies that a window's state changes, SurfaceManager updates the corresponding | ||
947 | 297 | * MirSurface state (just testing a single state, see no value in testing all possible states here) | ||
948 | 298 | */ | ||
949 | 299 | TEST_F(SurfaceManagerTests, miralWindowStateChangeUpdatesMirSurfaceState) | ||
950 | 300 | { | ||
951 | 301 | auto newState = Mir::FullscreenState; | ||
952 | 302 | |||
953 | 303 | // Setup: add window and get corresponding MirSurface | ||
954 | 304 | Q_EMIT wmNotifier.windowAdded(windowInfo); | ||
955 | 305 | qtApp->sendPostedEvents(); | ||
956 | 306 | auto mirSurface = surfaceManager->find(windowInfo); | ||
957 | 307 | ASSERT_TRUE(mirSurface); | ||
958 | 308 | |||
959 | 309 | QSignalSpy mirSurfaceStateSpy(mirSurface, &MirSurface::stateChanged); | ||
960 | 310 | |||
961 | 311 | // Test | ||
962 | 312 | Q_EMIT wmNotifier.windowStateChanged(windowInfo, newState); | ||
963 | 313 | qtApp->sendPostedEvents(); | ||
964 | 314 | |||
965 | 315 | // Check result | ||
966 | 316 | EXPECT_EQ(1, mirSurfaceStateSpy.count()); | ||
967 | 317 | EXPECT_EQ(mirSurface->state(), newState); | ||
968 | 318 | } | ||
969 | 319 | |||
970 | 320 | /* | ||
971 | 321 | * Test when miral raises a list of surfaces, the raise signal is fired by SurfaceManager with | ||
972 | 322 | * a list of MirSurfaces in the matching order | ||
973 | 323 | */ | ||
974 | 324 | TEST_F(SurfaceManagerTests, miralsRaiseWindowListTransformedToVectorOfMirSurfaces) | ||
975 | 325 | { | ||
976 | 326 | // Setup | ||
977 | 327 | miral::Window window1(stubSession, stubSurface); | ||
978 | 328 | miral::Window window2(stubSession, stubSurface); | ||
979 | 329 | miral::WindowInfo windowInfo1(window1, spec); | ||
980 | 330 | miral::WindowInfo windowInfo2(window2, spec); | ||
981 | 331 | |||
982 | 332 | // Setup: add 2 windows and get their MirSurfaces | ||
983 | 333 | Q_EMIT wmNotifier.windowAdded(windowInfo1); | ||
984 | 334 | Q_EMIT wmNotifier.windowAdded(windowInfo2); | ||
985 | 335 | qtApp->sendPostedEvents(); | ||
986 | 336 | auto mirSurface1 = surfaceManager->find(windowInfo1); | ||
987 | 337 | auto mirSurface2 = surfaceManager->find(windowInfo2); | ||
988 | 338 | ASSERT_TRUE(mirSurface1); | ||
989 | 339 | ASSERT_TRUE(mirSurface2); | ||
990 | 340 | |||
991 | 341 | QSignalSpy mirSurfacesRaisedSpy(surfaceManager.data(), &SurfaceManager::surfacesRaised); | ||
992 | 342 | |||
993 | 343 | // Test | ||
994 | 344 | std::vector<miral::Window> raiseWindowList{window2, window1}; | ||
995 | 345 | Q_EMIT wmNotifier.windowsRaised(raiseWindowList); | ||
996 | 346 | qtApp->sendPostedEvents(); | ||
997 | 347 | |||
998 | 348 | // Check results | ||
999 | 349 | ASSERT_EQ(1, mirSurfacesRaisedSpy.count()); | ||
1000 | 350 | auto raiseMirSurfaceList = qvariant_cast<QVector<unity::shell::application::MirSurfaceInterface*>>( | ||
1001 | 351 | mirSurfacesRaisedSpy.takeFirst().at(0)); // first argument of signal | ||
1002 | 352 | ASSERT_EQ(2, raiseMirSurfaceList.count()); | ||
1003 | 353 | EXPECT_EQ(mirSurface1, raiseMirSurfaceList.at(1)); | ||
1004 | 354 | EXPECT_EQ(mirSurface2, raiseMirSurfaceList.at(0)); | ||
1005 | 355 | } | ||
1006 | 356 | |||
1007 | 357 | /* | ||
1008 | 358 | * Test focus requests fire focusRequested signal of the MirSurface | ||
1009 | 359 | */ | ||
1010 | 360 | TEST_F(SurfaceManagerTests, focusRequestCausesMirSurfaceToFireFocusRequestedSignal) | ||
1011 | 361 | { | ||
1012 | 362 | // Setup: add window and get corresponding MirSurface | ||
1013 | 363 | Q_EMIT wmNotifier.windowAdded(windowInfo); | ||
1014 | 364 | qtApp->sendPostedEvents(); | ||
1015 | 365 | auto mirSurface = surfaceManager->find(windowInfo); | ||
1016 | 366 | ASSERT_TRUE(mirSurface); | ||
1017 | 367 | |||
1018 | 368 | QSignalSpy mirSurfaceFocusRequestedSpy(mirSurface, &MirSurface::focusRequested); | ||
1019 | 369 | |||
1020 | 370 | // Test | ||
1021 | 371 | Q_EMIT wmNotifier.windowRequestedRaise(windowInfo); | ||
1022 | 372 | qtApp->sendPostedEvents(); | ||
1023 | 373 | |||
1024 | 374 | // Check result | ||
1025 | 375 | EXPECT_EQ(1, mirSurfaceFocusRequestedSpy.count()); | ||
1026 | 376 | } | ||
1027 | 377 | |||
1028 | 378 | /* | ||
1029 | 379 | * If MirAL notifies that a window was removed, and its corresponding MirSurface is not | ||
1030 | 380 | * being displayed, test that SurfaceManager removes the corresponding MirSurface from | ||
1031 | 381 | * its internal list and deletes the MirSurface | ||
1032 | 382 | */ | ||
1033 | 383 | TEST_F(SurfaceManagerTests, miralWindowRemovedDeletesSurfaceManagerInternalEntryAndMirSurface) | ||
1034 | 384 | { | ||
1035 | 385 | // Setup: add window and get corresponding MirSurface | ||
1036 | 386 | Q_EMIT wmNotifier.windowAdded(windowInfo); | ||
1037 | 387 | qtApp->sendPostedEvents(); | ||
1038 | 388 | auto mirSurface = surfaceManager->find(windowInfo); | ||
1039 | 389 | ASSERT_TRUE(mirSurface); | ||
1040 | 390 | |||
1041 | 391 | QSignalSpy mirSurfaceDestroyedSpy(mirSurface, &QObject::destroyed); | ||
1042 | 392 | |||
1043 | 393 | // Test | ||
1044 | 394 | Q_EMIT wmNotifier.windowRemoved(windowInfo); | ||
1045 | 395 | qtApp->sendPostedEvents(); | ||
1046 | 396 | |||
1047 | 397 | // Check result | ||
1048 | 398 | ASSERT_EQ(2, mirSurfaceDestroyedSpy.count()); //FIXME - should be 1 | ||
1049 | 399 | EXPECT_FALSE(surfaceManager->find(windowInfo)); | ||
1050 | 400 | } | ||
1051 | 401 | |||
1052 | 402 | /* | ||
1053 | 403 | * If MirAL notifies that a window was removed, and its corresponding MirSurface *is* | ||
1054 | 404 | * being displayed, test that SurfaceManager removes the corresponding MirSurface from | ||
1055 | 405 | * its internal list but does *not* delete the MirSurface, but sets it as not "live" | ||
1056 | 406 | */ | ||
1057 | 407 | TEST_F(SurfaceManagerTests, miralWindowRemovedDeletesSurfaceManagerInternalEntryButNotMirSurface) | ||
1058 | 408 | { | ||
1059 | 409 | // Setup: add window and get corresponding MirSurface | ||
1060 | 410 | Q_EMIT wmNotifier.windowAdded(windowInfo); | ||
1061 | 411 | qtApp->sendPostedEvents(); | ||
1062 | 412 | auto mirSurface = surfaceManager->find(windowInfo); | ||
1063 | 413 | ASSERT_TRUE(mirSurface); | ||
1064 | 414 | |||
1065 | 415 | QSignalSpy mirSurfaceDestroyedSpy(mirSurface, &QObject::destroyed); | ||
1066 | 416 | |||
1067 | 417 | mirSurface->registerView(1); | ||
1068 | 418 | |||
1069 | 419 | // Test | ||
1070 | 420 | Q_EMIT wmNotifier.windowRemoved(windowInfo); | ||
1071 | 421 | qtApp->sendPostedEvents(); | ||
1072 | 422 | |||
1073 | 423 | // Check result | ||
1074 | 424 | ASSERT_EQ(0, mirSurfaceDestroyedSpy.count()); | ||
1075 | 425 | EXPECT_FALSE(surfaceManager->find(windowInfo)); | ||
1076 | 426 | EXPECT_FALSE(mirSurface->live()); | ||
1077 | 427 | } | ||
1078 | 428 | |||
1079 | 429 | /* | ||
1080 | 430 | * If MirAL notifies that a window was removed, and its corresponding MirSurface *is* | ||
1081 | 431 | * being displayed, SurfaceManager does *not* delete the MirSurface. Later when that | ||
1082 | 432 | * MirSurface is not being displayed any more, SurfaceManager should delete it. | ||
1083 | 433 | */ | ||
1084 | 434 | TEST_F(SurfaceManagerTests, miralWindowRemovedSurfaceManagerDeletesMirSurfaceWhenItDoneWith) | ||
1085 | 435 | { | ||
1086 | 436 | int viewId = 99; | ||
1087 | 437 | |||
1088 | 438 | // Setup: add window and get corresponding MirSurface | ||
1089 | 439 | Q_EMIT wmNotifier.windowAdded(windowInfo); | ||
1090 | 440 | qtApp->sendPostedEvents(); | ||
1091 | 441 | auto mirSurface = surfaceManager->find(windowInfo); | ||
1092 | 442 | ASSERT_TRUE(mirSurface); | ||
1093 | 443 | |||
1094 | 444 | QSignalSpy mirSurfaceDestroyedSpy(mirSurface, &QObject::destroyed); | ||
1095 | 445 | |||
1096 | 446 | // Setup: indicate MirSurface is being displayed | ||
1097 | 447 | mirSurface->registerView(viewId); | ||
1098 | 448 | |||
1099 | 449 | // Setup: notify that window removed | ||
1100 | 450 | Q_EMIT wmNotifier.windowRemoved(windowInfo); | ||
1101 | 451 | qtApp->sendPostedEvents(); | ||
1102 | 452 | |||
1103 | 453 | // Test | ||
1104 | 454 | mirSurface->unregisterView(viewId); | ||
1105 | 455 | // MirSurface is deleteLater()ed by SurfaceManager, so need to spin event loop. | ||
1106 | 456 | // But DeferredDelete is special: likes to be called out specifically or it won't come out | ||
1107 | 457 | qtApp->sendPostedEvents(mirSurface, QEvent::DeferredDelete); | ||
1108 | 458 | qtApp->sendPostedEvents(); | ||
1109 | 459 | |||
1110 | 460 | // Check result | ||
1111 | 461 | ASSERT_EQ(2, mirSurfaceDestroyedSpy.count()); //FIXME - should be 1 | ||
1112 | 462 | } | ||
1113 | 463 | |||
1114 | 464 | /* | ||
1115 | 465 | * Test that if a MirSurface is live, and stops being displayed, SurfaceManager does *not* | ||
1116 | 466 | * delete the MirSurface. | ||
1117 | 467 | */ | ||
1118 | 468 | TEST_F(SurfaceManagerTests, surfaceManagerDoesNotDeleteLiveMirSurfaceWhenStopsBeingDisplayed) | ||
1119 | 469 | { | ||
1120 | 470 | int viewId = 99; | ||
1121 | 471 | |||
1122 | 472 | // Setup: add window and get corresponding MirSurface | ||
1123 | 473 | Q_EMIT wmNotifier.windowAdded(windowInfo); | ||
1124 | 474 | qtApp->sendPostedEvents(); | ||
1125 | 475 | auto mirSurface = surfaceManager->find(windowInfo); | ||
1126 | 476 | ASSERT_TRUE(mirSurface); | ||
1127 | 477 | ASSERT_TRUE(mirSurface->live()); | ||
1128 | 478 | |||
1129 | 479 | QSignalSpy mirSurfaceDestroyedSpy(mirSurface, &QObject::destroyed); | ||
1130 | 480 | |||
1131 | 481 | // Setup: indicate MirSurface is being displayed | ||
1132 | 482 | mirSurface->registerView(viewId); | ||
1133 | 483 | |||
1134 | 484 | // Test | ||
1135 | 485 | mirSurface->unregisterView(viewId); | ||
1136 | 486 | |||
1137 | 487 | // Check result | ||
1138 | 488 | ASSERT_EQ(0, mirSurfaceDestroyedSpy.count()); | ||
1139 | 489 | } | ||
1140 | 0 | 490 | ||
1141 | === modified file 'tests/modules/WindowManager/mirsurface_test.cpp' | |||
1142 | --- tests/modules/WindowManager/mirsurface_test.cpp 2017-02-02 09:29:46 +0000 | |||
1143 | +++ tests/modules/WindowManager/mirsurface_test.cpp 2017-03-10 12:23:14 +0000 | |||
1144 | @@ -110,66 +110,6 @@ | |||
1145 | 110 | ASSERT_TRUE(spyFrameDropped.count() > 0); | 110 | ASSERT_TRUE(spyFrameDropped.count() > 0); |
1146 | 111 | } | 111 | } |
1147 | 112 | 112 | ||
1148 | 113 | |||
1149 | 114 | TEST_F(MirSurfaceTest, DeleteMirSurfaceOnLastNonLiveUnregisterView) | ||
1150 | 115 | { | ||
1151 | 116 | int argc = 0; | ||
1152 | 117 | char* argv[0]; | ||
1153 | 118 | QCoreApplication qtApp(argc, argv); // app for deleteLater event | ||
1154 | 119 | |||
1155 | 120 | miral::Window mockWindow(stubSession, stubSurface); | ||
1156 | 121 | ms::SurfaceCreationParameters spec; | ||
1157 | 122 | miral::WindowInfo mockWindowInfo(mockWindow, spec); | ||
1158 | 123 | |||
1159 | 124 | auto surface = new MirSurface(mockWindowInfo, nullptr); // lives on the heap, as it will delete itself | ||
1160 | 125 | |||
1161 | 126 | bool surfaceDeleted = false; | ||
1162 | 127 | QObject::connect(surface, &QObject::destroyed, [&surfaceDeleted](){ surfaceDeleted = true; }); | ||
1163 | 128 | |||
1164 | 129 | qintptr view1 = (qintptr)1; | ||
1165 | 130 | qintptr view2 = (qintptr)2; | ||
1166 | 131 | |||
1167 | 132 | surface->registerView(view1); | ||
1168 | 133 | surface->registerView(view2); | ||
1169 | 134 | surface->setLive(false); | ||
1170 | 135 | EXPECT_FALSE(surfaceDeleted); | ||
1171 | 136 | |||
1172 | 137 | surface->unregisterView(view1); | ||
1173 | 138 | surface->unregisterView(view2); | ||
1174 | 139 | |||
1175 | 140 | QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); | ||
1176 | 141 | EXPECT_TRUE(surfaceDeleted); | ||
1177 | 142 | } | ||
1178 | 143 | |||
1179 | 144 | |||
1180 | 145 | TEST_F(MirSurfaceTest, DISABLED_DoNotDeleteMirSurfaceOnLastLiveUnregisterView) | ||
1181 | 146 | { | ||
1182 | 147 | int argc = 0; | ||
1183 | 148 | char* argv[0]; | ||
1184 | 149 | QCoreApplication qtApp(argc, argv); // app for deleteLater event | ||
1185 | 150 | |||
1186 | 151 | miral::Window mockWindow(stubSession, stubSurface); | ||
1187 | 152 | ms::SurfaceCreationParameters spec; | ||
1188 | 153 | miral::WindowInfo mockWindowInfo(mockWindow, spec); | ||
1189 | 154 | |||
1190 | 155 | auto surface = new MirSurface(mockWindowInfo, nullptr); // lives on the heap, as it may delete itself | ||
1191 | 156 | |||
1192 | 157 | bool surfaceDeleted = false; | ||
1193 | 158 | QObject::connect(surface, &QObject::destroyed, [&surfaceDeleted](){ surfaceDeleted = true; }); | ||
1194 | 159 | |||
1195 | 160 | qintptr view1 = (qintptr)1; | ||
1196 | 161 | qintptr view2 = (qintptr)2; | ||
1197 | 162 | |||
1198 | 163 | surface->registerView(view1); | ||
1199 | 164 | surface->registerView(view2); | ||
1200 | 165 | |||
1201 | 166 | surface->unregisterView(view1); | ||
1202 | 167 | surface->unregisterView(view2); | ||
1203 | 168 | |||
1204 | 169 | QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); | ||
1205 | 170 | EXPECT_FALSE(surfaceDeleted); | ||
1206 | 171 | } | ||
1207 | 172 | |||
1208 | 173 | /* | 113 | /* |
1209 | 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. |
1210 | 175 | * A surface is not considered visible unless it has a non-hidden & non-minimized state, and | 115 | * A surface is not considered visible unless it has a non-hidden & non-minimized state, and |
Ok