Merge lp:~dandrader/qtmir/fixActiveFocusUpdate into lp:qtmir
- fixActiveFocusUpdate
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Nick Dedekind |
Approved revision: | 491 |
Merged at revision: | 499 |
Proposed branch: | lp:~dandrader/qtmir/fixActiveFocusUpdate |
Merge into: | lp:qtmir |
Diff against target: |
980 lines (+401/-217) 17 files modified
src/modules/Unity/Application/mirsurface.cpp (+21/-7) src/modules/Unity/Application/mirsurface.h (+7/-3) src/modules/Unity/Application/mirsurfaceinterface.h (+4/-3) src/modules/Unity/Application/mirsurfaceitem.cpp (+5/-11) src/modules/Unity/Application/mirsurfaceitem.h (+1/-1) tests/framework/CMakeLists.txt (+1/-1) tests/framework/fake_mirsurface.cpp (+0/-2) tests/framework/fake_mirsurface.h (+2/-1) tests/framework/fake_session.cpp (+2/-1) tests/framework/fake_session.h (+2/-0) tests/framework/fake_surface.h (+89/-69) tests/framework/mock_shell.h (+111/-0) tests/framework/stub_scene_surface.cpp (+0/-103) tests/modules/SessionManager/session_test.cpp (+0/-3) tests/modules/SurfaceManager/CMakeLists.txt (+1/-0) tests/modules/SurfaceManager/mirsurface_test.cpp (+10/-11) tests/modules/SurfaceManager/mirsurfaceitem_test.cpp (+145/-1) |
To merge this branch: | bzr merge lp:~dandrader/qtmir/fixActiveFocusUpdate |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Nick Dedekind (community) | Approve | ||
Unity8 CI Bot (community) | continuous-integration | Approve | |
Review via email: mp+295624@code.launchpad.net |
This proposal supersedes a proposal from 2016-05-09.
Commit message
Fix mir::scene::Surface focus attribute updates
Description of the change
* Are there any related MPs required for this MP to build/function as expected? Please list.
No
* Did you perform an exploratory manual test run of your code change and any related functionality?
Yes.
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
Not applicable.
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
Nick Dedekind (nick-dedekind) wrote : Posted in a previous version of this proposal | # |
Looks fine.
Nick Dedekind (nick-dedekind) wrote : Posted in a previous version of this proposal | # |
I don't believe there's any real way to test this at the moment, since consumes input doesn't currently change, but was tested in mock by branch:
https:/
Nick Dedekind (nick-dedekind) wrote : Posted in a previous version of this proposal | # |
I think this may be wrong.
We encounter an issue with this in unity8 shell tests (FUNCTION=
Problem arises from the active focus not being passed through when consumesInput=
Nick Dedekind (nick-dedekind) wrote : Posted in a previous version of this proposal | # |
perhaps:
void MirSurfaceItem:
{
if (m_surface && m_surface->live()) {
}
}
Nick Dedekind (nick-dedekind) wrote : Posted in a previous version of this proposal | # |
and updateMirSurfac
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
> and updateMirSurfac
> changes.
Imagine multiple views per surface:
- View A: hasActiveFocus(
- View B: hasActiveFocus(
- Surface: activeFocus=true (because of View A)
It's a wrong situation (two view consuming input for the same surface) but possible with the current API.
- m_consumesInput in View B turns false.
With the code you suggest, Surface would lose active focus despite of View A. That's why I only call update when m_consumesInput turns true (not obvious).
Looks like we might need a more involved solution...
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:490
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal | # |
An all-new patch. Should work in all situations now.
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:490
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
- 491. By Daniel d'Andrada
-
Remove dead code
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:491
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Nick Dedekind (nick-dedekind) wrote : | # |
Looks fine.
Preview Diff
1 | === modified file 'src/modules/Unity/Application/mirsurface.cpp' |
2 | --- src/modules/Unity/Application/mirsurface.cpp 2016-05-17 19:18:44 +0000 |
3 | +++ src/modules/Unity/Application/mirsurface.cpp 2016-05-24 21:32:26 +0000 |
4 | @@ -441,7 +441,18 @@ |
5 | Q_EMIT focusedChanged(value); |
6 | } |
7 | |
8 | -void MirSurface::setActiveFocus(bool focus) |
9 | +void MirSurface::setViewActiveFocus(qintptr viewId, bool value) |
10 | +{ |
11 | + if (value && !m_activelyFocusedViews.contains(viewId)) { |
12 | + m_activelyFocusedViews.insert(viewId); |
13 | + updateActiveFocus(); |
14 | + } else if (!value && (m_activelyFocusedViews.contains(viewId) || m_neverSetSurfaceFocus)) { |
15 | + m_activelyFocusedViews.remove(viewId); |
16 | + updateActiveFocus(); |
17 | + } |
18 | +} |
19 | + |
20 | +void MirSurface::updateActiveFocus() |
21 | { |
22 | if (!m_session) { |
23 | return; |
24 | @@ -450,17 +461,19 @@ |
25 | // Temporary hotfix for http://pad.lv/1483752 |
26 | if (m_session->childSessions()->rowCount() > 0) { |
27 | // has child trusted session, ignore any focus change attempts |
28 | - DEBUG_MSG << "(" << focus << ") - has child trusted session, ignore any focus change attempts"; |
29 | + DEBUG_MSG << "() has child trusted session, ignore any focus change attempts"; |
30 | return; |
31 | } |
32 | |
33 | - DEBUG_MSG << "(" << focus << ")"; |
34 | - |
35 | - if (focus) { |
36 | + if (m_activelyFocusedViews.isEmpty()) { |
37 | + DEBUG_MSG << "() unfocused"; |
38 | + m_shell->set_surface_attribute(m_session->session(), m_surface, mir_surface_attrib_focus, mir_surface_unfocused); |
39 | + } else { |
40 | + DEBUG_MSG << "() focused"; |
41 | m_shell->set_surface_attribute(m_session->session(), m_surface, mir_surface_attrib_focus, mir_surface_focused); |
42 | - } else { |
43 | - m_shell->set_surface_attribute(m_session->session(), m_surface, mir_surface_attrib_focus, mir_surface_unfocused); |
44 | } |
45 | + |
46 | + m_neverSetSurfaceFocus = false; |
47 | } |
48 | |
49 | void MirSurface::close() |
50 | @@ -739,6 +752,7 @@ |
51 | } |
52 | } |
53 | updateVisibility(); |
54 | + setViewActiveFocus(viewId, false); |
55 | } |
56 | |
57 | void MirSurface::setViewVisibility(qintptr viewId, bool visible) |
58 | |
59 | === modified file 'src/modules/Unity/Application/mirsurface.h' |
60 | --- src/modules/Unity/Application/mirsurface.h 2016-05-17 19:18:44 +0000 |
61 | +++ src/modules/Unity/Application/mirsurface.h 2016-05-24 21:32:26 +0000 |
62 | @@ -25,9 +25,8 @@ |
63 | #include <QMutex> |
64 | #include <QPointer> |
65 | #include <QSharedPointer> |
66 | -#include <QSGTextureProvider> |
67 | #include <QWeakPointer> |
68 | -#include <QPair> |
69 | +#include <QSet> |
70 | |
71 | #include "mirbuffersgtexture.h" |
72 | #include "session.h" |
73 | @@ -117,7 +116,8 @@ |
74 | // end of methods called from the rendering (scene graph) thread |
75 | |
76 | void setFocused(bool focus) override; |
77 | - void setActiveFocus(bool focus) override; |
78 | + |
79 | + void setViewActiveFocus(qintptr viewId, bool value) override; |
80 | |
81 | void mousePressEvent(QMouseEvent *event) override; |
82 | void mouseMoveEvent(QMouseEvent *event) override; |
83 | @@ -179,6 +179,7 @@ |
84 | bool clientIsRunning() const; |
85 | void updateVisibility(); |
86 | void applyKeymap(); |
87 | + void updateActiveFocus(); |
88 | |
89 | std::shared_ptr<mir::scene::Surface> m_surface; |
90 | QPointer<SessionInterface> m_session; |
91 | @@ -203,6 +204,9 @@ |
92 | }; |
93 | QHash<qintptr, View> m_views; |
94 | |
95 | + QSet<qintptr> m_activelyFocusedViews; |
96 | + bool m_neverSetSurfaceFocus{true}; |
97 | + |
98 | std::shared_ptr<SurfaceObserver> m_surfaceObserver; |
99 | |
100 | QSize m_size; |
101 | |
102 | === modified file 'src/modules/Unity/Application/mirsurfaceinterface.h' |
103 | --- src/modules/Unity/Application/mirsurfaceinterface.h 2016-04-29 15:41:00 +0000 |
104 | +++ src/modules/Unity/Application/mirsurfaceinterface.h 2016-05-24 21:32:26 +0000 |
105 | @@ -72,10 +72,11 @@ |
106 | /* |
107 | Defines the "focus" attribute of the underlying mir::scene::Surface, which is what |
108 | the client application sees. |
109 | - Set by a MirSurfaceItem and used to inform the client application about the actual |
110 | - focus, pretty much a one-to-one mapping with QML's active focus concept, hence the name. |
111 | + Set by MirSurfaceItems (aka views) and used to inform the client application about the |
112 | + actual focus, pretty much a one-to-one mapping with QML's active focus concept, hence |
113 | + the name. |
114 | */ |
115 | - virtual void setActiveFocus(bool focus) = 0; |
116 | + virtual void setViewActiveFocus(qintptr viewId, bool value) = 0; |
117 | |
118 | virtual void mousePressEvent(QMouseEvent *event) = 0; |
119 | virtual void mouseMoveEvent(QMouseEvent *event) = 0; |
120 | |
121 | === modified file 'src/modules/Unity/Application/mirsurfaceitem.cpp' |
122 | --- src/modules/Unity/Application/mirsurfaceitem.cpp 2016-04-29 15:43:46 +0000 |
123 | +++ src/modules/Unity/Application/mirsurfaceitem.cpp 2016-05-24 21:32:26 +0000 |
124 | @@ -566,10 +566,10 @@ |
125 | m_surface->setViewVisibility((qintptr)this, isVisible()); |
126 | } |
127 | |
128 | -void MirSurfaceItem::updateMirSurfaceActiveFocus(bool focused) |
129 | +void MirSurfaceItem::updateMirSurfaceActiveFocus() |
130 | { |
131 | - if (m_surface && m_consumesInput && m_surface->live()) { |
132 | - m_surface->setActiveFocus(focused); |
133 | + if (m_surface && m_surface->live()) { |
134 | + m_surface->setViewActiveFocus(qintptr(this), m_consumesInput && hasActiveFocus()); |
135 | } |
136 | } |
137 | |
138 | @@ -619,6 +619,7 @@ |
139 | setAcceptHoverEvents(false); |
140 | } |
141 | |
142 | + updateMirSurfaceActiveFocus(); |
143 | Q_EMIT consumesInputChanged(value); |
144 | } |
145 | |
146 | @@ -640,11 +641,6 @@ |
147 | |
148 | if (m_surface) { |
149 | disconnect(m_surface, nullptr, this, nullptr); |
150 | - |
151 | - if (hasActiveFocus() && m_consumesInput && m_surface->live()) { |
152 | - m_surface->setActiveFocus(false); |
153 | - } |
154 | - |
155 | m_surface->unregisterView((qintptr)this); |
156 | unsetCursor(); |
157 | } |
158 | @@ -690,9 +686,7 @@ |
159 | Q_EMIT orientationAngleChanged(m_surface->orientationAngle()); |
160 | } |
161 | |
162 | - if (m_consumesInput) { |
163 | - m_surface->setActiveFocus(hasActiveFocus()); |
164 | - } |
165 | + updateMirSurfaceActiveFocus(); |
166 | } |
167 | |
168 | update(); |
169 | |
170 | === modified file 'src/modules/Unity/Application/mirsurfaceitem.h' |
171 | --- src/modules/Unity/Application/mirsurfaceitem.h 2016-04-29 15:43:46 +0000 |
172 | +++ src/modules/Unity/Application/mirsurfaceitem.h 2016-05-24 21:32:26 +0000 |
173 | @@ -116,7 +116,7 @@ |
174 | void scheduleMirSurfaceSizeUpdate(); |
175 | void updateMirSurfaceSize(); |
176 | |
177 | - void updateMirSurfaceActiveFocus(bool focused); |
178 | + void updateMirSurfaceActiveFocus(); |
179 | void updateMirSurfaceVisibility(); |
180 | |
181 | void onActualSurfaceSizeChanged(const QSize &size); |
182 | |
183 | === modified file 'tests/framework/CMakeLists.txt' |
184 | --- tests/framework/CMakeLists.txt 2016-02-18 17:27:58 +0000 |
185 | +++ tests/framework/CMakeLists.txt 2016-05-24 21:32:26 +0000 |
186 | @@ -29,7 +29,7 @@ |
187 | mock_surface.cpp |
188 | mock_task_controller.cpp |
189 | stub_input_channel.cpp |
190 | - stub_scene_surface.cpp |
191 | + fake_surface.h |
192 | qtmir_test.cpp |
193 | ) |
194 | |
195 | |
196 | === modified file 'tests/framework/fake_mirsurface.cpp' |
197 | --- tests/framework/fake_mirsurface.cpp 2016-04-05 18:58:38 +0000 |
198 | +++ tests/framework/fake_mirsurface.cpp 2016-05-24 21:32:26 +0000 |
199 | @@ -152,8 +152,6 @@ |
200 | |
201 | void FakeMirSurface::setFocused(bool focus) { m_focused = focus; } |
202 | |
203 | -void FakeMirSurface::setActiveFocus(bool) {} |
204 | - |
205 | void FakeMirSurface::mousePressEvent(QMouseEvent *) {} |
206 | |
207 | void FakeMirSurface::mouseMoveEvent(QMouseEvent *) {} |
208 | |
209 | === modified file 'tests/framework/fake_mirsurface.h' |
210 | --- tests/framework/fake_mirsurface.h 2016-05-17 19:18:44 +0000 |
211 | +++ tests/framework/fake_mirsurface.h 2016-05-24 21:32:26 +0000 |
212 | @@ -110,7 +110,8 @@ |
213 | // end of methods called from the rendering (scene graph) thread |
214 | |
215 | void setFocused(bool focus) override; |
216 | - void setActiveFocus(bool focus) override; |
217 | + |
218 | + void setViewActiveFocus(qintptr, bool) override {}; |
219 | |
220 | void mousePressEvent(QMouseEvent *) override; |
221 | void mouseMoveEvent(QMouseEvent *) override; |
222 | |
223 | === modified file 'tests/framework/fake_session.cpp' |
224 | --- tests/framework/fake_session.cpp 2016-05-17 19:18:44 +0000 |
225 | +++ tests/framework/fake_session.cpp 2016-05-24 21:32:26 +0000 |
226 | @@ -28,6 +28,7 @@ |
227 | |
228 | FakeSession::~FakeSession() |
229 | { |
230 | + delete m_childSessions; |
231 | } |
232 | |
233 | QString FakeSession::name() const { return QString("foo-session"); } |
234 | @@ -38,7 +39,7 @@ |
235 | |
236 | MirSurfaceListModel* FakeSession::promptSurfaceList() { return &m_promptSurfaceList; } |
237 | |
238 | -SessionModel *FakeSession::childSessions() const { return nullptr; } |
239 | +SessionModel *FakeSession::childSessions() const { return m_childSessions; } |
240 | |
241 | SessionInterface::State FakeSession::state() const { return m_state; } |
242 | |
243 | |
244 | === modified file 'tests/framework/fake_session.h' |
245 | --- tests/framework/fake_session.h 2016-05-17 19:18:44 +0000 |
246 | +++ tests/framework/fake_session.h 2016-05-24 21:32:26 +0000 |
247 | @@ -15,6 +15,7 @@ |
248 | */ |
249 | |
250 | #include <Unity/Application/session_interface.h> |
251 | +#include <Unity/Application/sessionmodel.h> |
252 | #include <Unity/Application/mirsurfacelistmodel.h> |
253 | #include <QDebug> |
254 | |
255 | @@ -83,6 +84,7 @@ |
256 | std::shared_ptr<mir::scene::Session> m_session; |
257 | MirSurfaceListModel m_surfaceList; |
258 | MirSurfaceListModel m_promptSurfaceList; |
259 | + SessionModel *m_childSessions{new SessionModel}; |
260 | }; |
261 | |
262 | } // namespace qtmi |
263 | |
264 | === renamed file 'tests/framework/stub_scene_surface.h' => 'tests/framework/fake_surface.h' |
265 | --- tests/framework/stub_scene_surface.h 2016-02-01 12:18:00 +0000 |
266 | +++ tests/framework/fake_surface.h 2016-05-24 21:32:26 +0000 |
267 | @@ -1,88 +1,108 @@ |
268 | /* |
269 | - * Copyright (C) 2014-2015 Canonical, Ltd. |
270 | - * |
271 | - * This program is free software: you can redistribute it and/or modify it under |
272 | - * the terms of the GNU Lesser General Public License version 3, as published by |
273 | - * the Free Software Foundation. |
274 | - * |
275 | - * This program is distributed in the hope that it will be useful, but WITHOUT |
276 | - * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
277 | - * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
278 | - * Lesser General Public License for more details. |
279 | - * |
280 | - * You should have received a copy of the GNU Lesser General Public License |
281 | + * Copyright © 2014,2016 Canonical Ltd. |
282 | + * |
283 | + * This program is free software: you can redistribute it and/or modify it |
284 | + * under the terms of the GNU General Public License version 3, |
285 | + * as published by the Free Software Foundation. |
286 | + * |
287 | + * This program is distributed in the hope that it will be useful, |
288 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
289 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
290 | + * GNU General Public License for more details. |
291 | + * |
292 | + * You should have received a copy of the GNU General Public License |
293 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
294 | + * |
295 | + * Original file authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
296 | */ |
297 | |
298 | -#ifndef MIR_TEST_DOUBLES_STUB_SCENE_SURFACE_H_ |
299 | -#define MIR_TEST_DOUBLES_STUB_SCENE_SURFACE_H_ |
300 | +#ifndef MIR_SCENE_FAKESURFACE_H_ |
301 | +#define MIR_SCENE_FAKESURFACE_H_ |
302 | |
303 | -#include "mir/scene/surface.h" |
304 | +#include <mir/scene/surface.h> |
305 | #include "stub_input_channel.h" |
306 | |
307 | #include <memory> |
308 | #include <gmock/gmock.h> |
309 | |
310 | -namespace mir |
311 | -{ |
312 | -namespace test |
313 | -{ |
314 | -namespace doubles |
315 | -{ |
316 | +namespace mir { |
317 | +namespace scene { |
318 | |
319 | -class StubSceneSurface : |
320 | - public mir::scene::Surface |
321 | +class FakeSurface : public Surface |
322 | { |
323 | public: |
324 | - std::shared_ptr<StubInputChannel> channel; |
325 | + std::shared_ptr<mir::test::doubles::StubInputChannel> channel; |
326 | int fd; |
327 | mir::input::InputReceptionMode input_mode{mir::input::InputReceptionMode::normal}; |
328 | |
329 | - StubSceneSurface(int fd); |
330 | - virtual ~StubSceneSurface(); |
331 | - |
332 | - std::shared_ptr<mir::input::InputChannel> input_channel() const override; |
333 | - |
334 | - mir::input::InputReceptionMode reception_mode() const override; |
335 | - |
336 | - std::string name() const override; |
337 | - geometry::Point top_left() const override; |
338 | - geometry::Size client_size() const override; |
339 | - geometry::Size size() const override; |
340 | - geometry::Rectangle input_bounds() const override; |
341 | - bool input_area_contains(mir::geometry::Point const&) const override; |
342 | - |
343 | - graphics::RenderableList generate_renderables(compositor::CompositorID) const override; |
344 | - float alpha() const override; |
345 | - MirSurfaceType type() const override; |
346 | - MirSurfaceState state() const override; |
347 | - |
348 | - void hide() override; |
349 | - void show() override; |
350 | - void move_to(geometry::Point const&) override; |
351 | - void set_input_region(std::vector<geometry::Rectangle> const&) override; |
352 | - void resize(geometry::Size const&) override; |
353 | - void set_transformation(glm::mat4 const&) override; |
354 | - void set_alpha(float) override; |
355 | - void set_orientation(MirOrientation) override; |
356 | - |
357 | - void add_observer(std::shared_ptr<scene::SurfaceObserver> const&) override; |
358 | - void remove_observer(std::weak_ptr<scene::SurfaceObserver> const&) override; |
359 | - |
360 | - void set_reception_mode(input::InputReceptionMode mode) override; |
361 | - void consume(MirEvent const*) override; |
362 | - |
363 | - void set_cursor_image(std::shared_ptr<graphics::CursorImage> const& /* image */) override; |
364 | - std::shared_ptr<graphics::CursorImage> cursor_image() const override; |
365 | - |
366 | - bool supports_input() const override; |
367 | - int client_input_fd() const override; |
368 | - int configure(MirSurfaceAttrib, int) override; |
369 | - int query(MirSurfaceAttrib) const override; |
370 | + FakeSurface(int fd=123) |
371 | + : channel(std::make_shared<mir::test::doubles::StubInputChannel>(fd)), fd(fd) |
372 | + { |
373 | + } |
374 | + |
375 | + std::shared_ptr<mir::input::InputChannel> input_channel() const override |
376 | + { |
377 | + return channel; |
378 | + } |
379 | + |
380 | + mir::input::InputReceptionMode reception_mode() const override |
381 | + { |
382 | + return input_mode; |
383 | + } |
384 | + |
385 | + std::string name() const override { return {}; } |
386 | + geometry::Point top_left() const override { return {}; } |
387 | + geometry::Size client_size() const override { return {};} |
388 | + geometry::Size size() const override { return {}; } |
389 | + geometry::Rectangle input_bounds() const override { return {{},{}}; } |
390 | + bool input_area_contains(mir::geometry::Point const&) const override { return false; } |
391 | + |
392 | + void set_streams(std::list<scene::StreamInfo> const&) override {} |
393 | + graphics::RenderableList generate_renderables(compositor::CompositorID) const override { return {}; } |
394 | + int buffers_ready_for_compositor(void const*) const override { return 0; } |
395 | + |
396 | + float alpha() const override { return 0.0f;} |
397 | + MirSurfaceType type() const override { return mir_surface_type_normal; } |
398 | + MirSurfaceState state() const override { return mir_surface_state_unknown; } |
399 | + |
400 | + void hide() override {} |
401 | + void show() override {} |
402 | + bool visible() const override { return true; } |
403 | + void move_to(geometry::Point const&) override {} |
404 | + void set_input_region(std::vector<geometry::Rectangle> const&) override {} |
405 | + void resize(geometry::Size const&) override {} |
406 | + void set_transformation(glm::mat4 const&) override {} |
407 | + void set_alpha(float) override {} |
408 | + void set_orientation(MirOrientation) {} |
409 | + |
410 | + void add_observer(std::shared_ptr<scene::SurfaceObserver> const&) override {} |
411 | + void remove_observer(std::weak_ptr<scene::SurfaceObserver> const&) override {} |
412 | + |
413 | + void set_reception_mode(input::InputReceptionMode mode) override { input_mode = mode; } |
414 | + void consume(MirEvent const*) override {} |
415 | + |
416 | + void set_cursor_image(std::shared_ptr<graphics::CursorImage> const& /* image */) {} |
417 | + std::shared_ptr<graphics::CursorImage> cursor_image() const { return {}; } |
418 | + |
419 | + void request_client_surface_close() override {} |
420 | + |
421 | + bool supports_input() const override { return true;} |
422 | + int client_input_fd() const override { return fd;} |
423 | + int configure(MirSurfaceAttrib, int) override { return 0; } |
424 | + int query(MirSurfaceAttrib) const override { return 0; } |
425 | + void with_most_recent_buffer_do(std::function<void(graphics::Buffer&)> const&) {} |
426 | + |
427 | + std::shared_ptr<Surface> parent() const override { return nullptr; } |
428 | + |
429 | + void set_keymap(MirInputDeviceId, std::string const&, std::string const&, std::string const&, std::string const&) override |
430 | + {} |
431 | + |
432 | + void set_cursor_stream(std::shared_ptr<frontend::BufferStream> const&, geometry::Displacement const&) {} |
433 | + void rename(std::string const&) {} |
434 | + std::shared_ptr<frontend::BufferStream> primary_buffer_stream() const override { return nullptr; } |
435 | }; |
436 | |
437 | -} |
438 | -} |
439 | -} |
440 | +} // namespace scene |
441 | +} // namescape mir |
442 | |
443 | -#endif |
444 | +#endif // MIR_SCENE_FAKESURFACE_H_ |
445 | |
446 | === added file 'tests/framework/mock_shell.h' |
447 | --- tests/framework/mock_shell.h 1970-01-01 00:00:00 +0000 |
448 | +++ tests/framework/mock_shell.h 2016-05-24 21:32:26 +0000 |
449 | @@ -0,0 +1,111 @@ |
450 | +/* |
451 | + * Copyright (C) 2016 Canonical, Ltd. |
452 | + * |
453 | + * This program is free software: you can redistribute it and/or modify it under |
454 | + * the terms of the GNU Lesser General Public License version 3, as published by |
455 | + * the Free Software Foundation. |
456 | + * |
457 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
458 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
459 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
460 | + * Lesser General Public License for more details. |
461 | + * |
462 | + * You should have received a copy of the GNU Lesser General Public License |
463 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
464 | + */ |
465 | + |
466 | +#ifndef MOCK_MIR_SHELL_SHELL_H |
467 | +#define MOCK_MIR_SHELL_SHELL_H |
468 | + |
469 | +#include <mir/shell/shell.h> |
470 | + |
471 | +#include <mir/scene/prompt_session_creation_parameters.h> |
472 | +#include <mir/scene/surface_creation_parameters.h> |
473 | +#include <mir/shell/surface_specification.h> |
474 | + |
475 | +#include <gmock/gmock.h> |
476 | + |
477 | +namespace mir { |
478 | +namespace shell { |
479 | + |
480 | +class MockShell : public Shell |
481 | +{ |
482 | +public: |
483 | + |
484 | + // From mir::shell::Shell |
485 | + |
486 | + MOCK_METHOD3(open_session, std::shared_ptr<scene::Session>( |
487 | + pid_t client_pid, |
488 | + std::string const& name, |
489 | + std::shared_ptr<frontend::EventSink> const& sink)); |
490 | + |
491 | + MOCK_METHOD1(close_session, void(std::shared_ptr<scene::Session> const& session)); |
492 | + |
493 | + MOCK_METHOD2(start_prompt_session_for, std::shared_ptr<scene::PromptSession>( |
494 | + std::shared_ptr<scene::Session> const& session, |
495 | + scene::PromptSessionCreationParameters const& params)); |
496 | + |
497 | + MOCK_METHOD2(add_prompt_provider_for, void ( |
498 | + std::shared_ptr<scene::PromptSession> const& prompt_session, |
499 | + std::shared_ptr<scene::Session> const& session)); |
500 | + |
501 | + MOCK_METHOD1(stop_prompt_session, void (std::shared_ptr<scene::PromptSession> const& prompt_session)); |
502 | + |
503 | + MOCK_METHOD3(create_surface, frontend::SurfaceId ( |
504 | + std::shared_ptr<scene::Session> const& session, |
505 | + scene::SurfaceCreationParameters const& params, |
506 | + std::shared_ptr<frontend::EventSink> const& sink)); |
507 | + |
508 | + MOCK_METHOD3(modify_surface, void ( |
509 | + std::shared_ptr<scene::Session> const& session, |
510 | + std::shared_ptr<scene::Surface> const& surface, |
511 | + shell::SurfaceSpecification const& modifications)); |
512 | + |
513 | + MOCK_METHOD2(destroy_surface, void (std::shared_ptr<scene::Session> const& session, frontend::SurfaceId surface)); |
514 | + |
515 | + MOCK_METHOD4(set_surface_attribute, int ( |
516 | + std::shared_ptr<scene::Session> const& session, |
517 | + std::shared_ptr<scene::Surface> const& surface, |
518 | + MirSurfaceAttrib attrib, |
519 | + int value)); |
520 | + |
521 | + MOCK_METHOD2(get_surface_attribute, int ( |
522 | + std::shared_ptr<scene::Surface> const& surface, |
523 | + MirSurfaceAttrib attrib)); |
524 | + |
525 | + MOCK_METHOD3(raise_surface, void ( |
526 | + std::shared_ptr<scene::Session> const& session, |
527 | + std::shared_ptr<scene::Surface> const& surface, |
528 | + uint64_t timestamp)); |
529 | + |
530 | + // From mir::shell::FocusController |
531 | + |
532 | + MOCK_METHOD0(focus_next_session, void ()); |
533 | + |
534 | + MOCK_CONST_METHOD0(focused_session, std::shared_ptr<scene::Session>()); |
535 | + |
536 | + MOCK_METHOD2(set_focus_to, void ( |
537 | + std::shared_ptr<scene::Session> const& focus_session, |
538 | + std::shared_ptr<scene::Surface> const& focus_surface)); |
539 | + |
540 | + MOCK_CONST_METHOD0(focused_surface, std::shared_ptr<scene::Surface>()); |
541 | + |
542 | + MOCK_CONST_METHOD1(surface_at, std::shared_ptr<scene::Surface> (geometry::Point cursor)); |
543 | + |
544 | + MOCK_METHOD1(raise, void (SurfaceSet const& surfaces)); |
545 | + |
546 | + // From mir::input::EventFilter |
547 | + |
548 | + MOCK_METHOD1(handle, bool (MirEvent const& event)); |
549 | + |
550 | + // From mir::compositor::DisplayListener |
551 | + |
552 | + MOCK_METHOD1(add_display, void (geometry::Rectangle const& area)); |
553 | + |
554 | + MOCK_METHOD1(remove_display, void (geometry::Rectangle const& area)); |
555 | +}; |
556 | + |
557 | +} // namespace shell |
558 | +} // namespace mir |
559 | + |
560 | +#endif // MOCK_MIR_SHELL_SHELL_H |
561 | |
562 | === removed file 'tests/framework/stub_scene_surface.cpp' |
563 | --- tests/framework/stub_scene_surface.cpp 2016-02-01 12:18:00 +0000 |
564 | +++ tests/framework/stub_scene_surface.cpp 1970-01-01 00:00:00 +0000 |
565 | @@ -1,103 +0,0 @@ |
566 | -/* |
567 | - * Copyright (C) 2015 Canonical, Ltd. |
568 | - * |
569 | - * This program is free software: you can redistribute it and/or modify it under |
570 | - * the terms of the GNU Lesser General Public License version 3, as published by |
571 | - * the Free Software Foundation. |
572 | - * |
573 | - * This program is distributed in the hope that it will be useful, but WITHOUT |
574 | - * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
575 | - * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
576 | - * Lesser General Public License for more details. |
577 | - * |
578 | - * You should have received a copy of the GNU Lesser General Public License |
579 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
580 | - */ |
581 | - |
582 | -#include "stub_scene_surface.h" |
583 | - |
584 | -namespace mir |
585 | -{ |
586 | -namespace test |
587 | -{ |
588 | -namespace doubles |
589 | -{ |
590 | - |
591 | -StubSceneSurface::StubSceneSurface(int fd) |
592 | - : channel(std::make_shared<StubInputChannel>(fd)), fd(fd) |
593 | -{ |
594 | -} |
595 | - |
596 | -StubSceneSurface::~StubSceneSurface() |
597 | -{ |
598 | -} |
599 | - |
600 | -std::shared_ptr<mir::input::InputChannel> StubSceneSurface::input_channel() const |
601 | -{ |
602 | - return channel; |
603 | -} |
604 | - |
605 | -mir::input::InputReceptionMode StubSceneSurface::reception_mode() const |
606 | -{ |
607 | - return input_mode; |
608 | -} |
609 | - |
610 | -std::string StubSceneSurface::name() const { return {}; } |
611 | - |
612 | -mir::geometry::Point StubSceneSurface::top_left() const { return {}; } |
613 | - |
614 | -mir::geometry::Size StubSceneSurface::client_size() const { return {};} |
615 | - |
616 | -mir::geometry::Size StubSceneSurface::size() const { return {}; } |
617 | - |
618 | -mir::geometry::Rectangle StubSceneSurface::input_bounds() const { return {{},{}}; } |
619 | - |
620 | -bool StubSceneSurface::input_area_contains(mir::geometry::Point const&) const { return false; } |
621 | - |
622 | -mir::graphics::RenderableList StubSceneSurface::generate_renderables(mir::compositor::CompositorID) const { return {};} |
623 | - |
624 | -float StubSceneSurface::alpha() const { return 0.0f; } |
625 | - |
626 | -MirSurfaceType StubSceneSurface::type() const { return mir_surface_type_normal; } |
627 | - |
628 | -MirSurfaceState StubSceneSurface::state() const { return mir_surface_state_unknown; } |
629 | - |
630 | -void StubSceneSurface::hide() {} |
631 | - |
632 | -void StubSceneSurface::show() {} |
633 | - |
634 | -void StubSceneSurface::move_to(const mir::geometry::Point &) {} |
635 | - |
636 | -void StubSceneSurface::set_input_region(const std::vector<mir::geometry::Rectangle> &) {} |
637 | - |
638 | -void StubSceneSurface::resize(const mir::geometry::Size &) {} |
639 | - |
640 | -void StubSceneSurface::set_transformation(const glm::mat4 &) {} |
641 | - |
642 | -void StubSceneSurface::set_alpha(float) {} |
643 | - |
644 | -void StubSceneSurface::set_orientation(MirOrientation) {} |
645 | - |
646 | -void StubSceneSurface::add_observer(const std::shared_ptr<mir::scene::SurfaceObserver> &) {} |
647 | - |
648 | -void StubSceneSurface::remove_observer(const std::weak_ptr<mir::scene::SurfaceObserver> &) {} |
649 | - |
650 | -void StubSceneSurface::set_reception_mode(mir::input::InputReceptionMode mode) { input_mode = mode; } |
651 | - |
652 | -void StubSceneSurface::consume(const MirEvent *) {} |
653 | - |
654 | -void StubSceneSurface::set_cursor_image(const std::shared_ptr<mir::graphics::CursorImage> &) {} |
655 | - |
656 | -std::shared_ptr<mir::graphics::CursorImage> StubSceneSurface::cursor_image() const { return {}; } |
657 | - |
658 | -bool StubSceneSurface::supports_input() const { return true; } |
659 | - |
660 | -int StubSceneSurface::client_input_fd() const { return fd;} |
661 | - |
662 | -int StubSceneSurface::configure(MirSurfaceAttrib, int) { return 0; } |
663 | - |
664 | -int StubSceneSurface::query(MirSurfaceAttrib) const { return 0; } |
665 | - |
666 | -} // namespace doubles |
667 | -} // namespace test |
668 | -} // namespace mir |
669 | |
670 | === modified file 'tests/modules/SessionManager/session_test.cpp' |
671 | --- tests/modules/SessionManager/session_test.cpp 2016-05-17 19:18:44 +0000 |
672 | +++ tests/modules/SessionManager/session_test.cpp 2016-05-24 21:32:26 +0000 |
673 | @@ -20,13 +20,10 @@ |
674 | #include <Unity/Application/application.h> |
675 | #include <Unity/Application/mirsurfaceitem.h> |
676 | |
677 | -#include "stub_scene_surface.h" |
678 | - |
679 | using namespace qtmir; |
680 | using mir::scene::MockSession; |
681 | |
682 | namespace ms = mir::scene; |
683 | -namespace mtd = mir::test::doubles; |
684 | |
685 | class SessionTests : public ::testing::QtMirTest |
686 | { |
687 | |
688 | === modified file 'tests/modules/SurfaceManager/CMakeLists.txt' |
689 | --- tests/modules/SurfaceManager/CMakeLists.txt 2015-11-20 16:47:09 +0000 |
690 | +++ tests/modules/SurfaceManager/CMakeLists.txt 2016-05-24 21:32:26 +0000 |
691 | @@ -10,6 +10,7 @@ |
692 | ${CMAKE_SOURCE_DIR}/src/platforms/mirserver |
693 | ${CMAKE_SOURCE_DIR}/tests/framework |
694 | ${MIRSERVER_INCLUDE_DIRS} |
695 | + ${Qt5Quick_PRIVATE_INCLUDE_DIRS} |
696 | ) |
697 | |
698 | add_executable(surfacemanager_test ${MIR_SURFACE_MANAGER_TEST_SOURCES}) |
699 | |
700 | === modified file 'tests/modules/SurfaceManager/mirsurface_test.cpp' |
701 | --- tests/modules/SurfaceManager/mirsurface_test.cpp 2016-03-28 18:02:26 +0000 |
702 | +++ tests/modules/SurfaceManager/mirsurface_test.cpp 2016-05-24 21:32:26 +0000 |
703 | @@ -16,6 +16,8 @@ |
704 | |
705 | #define MIR_INCLUDE_DEPRECATED_EVENT_HEADER |
706 | |
707 | +struct MirEvent {}; // otherwise won't compile otherwise due to incomplete type |
708 | + |
709 | #include <gtest/gtest.h> |
710 | |
711 | #include <QLoggingCategory> |
712 | @@ -30,6 +32,7 @@ |
713 | // tests/framework |
714 | #include <fake_session.h> |
715 | #include <mock_mir_session.h> |
716 | +#include <mock_shell.h> |
717 | #include <mock_surface.h> |
718 | |
719 | // tests/modules/common |
720 | @@ -41,6 +44,7 @@ |
721 | using namespace qtmir; |
722 | |
723 | namespace ms = mir::scene; |
724 | +using namespace testing; |
725 | |
726 | class MirSurfaceTest : public ::testing::Test |
727 | { |
728 | @@ -50,12 +54,12 @@ |
729 | // We don't want the logging spam cluttering the test results |
730 | QLoggingCategory::setFilterRules(QStringLiteral("qtmir.surfaces=false")); |
731 | } |
732 | + |
733 | + NiceMock<mir::shell::MockShell> m_mockShell; |
734 | }; |
735 | |
736 | TEST_F(MirSurfaceTest, UpdateTextureBeforeDraw) |
737 | { |
738 | - using namespace testing; |
739 | - |
740 | int argc = 0; |
741 | char* argv[0]; |
742 | QCoreApplication qtApp(argc, argv); // app for deleteLater event |
743 | @@ -67,7 +71,7 @@ |
744 | EXPECT_CALL(*mockSurface.get(),buffers_ready_for_compositor(_)) |
745 | .WillRepeatedly(Return(1)); |
746 | |
747 | - MirSurface *surface = new MirSurface(mockSurface, fakeSession, nullptr, surfaceObserver, CreationHints()); |
748 | + MirSurface *surface = new MirSurface(mockSurface, fakeSession, &m_mockShell, surfaceObserver, CreationHints()); |
749 | surfaceObserver->frame_posted(1, mir::geometry::Size{1,1}); |
750 | |
751 | QSignalSpy spyFrameDropped(surface, SIGNAL(frameDropped())); |
752 | @@ -81,8 +85,6 @@ |
753 | |
754 | TEST_F(MirSurfaceTest, DeleteMirSurfaceOnLastNonLiveUnregisterView) |
755 | { |
756 | - using namespace testing; |
757 | - |
758 | int argc = 0; |
759 | char* argv[0]; |
760 | QCoreApplication qtApp(argc, argv); // app for deleteLater event |
761 | @@ -90,7 +92,7 @@ |
762 | auto fakeSession = new FakeSession(); |
763 | auto mockSurface = std::make_shared<NiceMock<ms::MockSurface>>(); |
764 | |
765 | - MirSurface *surface = new MirSurface(mockSurface, fakeSession, nullptr, nullptr, CreationHints()); |
766 | + MirSurface *surface = new MirSurface(mockSurface, fakeSession, &m_mockShell, nullptr, CreationHints()); |
767 | bool surfaceDeleted = false; |
768 | QObject::connect(surface, &QObject::destroyed, surface, [&surfaceDeleted](){ surfaceDeleted = true; }); |
769 | |
770 | @@ -114,8 +116,6 @@ |
771 | |
772 | TEST_F(MirSurfaceTest, DoNotDeleteMirSurfaceOnLastLiveUnregisterView) |
773 | { |
774 | - using namespace testing; |
775 | - |
776 | int argc = 0; |
777 | char* argv[0]; |
778 | QCoreApplication qtApp(argc, argv); // app for deleteLater event |
779 | @@ -123,7 +123,7 @@ |
780 | auto fakeSession = new FakeSession(); |
781 | auto mockSurface = std::make_shared<NiceMock<ms::MockSurface>>(); |
782 | |
783 | - MirSurface *surface = new MirSurface(mockSurface, fakeSession, nullptr, nullptr, CreationHints()); |
784 | + MirSurface *surface = new MirSurface(mockSurface, fakeSession, &m_mockShell, nullptr, CreationHints()); |
785 | bool surfaceDeleted = false; |
786 | QObject::connect(surface, &QObject::destroyed, surface, [&surfaceDeleted](){ surfaceDeleted = true; }); |
787 | |
788 | @@ -148,7 +148,6 @@ |
789 | */ |
790 | TEST_F(MirSurfaceTest, failedSurfaceCloseEventualyDestroysSurface) |
791 | { |
792 | - using namespace ::testing; |
793 | const pid_t pid = 1234; |
794 | const char appId[] = "test-app"; |
795 | |
796 | @@ -162,7 +161,7 @@ |
797 | |
798 | auto mockSurface = std::make_shared<NiceMock<ms::MockSurface>>(); |
799 | |
800 | - MirSurface *surface = new MirSurface(mockSurface, fakeSession, nullptr, nullptr, CreationHints()); |
801 | + MirSurface *surface = new MirSurface(mockSurface, fakeSession, &m_mockShell, nullptr, CreationHints()); |
802 | bool surfaceDeleted = false; |
803 | QObject::connect(surface, &QObject::destroyed, surface, [&surfaceDeleted](){ surfaceDeleted = true; }); |
804 | |
805 | |
806 | === modified file 'tests/modules/SurfaceManager/mirsurfaceitem_test.cpp' |
807 | --- tests/modules/SurfaceManager/mirsurfaceitem_test.cpp 2015-12-15 10:03:32 +0000 |
808 | +++ tests/modules/SurfaceManager/mirsurfaceitem_test.cpp 2016-05-24 21:32:26 +0000 |
809 | @@ -1,5 +1,5 @@ |
810 | /* |
811 | - * Copyright (C) 2014-2015 Canonical, Ltd. |
812 | + * Copyright (C) 2014-2016 Canonical, Ltd. |
813 | * |
814 | * This program is free software: you can redistribute it and/or modify it under |
815 | * the terms of the GNU Lesser General Public License version 3, as published by |
816 | @@ -16,16 +16,27 @@ |
817 | |
818 | #define MIR_INCLUDE_DEPRECATED_EVENT_HEADER |
819 | |
820 | +struct MirEvent {}; // otherwise won't compile otherwise due to incomplete type |
821 | + |
822 | #include <gtest/gtest.h> |
823 | |
824 | #include <QLoggingCategory> |
825 | #include <QTest> |
826 | +#include <private/qquickitem_p.h> |
827 | |
828 | // the test subject |
829 | #include <Unity/Application/mirsurfaceitem.h> |
830 | +// and friends |
831 | +#include <Unity/Application/mirsurface.h> |
832 | |
833 | // tests/framework |
834 | #include <fake_mirsurface.h> |
835 | +#include <fake_session.h> |
836 | +#include <mock_shell.h> |
837 | +#include <fake_surface.h> |
838 | + |
839 | +// tests/modules/common |
840 | +#include <surfaceobserver.h> |
841 | |
842 | using namespace qtmir; |
843 | |
844 | @@ -152,3 +163,136 @@ |
845 | delete surfaceItem2; |
846 | delete fakeSurface; |
847 | } |
848 | + |
849 | +TEST_F(MirSurfaceItemTest, NoSurfaceActiveFocusIfItemDoesNotConsumeInput) |
850 | +{ |
851 | + using namespace testing; |
852 | + |
853 | + // All the stuff qtmir::MirSurface needs |
854 | + auto fakeSession = new FakeSession(); |
855 | + std::shared_ptr<mir::scene::Surface> mockSurface = std::make_shared<mir::scene::FakeSurface>(); |
856 | + auto surfaceObserver = std::make_shared<SurfaceObserver>(); |
857 | + mir::shell::MockShell mockShell; |
858 | + |
859 | + MirSurface *surface = new MirSurface(mockSurface, fakeSession, &mockShell, surfaceObserver, CreationHints()); |
860 | + |
861 | + MirSurfaceItem *surfaceItem = new MirSurfaceItem; |
862 | + QQuickItemPrivate *surfaceItemPrivate = QQuickItemPrivate::get(surfaceItem); |
863 | + |
864 | + surfaceItem->setConsumesInput(true); |
865 | + surfaceItemPrivate->activeFocus = true; |
866 | + |
867 | + EXPECT_CALL(mockShell, set_surface_attribute(fakeSession->session(), mockSurface, mir_surface_attrib_focus, (int)mir_surface_focused)) |
868 | + .Times(AtLeast(1)); |
869 | + EXPECT_CALL(mockShell, set_surface_attribute(fakeSession->session(), mockSurface, mir_surface_attrib_focus, (int)mir_surface_unfocused)) |
870 | + .Times(0); |
871 | + |
872 | + surfaceItem->setSurface(surface); |
873 | + |
874 | + Mock::VerifyAndClearExpectations(&mockShell); |
875 | + EXPECT_CALL(mockShell, set_surface_attribute(fakeSession->session(), mockSurface, mir_surface_attrib_focus, (int)mir_surface_focused)) |
876 | + .Times(0); |
877 | + EXPECT_CALL(mockShell, set_surface_attribute(fakeSession->session(), mockSurface, mir_surface_attrib_focus, (int)mir_surface_unfocused)) |
878 | + .Times(AtLeast(1)); |
879 | + |
880 | + surfaceItem->setConsumesInput(false); |
881 | + |
882 | + Mock::VerifyAndClearExpectations(&mockShell); |
883 | + EXPECT_CALL(mockShell, set_surface_attribute(fakeSession->session(), mockSurface, mir_surface_attrib_focus, (int)mir_surface_focused)) |
884 | + .Times(AtLeast(1)); |
885 | + EXPECT_CALL(mockShell, set_surface_attribute(fakeSession->session(), mockSurface, mir_surface_attrib_focus, (int)mir_surface_unfocused)) |
886 | + .Times(0); |
887 | + |
888 | + surfaceItem->setConsumesInput(true); |
889 | + |
890 | + Mock::VerifyAndClearExpectations(&mockShell); |
891 | + EXPECT_CALL(mockShell, set_surface_attribute(fakeSession->session(), mockSurface, mir_surface_attrib_focus, (int)mir_surface_focused)) |
892 | + .Times(0); |
893 | + EXPECT_CALL(mockShell, set_surface_attribute(fakeSession->session(), mockSurface, mir_surface_attrib_focus, (int)mir_surface_unfocused)) |
894 | + .Times(AtLeast(1)); |
895 | + |
896 | + delete surfaceItem; |
897 | + |
898 | + Mock::VerifyAndClearExpectations(&mockShell); |
899 | + |
900 | + // clean up |
901 | + delete surface; |
902 | + delete fakeSession; |
903 | +} |
904 | + |
905 | +TEST_F(MirSurfaceItemTest, AggregateSurfaceActiveFocus) |
906 | +{ |
907 | + using namespace testing; |
908 | + |
909 | + // All the stuff qtmir::MirSurface needs |
910 | + auto fakeSession = new FakeSession(); |
911 | + std::shared_ptr<mir::scene::Surface> mockSurface = std::make_shared<mir::scene::FakeSurface>(); |
912 | + auto surfaceObserver = std::make_shared<SurfaceObserver>(); |
913 | + mir::shell::MockShell mockShell; |
914 | + |
915 | + MirSurface *surface = new MirSurface(mockSurface, fakeSession, &mockShell, surfaceObserver, CreationHints()); |
916 | + |
917 | + MirSurfaceItem *surfaceItem1 = new MirSurfaceItem; |
918 | + QQuickItemPrivate *surfaceItem1Private = QQuickItemPrivate::get(surfaceItem1); |
919 | + |
920 | + EXPECT_CALL(mockShell, set_surface_attribute(fakeSession->session(), mockSurface, mir_surface_attrib_focus, (int)mir_surface_focused)) |
921 | + .Times(0); |
922 | + EXPECT_CALL(mockShell, set_surface_attribute(fakeSession->session(), mockSurface, mir_surface_attrib_focus, (int)mir_surface_unfocused)); |
923 | + |
924 | + surfaceItem1->setConsumesInput(true); |
925 | + surfaceItem1Private->activeFocus = false; |
926 | + surfaceItem1->setSurface(surface); |
927 | + |
928 | + Mock::VerifyAndClearExpectations(&mockShell); |
929 | + EXPECT_CALL(mockShell, set_surface_attribute(fakeSession->session(), mockSurface, mir_surface_attrib_focus, (int)mir_surface_focused)) |
930 | + .Times(AtLeast(1)); |
931 | + EXPECT_CALL(mockShell, set_surface_attribute(fakeSession->session(), mockSurface, mir_surface_attrib_focus, (int)mir_surface_unfocused)) |
932 | + .Times(0); |
933 | + |
934 | + surfaceItem1Private->activeFocus = true; |
935 | + Q_EMIT surfaceItem1->activeFocusChanged(true); |
936 | + |
937 | + Mock::VerifyAndClearExpectations(&mockShell); |
938 | + EXPECT_CALL(mockShell, set_surface_attribute(fakeSession->session(), mockSurface, mir_surface_attrib_focus, (int)mir_surface_focused)) |
939 | + .Times(AtLeast(0)); // no harm in calling it unnecessarily |
940 | + EXPECT_CALL(mockShell, set_surface_attribute(fakeSession->session(), mockSurface, mir_surface_attrib_focus, (int)mir_surface_unfocused)) |
941 | + .Times(0); |
942 | + |
943 | + MirSurfaceItem *surfaceItem2 = new MirSurfaceItem; |
944 | + QQuickItemPrivate *surfaceItem2Private = QQuickItemPrivate::get(surfaceItem2); |
945 | + |
946 | + surfaceItem2->setConsumesInput(true); |
947 | + surfaceItem2Private->activeFocus = false; |
948 | + surfaceItem2->setSurface(surface); |
949 | + |
950 | + surfaceItem2Private->activeFocus = true; |
951 | + Q_EMIT surfaceItem2->activeFocusChanged(true); |
952 | + surfaceItem1Private->activeFocus = false; |
953 | + Q_EMIT surfaceItem1->activeFocusChanged(false); |
954 | + |
955 | + Mock::VerifyAndClearExpectations(&mockShell); |
956 | + EXPECT_CALL(mockShell, set_surface_attribute(fakeSession->session(), mockSurface, mir_surface_attrib_focus, (int)mir_surface_focused)) |
957 | + .Times(AtLeast(0)); // no harm in calling it unnecessarily |
958 | + EXPECT_CALL(mockShell, set_surface_attribute(fakeSession->session(), mockSurface, mir_surface_attrib_focus, (int)mir_surface_unfocused)) |
959 | + .Times(0); |
960 | + |
961 | + surfaceItem1Private->activeFocus = true; |
962 | + Q_EMIT surfaceItem1->activeFocusChanged(true); |
963 | + surfaceItem1->setConsumesInput(false); |
964 | + |
965 | + delete surfaceItem1; |
966 | + |
967 | + Mock::VerifyAndClearExpectations(&mockShell); |
968 | + EXPECT_CALL(mockShell, set_surface_attribute(fakeSession->session(), mockSurface, mir_surface_attrib_focus, (int)mir_surface_focused)) |
969 | + .Times(0); |
970 | + EXPECT_CALL(mockShell, set_surface_attribute(fakeSession->session(), mockSurface, mir_surface_attrib_focus, (int)mir_surface_unfocused)) |
971 | + .Times(AtLeast(1)); |
972 | + |
973 | + delete surfaceItem2; |
974 | + |
975 | + Mock::VerifyAndClearExpectations(&mockShell); |
976 | + |
977 | + // clean up |
978 | + delete surface; |
979 | + delete fakeSession; |
980 | +} |
FAILED: Continuous integration, rev:485 /unity8- jenkins. ubuntu. com/job/ lp-qtmir- ci/208/ /unity8- jenkins. ubuntu. com/job/ build-0- fetch/1545 /unity8- jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= vivid+overlay/ 1505 /unity8- jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= xenial+ overlay/ 1505 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= vivid+overlay/ 1505/console /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 1505 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 1505/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 1505 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 1505/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 1505 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 1505/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 1505 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 1505/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 1505 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 1505/artifact/ output/ *zip*/output. zip
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild: /unity8- jenkins. ubuntu. com/job/ lp-qtmir- ci/208/ rebuild
https:/