Merge lp:~alan-griffiths/qtmir/test-harness-for-MirWindowManager into lp:qtmir

Proposed by Alan Griffiths on 2015-10-13
Status: Merged
Approved by: Gerry Boland on 2015-10-29
Approved revision: no longer in the source branch.
Merged at revision: 402
Proposed branch: lp:~alan-griffiths/qtmir/test-harness-for-MirWindowManager
Merge into: lp:qtmir
Prerequisite: lp:~alan-griffiths/qtmir/small-refactoring-of-MirWindowManager
Diff against target: 833 lines (+795/-0)
7 files modified
tests/mirserver/CMakeLists.txt (+1/-0)
tests/mirserver/WindowManager/CMakeLists.txt (+21/-0)
tests/mirserver/WindowManager/stub_session.cpp (+125/-0)
tests/mirserver/WindowManager/stub_session.h (+59/-0)
tests/mirserver/WindowManager/stub_surface.cpp (+198/-0)
tests/mirserver/WindowManager/stub_surface.h (+67/-0)
tests/mirserver/WindowManager/window_manager.cpp (+324/-0)
To merge this branch: bzr merge lp:~alan-griffiths/qtmir/test-harness-for-MirWindowManager
Reviewer Review Type Date Requested Status
Gerry Boland 2015-10-13 Approve on 2015-10-29
PS Jenkins bot continuous-integration Needs Fixing on 2015-10-28
Michał Sawicz Needs Fixing on 2015-10-28
Review via email: mp+274221@code.launchpad.net

Commit Message

Test harness for MirWindowManager (in preparation for more intelligent window management)

Description of the Change

Test harness for MirWindowManager (in preparation for more intelligent window management)

To post a comment you must log in.
Gerry Boland (gerboland) wrote :

+// and there's not even a proper stub in the Mir-0.15 package mirtest-dev
how about mir 0.17, which will land before this will?

Alan Griffiths (alan-griffiths) wrote :

> +// and there's not even a proper stub in the Mir-0.15 package mirtest-dev
> how about mir 0.17, which will land before this will?

No, nothing much changed since then. But we can feedback to the Mir team. ;)

Gerry Boland (gerboland) wrote :

+struct AttribValuePair
+{
+ MirSurfaceAttrib attribute;
+ int value;
+ friend std::ostream& operator<<(std::ostream& out, AttribValuePair const& pair)
+ { return out << "attribute:" << pair.attribute << ", value:" << pair.value; }
+};

Qt has a QPair. STL has pair. This just for readability?

This is a decent foundation for what comes next.

Alan Griffiths (alan-griffiths) wrote :

> +struct AttribValuePair
...
> Qt has a QPair. STL has pair. This just for readability?

Yes.

    const auto attribute = GetParam().attribute;
    const auto value = GetParam().value;

is clearer than:

    const auto attribute = GetParam().first;
    const auto value = GetParam().second;

and the operator<<() injection here is cleaner than with "using AttribValuePair = std::pair<MirSurfaceAttrib, int>". C.f.

    namespace std
    {
    ostream& operator<<(ostream& out, AttribValuePair const& pair)
    { return out << "attribute:" << pair.first << ", value:" << pair.second; }
    }

Alan Griffiths (alan-griffiths) wrote :

> > +// and there's not even a proper stub in the Mir-0.15 package mirtest-dev
> > how about mir 0.17, which will land before this will?
>
> No, nothing much changed since then. But we can feedback to the Mir team. ;)

Vis: lp:~alan-griffiths/mir/dd-some-stubs-to-mirtest-dev/+merge/274262

Gerry Boland (gerboland) wrote :

LGTM

review: Approve
Michał Sawicz (saviq) wrote :

This stopped building, please the build output in:

http://s-jenkins.ubuntu-ci:8080/job/qtmir-vivid-i386-ci/111/console

review: Needs Fixing
Gerry Boland (gerboland) wrote :

Let's get this in

review: Approve
399. By Michał Sawicz on 2015-11-02

Clean up packaging and fix autopkgtest on armhf
Approved by: Gerry Boland

400. By Michael Terry on 2015-11-02

Support new isTouchApp property to ApplicationInfoInterface and move lifecycle policy logic out of qtmir.

Now that qtmir won't decide policy for suspending anymore, we don't need all the lifecycleException handling in qtmir either. That can move to unity8.

But since the GSettings key for that was registered under the qtmir namespace (and there's no technical reason to migrate settings), I left the schema and classes dealing with GSettings alone, for future use.

401. By Nick Dedekind on 2015-11-02

Support server->client visibility change to stop rendering (lp:#1475678) Fixes: #1475678
Approved by: Daniel d'Andrada

402. By Alan Griffiths on 2015-11-02

Test harness for MirWindowManager (in preparation for more intelligent window management)
Approved by: Gerry Boland

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'tests/mirserver/CMakeLists.txt'
2--- tests/mirserver/CMakeLists.txt 2015-08-20 10:16:54 +0000
3+++ tests/mirserver/CMakeLists.txt 2015-10-28 09:56:30 +0000
4@@ -2,3 +2,4 @@
5 add_subdirectory(Clipboard)
6 add_subdirectory(Screen)
7 add_subdirectory(ScreenController)
8+add_subdirectory(WindowManager)
9
10=== added directory 'tests/mirserver/WindowManager'
11=== added file 'tests/mirserver/WindowManager/CMakeLists.txt'
12--- tests/mirserver/WindowManager/CMakeLists.txt 1970-01-01 00:00:00 +0000
13+++ tests/mirserver/WindowManager/CMakeLists.txt 2015-10-28 09:56:30 +0000
14@@ -0,0 +1,21 @@
15+include_directories(
16+ ${CMAKE_SOURCE_DIR}/src/platforms/mirserver
17+ ${MIRSERVER_INCLUDE_DIRS}
18+)
19+
20+add_executable(WindowManagerTest
21+ window_manager.cpp
22+ stub_surface.cpp
23+ stub_session.cpp
24+)
25+
26+target_link_libraries(
27+ WindowManagerTest
28+
29+ qpa-mirserver
30+
31+ ${GTEST_BOTH_LIBRARIES}
32+ ${GMOCK_LIBRARIES}
33+)
34+
35+add_test(WindowManager, WindowManagerTest)
36
37=== added file 'tests/mirserver/WindowManager/stub_session.cpp'
38--- tests/mirserver/WindowManager/stub_session.cpp 1970-01-01 00:00:00 +0000
39+++ tests/mirserver/WindowManager/stub_session.cpp 2015-10-28 09:56:30 +0000
40@@ -0,0 +1,125 @@
41+/*
42+ * Copyright © 2015 Canonical Ltd.
43+ *
44+ * This program is free software: you can redistribute it and/or modify it under
45+ * the terms of the GNU Lesser General Public License version 3, as published by
46+ * the Free Software Foundation.
47+ *
48+ * This program is distributed in the hope that it will be useful, but WITHOUT
49+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
50+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
51+ * Lesser General Public License for more details.
52+ *
53+ * You should have received a copy of the GNU Lesser General Public License
54+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
55+ */
56+
57+#include "stub_session.h"
58+
59+std::shared_ptr<mir::frontend::Surface> StubSession::get_surface(
60+ mir::frontend::SurfaceId /*surface*/) const
61+{
62+ return {};
63+}
64+
65+std::string StubSession::name() const
66+{
67+ return {};
68+}
69+
70+void StubSession::force_requests_to_complete()
71+{
72+}
73+
74+pid_t StubSession::process_id() const
75+{
76+ return {0};
77+}
78+
79+void StubSession::take_snapshot(
80+ mir::scene::SnapshotCallback const& /*snapshot_taken*/)
81+{
82+}
83+
84+std::shared_ptr<mir::scene::Surface> StubSession::default_surface() const
85+{
86+ return {};
87+}
88+
89+void StubSession::set_lifecycle_state(MirLifecycleState /*state*/)
90+{
91+}
92+
93+void StubSession::send_display_config(
94+ mir::graphics::DisplayConfiguration const& /*configuration*/)
95+{
96+}
97+
98+void StubSession::hide()
99+{
100+}
101+
102+void StubSession::show()
103+{
104+}
105+
106+void StubSession::start_prompt_session()
107+{
108+}
109+
110+void StubSession::stop_prompt_session()
111+{
112+}
113+
114+void StubSession::suspend_prompt_session()
115+{
116+}
117+
118+void StubSession::resume_prompt_session()
119+{
120+}
121+
122+mir::frontend::SurfaceId StubSession::create_surface(
123+ mir::scene::SurfaceCreationParameters const& /*params*/,
124+ std::shared_ptr<mir::frontend::EventSink> const& /*sink*/)
125+{
126+ return mir::frontend::SurfaceId{0};
127+}
128+
129+void StubSession::destroy_surface(mir::frontend::SurfaceId /*surface*/)
130+{
131+}
132+
133+std::shared_ptr<mir::scene::Surface> StubSession::surface(
134+ mir::frontend::SurfaceId /*surface*/) const
135+{
136+ return {};
137+}
138+
139+std::shared_ptr<mir::scene::Surface> StubSession::surface_after(
140+ std::shared_ptr<mir::scene::Surface> const& /*ptr*/) const
141+{
142+ return {};
143+}
144+
145+std::shared_ptr<mir::frontend::BufferStream> StubSession::get_buffer_stream(
146+ mir::frontend::BufferStreamId /*stream*/) const
147+{
148+ return {};
149+}
150+
151+mir::frontend::BufferStreamId StubSession::create_buffer_stream(
152+ mir::graphics::BufferProperties const& /*props*/)
153+{
154+ return {};
155+}
156+
157+void StubSession::destroy_buffer_stream(mir::frontend::BufferStreamId /*stream*/)
158+{
159+}
160+
161+void StubSession::configure_streams(
162+ mir::scene::Surface& /*surface*/,
163+ std::vector<mir::shell::StreamSpecification> const& /*config*/)
164+{
165+}
166
167=== added file 'tests/mirserver/WindowManager/stub_session.h'
168--- tests/mirserver/WindowManager/stub_session.h 1970-01-01 00:00:00 +0000
169+++ tests/mirserver/WindowManager/stub_session.h 2015-10-28 09:56:30 +0000
170@@ -0,0 +1,59 @@
171+/*
172+ * Copyright © 2015 Canonical Ltd.
173+ *
174+ * This program is free software: you can redistribute it and/or modify it under
175+ * the terms of the GNU Lesser General Public License version 3, as published by
176+ * the Free Software Foundation.
177+ *
178+ * This program is distributed in the hope that it will be useful, but WITHOUT
179+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
180+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
181+ * Lesser General Public License for more details.
182+ *
183+ * You should have received a copy of the GNU Lesser General Public License
184+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
185+ */
186+
187+#ifndef QPAMIRSERVER_STUBSESSION_H
188+#define QPAMIRSERVER_STUBSESSION_H
189+
190+#include <mir/scene/session.h>
191+
192+struct StubSession : mir::scene::Session
193+{
194+ std::shared_ptr<mir::frontend::Surface> get_surface(mir::frontend::SurfaceId surface) const override;
195+ std::string name() const override;
196+
197+ void force_requests_to_complete() override;
198+ pid_t process_id() const override;
199+
200+ void take_snapshot(mir::scene::SnapshotCallback const& snapshot_taken) override;
201+ std::shared_ptr<mir::scene::Surface> default_surface() const override;
202+ void set_lifecycle_state(MirLifecycleState state) override;
203+ void send_display_config(mir::graphics::DisplayConfiguration const&) override;
204+
205+ void hide() override;
206+ void show() override;
207+
208+ void start_prompt_session() override;
209+ void stop_prompt_session() override;
210+ void suspend_prompt_session() override;
211+ void resume_prompt_session() override;
212+
213+ mir::frontend::SurfaceId create_surface(
214+ mir::scene::SurfaceCreationParameters const& params,
215+ std::shared_ptr<mir::frontend::EventSink> const& sink) override;
216+
217+ void destroy_surface(mir::frontend::SurfaceId surface) override;
218+
219+ std::shared_ptr<mir::scene::Surface> surface(mir::frontend::SurfaceId surface) const override;
220+ std::shared_ptr<mir::scene::Surface> surface_after(std::shared_ptr<mir::scene::Surface> const&) const override;
221+
222+ std::shared_ptr<mir::frontend::BufferStream> get_buffer_stream(mir::frontend::BufferStreamId stream) const override;
223+
224+ mir::frontend::BufferStreamId create_buffer_stream(mir::graphics::BufferProperties const& props) override;
225+ void destroy_buffer_stream(mir::frontend::BufferStreamId stream) override;
226+ void configure_streams(mir::scene::Surface& surface, std::vector<mir::shell::StreamSpecification> const& config) override;
227+};
228+
229+#endif //QPAMIRSERVER_STUBSESSION_H
230
231=== added file 'tests/mirserver/WindowManager/stub_surface.cpp'
232--- tests/mirserver/WindowManager/stub_surface.cpp 1970-01-01 00:00:00 +0000
233+++ tests/mirserver/WindowManager/stub_surface.cpp 2015-10-28 09:56:30 +0000
234@@ -0,0 +1,198 @@
235+/*
236+ * Copyright © 2015 Canonical Ltd.
237+ *
238+ * This program is free software: you can redistribute it and/or modify it under
239+ * the terms of the GNU Lesser General Public License version 3, as published by
240+ * the Free Software Foundation.
241+ *
242+ * This program is distributed in the hope that it will be useful, but WITHOUT
243+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
244+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
245+ * Lesser General Public License for more details.
246+ *
247+ * You should have received a copy of the GNU Lesser General Public License
248+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
249+ */
250+
251+#include "stub_surface.h"
252+#include <mir_toolkit/common.h>
253+//#include <mir/input/input_reception_mode.h>
254+
255+std::string StubSurface::name() const
256+{
257+ return {};
258+}
259+
260+void StubSurface::move_to(mir::geometry::Point const& /*top_left*/)
261+{
262+}
263+
264+float StubSurface::alpha() const
265+{
266+ return 0;
267+}
268+
269+mir::geometry::Size StubSurface::size() const
270+{
271+ return {};
272+}
273+
274+mir::geometry::Size StubSurface::client_size() const
275+{
276+ return {};
277+}
278+
279+std::shared_ptr <mir::frontend::BufferStream> StubSurface::primary_buffer_stream() const
280+{
281+ return {};
282+}
283+
284+void StubSurface::set_streams(std::list<mir::scene::StreamInfo> const& /*streams*/)
285+{
286+}
287+
288+bool StubSurface::supports_input() const
289+{
290+ return false;
291+}
292+
293+int StubSurface::client_input_fd() const
294+{
295+ return 0;
296+}
297+
298+std::shared_ptr <mir::input::InputChannel> StubSurface::input_channel() const
299+{
300+ return {};
301+}
302+
303+mir::input::InputReceptionMode StubSurface::reception_mode() const
304+{
305+ return mir::input::InputReceptionMode::normal;
306+}
307+
308+void StubSurface::set_reception_mode(mir::input::InputReceptionMode /*mode*/)
309+{
310+}
311+
312+void StubSurface::set_input_region(std::vector<mir::geometry::Rectangle> const& /*input_rectangles*/)
313+{
314+}
315+
316+void StubSurface::resize(mir::geometry::Size const& /*size*/)
317+{
318+}
319+
320+mir::geometry::Point StubSurface::top_left() const
321+{
322+ return {};
323+}
324+
325+mir::geometry::Rectangle StubSurface::input_bounds() const
326+{
327+ return {};
328+}
329+
330+bool StubSurface::input_area_contains(mir::geometry::Point const& /*point*/) const
331+{
332+ return false;
333+}
334+
335+void StubSurface::consume(MirEvent const& /*event*/)
336+{
337+}
338+
339+void StubSurface::set_alpha(float /*alpha*/)
340+{
341+}
342+
343+void StubSurface::set_orientation(MirOrientation /*orientation*/)
344+{
345+}
346+
347+void StubSurface::set_transformation(glm::mat4 const& /*mat4*/)
348+{
349+}
350+
351+bool StubSurface::visible() const
352+{
353+ return false;
354+}
355+
356+mir::graphics::RenderableList StubSurface::generate_renderables(mir::compositor::CompositorID /*id*/) const
357+{
358+ return {};
359+}
360+
361+int StubSurface::buffers_ready_for_compositor(void const* /*compositor_id*/) const
362+{
363+ return 0;
364+}
365+
366+MirSurfaceType StubSurface::type() const
367+{
368+ return MirSurfaceType::mir_surface_type_normal;
369+}
370+
371+MirSurfaceState StubSurface::state() const
372+{
373+ return MirSurfaceState::mir_surface_state_fullscreen;
374+}
375+
376+int StubSurface::configure(MirSurfaceAttrib /*attrib*/, int value)
377+{
378+ return value;
379+}
380+
381+int StubSurface::query(MirSurfaceAttrib /*attrib*/) const
382+{
383+ return 0;
384+}
385+
386+void StubSurface::hide()
387+{
388+}
389+
390+void StubSurface::show()
391+{
392+}
393+
394+void StubSurface::set_cursor_image(std::shared_ptr<mir::graphics::CursorImage> const& /*image*/)
395+{
396+}
397+
398+std::shared_ptr<mir::graphics::CursorImage> StubSurface::cursor_image() const
399+{
400+ return {};
401+}
402+
403+void StubSurface::set_cursor_stream(
404+ std::shared_ptr<mir::frontend::BufferStream> const& /*stream*/,
405+ mir::geometry::Displacement const& /*hotspot*/)
406+{
407+}
408+
409+void StubSurface::request_client_surface_close()
410+{
411+}
412+
413+std::shared_ptr<mir::scene::Surface> StubSurface::parent() const
414+{
415+ return {};
416+}
417+
418+void StubSurface::add_observer(std::shared_ptr<mir::scene::SurfaceObserver> const& /*observer*/)
419+{
420+}
421+
422+void StubSurface::remove_observer(std::weak_ptr < mir::scene::SurfaceObserver > const& /*observer*/)
423+{
424+}
425+
426+void StubSurface::set_keymap(xkb_rule_names const& /*rules*/)
427+{
428+}
429+
430+void StubSurface::rename(std::string const& /*title*/)
431+{
432+}
433
434=== added file 'tests/mirserver/WindowManager/stub_surface.h'
435--- tests/mirserver/WindowManager/stub_surface.h 1970-01-01 00:00:00 +0000
436+++ tests/mirserver/WindowManager/stub_surface.h 2015-10-28 09:56:30 +0000
437@@ -0,0 +1,67 @@
438+/*
439+ * Copyright © 2015 Canonical Ltd.
440+ *
441+ * This program is free software: you can redistribute it and/or modify it
442+ * under the terms of the GNU General Public License version 3,
443+ * as published by the Free Software Foundation.
444+ *
445+ * This program is distributed in the hope that it will be useful,
446+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
447+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
448+ * GNU General Public License for more details.
449+ *
450+ * You should have received a copy of the GNU General Public License
451+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
452+ */
453+
454+#ifndef QPAMIRSERVER_STUB_SURFACE_H
455+#define QPAMIRSERVER_STUB_SURFACE_H
456+
457+#include <mir/scene/surface.h>
458+
459+// mir::scene::Surface is a horribly wide interface to expose from Mir
460+// and there's not even a proper stub in the Mir-0.15 package mirtest-dev
461+struct StubSurface : mir::scene::Surface
462+{
463+ std::string name() const override;
464+ void move_to(mir::geometry::Point const& top_left) override;
465+ float alpha() const override;
466+ mir::geometry::Size size() const override;
467+ mir::geometry::Size client_size() const override;
468+ std::shared_ptr<mir::frontend::BufferStream> primary_buffer_stream() const override;
469+ void set_streams(std::list<mir::scene::StreamInfo> const& streams) override;
470+ bool supports_input() const override;
471+ int client_input_fd() const override;
472+ std::shared_ptr<mir::input::InputChannel> input_channel() const override;
473+ mir::input::InputReceptionMode reception_mode() const override;
474+ void set_reception_mode(mir::input::InputReceptionMode mode) override;
475+ void set_input_region(std::vector<mir::geometry::Rectangle> const& input_rectangles) override;
476+ void resize(mir::geometry::Size const& size) override;
477+ mir::geometry::Point top_left() const override;
478+ mir::geometry::Rectangle input_bounds() const override;
479+ bool input_area_contains(mir::geometry::Point const& point) const override;
480+ void consume(MirEvent const& event) override;
481+ void set_alpha(float alpha) override;
482+ void set_orientation(MirOrientation orientation) override;
483+ void set_transformation(glm::mat4 const&) override;
484+ bool visible() const override;
485+ mir::graphics::RenderableList generate_renderables(mir::compositor::CompositorID id) const override;
486+ int buffers_ready_for_compositor(void const* compositor_id) const override;
487+ MirSurfaceType type() const override;
488+ MirSurfaceState state() const override;
489+ int configure(MirSurfaceAttrib attrib, int value) override;
490+ int query(MirSurfaceAttrib attrib) const override;
491+ void hide() override;
492+ void show() override;
493+ void set_cursor_image(std::shared_ptr<mir::graphics::CursorImage> const& image) override;
494+ std::shared_ptr<mir::graphics::CursorImage> cursor_image() const override;
495+ void set_cursor_stream(std::shared_ptr<mir::frontend::BufferStream> const& stream, mir::geometry::Displacement const& hotspot) override;
496+ void request_client_surface_close() override;
497+ std::shared_ptr<Surface> parent() const override;
498+ void add_observer(std::shared_ptr<mir::scene::SurfaceObserver> const& observer) override;
499+ void remove_observer(std::weak_ptr<mir::scene::SurfaceObserver> const& observer) override;
500+ void set_keymap(xkb_rule_names const& rules) override;
501+ void rename(std::string const& title) override;
502+};
503+
504+#endif //QPAMIRSERVER_STUB_SURFACE_H
505
506=== added file 'tests/mirserver/WindowManager/window_manager.cpp'
507--- tests/mirserver/WindowManager/window_manager.cpp 1970-01-01 00:00:00 +0000
508+++ tests/mirserver/WindowManager/window_manager.cpp 2015-10-28 09:56:30 +0000
509@@ -0,0 +1,324 @@
510+/*
511+ * Copyright (C) 2015 Canonical, Ltd.
512+ *
513+ * This program is free software: you can redistribute it and/or modify it under
514+ * the terms of the GNU Lesser General Public License version 3, as published by
515+ * the Free Software Foundation.
516+ *
517+ * This program is distributed in the hope that it will be useful, but WITHOUT
518+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
519+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
520+ * Lesser General Public License for more details.
521+ *
522+ * You should have received a copy of the GNU Lesser General Public License
523+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
524+ *
525+ */
526+
527+#include "mirwindowmanager.h"
528+#include "stub_surface.h"
529+#include "stub_session.h"
530+
531+#include <mir/events/event_builders.h>
532+#include <mir/scene/surface_creation_parameters.h>
533+#include <mir/shell/display_layout.h>
534+#include <mir/shell/focus_controller.h>
535+
536+#include "gtest/gtest.h"
537+#include "gmock/gmock.h"
538+
539+namespace mf = mir::frontend;
540+namespace ms = mir::scene;
541+namespace msh = mir::shell;
542+
543+using namespace mir::geometry;
544+using namespace testing;
545+
546+using mir::events::make_event;
547+
548+namespace
549+{
550+struct MockDisplayLayout : msh::DisplayLayout
551+{
552+ MOCK_METHOD1(clip_to_output, void (Rectangle& rect));
553+ MOCK_METHOD1(size_to_output, void (Rectangle& rect));
554+ MOCK_METHOD2(place_in_output, void (mir::graphics::DisplayConfigurationOutputId id, Rectangle& rect));
555+};
556+
557+struct MockSurface : StubSurface
558+{
559+ MOCK_METHOD2(configure, int (MirSurfaceAttrib attrib, int value));
560+};
561+
562+struct MockSession : StubSession
563+{
564+ MOCK_CONST_METHOD1(surface, std::shared_ptr<ms::Surface> (mir::frontend::SurfaceId surface));
565+};
566+
567+struct StubFocusController : msh::FocusController
568+{
569+public:
570+ void focus_next_session() override {}
571+
572+ std::shared_ptr<ms::Session> focused_session() const override { return {}; }
573+
574+ void set_focus_to(
575+ std::shared_ptr<ms::Session> const& /*focus_session*/,
576+ std::shared_ptr<ms::Surface> const& /*focus_surface*/) override {}
577+
578+ std::shared_ptr<ms::Surface> focused_surface() const override { return {}; }
579+
580+ std::shared_ptr<ms::Surface> surface_at(Point /*cursor*/) const override { return {}; }
581+
582+ void raise(msh::SurfaceSet const& /*surfaces*/) override {}
583+};
584+
585+
586+struct WindowManager : Test
587+{
588+ const std::shared_ptr<MockDisplayLayout> mock_display_layout =
589+ std::make_shared<NiceMock<MockDisplayLayout>>();
590+
591+ StubFocusController focus_controller;
592+
593+ const std::unique_ptr<MirWindowManager> window_manager =
594+ MirWindowManager::create(&focus_controller, mock_display_layout);
595+
596+ const Rectangle arbitrary_display{{0, 0}, {97, 101}};
597+ const std::shared_ptr<MockSession> arbitrary_session = std::make_shared<NiceMock<MockSession>>();
598+ const std::shared_ptr<ms::Surface> arbitrary_surface = std::make_shared<StubSurface>();
599+ const ms::SurfaceCreationParameters arbitrary_params;
600+ const mf::SurfaceId arbitrary_surface_id{__LINE__};
601+
602+ MOCK_METHOD2(build_surface, mf::SurfaceId(std::shared_ptr<ms::Session> const& session, ms::SurfaceCreationParameters const& params));
603+
604+ void SetUp() override
605+ {
606+ ON_CALL(*this, build_surface(_, _)).WillByDefault(Return(arbitrary_surface_id));
607+ ON_CALL(*arbitrary_session, surface(_)).WillByDefault(Return(arbitrary_surface));
608+
609+ window_manager->add_session(arbitrary_session);
610+ }
611+
612+ void TearDown() override
613+ {
614+ window_manager->remove_session(arbitrary_session);
615+ }
616+
617+ void add_surface()
618+ {
619+ EXPECT_CALL(*this, build_surface(_, _));
620+
621+ window_manager->add_surface(
622+ arbitrary_session,
623+ arbitrary_params,
624+ [this](std::shared_ptr<ms::Session> const& session, ms::SurfaceCreationParameters const& params)
625+ {
626+ return build_surface(session, params);
627+ });
628+ }
629+
630+ static constexpr uint64_t arbitrary_mac = __LINE__;
631+};
632+}
633+
634+TEST_F(WindowManager, CreatesSurfaceUsingSuppliedBuilder)
635+{
636+ EXPECT_CALL(*this, build_surface(_, _));
637+
638+ const auto surface = window_manager->add_surface(
639+ arbitrary_session,
640+ arbitrary_params,
641+ [this](std::shared_ptr<ms::Session> const& session, ms::SurfaceCreationParameters const& params)
642+ {
643+ return build_surface(session, params);
644+ });
645+
646+ EXPECT_THAT(surface, Eq(arbitrary_surface_id));
647+}
648+
649+TEST_F(WindowManager, SizesNewSurfaceToOutput)
650+{
651+ EXPECT_CALL(*this, build_surface(_, _)).Times(AnyNumber());
652+
653+ const Size request_size{0, 0};
654+ const Size expect_size{57, 91};
655+
656+ ms::SurfaceCreationParameters params;
657+ params.size = request_size;
658+
659+ EXPECT_CALL(*mock_display_layout, size_to_output(_)).
660+ WillOnce(Invoke([&](Rectangle& rect)
661+ {
662+ EXPECT_THAT(rect.size, Eq(request_size));
663+ rect.size = expect_size;
664+ }));
665+
666+ add_surface();
667+}
668+
669+namespace
670+{
671+struct AttribValuePair
672+{
673+ MirSurfaceAttrib attribute;
674+ int value;
675+ friend std::ostream& operator<<(std::ostream& out, AttribValuePair const& pair)
676+ { return out << "attribute:" << pair.attribute << ", value:" << pair.value; }
677+};
678+struct SetAttribute : WindowManager, ::testing::WithParamInterface<AttribValuePair> {};
679+}
680+
681+TEST_P(SetAttribute, ConfiguresSurface)
682+{
683+ const auto attribute = GetParam().attribute;
684+ const auto value = GetParam().value;
685+
686+ const auto surface = std::make_shared<MockSurface>();
687+
688+ EXPECT_CALL(*arbitrary_session, surface(_)).Times(AnyNumber()).WillRepeatedly(Return(surface));
689+ add_surface();
690+
691+ EXPECT_CALL(*surface, configure(attribute, value)).WillOnce(Return(value));
692+
693+ window_manager->set_surface_attribute(arbitrary_session, surface, attribute, value);
694+}
695+
696+INSTANTIATE_TEST_CASE_P(WindowManager, SetAttribute,
697+ Values(
698+ AttribValuePair{mir_surface_attrib_state, mir_surface_state_restored},
699+ AttribValuePair{mir_surface_attrib_state, mir_surface_state_minimized},
700+ AttribValuePair{mir_surface_attrib_state, mir_surface_state_maximized},
701+ AttribValuePair{mir_surface_attrib_state, mir_surface_state_vertmaximized},
702+ AttribValuePair{mir_surface_attrib_state, mir_surface_state_fullscreen},
703+ AttribValuePair{mir_surface_attrib_state, mir_surface_state_horizmaximized},
704+ AttribValuePair{mir_surface_attrib_state, mir_surface_state_hidden},
705+
706+ AttribValuePair{mir_surface_attrib_type, mir_surface_type_normal},
707+ AttribValuePair{mir_surface_attrib_type, mir_surface_type_utility},
708+ AttribValuePair{mir_surface_attrib_type, mir_surface_type_dialog},
709+ AttribValuePair{mir_surface_attrib_type, mir_surface_type_overlay},
710+ AttribValuePair{mir_surface_attrib_type, mir_surface_type_freestyle},
711+ AttribValuePair{mir_surface_attrib_type, mir_surface_type_popover},
712+ AttribValuePair{mir_surface_attrib_type, mir_surface_type_inputmethod},
713+ AttribValuePair{mir_surface_attrib_type, mir_surface_type_satellite},
714+ AttribValuePair{mir_surface_attrib_type, mir_surface_type_tip},
715+
716+ AttribValuePair{mir_surface_attrib_preferred_orientation, mir_orientation_mode_portrait},
717+ AttribValuePair{mir_surface_attrib_preferred_orientation, mir_orientation_mode_landscape},
718+ AttribValuePair{mir_surface_attrib_preferred_orientation, mir_orientation_mode_portrait_inverted},
719+ AttribValuePair{mir_surface_attrib_preferred_orientation, mir_orientation_mode_landscape_inverted},
720+ AttribValuePair{mir_surface_attrib_preferred_orientation, mir_orientation_mode_portrait_any},
721+ AttribValuePair{mir_surface_attrib_preferred_orientation, mir_orientation_mode_landscape_any},
722+ AttribValuePair{mir_surface_attrib_preferred_orientation, mir_orientation_mode_any}
723+ ));
724+
725+// The following calls are /currently/ ignored, but we can check they don't "blow up"
726+TEST_F(WindowManager, HandlesAddSession)
727+{
728+ EXPECT_NO_THROW(window_manager->add_session(arbitrary_session));
729+}
730+
731+TEST_F(WindowManager, HandlesRemoveSession)
732+{
733+ EXPECT_NO_THROW(window_manager->remove_session(arbitrary_session));
734+}
735+
736+TEST_F(WindowManager, HandlesAddDisplay)
737+{
738+ EXPECT_NO_THROW(window_manager->add_display(arbitrary_display));
739+}
740+
741+TEST_F(WindowManager, HandlesRemoveDisplay)
742+{
743+ EXPECT_NO_THROW(window_manager->remove_display(arbitrary_display));
744+}
745+
746+TEST_F(WindowManager, HandlesModifySurface)
747+{
748+ add_surface();
749+
750+ msh::SurfaceSpecification spec;
751+
752+ EXPECT_NO_THROW(
753+ window_manager->modify_surface(arbitrary_session, arbitrary_surface, spec);
754+ );
755+
756+ window_manager->remove_surface(arbitrary_session, arbitrary_surface);
757+}
758+
759+TEST_F(WindowManager, HandlesKeyboardEvent)
760+{
761+ const MirInputDeviceId arbitrary_device{0};
762+ const auto arbitrary_timestamp = std::chrono::steady_clock().now().time_since_epoch();
763+ const auto arbitrary_action = mir_keyboard_action_down;
764+ const xkb_keysym_t arbitrary_key_code{0};
765+ const int arbitrary_scan_code = 0;
766+ const MirInputEventModifiers arbitrary_event_modifiers{0};
767+
768+ const auto generic_event = make_event(
769+ arbitrary_device,
770+ arbitrary_timestamp,
771+ arbitrary_mac,
772+ arbitrary_action,
773+ arbitrary_key_code,
774+ arbitrary_scan_code,
775+ arbitrary_event_modifiers);
776+
777+ const auto input_event = mir_event_get_input_event(generic_event.get());
778+ const auto event = mir_input_event_get_keyboard_event(input_event);
779+
780+ EXPECT_NO_THROW(window_manager->handle_keyboard_event(event));
781+}
782+
783+TEST_F(WindowManager, HandlesTouchEvent)
784+{
785+ const MirInputDeviceId arbitrary_device{0};
786+ const auto arbitrary_timestamp = std::chrono::steady_clock().now().time_since_epoch();
787+ const MirInputEventModifiers arbitrary_event_modifiers{0};
788+
789+ const auto generic_event = make_event(
790+ arbitrary_device,
791+ arbitrary_timestamp,
792+ arbitrary_mac,
793+ arbitrary_event_modifiers);
794+
795+ const auto input_event = mir_event_get_input_event(generic_event.get());
796+ const auto event = mir_input_event_get_touch_event(input_event);
797+
798+ EXPECT_NO_THROW(window_manager->handle_touch_event(event));
799+}
800+
801+TEST_F(WindowManager, HandlesPointerEvent)
802+{
803+ const MirInputDeviceId arbitrary_device{0};
804+ const auto arbitrary_timestamp = std::chrono::steady_clock().now().time_since_epoch();
805+ const MirInputEventModifiers arbitrary_event_modifiers{0};
806+ const auto arbitrary_pointer_action = mir_pointer_action_button_down;
807+ const auto arbitrary_pointer_buttons = mir_pointer_button_primary;
808+ const float arbitrary_x_axis_value{0};
809+ const float arbitrary_y_axis_value{0};
810+ const float arbitrary_hscroll_value{0};
811+ const float arbitrary_vscroll_value{0};
812+ const float arbitrary_relative_x_value{0};
813+ const float arbitrary_relative_y_value{0};
814+
815+ const auto generic_event = make_event(
816+ arbitrary_device,
817+ arbitrary_timestamp,
818+ arbitrary_mac,
819+ arbitrary_event_modifiers,
820+ arbitrary_pointer_action,
821+ arbitrary_pointer_buttons,
822+ arbitrary_x_axis_value,
823+ arbitrary_y_axis_value,
824+ arbitrary_hscroll_value,
825+ arbitrary_vscroll_value,
826+ arbitrary_relative_x_value,
827+ arbitrary_relative_y_value);
828+
829+ const auto input_event = mir_event_get_input_event(generic_event.get());
830+ const auto event = mir_input_event_get_pointer_event(input_event);
831+
832+ EXPECT_NO_THROW(window_manager->handle_pointer_event(event));
833+}

Subscribers

People subscribed via source and target branches