Merge lp:~dandrader/qtmir/fixActiveFocusUpdate into lp:qtmir

Proposed by Daniel d'Andrada
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
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.

To post a comment you must log in.
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:485
https://unity8-jenkins.ubuntu.com/job/lp-qtmir-ci/208/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/1545
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1505
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/1505
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1505/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1505
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1505/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1505
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1505/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1505
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1505/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1505
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1505/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/1505
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/1505/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Nick Dedekind (nick-dedekind) wrote : Posted in a previous version of this proposal

Looks fine.

review: Approve
Revision history for this message
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://code.launchpad.net/~nick-dedekind/unity8/sidestage-fixes

Revision history for this message
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=Shell::test_lifecyclePolicyForNonTouchApp) when the consumesInput is bound to interactive in https://code.launchpad.net/~unity-team/unity8/sidestage-fixes/+merge/295130.

Problem arises from the active focus not being passed through when consumesInput=false, even if the surfaceItem does not have active focus.

review: Needs Fixing
Revision history for this message
Nick Dedekind (nick-dedekind) wrote : Posted in a previous version of this proposal

perhaps:

void MirSurfaceItem::updateMirSurfaceActiveFocus()
{
    if (m_surface && m_surface->live()) {
        m_surface->setActiveFocus(hasActiveFocus() && m_consumesInput);
    }
}

Revision history for this message
Nick Dedekind (nick-dedekind) wrote : Posted in a previous version of this proposal

and updateMirSurfaceActiveFocus always needs calling when consumeInput changes.

Revision history for this message
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

> and updateMirSurfaceActiveFocus always needs calling when consumeInput
> changes.

Imagine multiple views per surface:

- View A: hasActiveFocus()=true, m_consumesInput=true (e.g. main view in desktop stage)
- View B: hasActiveFocus()=false, m_consumesInput=true (e.g. spread view in desktop stage)
- 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...

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:490
https://unity8-jenkins.ubuntu.com/job/lp-qtmir-ci/233/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/1725
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1674
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/1674
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1667
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1667/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1667
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1667/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/1667/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1667
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1667/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1667
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1667/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/1667/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1667
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1667/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/1667
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/1667/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/1667/console

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

An all-new patch. Should work in all situations now.

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

FAILED: Continuous integration, rev:490
https://unity8-jenkins.ubuntu.com/job/lp-qtmir-ci/234/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/1740
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1688
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/1688
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/1688
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1681/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1681/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/1681/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1681/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1681/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/1681/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1681/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/1681/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/1681/console

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

review: Needs Fixing (continuous-integration)
491. By Daniel d'Andrada

Remove dead code

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

PASSED: Continuous integration, rev:491
https://unity8-jenkins.ubuntu.com/job/lp-qtmir-ci/235/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/1741
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1689
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/1689
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/1689
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1682
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1682/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1682
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1682/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/1682
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/1682/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1682
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1682/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1682
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1682/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/1682
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/1682/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1682
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1682/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/1682
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/1682/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/1682
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/1682/artifact/output/*zip*/output.zip

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

review: Approve (continuous-integration)
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

Looks fine.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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+}

Subscribers

People subscribed via source and target branches