Mir

Merge lp:~alan-griffiths/mir/MVC-cleanup-of-FocusSetter into lp:mir

Proposed by Alan Griffiths
Status: Merged
Merged at revision: 2256
Proposed branch: lp:~alan-griffiths/mir/MVC-cleanup-of-FocusSetter
Merge into: lp:mir
Prerequisite: lp:~alan-griffiths/mir/MVC-introduce-default-controller-object
Diff against target: 950 lines (+199/-423)
15 files modified
src/include/server/mir/default_server_configuration.h (+0/-2)
src/include/server/mir/shell/focus_setter.h (+0/-50)
src/server/shell/CMakeLists.txt (+0/-1)
src/server/shell/default_configuration.cpp (+2/-14)
src/server/shell/default_focus_mechanism.cpp (+0/-66)
src/server/shell/default_focus_mechanism.h (+0/-60)
src/server/shell/default_shell.cpp (+30/-4)
src/server/shell/default_shell.h (+9/-4)
tests/acceptance-tests/throwback/test_focus_selection.cpp (+41/-22)
tests/include/mir_test_doubles/mock_focus_setter.h (+0/-42)
tests/include/mir_test_doubles/mock_surface_coordinator.h (+1/-0)
tests/integration-tests/test_default_shell.cpp (+96/-25)
tests/unit-tests/scene/test_session_manager.cpp (+20/-6)
tests/unit-tests/shell/CMakeLists.txt (+0/-1)
tests/unit-tests/shell/test_default_focus_mechanism.cpp (+0/-126)
To merge this branch: bzr merge lp:~alan-griffiths/mir/MVC-cleanup-of-FocusSetter
Reviewer Review Type Date Requested Status
Chris Halse Rogers Approve
Alan Griffiths Needs Information
Kevin DuBois (community) Needs Information
Robert Carr (community) Approve
Alberto Aguirre (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Alexandros Frantzis (community) Approve
Review via email: mp+247054@code.launchpad.net

Commit message

shell: merge the FocusSetter strategy into DefaultShell

Description of the change

shell: merge the FocusSetter strategy into DefaultShell

This doesn't make the "DefaultShell" controller customizable - that, and other cleanup is for a future MP

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

What is the advantage of folding this into DefaultShell?

Is it mainly to expose only a single point of customization by shells?

review: Needs Information
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

BTW, reviewing the latest Surface Management design we now finally do distinguish between the focussed and active windows. Keep it in mind that they will be different things.

Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Looks good.

698 +TEST_F(TestDefaultShellAndFocusSelectionStrategy, sets_input_focus)

I find the expectations in this test difficult to follow. The test would be clearer if it was split into separate tests for the 3 cases.

review: Approve
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> What is the advantage of folding this into DefaultShell?

FocusSetter is demonstrably not a useful abstraction - nothing (not the unity downstreams, not our proving server, nor our demo server) has ever made use of it.

> Is it mainly to expose only a single point of customization by shells?

Partly, also having all the "window management" stuff in one place will make it easier to separate out the different concerns.

As Daniel notes "focus" is not as simple a concept as the existing implementation assumes - I think that the FocusSetter interface would get in the way of changing that.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> Looks good.
>
> 698 +TEST_F(TestDefaultShellAndFocusSelectionStrategy, sets_input_focus)
>
> I find the expectations in this test difficult to follow. The test would be
> clearer if it was split into separate tests for the 3 cases.

True, but this make it clear that I have not changed the test during refactoring.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

OK.

review: Approve
Revision history for this message
Robert Carr (robertcarr) wrote :

LGTM

review: Approve
Revision history for this message
Kevin DuBois (kdub) wrote :

I was downstream yesterday, and noticed that I had to remove stuff related to the shell focus setter to get qtmir to compile, is there a branch floating around to fix qtmir with the focus setting changes? (all it wants to do is make the FocusSetter a NullFocusSetter)

review: Needs Information
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> I was downstream yesterday, and noticed that I had to remove stuff related to
> the shell focus setter to get qtmir to compile, is there a branch floating
> around to fix qtmir with the focus setting changes? (all it wants to do is
> make the FocusSetter a NullFocusSetter)

Oops! Somehow I missed that in my trawl of downstream.

This isn't directly affected by this branch (as FocusSetter has been unpublished on trunk).

I do intend a better mechanism. So we can either revert -c 2238 or land this and hope to publish the new approach soon.

review: Needs Information
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

"So we can either revert -c 2238 or land this and hope to publish the new approach soon."

I would say go for the latter.

Revision history for this message
Chris Halse Rogers (raof) wrote :

Looks sensible to me.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/include/server/mir/default_server_configuration.h'
2--- src/include/server/mir/default_server_configuration.h 2015-01-21 10:29:57 +0000
3+++ src/include/server/mir/default_server_configuration.h 2015-01-21 10:29:57 +0000
4@@ -249,7 +249,6 @@
5 /** @name shell configuration - customization
6 * configurable interfaces for modifying shell
7 * @{ */
8- virtual std::shared_ptr<shell::FocusSetter> the_shell_focus_setter();
9 virtual std::shared_ptr<scene::PlacementStrategy> the_placement_strategy();
10 virtual std::shared_ptr<scene::SessionListener> the_session_listener();
11 virtual std::shared_ptr<shell::DisplayLayout> the_shell_display_layout();
12@@ -399,7 +398,6 @@
13 CachedPtr<scene::SurfaceFactory> surface_factory;
14 CachedPtr<scene::SessionContainer> session_container;
15 CachedPtr<scene::SurfaceCoordinator> surface_coordinator;
16- CachedPtr<shell::FocusSetter> shell_focus_setter;
17 CachedPtr<scene::PlacementStrategy> shell_placement_strategy;
18 CachedPtr<scene::SessionListener> session_listener;
19 CachedPtr<scene::PixelBuffer> pixel_buffer;
20
21=== removed file 'src/include/server/mir/shell/focus_setter.h'
22--- src/include/server/mir/shell/focus_setter.h 2015-01-19 11:40:40 +0000
23+++ src/include/server/mir/shell/focus_setter.h 1970-01-01 00:00:00 +0000
24@@ -1,50 +0,0 @@
25-/*
26- * Copyright © 2012 Canonical Ltd.
27- *
28- * This program is free software: you can redistribute it and/or modify it
29- * under the terms of the GNU General Public License version 3,
30- * as published by the Free Software Foundation.
31- *
32- * This program is distributed in the hope that it will be useful,
33- * but WITHOUT ANY WARRANTY; without even the implied warranty of
34- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35- * GNU General Public License for more details.
36- *
37- * You should have received a copy of the GNU General Public License
38- * along with this program. If not, see <http://www.gnu.org/licenses/>.
39- *
40- * Authored by: Robert Carr <robert.carr@canonical.com>
41- */
42-
43-#ifndef MIR_SHELL_FOCUS_SETTER_H_
44-#define MIR_SHELL_FOCUS_SETTER_H_
45-
46-#include <memory>
47-
48-namespace mir
49-{
50-namespace scene { class Session; }
51-
52-
53-namespace shell
54-{
55-/// Interface used by the Shell to propagate changes in the focus model to interested views
56-/// e.g. Input, or Surfaces.
57-class FocusSetter
58-{
59-public:
60- virtual ~FocusSetter() {}
61-
62- virtual void set_focus_to(std::shared_ptr<scene::Session> const& new_focus) = 0;
63-
64-protected:
65- FocusSetter() = default;
66- FocusSetter(const FocusSetter&) = delete;
67- FocusSetter& operator=(const FocusSetter&) = delete;
68-};
69-
70-}
71-}
72-
73-
74-#endif // MIR_SHELL_FOCUS_SETTER_H_
75
76=== modified file 'src/server/shell/CMakeLists.txt'
77--- src/server/shell/CMakeLists.txt 2015-01-21 10:29:57 +0000
78+++ src/server/shell/CMakeLists.txt 2015-01-21 10:29:57 +0000
79@@ -1,7 +1,6 @@
80 set(
81 SHELL_SOURCES
82
83- default_focus_mechanism.cpp
84 default_placement_strategy.cpp
85 graphics_display_layout.cpp
86 default_configuration.cpp
87
88=== modified file 'src/server/shell/default_configuration.cpp'
89--- src/server/shell/default_configuration.cpp 2015-01-21 10:29:57 +0000
90+++ src/server/shell/default_configuration.cpp 2015-01-21 10:29:57 +0000
91@@ -21,7 +21,6 @@
92
93
94 #include "default_placement_strategy.h"
95-#include "default_focus_mechanism.h"
96 #include "default_shell.h"
97 #include "graphics_display_layout.h"
98
99@@ -34,7 +33,8 @@
100 return default_shell([this]
101 {
102 return std::make_shared<msh::DefaultShell>(
103- the_shell_focus_setter(),
104+ the_input_targeter(),
105+ the_surface_coordinator(),
106 the_session_coordinator());
107 });
108 }
109@@ -63,18 +63,6 @@
110 });
111 }
112
113-std::shared_ptr<msh::FocusSetter>
114-mir::DefaultServerConfiguration::the_shell_focus_setter()
115-{
116- return shell_focus_setter(
117- [this]
118- {
119- return std::make_shared<msh::DefaultFocusMechanism>(
120- the_input_targeter(),
121- the_surface_coordinator());
122- });
123-}
124-
125 std::shared_ptr<msh::DisplayLayout>
126 mir::DefaultServerConfiguration::the_shell_display_layout()
127 {
128
129=== removed file 'src/server/shell/default_focus_mechanism.cpp'
130--- src/server/shell/default_focus_mechanism.cpp 2015-01-14 06:39:13 +0000
131+++ src/server/shell/default_focus_mechanism.cpp 1970-01-01 00:00:00 +0000
132@@ -1,66 +0,0 @@
133-/*
134- * Copyright © 2012 Canonical Ltd.
135- *
136- * This program is free software: you can redistribute it and/or modify it
137- * under the terms of the GNU General Public License version 3,
138- * as published by the Free Software Foundation.
139- *
140- * This program is distributed in the hope that it will be useful,
141- * but WITHOUT ANY WARRANTY; without even the implied warranty of
142- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
143- * GNU General Public License for more details.
144- *
145- * You should have received a copy of the GNU General Public License
146- * along with this program. If not, see <http://www.gnu.org/licenses/>.
147- *
148- * Authored By: Robert Carr <robert.carr@canonical.com>
149- */
150-
151-#include "default_focus_mechanism.h"
152-#include "mir/frontend/session.h"
153-#include "mir/scene/surface_coordinator.h"
154-#include "mir/scene/surface.h"
155-#include "mir/shell/input_targeter.h"
156-#include "mir/scene/session.h"
157-#include "mir/scene/surface.h"
158-
159-namespace mf = mir::frontend;
160-namespace ms = mir::scene;
161-namespace msh = mir::shell;
162-
163-msh::DefaultFocusMechanism::DefaultFocusMechanism(std::shared_ptr<msh::InputTargeter> const& input_targeter,
164- std::shared_ptr<ms::SurfaceCoordinator> const& surface_coordinator)
165- : input_targeter(input_targeter),
166- surface_coordinator(surface_coordinator)
167-{
168-}
169-
170-void msh::DefaultFocusMechanism::set_focus_to(std::shared_ptr<ms::Session> const& focus_session)
171-{
172- // TODO: This path should be encapsulated in a seperate clear_focus message
173- if (!focus_session)
174- {
175- input_targeter->focus_cleared();
176- return;
177- }
178-
179- auto surface = focus_session->default_surface();
180- if (surface)
181- {
182- std::lock_guard<std::mutex> lg(surface_focus_lock);
183-
184- // Ensure the surface has really taken the focus before notifying it that it is focused
185- surface_coordinator->raise(surface);
186- surface->take_input_focus(input_targeter);
187-
188- auto current_focus = currently_focused_surface.lock();
189- if (current_focus)
190- current_focus->configure(mir_surface_attrib_focus, mir_surface_unfocused);
191- surface->configure(mir_surface_attrib_focus, mir_surface_focused);
192- currently_focused_surface = surface;
193- }
194- else
195- {
196- input_targeter->focus_cleared();
197- }
198-}
199
200=== removed file 'src/server/shell/default_focus_mechanism.h'
201--- src/server/shell/default_focus_mechanism.h 2015-01-14 06:39:13 +0000
202+++ src/server/shell/default_focus_mechanism.h 1970-01-01 00:00:00 +0000
203@@ -1,60 +0,0 @@
204-/*
205- * Copyright © 2012 Canonical Ltd.
206- *
207- * This program is free software: you can redistribute it and/or modify it
208- * under the terms of the GNU General Public License version 3,
209- * as published by the Free Software Foundation.
210- *
211- * This program is distributed in the hope that it will be useful,
212- * but WITHOUT ANY WARRANTY; without even the implied warranty of
213- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
214- * GNU General Public License for more details.
215- *
216- * You should have received a copy of the GNU General Public License
217- * along with this program. If not, see <http://www.gnu.org/licenses/>.
218- *
219- * Authored by: Robert Carr <robert.carr@canonical.com>
220- */
221-
222-#ifndef MIR_SHELL_SINGLE_VISIBILITY_FOCUS_MECHANISM_H_
223-#define MIR_SHELL_SINGLE_VISIBILITY_FOCUS_MECHANISM_H_
224-
225-#include "mir/shell/focus_setter.h"
226-
227-#include <memory>
228-#include <mutex>
229-
230-namespace mir
231-{
232-namespace scene { class SurfaceCoordinator; class Surface; }
233-
234-namespace shell
235-{
236-class InputTargeter;
237-
238-class DefaultFocusMechanism : public FocusSetter
239-{
240-public:
241- explicit DefaultFocusMechanism(std::shared_ptr<InputTargeter> const& input_targeter,
242- std::shared_ptr<scene::SurfaceCoordinator> const& surface_coordinator);
243- virtual ~DefaultFocusMechanism() = default;
244-
245- void set_focus_to(std::shared_ptr<scene::Session> const& new_focus);
246-
247-protected:
248- DefaultFocusMechanism(const DefaultFocusMechanism&) = delete;
249- DefaultFocusMechanism& operator=(const DefaultFocusMechanism&) = delete;
250-
251-private:
252- std::shared_ptr<InputTargeter> const input_targeter;
253- std::shared_ptr<scene::SurfaceCoordinator> const surface_coordinator;
254-
255- std::mutex surface_focus_lock;
256- std::weak_ptr<scene::Surface> currently_focused_surface;
257-};
258-
259-}
260-}
261-
262-
263-#endif // MIR_SHELL_SINGLE_VISIBILITY_FOCUS_MECHANISM_H_
264
265=== modified file 'src/server/shell/default_shell.cpp'
266--- src/server/shell/default_shell.cpp 2015-01-21 10:29:57 +0000
267+++ src/server/shell/default_shell.cpp 2015-01-21 10:29:57 +0000
268@@ -17,11 +17,12 @@
269 */
270
271 #include "default_shell.h"
272-#include "mir/shell/focus_setter.h"
273+#include "mir/shell/input_targeter.h"
274 #include "mir/scene/prompt_session.h"
275 #include "mir/scene/session_coordinator.h"
276 #include "mir/scene/session.h"
277 #include "mir/scene/surface.h"
278+#include "mir/scene/surface_coordinator.h"
279
280 #include <boost/throw_exception.hpp>
281
282@@ -32,9 +33,11 @@
283 namespace msh = mir::shell;
284
285 msh::DefaultShell::DefaultShell(
286- std::shared_ptr<FocusSetter> const& focus_setter,
287+ std::shared_ptr<InputTargeter> const& input_targeter,
288+ std::shared_ptr<scene::SurfaceCoordinator> const& surface_coordinator,
289 std::shared_ptr<scene::SessionCoordinator> const& session_coordinator) :
290- focus_setter(focus_setter),
291+ input_targeter(input_targeter),
292+ surface_coordinator(surface_coordinator),
293 session_coordinator(session_coordinator)
294 {
295 }
296@@ -164,7 +167,30 @@
297 {
298 auto old_focus = focus_application.lock();
299
300- focus_setter->set_focus_to(session);
301+ std::shared_ptr<ms::Surface> surface;
302+
303+ if (session)
304+ surface = session->default_surface();
305+
306+ if (surface)
307+ {
308+ std::lock_guard<std::mutex> lg(surface_focus_lock);
309+
310+ // Ensure the surface has really taken the focus before notifying it that it is focused
311+ surface_coordinator->raise(surface);
312+ surface->take_input_focus(input_targeter);
313+
314+ auto current_focus = currently_focused_surface.lock();
315+ if (current_focus)
316+ current_focus->configure(mir_surface_attrib_focus, mir_surface_unfocused);
317+ surface->configure(mir_surface_attrib_focus, mir_surface_focused);
318+ currently_focused_surface = surface;
319+ }
320+ else
321+ {
322+ input_targeter->focus_cleared();
323+ }
324+
325 focus_application = session;
326
327 if (session)
328
329=== modified file 'src/server/shell/default_shell.h'
330--- src/server/shell/default_shell.h 2015-01-21 10:29:57 +0000
331+++ src/server/shell/default_shell.h 2015-01-21 10:29:57 +0000
332@@ -26,17 +26,18 @@
333
334 namespace mir
335 {
336-namespace scene { class SessionCoordinator; }
337+namespace scene { class SessionCoordinator; class Surface; class SurfaceCoordinator; }
338
339 namespace shell
340 {
341-class FocusSetter;
342+class InputTargeter;
343
344 class DefaultShell : public frontend::Shell, public FocusController
345 {
346 public:
347 DefaultShell(
348- std::shared_ptr<FocusSetter> const& focus_setter,
349+ std::shared_ptr<InputTargeter> const& input_targeter,
350+ std::shared_ptr<scene::SurfaceCoordinator> const& surface_coordinator,
351 std::shared_ptr<scene::SessionCoordinator> const& session_coordinator);
352
353 void focus_next() override;
354@@ -80,9 +81,13 @@
355 MirSurfaceAttrib attrib) override;
356
357 private:
358- std::shared_ptr<FocusSetter> const focus_setter;
359+ std::shared_ptr<InputTargeter> const input_targeter;
360+ std::shared_ptr<scene::SurfaceCoordinator> const surface_coordinator;
361 std::shared_ptr<scene::SessionCoordinator> const session_coordinator;
362
363+ std::mutex surface_focus_lock;
364+ std::weak_ptr<scene::Surface> currently_focused_surface;
365+
366 std::mutex mutex;
367 std::weak_ptr<scene::Session> focus_application;
368
369
370=== modified file 'tests/acceptance-tests/throwback/test_focus_selection.cpp'
371--- tests/acceptance-tests/throwback/test_focus_selection.cpp 2015-01-14 06:39:13 +0000
372+++ tests/acceptance-tests/throwback/test_focus_selection.cpp 2015-01-21 10:29:57 +0000
373@@ -18,19 +18,18 @@
374
375 #include "clients.h"
376
377-#include "src/server/scene/session_container.h"
378-#include "src/server/scene/session_manager.h"
379+#include "mir/shell/session_coordinator_wrapper.h"
380 #include "mir/graphics/display.h"
381 #include "mir/shell/input_targeter.h"
382
383 #include "mir_test_framework/display_server_test_fixture.h"
384-#include "mir_test_doubles/mock_focus_setter.h"
385 #include "mir_test_doubles/mock_input_targeter.h"
386
387 #include <gtest/gtest.h>
388 #include <gmock/gmock.h>
389
390 namespace mf = mir::frontend;
391+namespace ms = mir::scene;
392 namespace msh = mir::shell;
393 namespace mi = mir::input;
394 namespace mt = mir::test;
395@@ -38,39 +37,59 @@
396 namespace mt = mir::test;
397 namespace mtf = mir_test_framework;
398
399+using namespace testing;
400+
401 namespace
402 {
403 MATCHER(NonNullSession, "")
404 {
405 return arg.operator bool();
406 }
407+
408+struct MockSessionManager : msh::SessionCoordinatorWrapper
409+{
410+ explicit MockSessionManager(std::shared_ptr<ms::SessionCoordinator> const& wrapped) :
411+ msh::SessionCoordinatorWrapper{wrapped}
412+ {
413+ ON_CALL(*this, set_focus_to(_)).
414+ WillByDefault(Invoke(this, &MockSessionManager::unmocked_set_focus_to));
415+
416+ ON_CALL(*this, unset_focus()).
417+ WillByDefault(Invoke(this, &MockSessionManager::unmocked_unset_focus));
418+}
419+
420+ MOCK_METHOD1(set_focus_to, void(std::shared_ptr<ms::Session> const& focus));
421+ MOCK_METHOD0(unset_focus, void());
422+
423+private:
424+ void unmocked_set_focus_to(std::shared_ptr<ms::Session> const& focus)
425+ { msh::SessionCoordinatorWrapper::set_focus_to(focus); }
426+
427+ void unmocked_unset_focus()
428+ { msh::SessionCoordinatorWrapper::unset_focus(); }
429+};
430 }
431
432 TEST_F(BespokeDisplayServerTestFixture, sessions_creating_surface_receive_focus)
433 {
434 struct ServerConfig : TestingServerConfiguration
435 {
436- std::shared_ptr<msh::FocusSetter>
437- the_shell_focus_setter() override
438+ std::shared_ptr<ms::SessionCoordinator>
439+ wrap_session_coordinator(
440+ std::shared_ptr<ms::SessionCoordinator> const& wrapped) override
441 {
442- return shell_focus_setter(
443- []
444- {
445- using namespace ::testing;
446-
447- auto focus_setter = std::make_shared<mtd::MockFocusSetter>();
448- {
449- InSequence seq;
450- // Once on application registration and once on surface creation
451- EXPECT_CALL(*focus_setter, set_focus_to(NonNullSession())).Times(2);
452- // Focus is cleared when the session is closed
453- EXPECT_CALL(*focus_setter, set_focus_to(_)).Times(1);
454- }
455- // TODO: Counterexample ~racarr
456-
457- return focus_setter;
458- });
459+ sm = std::make_shared<MockSessionManager>(wrapped);
460+
461+ InSequence seq;
462+ // Once on application registration and once on surface creation
463+ EXPECT_CALL(*sm, set_focus_to(NonNullSession())).Times(2);
464+ // Focus is cleared when the session is closed
465+ EXPECT_CALL(*sm, unset_focus()).Times(1);
466+
467+ return sm;
468 }
469+
470+ std::shared_ptr<MockSessionManager> sm;
471 } server_config;
472
473 launch_server_process(server_config);
474
475=== removed file 'tests/include/mir_test_doubles/mock_focus_setter.h'
476--- tests/include/mir_test_doubles/mock_focus_setter.h 2015-01-14 06:39:13 +0000
477+++ tests/include/mir_test_doubles/mock_focus_setter.h 1970-01-01 00:00:00 +0000
478@@ -1,42 +0,0 @@
479-/*
480- * Copyright © 2013 Canonical Ltd.
481- *
482- * This program is free software: you can redistribute it and/or modify it
483- * under the terms of the GNU General Public License version 3,
484- * as published by the Free Software Foundation.
485- *
486- * This program is distributed in the hope that it will be useful,
487- * but WITHOUT ANY WARRANTY; without even the implied warranty of
488- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
489- * GNU General Public License for more details.
490- *
491- * You should have received a copy of the GNU General Public License
492- * along with this program. If not, see <http://www.gnu.org/licenses/>.
493- *
494- * Authored by: Robert Carr <robert.carr@canonical.com>
495- */
496-
497-#ifndef MIR_TEST_DOUBLES_MOCK_FOCUS_SETTER_H_
498-#define MIR_TEST_DOUBLES_MOCK_FOCUS_SETTER_H_
499-
500-#include "mir/shell/focus_setter.h"
501-
502-#include <gmock/gmock.h>
503-
504-namespace mir
505-{
506-namespace test
507-{
508-namespace doubles
509-{
510-
511-struct MockFocusSetter : public shell::FocusSetter
512-{
513- MOCK_METHOD1(set_focus_to, void(std::shared_ptr<scene::Session> const&));
514-};
515-
516-}
517-}
518-} // namespace mir
519-
520-#endif // MIR_TEST_DOUBLES_MOCK_FOCUS_SETTER_H_
521
522=== modified file 'tests/include/mir_test_doubles/mock_surface_coordinator.h'
523--- tests/include/mir_test_doubles/mock_surface_coordinator.h 2015-01-14 06:39:13 +0000
524+++ tests/include/mir_test_doubles/mock_surface_coordinator.h 2015-01-21 10:29:57 +0000
525@@ -21,6 +21,7 @@
526 #define MIR_TEST_DOUBLES_MOCK_SURFACE_COORDINATOR_H_
527
528 #include "mir/scene/surface_coordinator.h"
529+#include "mir/scene/surface_creation_parameters.h"
530
531 #include <gmock/gmock.h>
532
533
534=== modified file 'tests/integration-tests/test_default_shell.cpp'
535--- tests/integration-tests/test_default_shell.cpp 2015-01-21 10:29:57 +0000
536+++ tests/integration-tests/test_default_shell.cpp 2015-01-21 10:29:57 +0000
537@@ -19,43 +19,48 @@
538 #include "src/server/shell/default_shell.h"
539 #include "src/server/scene/session_manager.h"
540 #include "mir/scene/session.h"
541-#include "mir/shell/focus_setter.h"
542 #include "src/server/scene/default_session_container.h"
543 #include "mir/scene/null_session_listener.h"
544-#include "mir/compositor/buffer_stream.h"
545-#include "src/server/scene/basic_surface.h"
546-#include "mir/scene/surface_creation_parameters.h"
547
548 #include "mir_test/gmock_fixes.h"
549 #include "mir_test/fake_shared.h"
550+#include "mir_test_doubles/mock_scene_session.h"
551+#include "mir_test_doubles/mock_surface.h"
552 #include "mir_test_doubles/mock_surface_coordinator.h"
553-#include "mir_test_doubles/mock_focus_setter.h"
554 #include "mir_test_doubles/null_snapshot_strategy.h"
555 #include "mir_test_doubles/null_event_sink.h"
556 #include "mir_test_doubles/null_session_event_sink.h"
557 #include "mir_test_doubles/null_prompt_session_manager.h"
558+#include "mir_test_doubles/mock_input_targeter.h"
559
560 #include <gmock/gmock.h>
561 #include <gtest/gtest.h>
562
563-namespace mc = mir::compositor;
564 namespace mf = mir::frontend;
565 namespace msh = mir::shell;
566 namespace ms = mir::scene;
567 namespace mt = mir::test;
568 namespace mtd = mir::test::doubles;
569
570+using namespace ::testing;
571+
572 namespace
573 {
574+struct MockSessionManager : ms::SessionManager
575+{
576+ using ms::SessionManager::SessionManager;
577+
578+ MOCK_METHOD1(set_focus_to, void (std::shared_ptr<ms::Session> const& focus));
579+};
580
581 struct TestDefaultShellAndFocusSelectionStrategy : public testing::Test
582 {
583- mtd::MockSurfaceCoordinator surface_coordinator; // TODO this isn't used as a mock
584+ NiceMock<mtd::MockSurfaceCoordinator> surface_coordinator;
585 ms::DefaultSessionContainer container;
586- mtd::MockFocusSetter focus_setter;
587+ NiceMock<mtd::MockInputTargeter> input_targeter;
588 std::shared_ptr<mf::Session> new_session;
589 ms::NullSessionListener session_listener;
590- ms::SessionManager session_manager
591+ NiceMock<MockSessionManager> session_manager
592 {
593 mt::fake_shared(surface_coordinator),
594 mt::fake_shared(container),
595@@ -65,62 +70,128 @@
596 std::make_shared<mtd::NullPromptSessionManager>()
597 };
598
599- msh::DefaultShell shell{mt::fake_shared(focus_setter), mt::fake_shared(session_manager)};
600+ msh::DefaultShell shell{
601+ mt::fake_shared(input_targeter),
602+ mt::fake_shared(surface_coordinator),
603+ mt::fake_shared(session_manager)};
604 };
605 }
606
607 TEST_F(TestDefaultShellAndFocusSelectionStrategy, cycle_focus)
608 {
609- using namespace ::testing;
610-
611- EXPECT_CALL(focus_setter, set_focus_to(_)).Times(3);
612+ EXPECT_CALL(session_manager, set_focus_to(_)).Times(3);
613
614 auto session1 = shell.open_session(__LINE__, "Visual Basic Studio", std::make_shared<mtd::NullEventSink>());
615 auto session2 = shell.open_session(__LINE__, "Microsoft Access", std::make_shared<mtd::NullEventSink>());
616 auto session3 = shell.open_session(__LINE__, "WordPerfect", std::make_shared<mtd::NullEventSink>());
617
618- Mock::VerifyAndClearExpectations(&focus_setter);
619+ Mock::VerifyAndClearExpectations(&session_manager);
620
621 {
622 InSequence seq;
623- EXPECT_CALL(focus_setter, set_focus_to(Eq(session1))).Times(1);
624- EXPECT_CALL(focus_setter, set_focus_to(Eq(session2))).Times(1);
625- EXPECT_CALL(focus_setter, set_focus_to(Eq(session3))).Times(1);
626+ EXPECT_CALL(session_manager, set_focus_to(Eq(session1))).Times(1);
627+ EXPECT_CALL(session_manager, set_focus_to(Eq(session2))).Times(1);
628+ EXPECT_CALL(session_manager, set_focus_to(Eq(session3))).Times(1);
629 }
630
631 shell.focus_next();
632 shell.focus_next();
633 shell.focus_next();
634
635- Mock::VerifyAndClearExpectations(&focus_setter);
636+ Mock::VerifyAndClearExpectations(&session_manager);
637
638 // Possible change of focus while sessions are closed on shutdown
639- EXPECT_CALL(focus_setter, set_focus_to(_)).Times(AtLeast(0));
640+ EXPECT_CALL(session_manager, set_focus_to(_)).Times(AnyNumber());
641 }
642
643 TEST_F(TestDefaultShellAndFocusSelectionStrategy, closing_applications_transfers_focus)
644 {
645 using namespace ::testing;
646
647- EXPECT_CALL(focus_setter, set_focus_to(_)).Times(3);
648+ EXPECT_CALL(session_manager, set_focus_to(_)).Times(3);
649
650 auto session1 = shell.open_session(__LINE__, "Visual Basic Studio", std::make_shared<mtd::NullEventSink>());
651 auto session2 = shell.open_session(__LINE__, "Microsoft Access", std::make_shared<mtd::NullEventSink>());
652 auto session3 = shell.open_session(__LINE__, "WordPerfect", std::make_shared<mtd::NullEventSink>());
653
654- Mock::VerifyAndClearExpectations(&focus_setter);
655+ Mock::VerifyAndClearExpectations(&session_manager);
656
657 {
658 InSequence seq;
659- EXPECT_CALL(focus_setter, set_focus_to(Eq(session2))).Times(1);
660- EXPECT_CALL(focus_setter, set_focus_to(Eq(session1))).Times(1);
661+ EXPECT_CALL(session_manager, set_focus_to(Eq(session2))).Times(1);
662+ EXPECT_CALL(session_manager, set_focus_to(Eq(session1))).Times(1);
663 }
664
665 shell.close_session(session3);
666 shell.close_session(session2);
667
668- Mock::VerifyAndClearExpectations(&focus_setter);
669+ Mock::VerifyAndClearExpectations(&session_manager);
670
671 // Possible change of focus while sessions are closed on shutdown
672- EXPECT_CALL(focus_setter, set_focus_to(_)).Times(AtLeast(0));
673+ EXPECT_CALL(session_manager, set_focus_to(_)).Times(AtLeast(0));
674+}
675+
676+TEST_F(TestDefaultShellAndFocusSelectionStrategy, mechanism_notifies_default_surface_of_focus_changes)
677+{
678+ using namespace ::testing;
679+
680+ NiceMock<mtd::MockSceneSession> app1, app2;
681+ auto const mock_surface1 = std::make_shared<NiceMock<mtd::MockSurface>>();
682+ auto const mock_surface2 = std::make_shared<NiceMock<mtd::MockSurface>>();
683+
684+ ON_CALL(app1, default_surface()).WillByDefault(Return(mock_surface1));
685+ ON_CALL(app2, default_surface()).WillByDefault(Return(mock_surface2));
686+
687+ InSequence seq;
688+ EXPECT_CALL(surface_coordinator, raise(_)).Times(1);
689+ EXPECT_CALL(*mock_surface1, configure(mir_surface_attrib_focus, mir_surface_focused)).Times(1);
690+ EXPECT_CALL(surface_coordinator, raise(_)).Times(1);
691+ EXPECT_CALL(*mock_surface1, configure(mir_surface_attrib_focus, mir_surface_unfocused)).Times(1);
692+ EXPECT_CALL(*mock_surface2, configure(mir_surface_attrib_focus, mir_surface_focused)).Times(1);
693+
694+ shell.set_focus_to(mt::fake_shared(app1));
695+ shell.set_focus_to(mt::fake_shared(app2));
696+}
697+
698+TEST_F(TestDefaultShellAndFocusSelectionStrategy, sets_input_focus)
699+{
700+ NiceMock<mtd::MockSceneSession> app1;
701+ NiceMock<mtd::MockSurface> mock_surface;
702+
703+ {
704+ InSequence seq;
705+ EXPECT_CALL(app1, default_surface()).Times(1)
706+ .WillOnce(Return(mt::fake_shared(mock_surface)));
707+ EXPECT_CALL(app1, default_surface()).Times(1)
708+ .WillOnce(Return(std::shared_ptr<ms::Surface>()));
709+ }
710+
711+ {
712+ InSequence seq;
713+ EXPECT_CALL(mock_surface, take_input_focus(_)).Times(1);
714+ // When we have no default surface.
715+ EXPECT_CALL(input_targeter, focus_cleared()).Times(1);
716+ // When we have no session.
717+ EXPECT_CALL(input_targeter, focus_cleared()).Times(1);
718+ }
719+ EXPECT_CALL(surface_coordinator, raise(_)).Times(1);
720+
721+ shell.set_focus_to(mt::fake_shared(app1));
722+ shell.set_focus_to(mt::fake_shared(app1));
723+ shell.set_focus_to(std::shared_ptr<ms::Session>());
724+}
725+
726+TEST_F(TestDefaultShellAndFocusSelectionStrategy, notifies_surface_of_focus_change_after_it_has_taken_the_focus)
727+{
728+ NiceMock<mtd::MockSceneSession> app;
729+ auto const mock_surface = std::make_shared<NiceMock<mtd::MockSurface>>();
730+
731+ ON_CALL(app, default_surface()).WillByDefault(Return(mock_surface));
732+
733+
734+ InSequence seq;
735+ EXPECT_CALL(*mock_surface, take_input_focus(_));
736+ EXPECT_CALL(*mock_surface, configure(mir_surface_attrib_focus, mir_surface_focused)).Times(1);
737+
738+ shell.set_focus_to(mt::fake_shared(app));
739 }
740
741=== modified file 'tests/unit-tests/scene/test_session_manager.cpp'
742--- tests/unit-tests/scene/test_session_manager.cpp 2015-01-21 10:29:57 +0000
743+++ tests/unit-tests/scene/test_session_manager.cpp 2015-01-21 10:29:57 +0000
744@@ -224,14 +224,23 @@
745 // TODO but as I'm reworking that interaction and they use mocks that only exist
746 // TODO in this file (e.g. MockSessionContainer) I've left them here temporarily.
747 #include "src/server/shell/default_shell.h"
748-#include "src/server/shell/default_focus_mechanism.h"
749-#include "mir_test_doubles/mock_focus_setter.h"
750+#include "mir_test_doubles/stub_input_targeter.h"
751
752 namespace msh = mir::shell;
753 using namespace ::testing;
754
755 namespace
756 {
757+struct MockSessionManager : ms::SessionManager
758+{
759+ using ms::SessionManager::SessionManager;
760+
761+ MOCK_METHOD1(set_focus_to, void (std::shared_ptr<ms::Session> const& focus));
762+
763+ void unmocked_set_focus_to(std::shared_ptr<ms::Session> const& focus)
764+ { ms::SessionManager::set_focus_to(focus); }
765+};
766+
767 struct DefaultShell : Test
768 {
769 mtd::MockSurfaceCoordinator surface_coordinator;
770@@ -239,7 +248,7 @@
771 NiceMock<MockSessionEventSink> session_event_sink;
772 NiceMock<mtd::MockSessionListener> session_listener;
773
774- ms::SessionManager session_manager{
775+ NiceMock<MockSessionManager> session_manager{
776 mt::fake_shared(surface_coordinator),
777 mt::fake_shared(container),
778 std::make_shared<mtd::NullSnapshotStrategy>(),
779@@ -247,12 +256,17 @@
780 mt::fake_shared(session_listener),
781 std::make_shared<mtd::NullPromptSessionManager>()};
782
783- NiceMock<mtd::MockFocusSetter> focus_setter;
784- msh::DefaultShell shell{mt::fake_shared(focus_setter), mt::fake_shared(session_manager)};
785+ mtd::StubInputTargeter input_targeter;
786+ msh::DefaultShell shell{
787+ mt::fake_shared(input_targeter),
788+ mt::fake_shared(surface_coordinator),
789+ mt::fake_shared(session_manager)};
790
791 void SetUp() override
792 {
793 ON_CALL(container, successor_of(_)).WillByDefault(Return((std::shared_ptr<ms::Session>())));
794+ ON_CALL(session_manager, set_focus_to(_)).
795+ WillByDefault(Invoke(&session_manager, &MockSessionManager::unmocked_set_focus_to));
796 }
797 };
798 }
799@@ -263,7 +277,7 @@
800 std::shared_ptr<ms::Session> new_session;
801
802 EXPECT_CALL(container, insert_session(_)).Times(1);
803- EXPECT_CALL(focus_setter, set_focus_to(_)).WillOnce(SaveArg<0>(&new_session));
804+ EXPECT_CALL(session_manager, set_focus_to(_)).WillOnce(SaveArg<0>(&new_session));
805
806 auto session = shell.open_session(__LINE__, "Visual Basic Studio", std::shared_ptr<mf::EventSink>());
807 EXPECT_EQ(session, new_session);
808
809=== modified file 'tests/unit-tests/shell/CMakeLists.txt'
810--- tests/unit-tests/shell/CMakeLists.txt 2015-01-14 06:39:13 +0000
811+++ tests/unit-tests/shell/CMakeLists.txt 2015-01-21 10:29:57 +0000
812@@ -1,7 +1,6 @@
813 list(APPEND UNIT_TEST_SOURCES
814 ${CMAKE_CURRENT_SOURCE_DIR}/test_default_placement_strategy.cpp
815 ${CMAKE_CURRENT_SOURCE_DIR}/test_graphics_display_layout.cpp
816- ${CMAKE_CURRENT_SOURCE_DIR}/test_default_focus_mechanism.cpp
817 )
818
819 set(
820
821=== removed file 'tests/unit-tests/shell/test_default_focus_mechanism.cpp'
822--- tests/unit-tests/shell/test_default_focus_mechanism.cpp 2015-01-14 06:39:13 +0000
823+++ tests/unit-tests/shell/test_default_focus_mechanism.cpp 1970-01-01 00:00:00 +0000
824@@ -1,126 +0,0 @@
825-/*
826- * Copyright © 2012 Canonical Ltd.
827- *
828- * This program is free software: you can redistribute it and/or modify
829- * it under the terms of the GNU General Public License version 3 as
830- * published by the Free Software Foundation.
831- *
832- * This program is distributed in the hope that it will be useful,
833- * but WITHOUT ANY WARRANTY; without even the implied warranty of
834- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
835- * GNU General Public License for more details.
836- *
837- * You should have received a copy of the GNU General Public License
838- * along with this program. If not, see <http://www.gnu.org/licenses/>.
839- *
840- * Authored By: Robert Carr <racarr@canonical.com>
841- */
842-
843-#include "src/server/scene/application_session.h"
844-#include "src/server/shell/default_focus_mechanism.h"
845-#include "mir/scene/session.h"
846-#include "mir/scene/surface_creation_parameters.h"
847-#include "src/server/scene/basic_surface.h"
848-#include "mir/graphics/display_configuration.h"
849-
850-#include "mir_test/fake_shared.h"
851-#include "mir_test_doubles/mock_buffer_stream.h"
852-#include "mir_test_doubles/mock_scene_session.h"
853-#include "mir_test_doubles/mock_surface.h"
854-#include "mir_test_doubles/mock_surface_coordinator.h"
855-#include "mir_test_doubles/stub_input_targeter.h"
856-#include "mir_test_doubles/mock_input_targeter.h"
857-
858-#include <gmock/gmock.h>
859-#include <gtest/gtest.h>
860-#include <string>
861-
862-namespace mc = mir::compositor;
863-namespace msh = mir::shell;
864-namespace ms = mir::scene;
865-namespace mf = mir::frontend;
866-namespace mt = mir::test;
867-namespace mtd = mir::test::doubles;
868-
869-TEST(DefaultFocusMechanism, mechanism_notifies_default_surface_of_focus_changes)
870-{
871- using namespace ::testing;
872-
873- NiceMock<mtd::MockSceneSession> app1, app2;
874- auto const mock_surface1 = std::make_shared<NiceMock<mtd::MockSurface>>();
875- auto const mock_surface2 = std::make_shared<NiceMock<mtd::MockSurface>>();
876- auto const surface_coordinator = std::make_shared<mtd::MockSurfaceCoordinator>();
877-
878- ON_CALL(app1, default_surface()).WillByDefault(Return(mock_surface1));
879- ON_CALL(app2, default_surface()).WillByDefault(Return(mock_surface2));
880-
881- msh::DefaultFocusMechanism focus_mechanism(
882- std::make_shared<mtd::StubInputTargeter>(),
883- surface_coordinator);
884-
885- InSequence seq;
886- EXPECT_CALL(*surface_coordinator, raise(_)).Times(1);
887- EXPECT_CALL(*mock_surface1, configure(mir_surface_attrib_focus, mir_surface_focused)).Times(1);
888- EXPECT_CALL(*surface_coordinator, raise(_)).Times(1);
889- EXPECT_CALL(*mock_surface1, configure(mir_surface_attrib_focus, mir_surface_unfocused)).Times(1);
890- EXPECT_CALL(*mock_surface2, configure(mir_surface_attrib_focus, mir_surface_focused)).Times(1);
891-
892- focus_mechanism.set_focus_to(mt::fake_shared(app1));
893- focus_mechanism.set_focus_to(mt::fake_shared(app2));
894-}
895-
896-TEST(DefaultFocusMechanism, sets_input_focus)
897-{
898- using namespace ::testing;
899-
900- NiceMock<mtd::MockSceneSession> app1;
901- NiceMock<mtd::MockSurface> mock_surface;
902- auto const surface_coordinator = std::make_shared<mtd::MockSurfaceCoordinator>();
903-
904- {
905- InSequence seq;
906- EXPECT_CALL(app1, default_surface()).Times(1)
907- .WillOnce(Return(mt::fake_shared(mock_surface)));
908- EXPECT_CALL(app1, default_surface()).Times(1)
909- .WillOnce(Return(std::shared_ptr<ms::Surface>()));
910- }
911-
912- NiceMock<mtd::MockInputTargeter> targeter;
913-
914- msh::DefaultFocusMechanism focus_mechanism(mt::fake_shared(targeter), surface_coordinator);
915-
916- {
917- InSequence seq;
918- EXPECT_CALL(mock_surface, take_input_focus(_)).Times(1);
919- // When we have no default surface.
920- EXPECT_CALL(targeter, focus_cleared()).Times(1);
921- // When we have no session.
922- EXPECT_CALL(targeter, focus_cleared()).Times(1);
923- }
924- EXPECT_CALL(*surface_coordinator, raise(_)).Times(1);
925-
926- focus_mechanism.set_focus_to(mt::fake_shared(app1));
927- focus_mechanism.set_focus_to(mt::fake_shared(app1));
928- focus_mechanism.set_focus_to(std::shared_ptr<ms::Session>());
929-}
930-
931-TEST(DefaultFocusMechanism, notifies_surface_of_focus_change_after_it_has_taken_the_focus)
932-{
933- using namespace ::testing;
934-
935- NiceMock<mtd::MockSceneSession> app;
936- auto const mock_surface = std::make_shared<NiceMock<mtd::MockSurface>>();
937- auto const surface_coordinator = std::make_shared<NiceMock<mtd::MockSurfaceCoordinator>>();
938-
939- ON_CALL(app, default_surface()).WillByDefault(Return(mock_surface));
940-
941- msh::DefaultFocusMechanism focus_mechanism(
942- std::make_shared<mtd::StubInputTargeter>(),
943- surface_coordinator);
944-
945- InSequence seq;
946- EXPECT_CALL(*mock_surface, take_input_focus(_));
947- EXPECT_CALL(*mock_surface, configure(mir_surface_attrib_focus, mir_surface_focused)).Times(1);
948-
949- focus_mechanism.set_focus_to(mt::fake_shared(app));
950-}

Subscribers

People subscribed via source and target branches