Merge lp:~alan-griffiths/miral/1.4 into lp:miral/zesty

Proposed by Alan Griffiths
Status: Rejected
Rejected by: Alan Griffiths
Proposed branch: lp:~alan-griffiths/miral/1.4
Merge into: lp:miral/zesty
Diff against target: 4800 lines (+1757/-1089)
63 files modified
CMakeLists.txt (+18/-23)
debian/changelog (+17/-2)
debian/control (+4/-9)
debian/libmiral2.symbols (+4/-0)
doc/introducing_the_miral_api.md (+2/-2)
include/mir/client/detail/mir_forward_compatibility.h (+0/-172)
include/mir/client/display_config.h (+0/-5)
include/mir/client/surface.h (+50/-0)
include/mir/client/window.h (+0/-12)
include/mir/client/window_id.h (+0/-17)
include/mir/client/window_spec.h (+36/-121)
include/miral/cursor_theme.h (+2/-2)
include/miral/window_management_policy.h (+0/-2)
include/miral/window_management_policy_addendum2.h (+70/-0)
include/miral/window_manager_tools.h (+12/-0)
include/miral/window_specification.h (+0/-2)
miral-kiosk/sw_splash.cpp (+29/-7)
miral-shell/CMakeLists.txt (+4/-5)
miral-shell/decoration_provider.cpp (+72/-47)
miral-shell/decoration_provider.h (+7/-1)
miral-shell/floating_window_manager.cpp (+23/-23)
miral-shell/floating_window_manager.h (+7/-7)
miral-shell/miral-app.sh (+1/-1)
miral-shell/miral-desktop.sh (+1/-1)
miral-shell/miral-run.sh (+1/-1)
miral-shell/miral-screencast.sh (+1/-1)
miral-shell/miral-xrun.sh (+1/-0)
miral-shell/shell_main.cpp (+3/-3)
miral-shell/spinner/CMakeLists.txt (+1/-0)
miral-shell/spinner/eglapp.cpp (+19/-100)
miral-shell/spinner/eglspinner.cpp (+2/-0)
miral-shell/spinner/miregl.cpp (+30/-39)
miral-shell/spinner/miregl.h (+7/-7)
miral/CMakeLists.txt (+53/-55)
miral/active_outputs.cpp (+1/-76)
miral/basic_window_manager.cpp (+76/-27)
miral/basic_window_manager.h (+14/-0)
miral/both_versions.h (+2/-7)
miral/cursor_theme.cpp (+7/-0)
miral/keymap.cpp (+0/-16)
miral/mir_features.h.in (+0/-29)
miral/mru_window_list.cpp (+0/-1)
miral/runner.cpp (+0/-15)
miral/set_window_management_policy.cpp (+0/-4)
miral/symbols.map (+21/-0)
miral/window_management_options.cpp (+1/-5)
miral/window_management_trace.cpp (+18/-0)
miral/window_management_trace.h (+2/-0)
miral/window_manager_tools.cpp (+6/-0)
miral/window_manager_tools_implementation.h (+3/-0)
miral/window_specification.cpp (+0/-57)
scripts/process_doxygen_xml.py (+12/-1)
test/CMakeLists.txt (+13/-1)
test/active_window.cpp (+76/-62)
test/client_mediated_gestures.cpp (+295/-0)
test/drag_and_drop.cpp (+653/-0)
test/select_active_window.cpp (+0/-2)
test/test_server.cpp (+0/-13)
test/test_server.h (+0/-1)
test/window_id.cpp (+3/-45)
test/window_placement_client_api.cpp (+2/-20)
test/window_properties.cpp (+23/-12)
test/workspaces.cpp (+52/-28)
To merge this branch: bzr merge lp:~alan-griffiths/miral/1.4
Reviewer Review Type Date Requested Status
Mir development team Pending
Review via email: mp+325737@code.launchpad.net

Description of the change

Merge MirAL 1.4 into zesty

To post a comment you must log in.
lp:~alan-griffiths/miral/1.4 updated
361. By Alan Griffiths

Merge lp:miral for 1.4

Unmerged revisions

361. By Alan Griffiths

Merge lp:miral for 1.4

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2017-03-24 17:44:48 +0000
3+++ CMakeLists.txt 2017-06-20 16:14:05 +0000
4@@ -1,16 +1,12 @@
5-cmake_minimum_required(VERSION 3.1)
6+cmake_minimum_required(VERSION 3.5)
7+cmake_policy(SET CMP0015 NEW)
8+cmake_policy(SET CMP0022 NEW)
9+
10 project(miral)
11
12-if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
13- set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "/usr install prefix" FORCE)
14-endif()
15-
16 include (GNUInstallDirs)
17 include(CheckCXXCompilerFlag)
18
19-cmake_policy(SET CMP0015 NEW)
20-cmake_policy(SET CMP0022 NEW)
21-
22 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
23
24 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
25@@ -36,16 +32,21 @@
26
27 include(FindPkgConfig)
28
29-pkg_check_modules(MIRCLIENT mirclient>=0.20 REQUIRED)
30+pkg_check_modules(MIRCLIENT mirclient>=0.26 REQUIRED)
31
32 include_directories(include SYSTEM ${MIRCLIENT_INCLUDE_DIRS})
33
34 set(MIRAL_VERSION_MAJOR 1)
35-set(MIRAL_VERSION_MINOR 3)
36-set(MIRAL_VERSION_PATCH 2)
37+set(MIRAL_VERSION_MINOR 4)
38+set(MIRAL_VERSION_PATCH 0)
39
40 set(MIRAL_VERSION ${MIRAL_VERSION_MAJOR}.${MIRAL_VERSION_MINOR}.${MIRAL_VERSION_PATCH})
41
42+if (MIRCLIENT_VERSION VERSION_LESS 0.26.3)
43+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations")
44+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-declarations")
45+endif()
46+
47 add_subdirectory(miral)
48 add_subdirectory(miral-shell)
49 add_subdirectory(miral-kiosk)
50@@ -54,19 +55,13 @@
51 if(NOT MIRTEST_FOUND)
52 message(WARNING "mirtest-dev package not installed - tests cannot be built")
53 else()
54- if (MIRTEST_VERSION VERSION_LESS 0.24)
55- # building the tests is disabled by default because the mirtest-dev package is broken on xenial
56- # (lp:1583536 and lp:1603080)
57- option(MIRAL_ENABLE_TESTS "Build tests" off)
58- else()
59- option(MIRAL_ENABLE_TESTS "Build tests" on)
60+ option(MIRAL_ENABLE_TESTS "Build tests" on)
61+
62+ if (MIRAL_ENABLE_TESTS)
63+ enable_testing()
64+ find_package(GMock REQUIRED)
65+ add_subdirectory(test)
66 endif()
67-
68-if (MIRAL_ENABLE_TESTS)
69- enable_testing()
70- find_package(GMock REQUIRED)
71- add_subdirectory(test)
72-endif()
73 endif()
74
75 include (cmake/Doxygen.cmake)
76
77=== modified file 'debian/changelog'
78--- debian/changelog 2017-03-30 14:18:38 +0000
79+++ debian/changelog 2017-06-20 16:14:05 +0000
80@@ -1,3 +1,18 @@
81+miral (1.4.0) UNRELEASED; urgency=medium
82+
83+ * New upstream release 1.4.0 (https://launchpad.net/miral/+milestone/1.4.0)
84+ - ABI summary:
85+ . miral ABI unchanged at 2
86+ - Enhancements:
87+ . Support for passing messages to enable Drag & Drop
88+ . Support for client requested move
89+ . Port to the undeprecated Mir APIs
90+ . Added "--cursor-theme" option when configuring a cursor theme
91+ . Drop support for Mir versions before 0.26
92+ - Bugs fixed:
93+
94+ -- Alan Griffiths <alan.griffiths@canonical.com> Tue, 21 Mar 2017 17:57:20 +0000
95+
96 miral (1.3.2+17.04.20170330.5-0ubuntu1) zesty; urgency=medium
97
98 * New upstream release 1.3.2 (https://launchpad.net/miral/+milestone/1.3.2)
99@@ -74,11 +89,11 @@
100 . Chrome-less shell hint does not work any more (LP: #1658117)
101 . WindowSpec::set_state() wrapper for mir_window_spec_set_state()
102 (LP: #1661256)
103- . "$ miral-app -kiosk" fails with "Unknown command line options:
104+ . "$ miral-app -kiosk" fails with "Unknown command line options:
105 --desktop_file_hint=miral-shell.desktop" (LP: #1660933)
106 . libmiral] Fix focus and movement rules for Input Method and Satellite
107 windows. (LP: #1660691)
108-
109+
110
111 -- Alan Griffiths <alan.griffiths@canonical.com> Wed, 15 Feb 2017 14:05:46 +0000
112
113
114=== modified file 'debian/control'
115--- debian/control 2017-02-16 11:13:26 +0000
116+++ debian/control 2017-06-20 16:14:05 +0000
117@@ -14,18 +14,13 @@
118 python-pil,
119 google-mock (>= 1.6.0+svn437),
120 python3:any,
121- libmirserver-dev,
122- libmirclient-dev,
123- mirtest-dev,
124+ libmirserver-dev (>= 0.26),
125+ libmirclient-dev (>= 0.26),
126+ mirtest-dev (>= 0.26),
127+ mir-test-tools (>= 0.26),
128 libglib2.0-dev,
129 libgles2-mesa-dev,
130 libfreetype6-dev,
131-# The following workaround missing dependencies in Mir packages
132- uuid-dev,
133- libboost-system-dev,
134- libboost-filesystem-dev,
135- mir-test-tools,
136- mir-renderer-gl-dev,
137 Standards-Version: 3.9.8
138 Homepage: https://launchpad.net/miral
139 # If you aren't a member of ~mir-team but need to upload packaging changes,
140
141=== modified file 'debian/libmiral2.symbols'
142--- debian/libmiral2.symbols 2017-03-15 17:44:36 +0000
143+++ debian/libmiral2.symbols 2017-06-20 16:14:05 +0000
144@@ -389,3 +389,7 @@
145 (c++)"miral::SetWindowManagementPolicy::~SetWindowManagementPolicy()@MIRAL_1.3.1" 1.3.1
146 (c++)"miral::SetWindowManagementPolicy::~SetWindowManagementPolicy()@MIRAL_1.3.1" 1.3.1
147 (c++)"miral::SetWindowManagementPolicy::operator()(mir::Server&) const@MIRAL_1.3.1" 1.3.1
148+ MIRAL_1.4.0@MIRAL_1.4.0 1.4.0
149+ (c++)"miral::WindowManagerTools::end_drag_and_drop()@MIRAL_1.4.0" 1.4.0
150+ (c++)"miral::WindowManagerTools::start_drag_and_drop(miral::WindowInfo&, std::vector<unsigned char, std::allocator<unsigned char> > const&)@MIRAL_1.4.0" 1.4.0
151+ (c++)"typeinfo for miral::WindowManagementPolicyAddendum2@MIRAL_1.4.0" 1.4.0
152
153=== removed directory 'debian/tmp'
154=== modified file 'doc/introducing_the_miral_api.md'
155--- doc/introducing_the_miral_api.md 2016-08-02 13:25:18 +0000
156+++ doc/introducing_the_miral_api.md 2017-06-20 16:14:05 +0000
157@@ -8,14 +8,14 @@
158
159 \include shell_main.cpp
160
161-This shell is providing TitlebarWindowManagerPolicy, TilingWindowManagerPolicy
162+This shell is providing FloatingWindowManagerPolicy, TilingWindowManagerPolicy
163 and SpinnerSplash. The rest is from MirAL.
164
165 If you look for the corresponding code in lp:qtmir and lp:mir you’ll find it
166 less clear, more verbose and scattered over multiple files.
167
168 A shell has to provide a window management policy (miral-shell provides two:
169-TitlebarWindowManagerPolicy and TilingWindowManagerPolicy). A window management
170+FloatingWindowManagerPolicy and TilingWindowManagerPolicy). A window management
171 policy needs to implement the \ref miral::WindowManagementPolicy interface for
172 handling a set of window management events.
173
174
175=== removed file 'include/mir/client/detail/mir_forward_compatibility.h'
176--- include/mir/client/detail/mir_forward_compatibility.h 2017-02-14 13:50:07 +0000
177+++ include/mir/client/detail/mir_forward_compatibility.h 1970-01-01 00:00:00 +0000
178@@ -1,172 +0,0 @@
179-/*
180- * Copyright © 2016 Canonical Ltd.
181- *
182- * This program is free software: you can redistribute it and/or modify it
183- * under the terms of the GNU General Public License version 3,
184- * as published by the Free Software Foundation.
185- *
186- * This program is distributed in the hope that it will be useful,
187- * but WITHOUT ANY WARRANTY; without even the implied warranty of
188- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
189- * GNU General Public License for more details.
190- *
191- * You should have received a copy of the GNU General Public License
192- * along with this program. If not, see <http://www.gnu.org/licenses/>.
193- *
194- * Authored by: Alan Griffiths <alan@octopull.co.uk>
195- */
196-
197-#ifndef MIRAL_MIR_FORWARD_COMPATIBILITY_H
198-#define MIRAL_MIR_FORWARD_COMPATIBILITY_H
199-
200-#include <mir_toolkit/version.h>
201-#include <mir_toolkit/common.h>
202-#include <mir/client/detail/mir_features.h>
203-
204-#if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 5, 0)
205-using MirWindowAttrib = MirSurfaceAttrib;
206-auto const mir_window_attrib_type = mir_surface_attrib_type;
207-auto const mir_window_attrib_state = mir_surface_attrib_state;
208-auto const mir_window_attrib_swapinterval = mir_surface_attrib_swapinterval;
209-auto const mir_window_attrib_focus = mir_surface_attrib_focus;
210-auto const mir_window_attrib_dpi = mir_surface_attrib_dpi;
211-auto const mir_window_attrib_visibility = mir_surface_attrib_visibility;
212-auto const mir_window_attrib_preferred_orientation = mir_surface_attrib_preferred_orientation;
213-auto const mir_window_attribs = mir_surface_attribs;
214-
215-using MirWindowType = MirSurfaceType;
216-auto const mir_window_type_normal = mir_surface_type_normal;
217-auto const mir_window_type_utility = mir_surface_type_utility;
218-auto const mir_window_type_dialog = mir_surface_type_dialog;
219-auto const mir_window_type_gloss = mir_surface_type_gloss;
220-auto const mir_window_type_freestyle = mir_surface_type_freestyle;
221-auto const mir_window_type_menu = mir_surface_type_menu;
222-auto const mir_window_type_inputmethod = mir_surface_type_inputmethod;
223-auto const mir_window_type_satellite = mir_surface_type_satellite;
224-auto const mir_window_type_tip = mir_surface_type_tip;
225-auto const mir_window_types = mir_surface_types;
226-
227-using MirWindowState = MirSurfaceState;
228-auto const mir_window_state_unknown = mir_surface_state_unknown;
229-auto const mir_window_state_restored = mir_surface_state_restored;
230-auto const mir_window_state_minimized = mir_surface_state_minimized;
231-auto const mir_window_state_maximized = mir_surface_state_maximized;
232-auto const mir_window_state_vertmaximized = mir_surface_state_vertmaximized;
233-auto const mir_window_state_fullscreen = mir_surface_state_fullscreen;
234-auto const mir_window_state_horizmaximized = mir_surface_state_horizmaximized;
235-auto const mir_window_state_hidden = mir_surface_state_hidden;
236-auto const mir_window_states = mir_surface_states;
237-
238-typedef struct MirSurface MirWindow;
239-typedef struct MirSurfaceParameters MirWindowParameters;
240-typedef struct MirSurfacePlacementEvent MirWindowPlacementEvent;
241-typedef struct MirSurfaceSpec MirWindowSpec;
242-#endif
243-
244-
245-// Types that don't exist in earlier versions of Mir's client
246-#if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 4, 0)
247-
248-// Inspired by GdkGravity
249-/**
250- * Reference point for aligning a surface relative to a rectangle.
251- * Each element (surface and rectangle) has a MirPlacementGravity assigned.
252- */
253-typedef enum MirPlacementGravity
254-{
255- /// the reference point is at the center.
256- mir_placement_gravity_center = 0,
257-
258- /// the reference point is at the middle of the left edge.
259- mir_placement_gravity_west = 1 << 0,
260-
261- /// the reference point is at the middle of the right edge.
262- mir_placement_gravity_east = 1 << 1,
263-
264- /// the reference point is in the middle of the top edge.
265- mir_placement_gravity_north = 1 << 2,
266-
267- /// the reference point is at the middle of the lower edge.
268- mir_placement_gravity_south = 1 << 3,
269-
270- /// the reference point is at the top left corner.
271- mir_placement_gravity_northwest = mir_placement_gravity_north | mir_placement_gravity_west,
272-
273- /// the reference point is at the top right corner.
274- mir_placement_gravity_northeast = mir_placement_gravity_north | mir_placement_gravity_east,
275-
276- /// the reference point is at the lower left corner.
277- mir_placement_gravity_southwest = mir_placement_gravity_south | mir_placement_gravity_west,
278-
279- /// the reference point is at the lower right corner.
280- mir_placement_gravity_southeast = mir_placement_gravity_south | mir_placement_gravity_east
281-} MirPlacementGravity;
282-
283-// Inspired by GdkAnchorHints
284-/**
285- * Positioning hints for aligning a window relative to a rectangle.
286- *
287- * These hints determine how the window should be positioned in the case that
288- * the surface would fall off-screen if placed in its ideal position.
289- *
290- * For example, \p mir_placement_hints_flip_x will invert the x component of
291- * \p aux_rect_placement_offset and replace \p mir_placement_gravity_northwest
292- * with \p mir_placement_gravity_northeast and vice versa if the window extends
293- * beyond the left or right edges of the monitor.
294- *
295- * If \p mir_placement_hints_slide_x is set, the window can be shifted
296- * horizontally to fit on-screen.
297- *
298- * If \p mir_placement_hints_resize_x is set, the window can be shrunken
299- * horizontally to fit.
300- *
301- * If \p mir_placement_hints_antipodes is set then the rect gravity may be
302- * substituted with the opposite corner (e.g. \p mir_placement_gravity_northeast
303- * to \p mir_placement_gravity_southwest) in combination with other options.
304- *
305- * When multiple flags are set, flipping should take precedence over sliding,
306- * which should take precedence over resizing.
307- */
308-typedef enum MirPlacementHints
309-{
310- /// allow flipping anchors horizontally
311- mir_placement_hints_flip_x = 1 << 0,
312-
313- /// allow flipping anchors vertically
314- mir_placement_hints_flip_y = 1 << 1,
315-
316- /// allow sliding window horizontally
317- mir_placement_hints_slide_x = 1 << 2,
318-
319- /// allow sliding window vertically
320- mir_placement_hints_slide_y = 1 << 3,
321-
322- /// allow resizing window horizontally
323- mir_placement_hints_resize_x = 1 << 4,
324-
325- /// allow resizing window vertically
326- mir_placement_hints_resize_y = 1 << 5,
327-
328- /// allow flipping aux_anchor to opposite corner
329- mir_placement_hints_antipodes= 1 << 6,
330-
331- /// allow flipping anchors on both axes
332- mir_placement_hints_flip_any = mir_placement_hints_flip_x|mir_placement_hints_flip_y,
333-
334- /// allow sliding window on both axes
335- mir_placement_hints_slide_any = mir_placement_hints_slide_x|mir_placement_hints_slide_y,
336-
337- /// allow resizing window on both axes
338- mir_placement_hints_resize_any = mir_placement_hints_resize_x|mir_placement_hints_resize_y,
339-} MirPlacementHints;
340-#endif
341-
342-#if !MIRAL_MIR_DEFINES_POINTER_CONFINEMENT
343-typedef enum MirPointerConfinementState
344-{
345- mir_pointer_unconfined,
346- mir_pointer_confined_to_surface,
347-} MirPointerConfinementState;
348-#endif
349-
350-#endif //MIRAL_MIR_FORWARD_COMPATIBILITY_H
351
352=== modified file 'include/mir/client/display_config.h'
353--- include/mir/client/display_config.h 2017-02-22 12:45:01 +0000
354+++ include/mir/client/display_config.h 2017-06-20 16:14:05 +0000
355@@ -21,7 +21,6 @@
356
357 #include <mir_toolkit/mir_connection.h>
358 #include <mir_toolkit/mir_display_configuration.h>
359-#include <mir/client/detail/mir_features.h>
360
361 #include <functional>
362 #include <memory>
363@@ -57,9 +56,6 @@
364 enumerator(mir_display_config_get_output(*this, i));
365 }
366
367-#if MIR_DEFINES_DISPLAY_CONFIG_GET_MUTABLE_OUTPUT
368- // Is it worthwhile to emulate this functionality for Mir 0.21?
369- // Too many API gaps I think.
370 void for_each_output(std::function<void(MirOutput*)> const& enumerator)
371 {
372 auto const count = mir_display_config_get_num_outputs(*this);
373@@ -67,7 +63,6 @@
374 for (int i = 0; i != count; ++i)
375 enumerator(mir_display_config_get_mutable_output(*this, i));
376 }
377-#endif
378
379 private:
380 static void deleter(MirDisplayConfig* config) { mir_display_config_release(config); }
381
382=== added file 'include/mir/client/surface.h'
383--- include/mir/client/surface.h 1970-01-01 00:00:00 +0000
384+++ include/mir/client/surface.h 2017-06-20 16:14:05 +0000
385@@ -0,0 +1,50 @@
386+/*
387+ * Copyright © 2017 Canonical Ltd.
388+ *
389+ * This program is free software: you can redistribute it and/or modify it
390+ * under the terms of the GNU General Public License version 3,
391+ * as published by the Free Software Foundation.
392+ *
393+ * This program is distributed in the hope that it will be useful,
394+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
395+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
396+ * GNU General Public License for more details.
397+ *
398+ * You should have received a copy of the GNU General Public License
399+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
400+ *
401+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
402+ */
403+
404+#ifndef MIRAL_SURFACE_H
405+#define MIRAL_SURFACE_H
406+
407+#include <mir_toolkit/rs/mir_render_surface.h>
408+
409+#include <memory>
410+
411+namespace mir
412+{
413+namespace client
414+{
415+/// Handle class for MirRenderSurface - provides automatic reference counting.
416+class Surface
417+{
418+public:
419+ Surface() = default;
420+ explicit Surface(MirRenderSurface* spec) : self{spec, &mir_render_surface_release} {}
421+
422+ operator MirRenderSurface*() const { return self.get(); }
423+
424+ void reset() { self.reset(); }
425+
426+private:
427+ std::shared_ptr<MirRenderSurface> self;
428+};
429+
430+// Provide a deleted overload to avoid double release "accidents".
431+void mir_render_surface_release(Surface const& surface) = delete;
432+}
433+}
434+
435+#endif //MIRAL_SURFACE_H
436
437=== modified file 'include/mir/client/window.h'
438--- include/mir/client/window.h 2017-02-22 12:45:01 +0000
439+++ include/mir/client/window.h 2017-06-20 16:14:05 +0000
440@@ -19,19 +19,7 @@
441 #ifndef MIR_CLIENT_WINDOW_H
442 #define MIR_CLIENT_WINDOW_H
443
444-#include <mir/client/detail/mir_forward_compatibility.h>
445-
446-#if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 5, 0)
447-#include <mir_toolkit/mir_surface.h>
448-auto const mir_window_release_sync = mir_surface_release_sync;
449-auto const mir_window_release = mir_surface_release;
450-auto const mir_window_get_buffer_stream = mir_surface_get_buffer_stream;
451-auto const mir_window_is_valid = mir_surface_is_valid;
452-auto const mir_window_get_error_message = mir_surface_get_error_message;
453-auto const mir_window_set_state = mir_surface_set_state;
454-#else
455 #include <mir_toolkit/mir_window.h>
456-#endif
457
458 #include <memory>
459
460
461=== modified file 'include/mir/client/window_id.h'
462--- include/mir/client/window_id.h 2017-02-24 10:36:29 +0000
463+++ include/mir/client/window_id.h 2017-06-20 16:14:05 +0000
464@@ -19,25 +19,8 @@
465 #ifndef MIR_CLIENT_WINDOW_ID_H
466 #define MIR_CLIENT_WINDOW_ID_H
467
468-#include <mir/client/detail/mir_forward_compatibility.h>
469-#if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 5, 0)
470-#include <mir_toolkit/mir_surface.h>
471-auto const mir_window_request_window_id_sync = mir_surface_request_persistent_id_sync;
472-#else
473 #include <mir_toolkit/mir_window.h>
474-#endif
475-
476-#if MIR_CLIENT_API_VERSION < MIR_VERSION_NUMBER(0, 26, 1)
477-#if MIR_CLIENT_VERSION == MIR_VERSION_NUMBER(3, 5, 0)
478-#include <mir_toolkit/mir_persistent_id.h>
479-auto const mir_window_request_window_id_sync = mir_window_request_persistent_id_sync;
480-#endif
481-auto const mir_window_id_as_string = mir_persistent_id_as_string;
482-auto const mir_window_id_release = mir_persistent_id_release;
483-typedef struct MirPersistentId MirWindowId;
484-#else
485 #include <mir_toolkit/mir_window_id.h>
486-#endif
487
488 #include <memory>
489
490
491=== modified file 'include/mir/client/window_spec.h'
492--- include/mir/client/window_spec.h 2017-03-03 12:31:47 +0000
493+++ include/mir/client/window_spec.h 2017-06-20 16:14:05 +0000
494@@ -20,50 +20,14 @@
495 #define MIR_CLIENT_WINDOW_SPEC_H
496
497 #include <mir/client/window.h>
498-#include <mir/client/detail/mir_forward_compatibility.h>
499
500 #include <mir_toolkit/mir_connection.h>
501-
502-#if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 5, 0)
503-#include <mir_toolkit/mir_surface.h>
504-#else
505 #include <mir_toolkit/mir_window.h>
506-#endif
507+#include <mir_toolkit/version.h>
508+#include <mir_toolkit/rs/mir_render_surface.h>
509
510 #include <memory>
511
512-// Forward compatibility hacks for earlier Mir versions
513-#if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 5, 0)
514-using MirWindowCallback = mir_surface_callback;
515-using MirWindowEventCallback = mir_surface_event_callback;
516-auto const mir_create_window_spec = mir_connection_create_spec_for_changes;
517-auto const mir_window_spec_set_event_handler = mir_surface_spec_set_event_handler;
518-auto const mir_window_spec_set_name = mir_surface_spec_set_name;
519-auto const mir_window_spec_set_width = mir_surface_spec_set_width;
520-auto const mir_window_spec_set_height = mir_surface_spec_set_height;
521-auto const mir_window_spec_set_width_increment = mir_surface_spec_set_width_increment;
522-auto const mir_window_spec_set_height_increment = mir_surface_spec_set_height_increment;
523-auto const mir_window_spec_set_buffer_usage = mir_surface_spec_set_buffer_usage;
524-auto const mir_window_spec_set_pixel_format = mir_surface_spec_set_pixel_format;
525-auto const mir_window_spec_set_type = mir_surface_spec_set_type;
526-auto const mir_window_spec_set_shell_chrome = mir_surface_spec_set_shell_chrome;
527-auto const mir_window_spec_set_min_width = mir_surface_spec_set_min_width;
528-auto const mir_window_spec_set_min_height = mir_surface_spec_set_min_height;
529-auto const mir_window_spec_set_max_width = mir_surface_spec_set_max_width;
530-auto const mir_window_spec_set_max_height = mir_surface_spec_set_max_height;
531-auto const mir_window_spec_set_parent = mir_surface_spec_set_parent;
532-auto const mir_window_spec_set_state = mir_surface_spec_set_state;
533-auto const mir_window_spec_set_fullscreen_on_output = mir_surface_spec_set_fullscreen_on_output;
534-auto const mir_create_window = mir_surface_create;
535-auto const mir_create_window_sync = mir_surface_create_sync;
536-auto const mir_window_apply_spec = mir_surface_apply_spec;
537-auto const mir_window_spec_release = mir_surface_spec_release;
538-
539-#if MIR_CLIENT_VERSION >= MIR_VERSION_NUMBER(3, 4, 0)
540-auto const mir_window_spec_set_placement = mir_surface_spec_set_placement;
541-#endif
542-#endif
543-
544 namespace mir
545 {
546 namespace client
547@@ -74,126 +38,87 @@
548 public:
549 explicit WindowSpec(MirWindowSpec* spec) : self{spec, deleter} {}
550
551- static auto for_normal_window(MirConnection* connection, int width, int height, MirPixelFormat format) -> WindowSpec
552- {
553-#if MIR_CLIENT_VERSION <= MIR_VERSION_NUMBER(3, 4, 0)
554- return WindowSpec{mir_connection_create_spec_for_normal_surface(connection, width, height, format)};
555-#else
556- auto spec = WindowSpec{mir_create_normal_window_spec(connection, width, height)};
557- mir_window_spec_set_pixel_format(spec, format);
558- return spec;
559-#endif
560- }
561-
562-#if MIR_CLIENT_VERSION > MIR_VERSION_NUMBER(3, 4, 0)
563 static auto for_normal_window(MirConnection* connection, int width, int height) -> WindowSpec
564 {
565 return WindowSpec{mir_create_normal_window_spec(connection, width, height)};
566 }
567-#endif
568
569 static auto for_menu(MirConnection* connection,
570 int width,
571 int height,
572- MirPixelFormat format,
573 MirWindow* parent,
574 MirRectangle* rect,
575 MirEdgeAttachment edge) -> WindowSpec
576 {
577-#if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 5, 0)
578- return WindowSpec{mir_connection_create_spec_for_menu(connection, width, height, format, parent, rect, edge)};
579-#else
580 auto spec = WindowSpec{mir_create_menu_window_spec(connection, width, height, parent, rect, edge)};
581- mir_window_spec_set_pixel_format(spec, format);
582 return spec;
583-#endif
584 }
585
586 static auto for_tip(MirConnection* connection,
587 int width,
588 int height,
589- MirPixelFormat format,
590 MirWindow* parent,
591 MirRectangle* rect,
592 MirEdgeAttachment edge) -> WindowSpec
593 {
594-#if MIR_CLIENT_VERSION >= MIR_VERSION_NUMBER(3, 4, 0)
595-#if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 5, 0)
596- return WindowSpec{mir_connection_create_spec_for_tip(connection, width, height, format, parent, rect, edge)};
597-#else
598 auto spec = WindowSpec{mir_create_tip_window_spec(connection, width, height, parent, rect, edge)};
599- mir_window_spec_set_pixel_format(spec, format);
600 return spec;
601-#endif
602-#else
603- (void)rect;
604- (void)edge;
605- return WindowSpec{mir_create_surface_spec(connection)}
606- .set_buffer_usage(mir_buffer_usage_hardware) // Required protobuf field for create_window()
607- .set_pixel_format(format) // Required protobuf field for create_window()
608- .set_size(width, height)
609- .set_parent(parent)
610- .set_type(mir_window_type_tip);
611-#endif
612 }
613
614 static auto for_dialog(MirConnection* connection,
615 int width,
616- int height,
617- MirPixelFormat format)-> WindowSpec
618+ int height)-> WindowSpec
619 {
620-#if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 5, 0)
621- return WindowSpec{mir_connection_create_spec_for_dialog(connection, width, height, format)};
622-#else
623 auto spec = WindowSpec{mir_create_dialog_window_spec(connection, width, height)};
624- mir_window_spec_set_pixel_format(spec, format);
625 return spec;
626-#endif
627 }
628
629 static auto for_dialog(MirConnection* connection,
630 int width,
631 int height,
632- MirPixelFormat format,
633 MirWindow* parent) -> WindowSpec
634 {
635- return for_dialog(connection, width, height, format).set_parent(parent);
636+ return for_dialog(connection, width, height).set_parent(parent);
637 }
638
639 static auto for_input_method(MirConnection* connection, int width, int height, MirWindow* parent)
640 {
641-#if MIR_CLIENT_VERSION >= MIR_VERSION_NUMBER(3, 5, 0)
642 auto spec = WindowSpec{mir_create_input_method_window_spec(connection, width, height)}
643-#else
644- auto spec = WindowSpec{mir_create_surface_spec(connection)}
645- .set_buffer_usage(mir_buffer_usage_hardware) // Required protobuf field for create_window()
646- .set_pixel_format(mir_pixel_format_invalid) // Required protobuf field for create_window()
647- .set_size(width, height)
648- .set_type(mir_window_type_inputmethod)
649-#endif
650 .set_parent(parent);
651 return spec;
652 }
653
654 static auto for_satellite(MirConnection* connection, int width, int height, MirWindow* parent)
655 {
656+#if MIR_CLIENT_API_VERSION >= MIR_VERSION_NUMBER(0, 27, 0)
657+ return WindowSpec{mir_create_satellite_window_spec(connection, width, height, parent)};
658+#else
659 // There's no mir_create_satellite_window_spec()
660- return WindowSpec{mir_create_window_spec(connection)}
661- .set_buffer_usage(mir_buffer_usage_hardware) // Required protobuf field for create_window()
662- .set_pixel_format(mir_pixel_format_invalid) // Required protobuf field for create_window()
663+ auto spec = WindowSpec{mir_create_window_spec(connection)}
664 .set_size(width, height)
665 .set_type(mir_window_type_satellite)
666 .set_parent(parent);
667+
668+ mir_window_spec_set_buffer_usage(spec, mir_buffer_usage_hardware); // Required protobuf field for create_window()
669+ mir_window_spec_set_pixel_format(spec, mir_pixel_format_invalid); // Required protobuf field for create_window()
670+ return spec;
671+#endif
672 }
673
674 static auto for_gloss(MirConnection* connection, int width, int height)
675 {
676+#if MIR_CLIENT_API_VERSION >= MIR_VERSION_NUMBER(0, 27, 0)
677+ return WindowSpec{mir_create_gloss_window_spec(connection, width, height)};
678+#else
679 // There's no mir_create_gloss_window_spec()
680- return WindowSpec{mir_create_window_spec(connection)}
681- .set_buffer_usage(mir_buffer_usage_hardware) // Required protobuf field for create_window()
682- .set_pixel_format(mir_pixel_format_invalid) // Required protobuf field for create_window()
683+ auto spec = WindowSpec{mir_create_window_spec(connection)}
684 .set_size(width, height)
685 .set_type(mir_window_type_gloss);
686+
687+ mir_window_spec_set_buffer_usage(spec, mir_buffer_usage_hardware); // Required protobuf field for create_window()
688+ mir_window_spec_set_pixel_format(spec, mir_pixel_format_invalid); // Required protobuf field for create_window()
689+ return spec;
690+#endif
691 }
692
693 static auto for_changes(MirConnection* connection) -> WindowSpec
694@@ -201,18 +126,6 @@
695 return WindowSpec{mir_create_window_spec(connection)};
696 }
697
698- auto set_buffer_usage(MirBufferUsage usage) -> WindowSpec&
699- {
700- mir_window_spec_set_buffer_usage(*this, usage);
701- return *this;
702- }
703-
704- auto set_pixel_format(MirPixelFormat format) -> WindowSpec&
705- {
706- mir_window_spec_set_pixel_format(*this, format);
707- return *this;
708- }
709-
710 auto set_type(MirWindowType type) -> WindowSpec&
711 {
712 mir_window_spec_set_type(*this, type);
713@@ -271,7 +184,6 @@
714 return *this;
715 }
716
717-#if MIR_CLIENT_VERSION >= MIR_VERSION_NUMBER(3, 4, 0)
718 auto set_placement(const MirRectangle* rect,
719 MirPlacementGravity rect_gravity,
720 MirPlacementGravity surface_gravity,
721@@ -282,17 +194,6 @@
722 mir_window_spec_set_placement(*this, rect, rect_gravity, surface_gravity, placement_hints, offset_dx, offset_dy);
723 return *this;
724 }
725-#else
726- auto set_placement(const MirRectangle* /*rect*/,
727- MirPlacementGravity /*rect_gravity*/,
728- MirPlacementGravity /*surface_gravity*/,
729- MirPlacementHints /*placement_hints*/,
730- int /*offset_dx*/,
731- int /*offset_dy*/) -> WindowSpec&
732- {
733- return *this;
734- }
735-#endif
736
737 auto set_parent(MirWindow* parent) -> WindowSpec&
738 {
739@@ -306,6 +207,20 @@
740 return *this;
741 }
742
743+ auto add_surface(MirRenderSurface* surface, int width, int height, int displacement_x, int displacement_y)
744+ -> WindowSpec&
745+ {
746+#if MIR_CLIENT_API_VERSION < MIR_VERSION_NUMBER(0, 27, 0)
747+#pragma GCC diagnostic push
748+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
749+#endif
750+ mir_window_spec_add_render_surface(*this, surface, width, height, displacement_x, displacement_y);
751+#if MIR_CLIENT_API_VERSION < MIR_VERSION_NUMBER(0, 27, 0)
752+#pragma GCC diagnostic pop
753+#endif
754+ return *this;
755+ }
756+
757 template<typename Context>
758 void create_window(void (* callback)(MirWindow*, Context*), Context* context) const
759 {
760
761=== modified file 'include/miral/cursor_theme.h'
762--- include/miral/cursor_theme.h 2016-09-28 10:38:36 +0000
763+++ include/miral/cursor_theme.h 2017-06-20 16:14:05 +0000
764@@ -25,11 +25,11 @@
765
766 namespace miral
767 {
768-/// Load a cursor theme
769+/// Load an X-cursor theme, either the supplied default, or through the --cursor-theme config option
770 class CursorTheme
771 {
772 public:
773- /// Specify a specific theme
774+ /// Specify a default theme
775 explicit CursorTheme(std::string const& theme);
776 ~CursorTheme();
777
778
779=== modified file 'include/miral/window_management_policy.h'
780--- include/miral/window_management_policy.h 2017-02-14 11:49:59 +0000
781+++ include/miral/window_management_policy.h 2017-06-20 16:14:05 +0000
782@@ -23,8 +23,6 @@
783 #include <mir/geometry/rectangles.h>
784 #include <mir_toolkit/event.h>
785
786-#include <mir/client/detail/mir_forward_compatibility.h>
787-
788 namespace miral
789 {
790 class Window;
791
792=== added file 'include/miral/window_management_policy_addendum2.h'
793--- include/miral/window_management_policy_addendum2.h 1970-01-01 00:00:00 +0000
794+++ include/miral/window_management_policy_addendum2.h 2017-06-20 16:14:05 +0000
795@@ -0,0 +1,70 @@
796+/*
797+ * Copyright © 2017 Canonical Ltd.
798+ *
799+ * This program is free software: you can redistribute it and/or modify it
800+ * under the terms of the GNU General Public License version 3,
801+ * as published by the Free Software Foundation.
802+ *
803+ * This program is distributed in the hope that it will be useful,
804+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
805+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
806+ * GNU General Public License for more details.
807+ *
808+ * You should have received a copy of the GNU General Public License
809+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
810+ *
811+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
812+ */
813+
814+#ifndef MIRAL_WINDOW_MANAGEMENT_ADDENDUM2_H
815+#define MIRAL_WINDOW_MANAGEMENT_ADDENDUM2_H
816+
817+#include <mir_toolkit/client_types.h>
818+#include <mir/version.h>
819+
820+namespace miral
821+{
822+struct WindowInfo;
823+
824+/**
825+ * Handle additional client requests.
826+ *
827+ * \note This interface is intended to be implemented by a WindowManagementPolicy
828+ * implementation, we can't add these functions directly to that interface without
829+ * breaking ABI (the vtab could be incompatible).
830+ * When initializing the window manager this interface will be detected by
831+ * dynamic_cast and registered accordingly.
832+ */
833+class WindowManagementPolicyAddendum2
834+{
835+public:
836+/** @name handle requests originating from the client
837+ * The policy is expected to update the model as appropriate
838+ * @{ */
839+ /** request from client to initiate drag and drop
840+ * \note the request has already been validated against the requesting event
841+ *
842+ * @param window_info the window
843+ */
844+ virtual void handle_request_drag_and_drop(WindowInfo& window_info) = 0;
845+
846+ /** request from client to initiate move
847+ * \note the request has already been validated against the requesting event
848+ *
849+ * @param window_info the window
850+ * @param input_event the requesting event
851+ */
852+ virtual void handle_request_move(WindowInfo& window_info, MirInputEvent const* input_event) = 0;
853+/** @} */
854+
855+ virtual ~WindowManagementPolicyAddendum2() = default;
856+ WindowManagementPolicyAddendum2() = default;
857+ WindowManagementPolicyAddendum2(WindowManagementPolicyAddendum2 const&) = delete;
858+ WindowManagementPolicyAddendum2& operator=(WindowManagementPolicyAddendum2 const&) = delete;
859+};
860+#if MIRAL_VERSION >= MIR_VERSION_NUMBER(2, 0, 0)
861+#error "We've presumably broken ABI - please roll this interface into WindowManagementPolicy"
862+#endif
863+}
864+
865+#endif //MIRAL_WINDOW_MANAGEMENT_ADDENDUM2_H
866
867=== modified file 'include/miral/window_manager_tools.h'
868--- include/miral/window_manager_tools.h 2017-03-02 14:29:04 +0000
869+++ include/miral/window_manager_tools.h 2017-06-20 16:14:05 +0000
870@@ -166,6 +166,18 @@
871 /// Raise window and all its children
872 void raise_tree(Window const& root);
873
874+ /** Start drag and drop. The handle will be passed to the client which can
875+ * then use it to talk to the whatever service is being used to support drag
876+ * and drop (e.g. on Ubuntu the content hub).
877+ *
878+ * @param window_info source window
879+ * @param handle drag handle
880+ */
881+ void start_drag_and_drop(WindowInfo& window_info, std::vector<uint8_t> const& handle);
882+
883+ /// End drag and drop
884+ void end_drag_and_drop();
885+
886 /// Apply modifications to a window
887 void modify_window(WindowInfo& window_info, WindowSpecification const& modifications);
888
889
890=== modified file 'include/miral/window_specification.h'
891--- include/miral/window_specification.h 2017-02-14 11:49:59 +0000
892+++ include/miral/window_specification.h 2017-06-20 16:14:05 +0000
893@@ -21,8 +21,6 @@
894
895 #include <mir_toolkit/common.h>
896
897-#include <mir/client/detail/mir_forward_compatibility.h>
898-
899 #include <mir/geometry/displacement.h>
900 #include <mir/geometry/rectangles.h>
901 #include <mir/optional_value.h>
902
903=== modified file 'miral-kiosk/sw_splash.cpp'
904--- miral-kiosk/sw_splash.cpp 2017-02-20 15:22:29 +0000
905+++ miral-kiosk/sw_splash.cpp 2017-06-20 16:14:05 +0000
906@@ -18,7 +18,10 @@
907
908 #include "sw_splash.h"
909
910+#include <mir/client/display_config.h>
911+#include <mir/client/surface.h>
912 #include <mir/client/window.h>
913+#include <mir/client/window_spec.h>
914
915 #include <mir_toolkit/mir_buffer_stream.h>
916
917@@ -26,7 +29,6 @@
918 #include <cstring>
919 #include <thread>
920 #include <mutex>
921-#include <mir/client/window_spec.h>
922
923 namespace
924 {
925@@ -60,12 +62,29 @@
926 return *pixel_formats;
927 }
928
929-auto create_window(MirConnection* connection, MirPixelFormat pixel_format) -> mir::client::Window
930+auto create_window(MirConnection* connection, mir::client::Surface const& surface) -> mir::client::Window
931 {
932- return mir::client::WindowSpec::for_normal_window(connection, 42, 42, pixel_format)
933+ int id = 0;
934+ int width = 0;
935+ int height = 0;
936+
937+ mir::client::DisplayConfig{connection}.for_each_output([&](MirOutput const* output)
938+ {
939+ if (mir_output_get_connection_state(output) == mir_output_connection_state_connected &&
940+ mir_output_is_enabled(output))
941+ {
942+ id = mir_output_get_id(output);
943+
944+ MirOutputMode const* mode = mir_output_get_current_mode(output);
945+ width = mir_output_mode_get_width(mode);
946+ height = mir_output_mode_get_height(mode);
947+ }
948+ });
949+
950+ return mir::client::WindowSpec::for_normal_window(connection, width, height)
951 .set_name("splash")
952- .set_buffer_usage(mir_buffer_usage_software)
953- .set_fullscreen_on_output(0)
954+ .set_fullscreen_on_output(id)
955+ .add_surface(surface, width, height, 0, 0)
956 .create_window();
957 }
958
959@@ -128,10 +147,13 @@
960 return;
961 };
962
963- auto const surface = create_window(connection, pixel_format);
964+
965+ mir::client::Surface surface{mir_connection_create_render_surface_sync(connection, 42, 42)};
966+ MirBufferStream* buffer_stream = mir_render_surface_get_buffer_stream(surface, 42, 42, pixel_format);
967+
968+ auto const window = create_window(connection, surface);
969
970 MirGraphicsRegion graphics_region;
971- MirBufferStream* buffer_stream = mir_window_get_buffer_stream(surface);
972
973 auto const time_limit = std::chrono::steady_clock::now() + std::chrono::seconds(2);
974
975
976=== modified file 'miral-shell/CMakeLists.txt'
977--- miral-shell/CMakeLists.txt 2017-02-17 10:37:47 +0000
978+++ miral-shell/CMakeLists.txt 2017-06-20 16:14:05 +0000
979@@ -44,19 +44,18 @@
980 add_executable(miral-shell
981 shell_main.cpp
982 tiling_window_manager.cpp tiling_window_manager.h
983- titlebar_window_manager.cpp titlebar_window_manager.h
984+ floating_window_manager.cpp floating_window_manager.h
985 decoration_provider.cpp decoration_provider.h
986 titlebar_config.cpp titlebar_config.h
987 )
988
989 pkg_check_modules(FREETYPE freetype2 REQUIRED)
990-target_include_directories(miral-shell PUBLIC ${FREETYPE_INCLUDE_DIRS})
991-target_compile_definitions(miral-shell PUBLIC -DTYPO_SUPPORTS_FREETYPE)
992-target_link_libraries(miral-shell ${FREETYPE_LIBRARIES})
993-
994+target_include_directories(miral-shell PRIVATE ${FREETYPE_INCLUDE_DIRS})
995+target_compile_definitions(miral-shell PRIVATE -DTYPO_SUPPORTS_FREETYPE)
996 target_link_libraries(miral-shell
997 miral-spinner
998 miral
999+ ${FREETYPE_LIBRARIES}
1000 )
1001
1002 install(TARGETS miral-shell
1003
1004=== modified file 'miral-shell/decoration_provider.cpp'
1005--- miral-shell/decoration_provider.cpp 2017-03-30 14:12:50 +0000
1006+++ miral-shell/decoration_provider.cpp 2017-06-20 16:14:05 +0000
1007@@ -66,10 +66,8 @@
1008 FT_Face face;
1009 };
1010
1011-void paint_surface(MirWindow* surface, std::string const& title, int const intensity)
1012+void paint_surface(MirBufferStream* buffer_stream, std::string const& title, int const intensity)
1013 {
1014- MirBufferStream* buffer_stream = mir_window_get_buffer_stream(surface);
1015-
1016 // TODO sometimes buffer_stream is nullptr - find out why (and fix).
1017 // (Only observed when creating a lot of clients at once)
1018 if (!buffer_stream)
1019@@ -286,11 +284,6 @@
1020 {
1021 if (connection)
1022 {
1023-#if MIR_CLIENT_API_VERSION < MIR_VERSION_NUMBER(0, 26, 2)
1024- auto const Workaround_lp_1667645 =
1025- WindowSpec::for_normal_window(connection, 100, 100, mir_pixel_format_xrgb_8888)
1026- .set_name(wallpaper_name).create_window();
1027-#endif
1028 wallpaper.erase(begin(wallpaper), end(wallpaper));
1029 }
1030 connection.reset();
1031@@ -326,24 +319,36 @@
1032 DisplayConfig const display_conf{this->connection};
1033
1034 display_conf.for_each_output([this](MirOutput const* output)
1035- {
1036- wallpaper.push_back(
1037- WindowSpec::for_gloss(this->connection, 100, 100)
1038- .set_pixel_format(mir_pixel_format_xrgb_8888)
1039- .set_buffer_usage(mir_buffer_usage_software)
1040- .set_fullscreen_on_output(mir_output_get_id(output))
1041- .set_name(wallpaper_name).create_window());
1042-
1043- MirGraphicsRegion graphics_region;
1044- MirBufferStream* buffer_stream = mir_window_get_buffer_stream(wallpaper.back());
1045-
1046- mir_buffer_stream_get_graphics_region(buffer_stream, &graphics_region);
1047-
1048- static uint8_t const pattern[4] = { 0x00, 0x00, 0x00, 0x00 };
1049-
1050- render_pattern(&graphics_region, pattern);
1051- mir_buffer_stream_swap_buffers_sync(buffer_stream);
1052- });
1053+ {
1054+ if (!mir_output_is_enabled(output))
1055+ return;
1056+
1057+ auto const mode = mir_output_get_current_mode(output);
1058+ auto const output_id = mir_output_get_id(output);
1059+ auto const width = mir_output_mode_get_width(mode);
1060+ auto const height = mir_output_mode_get_height(mode);
1061+
1062+ Surface surface{mir_connection_create_render_surface_sync(this->connection, width, height)};
1063+
1064+ auto const buffer_stream =
1065+ mir_render_surface_get_buffer_stream(surface, width, height, mir_pixel_format_xrgb_8888);
1066+
1067+ auto window = WindowSpec::for_gloss(this->connection, width, height)
1068+ .set_fullscreen_on_output(output_id)
1069+ .add_surface(surface, width, height, 0, 0)
1070+ .set_name(wallpaper_name).create_window();
1071+
1072+ wallpaper.push_back(Wallpaper{surface, window, buffer_stream});
1073+
1074+ MirGraphicsRegion graphics_region;
1075+
1076+ mir_buffer_stream_get_graphics_region(buffer_stream, &graphics_region);
1077+
1078+ static uint8_t const pattern[4] = { 0x00, 0x00, 0x00, 0x00 };
1079+
1080+ render_pattern(&graphics_region, pattern);
1081+ mir_buffer_stream_swap_buffers_sync(buffer_stream);
1082+ });
1083
1084 start_work();
1085 }
1086@@ -360,23 +365,54 @@
1087 return weak_session.lock();
1088 }
1089
1090+void DecorationProvider::handle_event(MirWindow* window, MirEvent const* ev, void* context_)
1091+{
1092+ auto* const context = (Data*)context_;
1093+
1094+ switch (mir_event_get_type(ev))
1095+ {
1096+ case mir_event_type_resize:
1097+ {
1098+ MirResizeEvent const* resize = mir_event_get_resize_event(ev);
1099+ int const new_width = mir_resize_event_get_width(resize);
1100+ int const new_height = mir_resize_event_get_height(resize);
1101+ mir_render_surface_set_size(context->surface, new_width, new_height);
1102+ WindowSpec::for_changes(context->connection)
1103+ .add_surface(context->surface, new_width, new_height, 0, 0)
1104+ .apply_to(window);
1105+ break;
1106+ }
1107+
1108+ default:
1109+ break;
1110+ }
1111+}
1112+
1113 void DecorationProvider::create_titlebar_for(miral::Window const& window)
1114 {
1115+ if (is_decoration(window)) return;
1116+
1117 enqueue_work([this, window]
1118 {
1119+ auto const width = window.size().width.as_int();
1120 std::ostringstream buffer;
1121-
1122 buffer << std::shared_ptr<mir::scene::Surface>(window).get();
1123
1124- auto const spec = WindowSpec::for_normal_window(
1125- connection, window.size().width.as_int(), title_bar_height, mir_pixel_format_xrgb_8888)
1126- .set_buffer_usage(mir_buffer_usage_software)
1127- .set_type(mir_window_type_gloss)
1128- .set_name(buffer.str().c_str());
1129+ Surface surface{mir_connection_create_render_surface_sync(this->connection, width, title_bar_height)};
1130
1131 std::lock_guard<decltype(mutex)> lock{mutex};
1132+
1133+ auto const data = &window_to_titlebar[window];
1134+ data->connection = connection;
1135+ data->surface = surface;
1136+ data->stream = mir_render_surface_get_buffer_stream(surface, width, title_bar_height, mir_pixel_format_xrgb_8888);
1137 windows_awaiting_titlebar[buffer.str()] = window;
1138- spec.create_window(insert, &window_to_titlebar[window]);
1139+
1140+ WindowSpec::for_gloss(connection, width, title_bar_height)
1141+ .add_surface(surface, width, title_bar_height, 0, 0)
1142+ .set_name(buffer.str().c_str())
1143+ .set_event_handler(&handle_event, data)
1144+ .create_window(insert, data);
1145 });
1146 }
1147
1148@@ -388,15 +424,7 @@
1149
1150 auto const title = info.name();
1151
1152- if (auto surface = data->titlebar.load())
1153- {
1154- enqueue_work([this, surface, title, intensity]{ paint_surface(surface, title, intensity); });
1155- }
1156- else
1157- {
1158- data->on_create = [this, title, intensity](MirWindow* surface)
1159- { enqueue_work([this, surface, title, intensity]{ paint_surface(surface, title, intensity); }); };
1160- }
1161+ enqueue_work([this, stream=data->stream, title, intensity]{ paint_surface(stream, title, intensity); });
1162 }
1163 }
1164
1165@@ -511,11 +539,8 @@
1166 {
1167 auto const title = window_info.name();
1168
1169- if (auto surface = data->titlebar.load())
1170- {
1171- enqueue_work([this, surface, title, intensity=data->intensity.load()]
1172- { paint_surface(surface, title, intensity); });
1173- }
1174+ enqueue_work([this, stream=data->stream, title, intensity=data->intensity.load()]
1175+ { paint_surface(stream, title, intensity); });
1176 }
1177 }
1178
1179
1180=== modified file 'miral-shell/decoration_provider.h'
1181--- miral-shell/decoration_provider.h 2017-03-01 14:02:59 +0000
1182+++ miral-shell/decoration_provider.h 2017-06-20 16:14:05 +0000
1183@@ -23,6 +23,7 @@
1184 #include <miral/window_manager_tools.h>
1185
1186 #include <mir/client/connection.h>
1187+#include <mir/client/surface.h>
1188 #include <mir/client/window.h>
1189
1190 #include <mir/geometry/rectangle.h>
1191@@ -81,6 +82,9 @@
1192 private:
1193 struct Data
1194 {
1195+ MirConnection* connection{nullptr};
1196+ mir::client::Surface surface;
1197+ MirBufferStream* stream{nullptr};
1198 std::atomic<MirWindow*> titlebar{nullptr};
1199 std::atomic<int> intensity{0xff};
1200 std::function<void(MirWindow* surface)> on_create{[](MirWindow*){}};
1201@@ -95,7 +99,8 @@
1202 miral::WindowManagerTools tools;
1203 std::mutex mutable mutex;
1204 mir::client::Connection connection;
1205- std::vector<mir::client::Window> wallpaper;
1206+ struct Wallpaper { mir::client::Surface surface; mir::client::Window window; MirBufferStream* stream; };
1207+ std::vector<Wallpaper> wallpaper;
1208 std::weak_ptr<mir::scene::Session> weak_session;
1209
1210 SurfaceMap window_to_titlebar;
1211@@ -105,6 +110,7 @@
1212 Data* find_titlebar_data(miral::Window const& window);
1213 miral::Window find_titlebar_window(miral::Window const& window) const;
1214 void repaint_titlebar_for(miral::WindowInfo const& window_info);
1215+ static void handle_event(MirWindow* window, MirEvent const* ev, void* context_);
1216 };
1217
1218
1219
1220=== renamed file 'miral-shell/titlebar_window_manager.cpp' => 'miral-shell/floating_window_manager.cpp'
1221--- miral-shell/titlebar_window_manager.cpp 2017-03-20 10:57:31 +0000
1222+++ miral-shell/floating_window_manager.cpp 2017-06-20 16:14:05 +0000
1223@@ -16,7 +16,7 @@
1224 * Authored by: Alan Griffiths <alan@octopull.co.uk>
1225 */
1226
1227-#include "titlebar_window_manager.h"
1228+#include "floating_window_manager.h"
1229 #include "decoration_provider.h"
1230
1231 #include <miral/application_info.h>
1232@@ -46,7 +46,7 @@
1233 }
1234 }
1235
1236-TitlebarWindowManagerPolicy::TitlebarWindowManagerPolicy(
1237+FloatingWindowManagerPolicy::FloatingWindowManagerPolicy(
1238 WindowManagerTools const& tools,
1239 SpinnerSplash const& spinner,
1240 miral::InternalClientLauncher const& launcher,
1241@@ -64,9 +64,9 @@
1242 active_workspace = key_to_workspace[KEY_F1];
1243 }
1244
1245-TitlebarWindowManagerPolicy::~TitlebarWindowManagerPolicy() = default;
1246+FloatingWindowManagerPolicy::~FloatingWindowManagerPolicy() = default;
1247
1248-bool TitlebarWindowManagerPolicy::handle_pointer_event(MirPointerEvent const* event)
1249+bool FloatingWindowManagerPolicy::handle_pointer_event(MirPointerEvent const* event)
1250 {
1251 auto const action = mir_pointer_event_action(event);
1252 auto const modifiers = mir_pointer_event_modifiers(event) & modifier_mask;
1253@@ -137,7 +137,7 @@
1254 return consumes_event;
1255 }
1256
1257-void TitlebarWindowManagerPolicy::end_resize()
1258+void FloatingWindowManagerPolicy::end_resize()
1259 {
1260 if (!resizing && !pinching)
1261 return;
1262@@ -160,7 +160,7 @@
1263 pinching = false;
1264 }
1265
1266-bool TitlebarWindowManagerPolicy::handle_touch_event(MirTouchEvent const* event)
1267+bool FloatingWindowManagerPolicy::handle_touch_event(MirTouchEvent const* event)
1268 {
1269 auto const count = mir_touch_event_point_count(event);
1270
1271@@ -281,7 +281,7 @@
1272 return consumes_event;
1273 }
1274
1275-void TitlebarWindowManagerPolicy::advise_new_window(WindowInfo const& window_info)
1276+void FloatingWindowManagerPolicy::advise_new_window(WindowInfo const& window_info)
1277 {
1278 CanonicalWindowManagerPolicy::advise_new_window(window_info);
1279
1280@@ -306,7 +306,7 @@
1281 }
1282 }
1283
1284-void TitlebarWindowManagerPolicy::handle_window_ready(WindowInfo& window_info)
1285+void FloatingWindowManagerPolicy::handle_window_ready(WindowInfo& window_info)
1286 {
1287 if (window_info.window().application() != spinner.session() && window_info.needs_titlebar(window_info.type()))
1288 decoration_provider->create_titlebar_for(window_info.window());
1289@@ -314,14 +314,14 @@
1290 CanonicalWindowManagerPolicy::handle_window_ready(window_info);
1291 }
1292
1293-void TitlebarWindowManagerPolicy::advise_focus_lost(WindowInfo const& info)
1294+void FloatingWindowManagerPolicy::advise_focus_lost(WindowInfo const& info)
1295 {
1296 CanonicalWindowManagerPolicy::advise_focus_lost(info);
1297
1298 decoration_provider->paint_titlebar_for(info, 0x3F);
1299 }
1300
1301-void TitlebarWindowManagerPolicy::advise_focus_gained(WindowInfo const& info)
1302+void FloatingWindowManagerPolicy::advise_focus_gained(WindowInfo const& info)
1303 {
1304 CanonicalWindowManagerPolicy::advise_focus_gained(info);
1305
1306@@ -337,28 +337,28 @@
1307 }
1308 }
1309
1310-void TitlebarWindowManagerPolicy::advise_state_change(WindowInfo const& window_info, MirWindowState state)
1311+void FloatingWindowManagerPolicy::advise_state_change(WindowInfo const& window_info, MirWindowState state)
1312 {
1313 CanonicalWindowManagerPolicy::advise_state_change(window_info, state);
1314
1315 decoration_provider->advise_state_change(window_info, state);
1316 }
1317
1318-void TitlebarWindowManagerPolicy::advise_resize(WindowInfo const& window_info, Size const& new_size)
1319+void FloatingWindowManagerPolicy::advise_resize(WindowInfo const& window_info, Size const& new_size)
1320 {
1321 CanonicalWindowManagerPolicy::advise_resize(window_info, new_size);
1322
1323 decoration_provider->resize_titlebar_for(window_info, new_size);
1324 }
1325
1326-void TitlebarWindowManagerPolicy::advise_delete_window(WindowInfo const& window_info)
1327+void FloatingWindowManagerPolicy::advise_delete_window(WindowInfo const& window_info)
1328 {
1329 CanonicalWindowManagerPolicy::advise_delete_window(window_info);
1330
1331 decoration_provider->destroy_titlebar_for(window_info.window());
1332 }
1333
1334-bool TitlebarWindowManagerPolicy::handle_keyboard_event(MirKeyboardEvent const* event)
1335+bool FloatingWindowManagerPolicy::handle_keyboard_event(MirKeyboardEvent const* event)
1336 {
1337 auto const action = mir_keyboard_event_action(event);
1338 auto const scan_code = mir_keyboard_event_scan_code(event);
1339@@ -514,7 +514,7 @@
1340 return false;
1341 }
1342
1343-void TitlebarWindowManagerPolicy::toggle(MirWindowState state)
1344+void FloatingWindowManagerPolicy::toggle(MirWindowState state)
1345 {
1346 if (auto const window = tools.active_window())
1347 {
1348@@ -528,7 +528,7 @@
1349 }
1350 }
1351
1352-bool TitlebarWindowManagerPolicy::resize(Window const& window, Point cursor, Point old_cursor)
1353+bool FloatingWindowManagerPolicy::resize(Window const& window, Point cursor, Point old_cursor)
1354 {
1355 if (!window)
1356 return false;
1357@@ -579,7 +579,7 @@
1358 return true;
1359 }
1360
1361-void TitlebarWindowManagerPolicy::keep_size_within_limits(
1362+void FloatingWindowManagerPolicy::keep_size_within_limits(
1363 WindowInfo const& window_info, Displacement& delta, Width& new_width, Height& new_height) const
1364 {
1365 auto const min_width = std::max(window_info.min_width(), Width{5});
1366@@ -617,7 +617,7 @@
1367 }
1368 }
1369
1370-WindowSpecification TitlebarWindowManagerPolicy::place_new_window(
1371+WindowSpecification FloatingWindowManagerPolicy::place_new_window(
1372 ApplicationInfo const& app_info, WindowSpecification const& request_parameters)
1373 {
1374 auto parameters = CanonicalWindowManagerPolicy::place_new_window(app_info, request_parameters);
1375@@ -634,7 +634,7 @@
1376 return parameters;
1377 }
1378
1379-void TitlebarWindowManagerPolicy::advise_adding_to_workspace(
1380+void FloatingWindowManagerPolicy::advise_adding_to_workspace(
1381 std::shared_ptr<Workspace> const& workspace, std::vector<Window> const& windows)
1382 {
1383 if (windows.empty())
1384@@ -653,7 +653,7 @@
1385 }
1386 }
1387
1388-void TitlebarWindowManagerPolicy::switch_workspace_to(
1389+void FloatingWindowManagerPolicy::switch_workspace_to(
1390 std::shared_ptr<Workspace> const& workspace,
1391 Window const& window)
1392 {
1393@@ -716,7 +716,7 @@
1394 }
1395 }
1396
1397-void TitlebarWindowManagerPolicy::apply_workspace_hidden_to(Window const& window)
1398+void FloatingWindowManagerPolicy::apply_workspace_hidden_to(Window const& window)
1399 {
1400 auto const& window_info = tools.info_for(window);
1401 auto& pdata = policy_data_for(window_info);
1402@@ -732,7 +732,7 @@
1403 }
1404 }
1405
1406-void TitlebarWindowManagerPolicy::apply_workspace_visible_to(Window const& window)
1407+void FloatingWindowManagerPolicy::apply_workspace_visible_to(Window const& window)
1408 {
1409 auto const& window_info = tools.info_for(window);
1410 auto& pdata = policy_data_for(window_info);
1411@@ -746,7 +746,7 @@
1412 }
1413 }
1414
1415-void TitlebarWindowManagerPolicy::handle_modify_window(WindowInfo& window_info, WindowSpecification const& modifications)
1416+void FloatingWindowManagerPolicy::handle_modify_window(WindowInfo& window_info, WindowSpecification const& modifications)
1417 {
1418 auto mods = modifications;
1419
1420
1421=== renamed file 'miral-shell/titlebar_window_manager.h' => 'miral-shell/floating_window_manager.h'
1422--- miral-shell/titlebar_window_manager.h 2017-03-01 14:02:59 +0000
1423+++ miral-shell/floating_window_manager.h 2017-06-20 16:14:05 +0000
1424@@ -6,7 +6,7 @@
1425 * as published by the Free Software Foundation.
1426 *
1427 * This program is distributed in the hope that it will be useful,
1428- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1429+ * but WITHOUT ANY WARRANTY; without even the implied warranty ofb
1430 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1431 * GNU General Public License for more details.
1432 *
1433@@ -16,8 +16,8 @@
1434 * Authored by: Alan Griffiths <alan@octopull.co.uk>
1435 */
1436
1437-#ifndef MIRAL_SHELL_TITLEBAR_WINDOW_MANAGER_H
1438-#define MIRAL_SHELL_TITLEBAR_WINDOW_MANAGER_H
1439+#ifndef MIRAL_SHELL_FLOATING_WINDOW_MANAGER_H
1440+#define MIRAL_SHELL_FLOATING_WINDOW_MANAGER_H
1441
1442 #include <miral/canonical_window_manager.h>
1443 #include <miral/workspace_policy.h>
1444@@ -33,15 +33,15 @@
1445
1446 class DecorationProvider;
1447
1448-class TitlebarWindowManagerPolicy : public miral::CanonicalWindowManagerPolicy, miral::WorkspacePolicy
1449+class FloatingWindowManagerPolicy : public miral::CanonicalWindowManagerPolicy, miral::WorkspacePolicy
1450 {
1451 public:
1452- TitlebarWindowManagerPolicy(
1453+ FloatingWindowManagerPolicy(
1454 miral::WindowManagerTools const& tools,
1455 SpinnerSplash const& spinner,
1456 miral::InternalClientLauncher const& launcher,
1457 std::function<void()>& shutdown_hook);
1458- ~TitlebarWindowManagerPolicy();
1459+ ~FloatingWindowManagerPolicy();
1460
1461 virtual miral::WindowSpecification place_new_window(
1462 miral::ApplicationInfo const& app_info, miral::WindowSpecification const& request_parameters) override;
1463@@ -133,4 +133,4 @@
1464 void apply_workspace_hidden_to(miral::Window const& window);
1465 };
1466
1467-#endif //MIRAL_SHELL_TITLEBAR_WINDOW_MANAGER_H
1468+#endif //MIRAL_SHELL_FLOATING_WINDOW_MANAGER_H
1469
1470=== modified file 'miral-shell/miral-app.sh'
1471--- miral-shell/miral-app.sh 2017-03-24 14:54:48 +0000
1472+++ miral-shell/miral-app.sh 2017-06-20 16:14:05 +0000
1473@@ -46,6 +46,6 @@
1474 while [ ! -e "${socket}" ]; do echo "waiting for ${socket}"; sleep 1 ;done
1475
1476 unset QT_QPA_PLATFORMTHEME
1477-MIR_SOCKET=${socket} GDK_BACKEND=mir QT_QPA_PLATFORM=ubuntumirclient SDL_VIDEODRIVER=mir dbus-run-session -- ${launcher}
1478+MIR_SOCKET=${socket} XDG_SESSION_TYPE=mir GDK_BACKEND=mir QT_QPA_PLATFORM=ubuntumirclient SDL_VIDEODRIVER=mir dbus-run-session -- ${launcher}
1479 killall ${bindir}${miral_server}
1480
1481
1482=== modified file 'miral-shell/miral-desktop.sh'
1483--- miral-shell/miral-desktop.sh 2017-03-24 14:54:48 +0000
1484+++ miral-shell/miral-desktop.sh 2017-06-20 16:14:05 +0000
1485@@ -40,6 +40,6 @@
1486 while [ ! -e "${socket}" ]; do echo "waiting for ${socket}"; sleep 1 ;done
1487
1488 unset QT_QPA_PLATFORMTHEME
1489-MIR_SOCKET=${socket} GDK_BACKEND=mir QT_QPA_PLATFORM=ubuntumirclient SDL_VIDEODRIVER=mir dbus-run-session -- ${launcher}
1490+MIR_SOCKET=${socket} XDG_SESSION_TYPE=mir GDK_BACKEND=mir QT_QPA_PLATFORM=ubuntumirclient SDL_VIDEODRIVER=mir dbus-run-session -- ${launcher}
1491 sudo killall ${bindir}${miral_server}
1492
1493
1494=== modified file 'miral-shell/miral-run.sh'
1495--- miral-shell/miral-run.sh 2017-03-24 14:54:48 +0000
1496+++ miral-shell/miral-run.sh 2017-06-20 16:14:05 +0000
1497@@ -3,4 +3,4 @@
1498 then extras='--app-id com.canonical.miral.Terminal'
1499 fi
1500 unset QT_QPA_PLATFORMTHEME
1501-MIR_SOCKET=${XDG_RUNTIME_DIR}/miral_socket GDK_BACKEND=mir QT_QPA_PLATFORM=ubuntumirclient SDL_VIDEODRIVER=mir "$@" ${extras}&
1502+MIR_SOCKET=${XDG_RUNTIME_DIR}/miral_socket XDG_SESSION_TYPE=mir GDK_BACKEND=mir QT_QPA_PLATFORM=ubuntumirclient SDL_VIDEODRIVER=mir "$@" ${extras}&
1503
1504=== modified file 'miral-shell/miral-screencast.sh'
1505--- miral-shell/miral-screencast.sh 2016-12-09 11:08:07 +0000
1506+++ miral-shell/miral-screencast.sh 2017-06-20 16:14:05 +0000
1507@@ -2,7 +2,7 @@
1508 width=1920
1509 height=1080
1510 output=screencast.mp4
1511-socket=${XDG_RUNTIME_DIR}/mir_socket
1512+socket=${XDG_RUNTIME_DIR}/miral_socket
1513 if [ -v MIR_SERVER ]; then socket=${MIR_SERVER}; fi
1514
1515 while [ $# -gt 0 ]
1516
1517=== modified file 'miral-shell/miral-xrun.sh'
1518--- miral-shell/miral-xrun.sh 2017-03-24 15:47:07 +0000
1519+++ miral-shell/miral-xrun.sh 2017-06-20 16:14:05 +0000
1520@@ -21,6 +21,7 @@
1521 exit 0
1522 elif [ "$1" == "-force" ];
1523 then
1524+ export XDG_SESSION_TYPE=x11
1525 export GDK_BACKEND=x11
1526 export QT_QPA_PLATFORM=xcb
1527 export SDL_VIDEODRIVER=x11
1528
1529=== modified file 'miral-shell/shell_main.cpp'
1530--- miral-shell/shell_main.cpp 2017-03-06 09:45:37 +0000
1531+++ miral-shell/shell_main.cpp 2017-06-20 16:14:05 +0000
1532@@ -17,7 +17,7 @@
1533 */
1534
1535 #include "tiling_window_manager.h"
1536-#include "titlebar_window_manager.h"
1537+#include "floating_window_manager.h"
1538 #include "titlebar_config.h"
1539 #include "spinner/splash.h"
1540
1541@@ -44,7 +44,7 @@
1542 ActiveOutputsMonitor outputs_monitor;
1543 WindowManagerOptions window_managers
1544 {
1545- add_window_manager_policy<TitlebarWindowManagerPolicy>("titlebar", spinner, launcher, shutdown_hook),
1546+ add_window_manager_policy<FloatingWindowManagerPolicy>("floating", spinner, launcher, shutdown_hook),
1547 add_window_manager_policy<TilingWindowManagerPolicy>("tiling", spinner, launcher, outputs_monitor),
1548 };
1549
1550@@ -83,7 +83,7 @@
1551 {
1552 CommandLineOption{[&](std::string const& ) { },
1553 "desktop_file_hint", "Ignored for Unity8 compatibility", "miral-shell.desktop"},
1554- CursorTheme{"default"},
1555+ CursorTheme{"DMZ-White"},
1556 window_managers,
1557 display_configuration_options,
1558 launcher,
1559
1560=== modified file 'miral-shell/spinner/CMakeLists.txt'
1561--- miral-shell/spinner/CMakeLists.txt 2016-05-20 09:20:19 +0000
1562+++ miral-shell/spinner/CMakeLists.txt 2017-06-20 16:14:05 +0000
1563@@ -59,6 +59,7 @@
1564 )
1565
1566 target_link_libraries(miral-spinner
1567+ mirclientcpp
1568 EGL
1569 ${GLIB_LDFLAGS}
1570 ${GLESv2_LIBRARIES}
1571
1572=== modified file 'miral-shell/spinner/eglapp.cpp'
1573--- miral-shell/spinner/eglapp.cpp 2017-01-19 15:13:51 +0000
1574+++ miral-shell/spinner/eglapp.cpp 2017-06-20 16:14:05 +0000
1575@@ -16,61 +16,16 @@
1576
1577 #include "eglapp.h"
1578
1579+#include <mir/client/display_config.h>
1580+
1581 #include "miregl.h"
1582
1583-#include <mir_toolkit/version.h>
1584-
1585
1586 float mir_eglapp_background_opacity = 1.0f;
1587
1588
1589 namespace
1590 {
1591-template<typename ActiveOutputHandler>
1592-void for_each_active_output(
1593- MirConnection* const connection, ActiveOutputHandler const& handler)
1594-{
1595- /* eglapps are interested in the screen size, so
1596- use mir_connection_create_display_config */
1597-#if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 5, 0)
1598- MirDisplayConfiguration* display_config =
1599- mir_connection_create_display_config(connection);
1600-
1601- for (MirDisplayOutput* output = display_config->outputs;
1602- output != display_config->outputs + display_config->num_outputs;
1603- ++output)
1604- {
1605- if (output->used &&
1606- output->connected &&
1607- output->num_modes &&
1608- output->current_mode < output->num_modes)
1609- {
1610- handler(output);
1611- }
1612- }
1613-
1614- mir_display_config_destroy(display_config);
1615-#else
1616- MirDisplayConfig* display_config =
1617- mir_connection_create_display_configuration(connection);
1618-
1619- int const n = mir_display_config_get_num_outputs(display_config);
1620-
1621- for (int i = 0; i != n; ++i)
1622- {
1623- MirOutput const *const output = mir_display_config_get_output(display_config, i);
1624- if (mir_output_is_enabled(output) &&
1625- mir_output_get_connection_state(output) == mir_output_connection_state_connected &&
1626- mir_output_get_num_modes(output) &&
1627- mir_output_get_current_mode_index(output) < (size_t)mir_output_get_num_modes(output))
1628- {
1629- handler(output);
1630- }
1631- }
1632- mir_display_config_release(display_config);
1633-#endif
1634-}
1635-
1636 MirPixelFormat select_pixel_format(MirConnection* connection)
1637 {
1638 unsigned int format[mir_pixel_formats];
1639@@ -93,69 +48,33 @@
1640
1641 std::vector<std::shared_ptr<MirEglSurface>> mir_eglapp_init(MirConnection* const connection)
1642 {
1643- MirWindowParameters surfaceparm =
1644- {
1645- "eglappsurface",
1646- 0, 0,
1647- mir_pixel_format_xbgr_8888,
1648- mir_buffer_usage_hardware,
1649- mir_display_output_id_invalid
1650- };
1651-
1652- EGLint swapinterval = 1;
1653+ char const * const name = "eglappsurface";
1654
1655 if (!mir_connection_is_valid(connection))
1656 throw std::runtime_error("Can't get connection");
1657
1658 auto const pixel_format = select_pixel_format(connection);
1659- surfaceparm.pixel_format = pixel_format;
1660
1661 auto const mir_egl_app = make_mir_eglapp(connection, pixel_format);
1662
1663 std::vector<std::shared_ptr<MirEglSurface>> result;
1664
1665- // If a size has been specified just do that
1666- if (surfaceparm.width && surfaceparm.height)
1667- {
1668- result.push_back(std::make_shared<MirEglSurface>(mir_egl_app, surfaceparm, swapinterval));
1669- return result;
1670- }
1671-
1672- // If an output has been specified just do that
1673- if (surfaceparm.output_id != mir_display_output_id_invalid)
1674- {
1675- result.push_back(std::make_shared<MirEglSurface>(mir_egl_app, surfaceparm, swapinterval));
1676- return result;
1677- }
1678-
1679- // but normally, we're fullscreen on every active output
1680-#if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 5, 0)
1681- for_each_active_output(connection, [&](MirDisplayOutput const* output)
1682- {
1683- auto const& mode = output->modes[output->current_mode];
1684-
1685- printf("Active output [%u] at (%d, %d) is %dx%d\n",
1686- output->output_id,
1687- output->position_x, output->position_y,
1688- mode.horizontal_resolution, mode.vertical_resolution);
1689-
1690- surfaceparm.output_id = output->output_id;
1691- result.push_back(std::make_shared<MirEglSurface>(mir_egl_app, surfaceparm, swapinterval));
1692- });
1693-#else
1694- for_each_active_output(connection, [&](MirOutput const* output)
1695- {
1696- auto const& mode = mir_output_get_current_mode(output);
1697-
1698- printf("Active output [%u] at (%d, %d) is %dx%d\n",
1699- mir_output_get_id(output),
1700- mir_output_get_position_x(output), mir_output_get_position_y(output),
1701- mir_output_mode_get_width(mode), mir_output_mode_get_height(mode));
1702-
1703- surfaceparm.output_id = mir_output_get_id(output);
1704- result.push_back(std::make_shared<MirEglSurface>(mir_egl_app, surfaceparm, swapinterval));
1705- });
1706-#endif
1707+ mir::client::DisplayConfig{connection}.for_each_output([&](MirOutput const* output)
1708+ {
1709+ if (mir_output_get_connection_state(output) == mir_output_connection_state_connected &&
1710+ mir_output_is_enabled(output))
1711+ {
1712+ auto const mode = mir_output_get_current_mode(output);
1713+ auto const output_id = mir_output_get_id(output);
1714+
1715+ printf("Active output [%u] at (%d, %d) is %dx%d\n",
1716+ output_id,
1717+ mir_output_get_position_x(output), mir_output_get_position_y(output),
1718+ mir_output_mode_get_width(mode), mir_output_mode_get_height(mode));
1719+
1720+ result.push_back(std::make_shared<MirEglSurface>(mir_egl_app, name, output));
1721+ }
1722+ });
1723
1724 if (result.empty())
1725 throw std::runtime_error("No active outputs found.");
1726
1727=== modified file 'miral-shell/spinner/eglspinner.cpp'
1728--- miral-shell/spinner/eglspinner.cpp 2016-04-17 00:20:00 +0000
1729+++ miral-shell/spinner/eglspinner.cpp 2017-06-20 16:14:05 +0000
1730@@ -34,6 +34,8 @@
1731 #include <atomic>
1732 #include <mutex>
1733
1734+#include <mir_toolkit/mir_client_library.h>
1735+
1736 #include "spinner_glow.h"
1737 #include "spinner_logo.h"
1738
1739
1740=== modified file 'miral-shell/spinner/miregl.cpp'
1741--- miral-shell/spinner/miregl.cpp 2017-02-14 11:49:59 +0000
1742+++ miral-shell/spinner/miregl.cpp 2017-06-20 16:14:05 +0000
1743@@ -15,21 +15,22 @@
1744 */
1745
1746 #include "miregl.h"
1747+#include <miral/window_specification.h>
1748 #include <mir/client/window_spec.h>
1749-#include <mir_toolkit/version.h>
1750+#include <mir_toolkit/mir_client_library.h>
1751
1752 #include <cstring>
1753
1754 #include <GLES2/gl2.h>
1755-#include <miral/window_specification.h>
1756-#include <mir/client/window_spec.h>
1757+
1758+using namespace mir::client;
1759
1760 class MirEglApp
1761 {
1762 public:
1763 MirEglApp(MirConnection* const connection, MirPixelFormat pixel_format);
1764
1765- EGLSurface create_surface(MirWindow* window);
1766+ EGLSurface create_surface(MirRenderSurface* surface);
1767
1768 void make_current(EGLSurface eglsurface) const;
1769
1770@@ -60,47 +61,37 @@
1771 return std::make_shared<MirEglApp>(connection, pixel_format);
1772 }
1773
1774-namespace
1775-{
1776-MirWindow* create_window(MirConnection* const connection, MirWindowParameters const& parameters)
1777-{
1778-
1779- auto spec = mir::client::WindowSpec::for_normal_window(
1780- connection, parameters.width, parameters.height, parameters.pixel_format)
1781- .set_name(parameters.name)
1782- .set_buffer_usage(parameters.buffer_usage);
1783-
1784-
1785- if (!parameters.width && !parameters.height)
1786- spec.set_fullscreen_on_output(parameters.output_id);
1787-
1788- auto const window = mir_create_window_sync(spec);
1789+MirEglSurface::MirEglSurface(
1790+ std::shared_ptr<MirEglApp> const& mir_egl_app,
1791+ char const* name,
1792+ MirOutput const* output)
1793+:
1794+ mir_egl_app{mir_egl_app}
1795+{
1796+ auto const mode = mir_output_get_current_mode(output);
1797+ auto const output_id = mir_output_get_id(output);
1798+ auto const width = mir_output_mode_get_width(mode);
1799+ auto const height = mir_output_mode_get_height(mode);
1800+
1801+ surface = Surface{mir_connection_create_render_surface_sync(mir_egl_app->connection, width, height)};
1802+
1803+ eglsurface = mir_egl_app->create_surface(surface);
1804+
1805+ window = WindowSpec::for_normal_window(mir_egl_app->connection, width, height)
1806+ .add_surface(surface, width, height, 0, 0)
1807+ .set_name(name)
1808+ .set_fullscreen_on_output(output_id)
1809+ .create_window();
1810
1811 if (!mir_window_is_valid(window))
1812 throw std::runtime_error(std::string("Can't create a window ") + mir_window_get_error_message(window));
1813
1814- if (parameters.output_id != mir_display_output_id_invalid)
1815- mir_window_set_state(window, mir_window_state_fullscreen);
1816-
1817- return window;
1818-}
1819-}
1820-
1821-MirEglSurface::MirEglSurface(
1822- std::shared_ptr<MirEglApp> const& mir_egl_app, MirWindowParameters const& parm, int swapinterval) :
1823- mir_egl_app{mir_egl_app},
1824- window{create_window(mir_egl_app->connection, parm)},
1825- eglsurface{mir_egl_app->create_surface(window)},
1826- width_{0},
1827- height_{0}
1828-{
1829- mir_egl_app->set_swap_interval(eglsurface, swapinterval);
1830+ mir_egl_app->set_swap_interval(eglsurface, -1);
1831 }
1832
1833 MirEglSurface::~MirEglSurface()
1834 {
1835 mir_egl_app->destroy_surface(eglsurface);
1836- mir_window_release_sync(window);
1837 }
1838
1839 void MirEglSurface::egl_make_current()
1840@@ -139,7 +130,7 @@
1841 EGL_NONE
1842 };
1843
1844- egldisplay = eglGetDisplay((EGLNativeDisplayType) mir_connection_get_egl_native_display(connection));
1845+ egldisplay = eglGetDisplay((EGLNativeDisplayType)(connection));
1846 if (egldisplay == EGL_NO_DISPLAY)
1847 throw std::runtime_error("Can't eglGetDisplay");
1848
1849@@ -184,12 +175,12 @@
1850 make_current(dummy_surface);
1851 }
1852
1853-EGLSurface MirEglApp::create_surface(MirWindow* window)
1854+EGLSurface MirEglApp::create_surface(MirRenderSurface* surface)
1855 {
1856 auto const eglsurface = eglCreateWindowSurface(
1857 egldisplay,
1858 eglconfig,
1859- (EGLNativeWindowType) mir_buffer_stream_get_egl_native_window(mir_window_get_buffer_stream(window)), NULL);
1860+ (EGLNativeWindowType)surface, NULL);
1861
1862 if (eglsurface == EGL_NO_SURFACE)
1863 throw std::runtime_error("eglCreateWindowSurface failed");
1864
1865=== modified file 'miral-shell/spinner/miregl.h'
1866--- miral-shell/spinner/miregl.h 2017-03-06 09:49:23 +0000
1867+++ miral-shell/spinner/miregl.h 2017-06-20 16:14:05 +0000
1868@@ -17,9 +17,8 @@
1869 #ifndef UNITYSYSTEMCOMPOSITOR_MIREGL_H
1870 #define UNITYSYSTEMCOMPOSITOR_MIREGL_H
1871
1872-#include <mir/client/detail/mir_forward_compatibility.h>
1873-#include <mir_toolkit/client_types.h>
1874-#include "mir_toolkit/mir_client_library.h"
1875+#include <mir/client/surface.h>
1876+#include <mir/client/window.h>
1877
1878 #include <EGL/egl.h>
1879
1880@@ -37,8 +36,8 @@
1881 public:
1882 MirEglSurface(
1883 std::shared_ptr<MirEglApp> const& mir_egl_app,
1884- MirWindowParameters const& parm,
1885- int swapinterval);
1886+ char const* name,
1887+ MirOutput const* output);
1888
1889 ~MirEglSurface();
1890
1891@@ -58,8 +57,9 @@
1892 unsigned int height() const;
1893
1894 std::shared_ptr<MirEglApp> const mir_egl_app;
1895- MirWindow* const window;
1896- EGLSurface const eglsurface;
1897+ mir::client::Surface surface;
1898+ mir::client::Window window;
1899+ EGLSurface eglsurface;
1900 int width_;
1901 int height_;
1902 };
1903
1904=== modified file 'miral/CMakeLists.txt'
1905--- miral/CMakeLists.txt 2017-03-20 12:28:06 +0000
1906+++ miral/CMakeLists.txt 2017-06-20 16:14:05 +0000
1907@@ -1,4 +1,4 @@
1908-pkg_check_modules(MIRSERVER mirserver>=0.20 REQUIRED)
1909+pkg_check_modules(MIRSERVER mirserver>=0.26 REQUIRED)
1910
1911 if(${CMAKE_COMPILER_IS_GNUCXX})
1912 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flto")
1913@@ -11,8 +11,9 @@
1914
1915 set(MIRAL_ABI 2)
1916 set(symbol_map ${CMAKE_CURRENT_SOURCE_DIR}/symbols.map)
1917+set(miral_include ${PROJECT_SOURCE_DIR}/include)
1918
1919-include_directories(include SYSTEM ${MIRSERVER_INCLUDE_DIRS})
1920+add_library(mirclientcpp INTERFACE)
1921
1922 add_library(miral-internal STATIC
1923 basic_window_manager.cpp basic_window_manager.h window_manager_tools_implementation.h
1924@@ -28,39 +29,53 @@
1925 set_source_files_properties(xcursor.c PROPERTIES COMPILE_DEFINITIONS _GNU_SOURCE)
1926
1927 add_library(miral SHARED
1928- active_outputs.cpp ${CMAKE_SOURCE_DIR}/include/miral/active_outputs.h
1929- add_init_callback.cpp ${CMAKE_SOURCE_DIR}/include/miral/add_init_callback.h
1930- application.cpp ${CMAKE_SOURCE_DIR}/include/miral/application.h
1931- application_authorizer.cpp ${CMAKE_SOURCE_DIR}/include/miral/application_authorizer.h
1932- application_info.cpp ${CMAKE_SOURCE_DIR}/include/miral/application_info.h
1933- canonical_window_manager.cpp ${CMAKE_SOURCE_DIR}/include/miral/canonical_window_manager.h
1934- command_line_option.cpp ${CMAKE_SOURCE_DIR}/include/miral/command_line_option.h
1935- cursor_theme.cpp ${CMAKE_SOURCE_DIR}/include/miral/cursor_theme.h
1936- debug_extension.cpp ${CMAKE_SOURCE_DIR}/include/miral/debug_extension.h
1937- keymap.cpp ${CMAKE_SOURCE_DIR}/include/miral/keymap.h
1938- runner.cpp ${CMAKE_SOURCE_DIR}/include/miral/runner.h
1939- display_configuration_option.cpp ${CMAKE_SOURCE_DIR}/include/miral/display_configuration_option.h
1940- output.cpp ${CMAKE_SOURCE_DIR}/include/miral/output.h
1941- append_event_filter.cpp ${CMAKE_SOURCE_DIR}/include/miral/append_event_filter.h
1942- window.cpp ${CMAKE_SOURCE_DIR}/include/miral/window.h
1943- window_info.cpp ${CMAKE_SOURCE_DIR}/include/miral/window_info.h
1944- window_management_options.cpp ${CMAKE_SOURCE_DIR}/include/miral/window_management_options.h
1945- window_specification.cpp ${CMAKE_SOURCE_DIR}/include/miral/window_specification.h
1946- internal_client.cpp ${CMAKE_SOURCE_DIR}/include/miral/internal_client.h
1947- set_command_line_handler.cpp ${CMAKE_SOURCE_DIR}/include/miral/set_command_line_handler.h
1948- set_terminator.cpp ${CMAKE_SOURCE_DIR}/include/miral/set_terminator.h
1949- set_window_management_policy.cpp ${CMAKE_SOURCE_DIR}/include/miral/set_window_management_policy.h
1950- workspace_policy.cpp ${CMAKE_SOURCE_DIR}/include/miral/workspace_policy.h
1951- window_management_policy.cpp ${CMAKE_SOURCE_DIR}/include/miral/window_management_policy.h
1952- window_manager_tools.cpp ${CMAKE_SOURCE_DIR}/include/miral/window_manager_tools.h
1953- ${CMAKE_SOURCE_DIR}/include/mir/client/blob.h
1954- ${CMAKE_SOURCE_DIR}/include/mir/client/cookie.h
1955- ${CMAKE_SOURCE_DIR}/include/mir/client/window_spec.h
1956- ${CMAKE_SOURCE_DIR}/include/mir/client/window_id.h
1957- ${CMAKE_SOURCE_DIR}/include/mir/client/connection.h
1958- ${CMAKE_SOURCE_DIR}/include/mir/client/display_config.h
1959- ${CMAKE_SOURCE_DIR}/include/mir/client/window.h
1960- ${CMAKE_SOURCE_DIR}/include/mir/client/detail/mir_forward_compatibility.h
1961+ active_outputs.cpp ${miral_include}/miral/active_outputs.h
1962+ add_init_callback.cpp ${miral_include}/miral/add_init_callback.h
1963+ application.cpp ${miral_include}/miral/application.h
1964+ application_authorizer.cpp ${miral_include}/miral/application_authorizer.h
1965+ application_info.cpp ${miral_include}/miral/application_info.h
1966+ canonical_window_manager.cpp ${miral_include}/miral/canonical_window_manager.h
1967+ command_line_option.cpp ${miral_include}/miral/command_line_option.h
1968+ cursor_theme.cpp ${miral_include}/miral/cursor_theme.h
1969+ debug_extension.cpp ${miral_include}/miral/debug_extension.h
1970+ keymap.cpp ${miral_include}/miral/keymap.h
1971+ runner.cpp ${miral_include}/miral/runner.h
1972+ display_configuration_option.cpp ${miral_include}/miral/display_configuration_option.h
1973+ output.cpp ${miral_include}/miral/output.h
1974+ append_event_filter.cpp ${miral_include}/miral/append_event_filter.h
1975+ window.cpp ${miral_include}/miral/window.h
1976+ window_info.cpp ${miral_include}/miral/window_info.h
1977+ window_management_options.cpp ${miral_include}/miral/window_management_options.h
1978+ window_specification.cpp ${miral_include}/miral/window_specification.h
1979+ internal_client.cpp ${miral_include}/miral/internal_client.h
1980+ set_command_line_handler.cpp ${miral_include}/miral/set_command_line_handler.h
1981+ set_terminator.cpp ${miral_include}/miral/set_terminator.h
1982+ set_window_management_policy.cpp ${miral_include}/miral/set_window_management_policy.h
1983+ workspace_policy.cpp ${miral_include}/miral/workspace_policy.h
1984+ window_management_policy.cpp ${miral_include}/miral/window_management_policy.h
1985+ window_manager_tools.cpp ${miral_include}/miral/window_manager_tools.h
1986+ ${miral_include}/miral/window_management_policy_addendum2.h
1987+ ${miral_include}/mir/client/blob.h
1988+ ${miral_include}/mir/client/cookie.h
1989+ ${miral_include}/mir/client/window_spec.h
1990+ ${miral_include}/mir/client/window_id.h
1991+ ${miral_include}/mir/client/connection.h
1992+ ${miral_include}/mir/client/display_config.h
1993+ ${miral_include}/mir/client/window.h
1994+)
1995+
1996+target_include_directories(mirclientcpp
1997+ INTERFACE "${miral_include}" ${MIRCLIENT_INCLUDE_DIRS}
1998+)
1999+
2000+target_include_directories(miral-internal
2001+ PRIVATE "${miral_include}" ${MIRCLIENT_INCLUDE_DIRS}
2002+ PRIVATE ${MIRSERVER_INCLUDE_DIRS}
2003+)
2004+
2005+target_include_directories(miral
2006+ PUBLIC "${miral_include}" ${MIRCLIENT_INCLUDE_DIRS}
2007+ PRIVATE ${MIRSERVER_INCLUDE_DIRS}
2008 )
2009
2010 target_link_libraries(miral
2011@@ -99,26 +114,9 @@
2012 @ONLY
2013 )
2014
2015-if (MIRSERVER_VERSION VERSION_LESS 0.24)
2016- set(MIR_POINTER_CONFINEMENT 0)
2017-else()
2018- set(MIR_POINTER_CONFINEMENT 1)
2019-endif()
2020-
2021-if (MIRSERVER_VERSION VERSION_LESS 0.22)
2022- set(MIR_DISPLAY_CONFIG_GET_MUTABLE 0)
2023-else()
2024- set(MIR_DISPLAY_CONFIG_GET_MUTABLE 1)
2025-endif()
2026-
2027-configure_file(
2028- ${CMAKE_CURRENT_SOURCE_DIR}/mir_features.h.in
2029- ${PROJECT_SOURCE_DIR}/include/mir/client/detail/mir_features.h
2030-)
2031-
2032-configure_file(
2033- ${CMAKE_CURRENT_SOURCE_DIR}/version.h.in
2034- ${PROJECT_SOURCE_DIR}/include/miral/version.h
2035+configure_file(
2036+ ${CMAKE_CURRENT_SOURCE_DIR}/version.h.in
2037+ ${miral_include}/miral/version.h
2038 )
2039
2040 install(TARGETS miral LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}")
2041
2042=== modified file 'miral/active_outputs.cpp'
2043--- miral/active_outputs.cpp 2017-01-13 18:17:01 +0000
2044+++ miral/active_outputs.cpp 2017-06-20 16:14:05 +0000
2045@@ -23,12 +23,8 @@
2046 #include <mir/graphics/display_configuration.h>
2047 #include <mir/server.h>
2048
2049-#if MIR_SERVER_VERSION < MIR_VERSION_NUMBER(0, 26, 0)
2050-#include <mir/graphics/display_configuration_report.h>
2051-#else
2052 #include <mir/graphics/display_configuration_observer.h>
2053 #include <mir/observer_registrar.h>
2054-#endif
2055
2056 #include <algorithm>
2057 #include <mutex>
2058@@ -40,17 +36,6 @@
2059 void miral::ActiveOutputsListener::advise_output_update(Output const& /*updated*/, Output const& /*original*/) {}
2060 void miral::ActiveOutputsListener::advise_output_delete(Output const& /*output*/) {}
2061
2062-#if MIR_SERVER_VERSION < MIR_VERSION_NUMBER(0, 26, 0)
2063-struct miral::ActiveOutputsMonitor::Self : mir::graphics::DisplayConfigurationReport
2064-{
2065- virtual void initial_configuration(mir::graphics::DisplayConfiguration const& configuration) override;
2066- virtual void new_configuration(mir::graphics::DisplayConfiguration const& configuration) override;
2067-
2068- std::mutex mutex;
2069- std::vector<ActiveOutputsListener*> listeners;
2070- std::vector<Output> outputs;
2071-};
2072-#else
2073 struct miral::ActiveOutputsMonitor::Self : mir::graphics::DisplayConfigurationObserver
2074 {
2075 void initial_configuration(std::shared_ptr<mir::graphics::DisplayConfiguration const> const& configuration) override;
2076@@ -79,7 +64,6 @@
2077 std::vector<ActiveOutputsListener*> listeners;
2078 std::vector<Output> outputs;
2079 };
2080-#endif
2081
2082 miral::ActiveOutputsMonitor::ActiveOutputsMonitor() :
2083 self{std::make_shared<Self>()}
2084@@ -109,12 +93,8 @@
2085 {
2086 std::lock_guard<decltype(self->mutex)> lock{self->mutex};
2087
2088-#if MIR_SERVER_VERSION < MIR_VERSION_NUMBER(0, 26, 0)
2089- server.override_the_display_configuration_report([this]{ return self; });
2090-#else
2091 server.add_pre_init_callback([this, &server]
2092 { server.the_display_configuration_observer_registrar()->register_interest(self); });
2093-#endif
2094 }
2095
2096 void miral::ActiveOutputsMonitor::process_outputs(
2097@@ -125,65 +105,11 @@
2098 }
2099
2100
2101-#if MIR_SERVER_VERSION < MIR_VERSION_NUMBER(0, 26, 0)
2102-void miral::ActiveOutputsMonitor::Self::initial_configuration(mir::graphics::DisplayConfiguration const& configuration)
2103-{
2104- new_configuration(configuration);
2105-}
2106-#else
2107 void miral::ActiveOutputsMonitor::Self::initial_configuration(std::shared_ptr<mir::graphics::DisplayConfiguration const> const& configuration)
2108 {
2109 configuration_applied(configuration);
2110 }
2111-#endif
2112-
2113-#if MIR_SERVER_VERSION < MIR_VERSION_NUMBER(0, 26, 0)
2114-void miral::ActiveOutputsMonitor::Self::new_configuration(mir::graphics::DisplayConfiguration const& configuration)
2115-{
2116- std::lock_guard<decltype(mutex)> lock{mutex};
2117-
2118- decltype(outputs) current_outputs;
2119-
2120- for (auto const l : listeners)
2121- l->advise_output_begin();
2122-
2123- configuration.for_each_output([&current_outputs, this](mir::graphics::DisplayConfigurationOutput const& output)
2124- {
2125- Output o{output};
2126-
2127- if (!o.connected() || !o.valid()) return;
2128-
2129- auto op = find_if(begin(outputs), end(outputs), [&](Output const& oo) { return oo.is_same_output(o); });
2130-
2131- if (op == end(outputs))
2132- {
2133- for (auto const l : listeners)
2134- l->advise_output_create(o);
2135- }
2136- else if (!equivalent_display_area(o, *op))
2137- {
2138- for (auto const l : listeners)
2139- l->advise_output_update(o, *op);
2140- }
2141-
2142- current_outputs.push_back(o);
2143- });
2144-
2145- for (auto const& o : outputs)
2146- {
2147- auto op = find_if(begin(current_outputs), end(current_outputs), [&](Output const& oo)
2148- { return oo.is_same_output(o); });
2149-
2150- if (op == end(current_outputs))
2151- for (auto const l : listeners)
2152- l->advise_output_delete(o);
2153- }
2154-
2155- current_outputs.swap(outputs);
2156- for (auto const l : listeners)
2157- l->advise_output_end();
2158-}
2159-#else
2160+
2161 void miral::ActiveOutputsMonitor::Self::configuration_applied(std::shared_ptr<mir::graphics::DisplayConfiguration const> const& config)
2162 {
2163 std::lock_guard<decltype(mutex)> lock{mutex};
2164@@ -233,4 +159,3 @@
2165 for (auto const l : listeners)
2166 l->advise_output_end();
2167 }
2168-#endif
2169
2170=== modified file 'miral/basic_window_manager.cpp'
2171--- miral/basic_window_manager.cpp 2017-03-21 12:30:42 +0000
2172+++ miral/basic_window_manager.cpp 2017-06-20 16:14:05 +0000
2173@@ -19,6 +19,7 @@
2174 #include "basic_window_manager.h"
2175 #include "miral/window_manager_tools.h"
2176 #include "miral/workspace_policy.h"
2177+#include "miral/window_management_policy_addendum2.h"
2178
2179 #include <mir/scene/session.h>
2180 #include <mir/scene/surface.h>
2181@@ -70,7 +71,6 @@
2182
2183 namespace
2184 {
2185-
2186 auto find_workspace_policy(std::unique_ptr<miral::WindowManagementPolicy> const& policy) -> miral::WorkspacePolicy*
2187 {
2188 miral::WorkspacePolicy* result = dynamic_cast<miral::WorkspacePolicy*>(policy.get());
2189@@ -82,6 +82,23 @@
2190
2191 return &null_workspace_policy;
2192 }
2193+
2194+auto find_policy_addendum2(std::unique_ptr<miral::WindowManagementPolicy> const& policy) -> miral::WindowManagementPolicyAddendum2*
2195+{
2196+ miral::WindowManagementPolicyAddendum2* result = dynamic_cast<miral::WindowManagementPolicyAddendum2*>(policy.get());
2197+
2198+ if (result)
2199+ return result;
2200+
2201+ struct NullWindowManagementPolicyAddendum2 : miral::WindowManagementPolicyAddendum2
2202+ {
2203+ void handle_request_drag_and_drop(miral::WindowInfo&) override {}
2204+ void handle_request_move(miral::WindowInfo&, MirInputEvent const*) override {}
2205+ };
2206+ static NullWindowManagementPolicyAddendum2 null_workspace_policy;
2207+
2208+ return &null_workspace_policy;
2209+}
2210 }
2211
2212
2213@@ -94,10 +111,18 @@
2214 display_layout(display_layout),
2215 persistent_surface_store{persistent_surface_store},
2216 policy(build(WindowManagerTools{this})),
2217- workspace_policy{find_workspace_policy(policy)}
2218+ workspace_policy{find_workspace_policy(policy)},
2219+ policy2{find_policy_addendum2(policy)}
2220 {
2221 }
2222
2223+miral::BasicWindowManager::~BasicWindowManager()
2224+{
2225+#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 27, 0)
2226+ if (last_input_event)
2227+ mir_event_unref(last_input_event);
2228+#endif
2229+}
2230 void miral::BasicWindowManager::add_session(std::shared_ptr<scene::Session> const& session)
2231 {
2232 Locker lock{this};
2233@@ -156,14 +181,12 @@
2234 session,
2235 scene_surface));
2236
2237-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 25, 0)
2238 if (parent && spec.aux_rect().is_set() && spec.placement_hints().is_set())
2239 {
2240 Rectangle relative_placement{window.top_left() - (parent.top_left()-Point{}), window.size()};
2241 auto const mir_surface = std::shared_ptr<scene::Surface>(window);
2242 mir_surface->placed_relative(relative_placement);
2243 }
2244-#endif
2245
2246 return surface_id;
2247 }
2248@@ -362,10 +385,24 @@
2249 #if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 27, 0)
2250 void miral::BasicWindowManager::handle_request_drag_and_drop(
2251 std::shared_ptr<mir::scene::Session> const& /*session*/,
2252- std::shared_ptr<mir::scene::Surface> const& /*surface*/,
2253- uint64_t /*timestamp*/)
2254-{
2255- // TODO
2256+ std::shared_ptr<mir::scene::Surface> const& surface,
2257+ uint64_t timestamp)
2258+{
2259+ Locker lock{this};
2260+ if (timestamp >= last_input_event_timestamp)
2261+ policy2->handle_request_drag_and_drop(info_for(surface));
2262+}
2263+
2264+void miral::BasicWindowManager::handle_request_move(
2265+ std::shared_ptr<mir::scene::Session> const& /*session*/,
2266+ std::shared_ptr<mir::scene::Surface> const& surface,
2267+ uint64_t timestamp)
2268+{
2269+ std::lock_guard<decltype(mutex)> lock(mutex);
2270+ if (timestamp >= last_input_event_timestamp && last_input_event)
2271+ {
2272+ policy2->handle_request_move(info_for(surface), mir_event_get_input_event(last_input_event));
2273+ }
2274 }
2275 #endif
2276
2277@@ -741,6 +778,24 @@
2278 focus_controller->raise({begin(windows), end(windows)});
2279 }
2280
2281+void miral::BasicWindowManager::start_drag_and_drop(WindowInfo& window_info, std::vector<uint8_t> const& handle)
2282+{
2283+#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 27, 0)
2284+ std::shared_ptr<scene::Surface>(window_info.window())->start_drag_and_drop(handle);
2285+ focus_controller->set_drag_and_drop_handle(handle);
2286+#else
2287+ (void)window_info;
2288+ (void)handle;
2289+#endif
2290+}
2291+
2292+void miral::BasicWindowManager::end_drag_and_drop()
2293+{
2294+#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 27, 0)
2295+ focus_controller->clear_drag_and_drop_handle();
2296+#endif
2297+}
2298+
2299 void miral::BasicWindowManager::move_tree(miral::WindowInfo& root, mir::geometry::Displacement movement)
2300 {
2301 if (movement == mir::geometry::Displacement{})
2302@@ -900,11 +955,9 @@
2303 if (new_pos.is_set())
2304 place_and_size(window_info, new_pos.value().top_left, new_pos.value().size);
2305
2306-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 25, 0)
2307 Rectangle relative_placement{window.top_left() - (parent.top_left()-Point{}), window.size()};
2308 auto const mir_surface = std::shared_ptr<scene::Surface>(window);
2309 mir_surface->placed_relative(relative_placement);
2310-#endif
2311 }
2312 }
2313
2314@@ -913,25 +966,18 @@
2315 set_state(window_info, modifications.state().value());
2316 }
2317
2318-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 24, 0)
2319 if (modifications.confine_pointer().is_set())
2320 std::shared_ptr<scene::Surface>(window)->set_confine_pointer_state(modifications.confine_pointer().value());
2321-#endif
2322 }
2323
2324 auto miral::BasicWindowManager::info_for_window_id(std::string const& id) const -> WindowInfo&
2325 {
2326-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 24, 0)
2327 auto surface = persistent_surface_store->surface_for_id(mir::shell::PersistentSurfaceStore::Id{id});
2328
2329 if (!surface)
2330 BOOST_THROW_EXCEPTION(std::runtime_error{"No surface matching ID"});
2331
2332 return info_for(surface);
2333-#else
2334- (void)id;
2335- BOOST_THROW_EXCEPTION(std::runtime_error{"No surface matching ID"});
2336-#endif
2337 }
2338
2339 auto miral::BasicWindowManager::id_for_window(Window const& window) const -> std::string
2340@@ -939,11 +985,7 @@
2341 if (!window)
2342 BOOST_THROW_EXCEPTION(std::runtime_error{"Null Window has no Persistent ID"});
2343
2344-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 24, 0)
2345 return persistent_surface_store->id_for_surface(window).serialize_to_string();
2346-#else
2347- BOOST_THROW_EXCEPTION(std::runtime_error{"Persistent IDs unavailable with this Mir server version"});
2348-#endif
2349 }
2350
2351 void miral::BasicWindowManager::place_and_size(WindowInfo& root, Point const& new_pos, Size const& new_size)
2352@@ -1163,25 +1205,22 @@
2353
2354 void miral::BasicWindowManager::update_event_timestamp(MirKeyboardEvent const* kev)
2355 {
2356- auto iev = mir_keyboard_event_input_event(kev);
2357- last_input_event_timestamp = mir_input_event_get_event_time(iev);
2358+ update_event_timestamp(mir_keyboard_event_input_event(kev));
2359 }
2360
2361 void miral::BasicWindowManager::update_event_timestamp(MirPointerEvent const* pev)
2362 {
2363- auto iev = mir_pointer_event_input_event(pev);
2364 auto pointer_action = mir_pointer_event_action(pev);
2365
2366 if (pointer_action == mir_pointer_action_button_up ||
2367 pointer_action == mir_pointer_action_button_down)
2368 {
2369- last_input_event_timestamp = mir_input_event_get_event_time(iev);
2370+ update_event_timestamp(mir_pointer_event_input_event(pev));
2371 }
2372 }
2373
2374 void miral::BasicWindowManager::update_event_timestamp(MirTouchEvent const* tev)
2375 {
2376- auto iev = mir_touch_event_input_event(tev);
2377 auto touch_count = mir_touch_event_point_count(tev);
2378 for (unsigned i = 0; i < touch_count; i++)
2379 {
2380@@ -1189,12 +1228,22 @@
2381 if (touch_action == mir_touch_action_up ||
2382 touch_action == mir_touch_action_down)
2383 {
2384- last_input_event_timestamp = mir_input_event_get_event_time(iev);
2385+ update_event_timestamp(mir_touch_event_input_event(tev));
2386 break;
2387 }
2388 }
2389 }
2390
2391+void miral::BasicWindowManager::update_event_timestamp(MirInputEvent const* iev)
2392+{
2393+ last_input_event_timestamp = mir_input_event_get_event_time(iev);
2394+#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 27, 0)
2395+ if (last_input_event)
2396+ mir_event_unref(last_input_event);
2397+ last_input_event = mir_event_ref(mir_input_event_get_event(iev));
2398+#endif
2399+}
2400+
2401 void miral::BasicWindowManager::invoke_under_lock(std::function<void()> const& callback)
2402 {
2403 Locker lock{this};
2404
2405=== modified file 'miral/basic_window_manager.h'
2406--- miral/basic_window_manager.h 2017-03-21 12:30:42 +0000
2407+++ miral/basic_window_manager.h 2017-06-20 16:14:05 +0000
2408@@ -46,6 +46,7 @@
2409 namespace miral
2410 {
2411 class WorkspacePolicy;
2412+class WindowManagementPolicyAddendum2;
2413 using mir::shell::SurfaceSet;
2414 using WindowManagementPolicyBuilder =
2415 std::function<std::unique_ptr<miral::WindowManagementPolicy>(miral::WindowManagerTools const& tools)>;
2416@@ -61,6 +62,7 @@
2417 std::shared_ptr<mir::shell::DisplayLayout> const& display_layout,
2418 std::shared_ptr<mir::shell::PersistentSurfaceStore> const& persistent_surface_store,
2419 WindowManagementPolicyBuilder const& build);
2420+ ~BasicWindowManager();
2421
2422 void add_session(std::shared_ptr<mir::scene::Session> const& session) override;
2423
2424@@ -101,6 +103,11 @@
2425 std::shared_ptr<mir::scene::Session> const& session,
2426 std::shared_ptr<mir::scene::Surface> const& surface,
2427 uint64_t timestamp) override;
2428+
2429+ void handle_request_move(
2430+ std::shared_ptr<mir::scene::Session> const& session,
2431+ std::shared_ptr<mir::scene::Surface> const& surface,
2432+ uint64_t timestamp) override;
2433 #endif
2434
2435 int set_surface_attribute(
2436@@ -161,6 +168,8 @@
2437 auto active_display() -> mir::geometry::Rectangle const override;
2438
2439 void raise_tree(Window const& root) override;
2440+ void start_drag_and_drop(WindowInfo& window_info, std::vector<uint8_t> const& handle) override;
2441+ void end_drag_and_drop() override;
2442
2443 void modify_window(WindowInfo& window_info, WindowSpecification const& modifications) override;
2444
2445@@ -190,6 +199,7 @@
2446
2447 std::unique_ptr<WindowManagementPolicy> const policy;
2448 WorkspacePolicy* const workspace_policy;
2449+ WindowManagementPolicyAddendum2* const policy2;
2450
2451 std::mutex mutex;
2452 SessionInfoMap app_info;
2453@@ -197,6 +207,9 @@
2454 mir::geometry::Rectangles displays;
2455 mir::geometry::Point cursor;
2456 uint64_t last_input_event_timestamp{0};
2457+#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 27, 0)
2458+ MirEvent const* last_input_event{nullptr};
2459+#endif
2460 miral::MRUWindowList mru_active_windows;
2461 using FullscreenSurfaces = std::set<Window>;
2462 FullscreenSurfaces fullscreen_surfaces;
2463@@ -213,6 +226,7 @@
2464 void update_event_timestamp(MirKeyboardEvent const* kev);
2465 void update_event_timestamp(MirPointerEvent const* pev);
2466 void update_event_timestamp(MirTouchEvent const* tev);
2467+ void update_event_timestamp(MirInputEvent const* iev);
2468
2469 auto can_activate_window_for_session(miral::Application const& session) -> bool;
2470 auto can_activate_window_for_session_in_workspace(
2471
2472=== modified file 'miral/both_versions.h'
2473--- miral/both_versions.h 2017-02-15 12:17:12 +0000
2474+++ miral/both_versions.h 2017-06-20 16:14:05 +0000
2475@@ -27,12 +27,7 @@
2476 #define MIRAL_FAKE_NEW_SYMBOL(old_sym, new_sym)\
2477 extern "C" __attribute__((alias(#old_sym))) void new_sym();
2478
2479-#if (MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 26, 0))
2480- #define MIRAL_BOTH_VERSIONS(old_sym, new_sym)\
2481- MIRAL_FAKE_OLD_SYMBOL(old_sym, new_sym)
2482-#else
2483- #define MIRAL_BOTH_VERSIONS(old_sym, new_sym)\
2484- MIRAL_FAKE_NEW_SYMBOL(old_sym, new_sym)
2485-#endif
2486+#define MIRAL_BOTH_VERSIONS(old_sym, new_sym)\
2487+MIRAL_FAKE_OLD_SYMBOL(old_sym, new_sym)
2488
2489 #endif //MIRAL_BOTH_VERSIONS_H
2490
2491=== modified file 'miral/cursor_theme.cpp'
2492--- miral/cursor_theme.cpp 2016-09-28 10:57:41 +0000
2493+++ miral/cursor_theme.cpp 2017-06-20 16:14:05 +0000
2494@@ -19,6 +19,7 @@
2495 #include "miral/cursor_theme.h"
2496 #include "xcursor_loader.h"
2497
2498+#include <mir/options/option.h>
2499 #include <mir/server.h>
2500 #include <mir_toolkit/cursors.h>
2501
2502@@ -43,8 +44,14 @@
2503
2504 void miral::CursorTheme::operator()(mir::Server& server) const
2505 {
2506+ static char const* const option = "cursor-theme";
2507+
2508+ server.add_configuration_option(option, "Cursor theme (e.g. \"DMZ-Black\")", theme);
2509+
2510 server.override_the_cursor_images([&]
2511 {
2512+ auto const theme = server.get_options()->get<std::string const>(option);
2513+
2514 std::shared_ptr<mi::CursorImages> const xcursor_loader{std::make_shared<XCursorLoader>(theme)};
2515
2516 if (has_default_cursor(*xcursor_loader))
2517
2518=== modified file 'miral/keymap.cpp'
2519--- miral/keymap.cpp 2017-01-17 16:42:33 +0000
2520+++ miral/keymap.cpp 2017-06-20 16:14:05 +0000
2521@@ -25,13 +25,8 @@
2522 #include <mir/server.h>
2523 #include <mir/version.h>
2524
2525-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 26, 0)
2526 #include <mir/input/keymap.h>
2527 #include <mir/input/mir_keyboard_config.h>
2528-#elif MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 24, 1)
2529-#include <mir/input/keymap.h>
2530-#include <mir/input/keyboard_configuration.h>
2531-#endif
2532
2533 #define MIR_LOG_COMPONENT "miral::Keymap"
2534 #include <mir/log.h>
2535@@ -107,7 +102,6 @@
2536 apply_keymap(keyboard);
2537 }
2538
2539-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 24, 1)
2540 void apply_keymap(std::shared_ptr<mir::input::Device> const& keyboard)
2541 {
2542 auto const keyboard_config = keyboard->keyboard_configuration();
2543@@ -115,11 +109,7 @@
2544
2545 if (keyboard_config.is_set())
2546 {
2547-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 26, 0)
2548 keymap = keyboard_config.value().device_keymap();
2549-#else
2550- keymap = keyboard_config.value().device_keymap;
2551-#endif
2552 }
2553
2554 keymap.layout = layout;
2555@@ -127,12 +117,6 @@
2556 keymap.options = options;
2557 keyboard->apply_keyboard_configuration(std::move(keymap));
2558 }
2559-#else
2560- void apply_keymap(std::shared_ptr<mir::input::Device> const&)
2561- {
2562- mir::log_warning("Cannot apply keymap - not supported for Mir versions prior to 0.24.1");
2563- }
2564-#endif
2565
2566 void device_removed(std::shared_ptr<mir::input::Device> const& device) override
2567 {
2568
2569=== removed file 'miral/mir_features.h.in'
2570--- miral/mir_features.h.in 2017-02-17 15:06:53 +0000
2571+++ miral/mir_features.h.in 1970-01-01 00:00:00 +0000
2572@@ -1,29 +0,0 @@
2573-/*
2574- * Copyright © 2016 Canonical Ltd.
2575- *
2576- * This program is free software: you can redistribute it and/or modify it
2577- * under the terms of the GNU General Public License version 3,
2578- * as published by the Free Software Foundation.
2579- *
2580- * This program is distributed in the hope that it will be useful,
2581- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2582- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2583- * GNU General Public License for more details.
2584- *
2585- * You should have received a copy of the GNU General Public License
2586- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2587- */
2588-
2589-#ifndef MIRAL_MIR_FEATURES_H
2590-#define MIRAL_MIR_FEATURES_H
2591-
2592-// ============================================================
2593-// ==> miral/detail/mir_features.h is generated by cmake. <==
2594-// ==> DO NOT EDIT! <==
2595-// ==> (edit mir_features.h.in instead) <==
2596-// ============================================================
2597-
2598-#define MIRAL_MIR_DEFINES_POINTER_CONFINEMENT (@MIR_POINTER_CONFINEMENT@)
2599-#define MIR_DEFINES_DISPLAY_CONFIG_GET_MUTABLE_OUTPUT (@MIR_DISPLAY_CONFIG_GET_MUTABLE@)
2600-
2601-#endif // MIRAL_MIR_FEATURES_H
2602
2603=== modified file 'miral/mru_window_list.cpp'
2604--- miral/mru_window_list.cpp 2017-02-17 15:23:49 +0000
2605+++ miral/mru_window_list.cpp 2017-06-20 16:14:05 +0000
2606@@ -18,7 +18,6 @@
2607
2608 #include "mru_window_list.h"
2609
2610-#include <mir/client/detail/mir_forward_compatibility.h>
2611 #include <mir/scene/surface.h>
2612
2613 #include <algorithm>
2614
2615=== modified file 'miral/runner.cpp'
2616--- miral/runner.cpp 2017-03-02 13:47:28 +0000
2617+++ miral/runner.cpp 2017-06-20 16:14:05 +0000
2618@@ -30,10 +30,6 @@
2619 #include <mutex>
2620 #include <thread>
2621
2622-#if MIR_SERVER_VERSION < MIR_VERSION_NUMBER(0, 24, 0)
2623-#include <csignal>
2624-#endif
2625-
2626 namespace
2627 {
2628 inline auto filename(std::string path) -> std::string
2629@@ -198,9 +194,7 @@
2630 for (auto& option : options)
2631 option(*server);
2632
2633-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 24, 0)
2634 server->add_stop_callback(stop_callback);
2635-#endif
2636
2637 // Provide the command line and run the server
2638 server->set_command_line(argc, argv);
2639@@ -220,10 +214,6 @@
2640 auto const main_loop = server->the_main_loop();
2641 main_loop->enqueue(this, start_callback);
2642
2643-#if MIR_SERVER_VERSION < MIR_VERSION_NUMBER(0, 24, 0)
2644- main_loop->register_signal_handler({SIGINT, SIGTERM}, [this](int) {stop_callback();});
2645-#endif
2646-
2647 server->run();
2648 }
2649
2650@@ -282,11 +272,6 @@
2651
2652 if (auto const server = self->weak_server.lock())
2653 {
2654-#if MIR_SERVER_VERSION < MIR_VERSION_NUMBER(0, 24, 0)
2655- // Before Mir-0.24 we can't intercept all stop() invocations,
2656- // but we can deal with the ones we pass on
2657- self->stop_callback();
2658-#endif
2659 server->stop();
2660 }
2661 }
2662
2663=== modified file 'miral/set_window_management_policy.cpp'
2664--- miral/set_window_management_policy.cpp 2017-03-22 10:03:25 +0000
2665+++ miral/set_window_management_policy.cpp 2017-06-20 16:14:05 +0000
2666@@ -64,11 +64,7 @@
2667 {
2668 auto const display_layout = server.the_shell_display_layout();
2669
2670-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 24, 0)
2671 auto const persistent_surface_store = server.the_persistent_surface_store();
2672-#else
2673- std::shared_ptr<mir::shell::PersistentSurfaceStore> const persistent_surface_store;
2674-#endif
2675
2676 if (server.get_options()->is_set(trace_option))
2677 {
2678
2679=== modified file 'miral/symbols.map'
2680--- miral/symbols.map 2017-03-15 17:44:36 +0000
2681+++ miral/symbols.map 2017-06-20 16:14:05 +0000
2682@@ -401,3 +401,24 @@
2683 vtable?for?miral::SetWindowManagementPolicy;
2684 };
2685 } MIRAL_1.3;
2686+
2687+MIRAL_1.4.0 {
2688+global:
2689+ extern "C++" {
2690+ miral::WindowManagementPolicyAddendum2::?WindowManagementPolicyAddendum2*;
2691+ miral::WindowManagementPolicyAddendum2::WindowManagementPolicyAddendum2*;
2692+ miral::WindowManagementPolicyAddendum2::operator*;
2693+ miral::WindowManagerTools::end_drag_and_drop*;
2694+ miral::WindowManagerTools::start_drag_and_drop*;
2695+ miral::toolkit::Window::Window*;
2696+ non-virtual?thunk?to?miral::WindowManagementPolicyAddendum2::?WindowManagementPolicyAddendum2*;
2697+ typeinfo?for?miral::WindowManagementPolicyAddendum2;
2698+ typeinfo?for?miral::toolkit::Window;
2699+ typeinfo?for?miral::toolkit::WindowId;
2700+ typeinfo?for?miral::toolkit::WindowSpec;
2701+ vtable?for?miral::WindowManagementPolicyAddendum2;
2702+ vtable?for?miral::toolkit::Window;
2703+ vtable?for?miral::toolkit::WindowId;
2704+ vtable?for?miral::toolkit::WindowSpec;
2705+ };
2706+} MIRAL_1.3.1;
2707
2708=== modified file 'miral/window_management_options.cpp'
2709--- miral/window_management_options.cpp 2016-09-21 14:43:46 +0000
2710+++ miral/window_management_options.cpp 2017-06-20 16:14:05 +0000
2711@@ -56,12 +56,8 @@
2712 auto const selection = options->get<std::string>(wm_option);
2713
2714 auto const display_layout = server.the_shell_display_layout();
2715-
2716-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 24, 0)
2717 auto const persistent_surface_store = server.the_persistent_surface_store();
2718-#else
2719- std::shared_ptr<mir::shell::PersistentSurfaceStore> const persistent_surface_store;
2720-#endif
2721+
2722 for (auto const& option : policies)
2723 {
2724 if (selection == option.name)
2725
2726=== modified file 'miral/window_management_trace.cpp'
2727--- miral/window_management_trace.cpp 2017-03-03 10:06:02 +0000
2728+++ miral/window_management_trace.cpp 2017-06-20 16:14:05 +0000
2729@@ -547,6 +547,24 @@
2730 }
2731 MIRAL_TRACE_EXCEPTION
2732
2733+void miral::WindowManagementTrace::start_drag_and_drop(miral::WindowInfo& window_info, std::vector<uint8_t> const& handle)
2734+try {
2735+ log_input();
2736+ mir::log_info("%s window_info=%s", __func__, dump_of(window_info).c_str());
2737+ trace_count++;
2738+ wrapped.start_drag_and_drop(window_info, handle);
2739+}
2740+MIRAL_TRACE_EXCEPTION
2741+
2742+void miral::WindowManagementTrace::end_drag_and_drop()
2743+try {
2744+ log_input();
2745+ mir::log_info("%s window_info=%s", __func__);
2746+ trace_count++;
2747+ wrapped.end_drag_and_drop();
2748+}
2749+MIRAL_TRACE_EXCEPTION
2750+
2751 void miral::WindowManagementTrace::modify_window(
2752 miral::WindowInfo& window_info, miral::WindowSpecification const& modifications)
2753 try {
2754
2755=== modified file 'miral/window_management_trace.h'
2756--- miral/window_management_trace.h 2017-03-02 14:29:04 +0000
2757+++ miral/window_management_trace.h 2017-06-20 16:14:05 +0000
2758@@ -69,6 +69,8 @@
2759 virtual void focus_prev_within_application() override;
2760
2761 virtual void raise_tree(Window const& root) override;
2762+ virtual void start_drag_and_drop(WindowInfo& window_info, std::vector<uint8_t> const& handle) override;
2763+ virtual void end_drag_and_drop() override;
2764
2765 virtual void modify_window(WindowInfo& window_info, WindowSpecification const& modifications) override;
2766
2767
2768=== modified file 'miral/window_manager_tools.cpp'
2769--- miral/window_manager_tools.cpp 2017-03-02 14:29:04 +0000
2770+++ miral/window_manager_tools.cpp 2017-06-20 16:14:05 +0000
2771@@ -83,6 +83,12 @@
2772 void miral::WindowManagerTools::raise_tree(Window const& root)
2773 { tools->raise_tree(root); }
2774
2775+void miral::WindowManagerTools::start_drag_and_drop(WindowInfo& window_info, std::vector<uint8_t> const& handle)
2776+{ tools->start_drag_and_drop(window_info, handle); }
2777+
2778+void miral::WindowManagerTools::end_drag_and_drop()
2779+{ tools->end_drag_and_drop(); }
2780+
2781 void miral::WindowManagerTools::modify_window(WindowInfo& window_info, WindowSpecification const& modifications)
2782 { tools->modify_window(window_info,modifications); }
2783
2784
2785=== modified file 'miral/window_manager_tools_implementation.h'
2786--- miral/window_manager_tools_implementation.h 2017-03-02 14:29:04 +0000
2787+++ miral/window_manager_tools_implementation.h 2017-06-20 16:14:05 +0000
2788@@ -26,6 +26,7 @@
2789
2790 #include <functional>
2791 #include <memory>
2792+#include <vector>
2793
2794 namespace mir { namespace scene { class Surface; } }
2795
2796@@ -66,6 +67,8 @@
2797 virtual auto window_at(mir::geometry::Point cursor) const -> Window = 0;
2798 virtual auto active_display() -> mir::geometry::Rectangle const = 0;
2799 virtual void raise_tree(Window const& root) = 0;
2800+ virtual void start_drag_and_drop(WindowInfo& window_info, std::vector<uint8_t> const& handle) = 0;
2801+ virtual void end_drag_and_drop() = 0;
2802 virtual void modify_window(WindowInfo& window_info, WindowSpecification const& modifications) = 0;
2803 virtual auto info_for_window_id(std::string const& id) const -> WindowInfo& = 0;
2804 virtual auto id_for_window(Window const& window) const -> std::string = 0;
2805
2806=== modified file 'miral/window_specification.cpp'
2807--- miral/window_specification.cpp 2017-01-13 18:17:01 +0000
2808+++ miral/window_specification.cpp 2017-06-20 16:14:05 +0000
2809@@ -74,11 +74,9 @@
2810 state(spec.state),
2811 preferred_orientation(spec.preferred_orientation),
2812 aux_rect(spec.aux_rect),
2813-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 25, 0)
2814 placement_hints(spec.placement_hints),
2815 window_placement_gravity(spec.surface_placement_gravity),
2816 aux_rect_placement_gravity(spec.aux_rect_placement_gravity),
2817-#endif
2818 min_width(spec.min_width),
2819 min_height(spec.min_height),
2820 max_width(spec.max_width),
2821@@ -92,24 +90,10 @@
2822 input_shape(spec.input_shape),
2823 input_mode(),
2824 shell_chrome(spec.shell_chrome)
2825-#if MIRAL_MIR_DEFINES_POINTER_CONFINEMENT
2826 ,confine_pointer(spec.confine_pointer)
2827-#endif
2828 {
2829-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 25, 0)
2830 if (spec.aux_rect_placement_offset_x.is_set() && spec.aux_rect_placement_offset_y.is_set())
2831 aux_rect_placement_offset = Displacement{spec.aux_rect_placement_offset_x.value(), spec.aux_rect_placement_offset_y.value()};
2832-#endif
2833-
2834-#if MIR_SERVER_VERSION < MIR_VERSION_NUMBER(0, 25, 0)
2835- // mir_connection_create_spec_for_tooltip() didn't set an edge_attachment preference
2836- if (aux_rect.is_set() && !spec.edge_attachment.is_set())
2837- {
2838- window_placement_gravity = mir_placement_gravity_northwest;
2839- aux_rect_placement_gravity = mir_placement_gravity_northeast;
2840- placement_hints = mir_placement_hints_flip_any;
2841- }
2842-#endif
2843
2844 if (spec.edge_attachment.is_set() && !placement_hints.is_set())
2845 {
2846@@ -166,12 +150,6 @@
2847 }
2848
2849 template<typename Source>
2850-void copy_if_set(mir::optional_value<mir::graphics::BufferUsage>& dest, mir::optional_value<Source> const& source)
2851-{
2852- if (source.is_set()) dest = static_cast<mir::graphics::BufferUsage>(source.value());
2853-}
2854-
2855-template<typename Source>
2856 void copy_if_set(mir::graphics::BufferUsage& dest, mir::optional_value<Source> const& source)
2857 {
2858 if (source.is_set()) dest = static_cast<mir::graphics::BufferUsage>(source.value());
2859@@ -179,14 +157,6 @@
2860
2861 template<typename Source>
2862 void copy_if_set(
2863- mir::optional_value<mir::graphics::DisplayConfigurationOutputId>& dest,
2864- mir::optional_value<Source> const& source)
2865-{
2866- if (source.is_set()) dest = static_cast<mir::graphics::DisplayConfigurationOutputId>(source.value());
2867-}
2868-
2869-template<typename Source>
2870-void copy_if_set(
2871 mir::graphics::DisplayConfigurationOutputId& dest,
2872 mir::optional_value<Source> const& source)
2873 {
2874@@ -229,11 +199,9 @@
2875 state(params.state),
2876 preferred_orientation(params.preferred_orientation),
2877 aux_rect(params.aux_rect),
2878-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 25, 0)
2879 placement_hints(params.placement_hints),
2880 window_placement_gravity(params.surface_placement_gravity),
2881 aux_rect_placement_gravity(params.aux_rect_placement_gravity),
2882-#endif
2883 min_width(params.min_width),
2884 min_height(params.min_height),
2885 max_width(params.max_width),
2886@@ -242,33 +210,15 @@
2887 height_inc(params.height_inc),
2888 min_aspect(),
2889 max_aspect(),
2890-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 22, 0)
2891 streams(params.streams),
2892-#else
2893- streams(),
2894-#endif
2895 parent(params.parent),
2896 input_shape(params.input_shape),
2897 input_mode(static_cast<InputReceptionMode>(params.input_mode)),
2898 shell_chrome(params.shell_chrome)
2899-#if MIRAL_MIR_DEFINES_POINTER_CONFINEMENT
2900 ,confine_pointer(params.confine_pointer)
2901-#endif
2902 {
2903-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 25, 0)
2904 if (params.aux_rect_placement_offset_x.is_set() && params.aux_rect_placement_offset_y.is_set())
2905 aux_rect_placement_offset = Displacement{params.aux_rect_placement_offset_x.value(), params.aux_rect_placement_offset_y.value()};
2906-#endif
2907-
2908-#if MIR_SERVER_VERSION < MIR_VERSION_NUMBER(0, 25, 0)
2909- // mir_connection_create_spec_for_tooltip() didn't set an edge_attachment preference
2910- if (aux_rect.is_set() && !params.edge_attachment.is_set())
2911- {
2912- window_placement_gravity = mir_placement_gravity_northwest;
2913- aux_rect_placement_gravity = mir_placement_gravity_northeast;
2914- placement_hints = mir_placement_hints_flip_any;
2915- }
2916-#endif
2917
2918 if (params.edge_attachment.is_set() && !placement_hints.is_set())
2919 {
2920@@ -325,18 +275,12 @@
2921 copy_if_set(params.height_inc, height_inc);
2922 copy_if_set(params.min_aspect, min_aspect);
2923 copy_if_set(params.max_aspect, max_aspect);
2924-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 22, 0)
2925 copy_if_set(params.streams, streams);
2926-#endif
2927 copy_if_set(params.parent, parent);
2928 copy_if_set(params.input_shape, input_shape);
2929 copy_if_set(params.input_mode, input_mode);
2930 copy_if_set(params.shell_chrome, shell_chrome);
2931-#if MIRAL_MIR_DEFINES_POINTER_CONFINEMENT
2932 copy_if_set(params.confine_pointer, confine_pointer);
2933-#endif
2934-
2935-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 25, 0)
2936 copy_if_set(params.placement_hints, placement_hints);
2937 copy_if_set(params.surface_placement_gravity, window_placement_gravity);
2938 copy_if_set(params.aux_rect_placement_gravity, aux_rect_placement_gravity);
2939@@ -347,7 +291,6 @@
2940 params.aux_rect_placement_offset_x = offset.dx.as_int();
2941 params.aux_rect_placement_offset_y = offset.dy.as_int();
2942 }
2943-#endif
2944 }
2945
2946 miral::WindowSpecification::WindowSpecification() :
2947
2948=== modified file 'scripts/process_doxygen_xml.py'
2949--- scripts/process_doxygen_xml.py 2017-03-15 17:44:36 +0000
2950+++ scripts/process_doxygen_xml.py 2017-06-20 16:14:05 +0000
2951@@ -476,10 +476,21 @@
2952
2953 MIRAL_1.3.1 {
2954 global:
2955+ extern "C++" {
2956+ miral::SetWindowManagementPolicy::?SetWindowManagementPolicy*;
2957+ miral::SetWindowManagementPolicy::SetWindowManagementPolicy*;
2958+ miral::SetWindowManagementPolicy::operator*;
2959+ typeinfo?for?miral::SetWindowManagementPolicy;
2960+ vtable?for?miral::SetWindowManagementPolicy;
2961+ };
2962+} MIRAL_1.3;
2963+
2964+MIRAL_1.4.0 {
2965+global:
2966 extern "C++" {'''
2967
2968 END_NEW_STANZA = ''' };
2969-} MIRAL_1.3;'''
2970+} MIRAL_1.3.1;'''
2971
2972 def _print_report():
2973 print OLD_STANZAS
2974
2975=== modified file 'test/CMakeLists.txt'
2976--- test/CMakeLists.txt 2017-02-13 16:23:29 +0000
2977+++ test/CMakeLists.txt 2017-06-20 16:14:05 +0000
2978@@ -39,6 +39,16 @@
2979 ${GTEST_INCLUDE_DIR}
2980 )
2981
2982+# MIRAL_TEST_MODERN_FEATURES lists test sourcefiles that require a recent version of Mir
2983+if (MIRTEST_VERSION VERSION_LESS 0.27)
2984+ set(MIRAL_TEST_MODERN_FEATURES)
2985+else()
2986+ set(MIRAL_TEST_MODERN_FEATURES
2987+ drag_and_drop.cpp
2988+ client_mediated_gestures.cpp
2989+ )
2990+endif()
2991+
2992 add_executable(miral-test
2993 mru_window_list.cpp
2994 active_outputs.cpp
2995@@ -56,7 +66,9 @@
2996 display_reconfiguration.cpp
2997 active_window.cpp
2998 raise_tree.cpp
2999- workspaces.cpp)
3000+ workspaces.cpp
3001+ ${MIRAL_TEST_MODERN_FEATURES}
3002+)
3003
3004 target_link_libraries(miral-test
3005 ${MIRTEST_LDFLAGS}
3006
3007=== modified file 'test/active_window.cpp'
3008--- test/active_window.cpp 2017-03-16 16:57:38 +0000
3009+++ test/active_window.cpp 2017-06-20 16:14:05 +0000
3010@@ -18,10 +18,10 @@
3011
3012 #include "test_server.h"
3013
3014+#include <mir/client/surface.h>
3015 #include <mir/client/window.h>
3016 #include <mir/client/window_spec.h>
3017 #include <mir_toolkit/mir_buffer_stream.h>
3018-#include <mir_toolkit/version.h>
3019
3020 #include <miral/application_info.h>
3021
3022@@ -35,11 +35,6 @@
3023 using namespace std::chrono_literals;
3024 using miral::WindowManagerTools;
3025
3026-#if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 5, 0)
3027-auto const mir_event_type_window = mir_event_type_surface;
3028-auto const mir_window_event_get_attribute = mir_surface_event_get_attribute;
3029-auto const mir_event_get_window_event = mir_event_get_surface_event;
3030-#endif
3031
3032 namespace
3033 {
3034@@ -68,58 +63,79 @@
3035 mir::test::Signal signal;
3036 };
3037
3038+struct TestWindow : Surface, Window
3039+{
3040+ using Surface::operator=;
3041+ using Window::operator=;
3042+};
3043+
3044 struct ActiveWindow : public miral::TestServer
3045 {
3046 FocusChangeSync sync1;
3047 FocusChangeSync sync2;
3048
3049- auto create_surface(Connection const& connection, char const* name, FocusChangeSync& sync) -> Window
3050- {
3051- auto const spec = WindowSpec::for_normal_window(connection, 50, 50, mir_pixel_format_argb_8888)
3052- .set_buffer_usage(mir_buffer_usage_software)
3053+ void paint(Surface const& surface)
3054+ {
3055+ mir_buffer_stream_swap_buffers_sync(
3056+ mir_render_surface_get_buffer_stream(surface, 50, 50, mir_pixel_format_argb_8888));
3057+ }
3058+
3059+ auto create_window(Connection const& connection, char const* name, FocusChangeSync& sync) -> TestWindow
3060+ {
3061+ TestWindow result;
3062+
3063+ result = Surface{mir_connection_create_render_surface_sync(connection, 50, 50)};
3064+
3065+ auto const spec = WindowSpec::for_normal_window(connection, 50, 50)
3066 .set_event_handler(&FocusChangeSync::raise_signal_on_focus_change, &sync)
3067+ .add_surface(result, 50, 50, 0, 0)
3068 .set_name(name);
3069
3070- Window const surface{spec.create_window()};
3071-
3072- sync.exec([&]{ mir_buffer_stream_swap_buffers_sync(mir_window_get_buffer_stream(surface)); });
3073+ result = Window{spec.create_window()};
3074+
3075+ sync.exec([&]{ paint(result); });
3076+
3077 EXPECT_TRUE(sync.signal_raised());
3078
3079- return surface;
3080+ return result;
3081 }
3082
3083-#if MIR_CLIENT_VERSION >= MIR_VERSION_NUMBER(3, 4, 0)
3084- auto create_tip(Connection const& connection, char const* name, Window const& parent, FocusChangeSync& sync) -> Window
3085+ auto create_tip(Connection const& connection, char const* name, Window const& parent, FocusChangeSync& sync) -> TestWindow
3086 {
3087+ TestWindow result;
3088+ result = Surface{mir_connection_create_render_surface_sync(connection, 50, 50)};
3089+
3090 MirRectangle aux_rect{10, 10, 10, 10};
3091- auto const spec = WindowSpec::for_tip(connection, 50, 50, mir_pixel_format_argb_8888, parent, &aux_rect, mir_edge_attachment_any)
3092- .set_buffer_usage(mir_buffer_usage_software)
3093+ auto const spec = WindowSpec::for_tip(connection, 50, 50, parent, &aux_rect, mir_edge_attachment_any)
3094 .set_event_handler(&FocusChangeSync::raise_signal_on_focus_change, &sync)
3095+ .add_surface(result, 50, 50, 0, 0)
3096 .set_name(name);
3097
3098- Window const surface{spec.create_window()};
3099+ result = Window{spec.create_window()};
3100
3101 // Expect this to timeout: A tip should not receive focus
3102- sync.exec([&]{ mir_buffer_stream_swap_buffers_sync(mir_window_get_buffer_stream(surface)); });
3103+ sync.exec([&]{ paint(result); });
3104 EXPECT_FALSE(sync.signal_raised());
3105
3106- return surface;
3107+ return result;
3108 }
3109-#endif
3110
3111- auto create_dialog(Connection const& connection, char const* name, Window const& parent, FocusChangeSync& sync) -> Window
3112+ auto create_dialog(Connection const& connection, char const* name, Window const& parent, FocusChangeSync& sync) -> TestWindow
3113 {
3114- auto const spec = WindowSpec::for_dialog(connection, 50, 50, mir_pixel_format_argb_8888, parent)
3115- .set_buffer_usage(mir_buffer_usage_software)
3116+ TestWindow result;
3117+ result = Surface{mir_connection_create_render_surface_sync(connection, 50, 50)};
3118+
3119+ auto const spec = WindowSpec::for_dialog(connection, 50, 50, parent)
3120 .set_event_handler(&FocusChangeSync::raise_signal_on_focus_change, &sync)
3121+ .add_surface(result, 50, 50, 0, 0)
3122 .set_name(name);
3123
3124- Window const surface{spec.create_window()};
3125+ result = Window{spec.create_window()};
3126
3127- sync.exec([&]{ mir_buffer_stream_swap_buffers_sync(mir_window_get_buffer_stream(surface)); });
3128+ sync.exec([&]{ paint(result); });
3129 EXPECT_TRUE(sync.signal_raised());
3130
3131- return surface;
3132+ return result;
3133 }
3134
3135 void assert_no_active_window()
3136@@ -151,7 +167,7 @@
3137 char const* const test_name = __PRETTY_FUNCTION__;
3138 auto const connection = connect_client(test_name);
3139
3140- auto const surface = create_surface(connection, test_name, sync1);
3141+ auto const window = create_window(connection, test_name, sync1);
3142
3143 assert_active_window_is(test_name);
3144 }
3145@@ -160,9 +176,9 @@
3146 {
3147 char const* const test_name = __PRETTY_FUNCTION__;
3148 auto const connection = connect_client(test_name);
3149- auto const surface = create_surface(connection, test_name, sync1);
3150+ auto const window = create_window(connection, test_name, sync1);
3151
3152- sync1.exec([&]{ mir_window_set_state(surface, mir_window_state_hidden); });
3153+ sync1.exec([&]{ mir_window_set_state(window, mir_window_state_hidden); });
3154
3155 EXPECT_TRUE(sync1.signal_raised());
3156 assert_no_active_window();
3157@@ -172,11 +188,11 @@
3158 {
3159 char const* const test_name = __PRETTY_FUNCTION__;
3160 auto const connection = connect_client(test_name);
3161- auto const surface = create_surface(connection, test_name, sync1);
3162-
3163- sync1.exec([&]{ mir_window_set_state(surface, mir_window_state_hidden); });
3164-
3165- sync1.exec([&]{ mir_window_set_state(surface, mir_window_state_restored); });
3166+ auto const window = create_window(connection, test_name, sync1);
3167+
3168+ sync1.exec([&]{ mir_window_set_state(window, mir_window_state_hidden); });
3169+
3170+ sync1.exec([&]{ mir_window_set_state(window, mir_window_state_restored); });
3171
3172 EXPECT_TRUE(sync1.signal_raised());
3173
3174@@ -188,8 +204,8 @@
3175 char const* const test_name = __PRETTY_FUNCTION__;
3176 auto const connection = connect_client(test_name);
3177
3178- auto const first_surface = create_surface(connection, "first", sync1);
3179- auto const surface = create_surface(connection, test_name, sync2);
3180+ auto const first_window = create_window(connection, "first", sync1);
3181+ auto const window = create_window(connection, test_name, sync2);
3182
3183 assert_active_window_is(test_name);
3184 }
3185@@ -199,10 +215,10 @@
3186 char const* const test_name = __PRETTY_FUNCTION__;
3187 auto const connection = connect_client(test_name);
3188
3189- auto const first_surface = create_surface(connection, test_name, sync1);
3190- auto const surface = create_surface(connection, another_name, sync2);
3191+ auto const first_window = create_window(connection, test_name, sync1);
3192+ auto const window = create_window(connection, another_name, sync2);
3193
3194- sync2.exec([&]{ mir_window_set_state(surface, mir_window_state_hidden); });
3195+ sync2.exec([&]{ mir_window_set_state(window, mir_window_state_hidden); });
3196
3197 EXPECT_TRUE(sync2.signal_raised());
3198 assert_active_window_is(test_name);
3199@@ -213,13 +229,13 @@
3200 char const* const test_name = __PRETTY_FUNCTION__;
3201 auto const connection = connect_client(test_name);
3202
3203- auto const first_surface = create_surface(connection, test_name, sync1);
3204- auto const surface = create_surface(connection, another_name, sync2);
3205+ auto const first_window = create_window(connection, test_name, sync1);
3206+ auto const window = create_window(connection, another_name, sync2);
3207
3208- sync1.exec([&]{ mir_window_set_state(surface, mir_window_state_hidden); });
3209+ sync1.exec([&]{ mir_window_set_state(window, mir_window_state_hidden); });
3210
3211 // Expect this to timeout
3212- sync2.exec([&]{ mir_window_set_state(surface, mir_window_state_restored); });
3213+ sync2.exec([&]{ mir_window_set_state(window, mir_window_state_restored); });
3214
3215 EXPECT_THAT(sync2.signal_raised(), Eq(false));
3216 assert_active_window_is(test_name);
3217@@ -230,8 +246,8 @@
3218 char const* const test_name = __PRETTY_FUNCTION__;
3219 auto const connection = connect_client(test_name);
3220
3221- auto const first_surface = create_surface(connection, test_name, sync1);
3222- auto const surface = create_surface(connection, another_name, sync2);
3223+ auto const first_window = create_window(connection, test_name, sync1);
3224+ auto const window = create_window(connection, another_name, sync2);
3225
3226 sync1.exec([&]{ invoke_tools([](WindowManagerTools& tools){ tools.focus_next_within_application(); }); });
3227
3228@@ -245,8 +261,8 @@
3229 auto const connection = connect_client(test_name);
3230 auto const second_connection = connect_client(another_name);
3231
3232- auto const first_surface = create_surface(connection, test_name, sync1);
3233- auto const surface = create_surface(second_connection, another_name, sync2);
3234+ auto const first_window = create_window(connection, test_name, sync1);
3235+ auto const window = create_window(second_connection, another_name, sync2);
3236
3237 sync1.exec([&]{ invoke_tools([](WindowManagerTools& tools){ tools.focus_next_application(); }); });
3238
3239@@ -259,12 +275,12 @@
3240 char const* const test_name = __PRETTY_FUNCTION__;
3241 auto const connection = connect_client(test_name);
3242
3243- auto const first_surface = create_surface(connection, test_name, sync1);
3244+ auto const first_window = create_window(connection, test_name, sync1);
3245
3246 sync1.exec([&]
3247 {
3248 auto const second_connection = connect_client(another_name);
3249- auto const surface = create_surface(second_connection, another_name, sync2);
3250+ auto const window = create_window(second_connection, another_name, sync2);
3251 assert_active_window_is(another_name);
3252 });
3253
3254@@ -272,20 +288,19 @@
3255 assert_active_window_is(test_name);
3256 }
3257
3258-#if MIR_CLIENT_VERSION >= MIR_VERSION_NUMBER(3, 4, 0)
3259 TEST_F(ActiveWindow, selecting_a_tip_makes_parent_active)
3260 {
3261 char const* const test_name = __PRETTY_FUNCTION__;
3262 auto const connection = connect_client(test_name);
3263
3264- auto const parent = create_surface(connection, test_name, sync1);
3265+ auto const parent = create_window(connection, test_name, sync1);
3266
3267 miral::Window parent_window;
3268 invoke_tools([&](WindowManagerTools& tools){ parent_window = tools.active_window(); });
3269
3270 // Steal the focus
3271 auto second_connection = connect_client(another_name);
3272- auto second_surface = create_surface(second_connection, another_name, sync2);
3273+ auto second_surface = create_window(second_connection, another_name, sync2);
3274
3275 auto const tip = create_tip(connection, "tip", parent, sync2);
3276
3277@@ -298,7 +313,6 @@
3278
3279 assert_active_window_is(test_name);
3280 }
3281-#endif
3282
3283 TEST_F(ActiveWindow, selecting_a_parent_makes_dialog_active)
3284 {
3285@@ -306,7 +320,7 @@
3286 auto const dialog_name = "dialog";
3287 auto const connection = connect_client(test_name);
3288
3289- auto const parent = create_surface(connection, test_name, sync1);
3290+ auto const parent = create_window(connection, test_name, sync1);
3291
3292 miral::Window parent_window;
3293 invoke_tools([&](WindowManagerTools& tools){ parent_window = tools.active_window(); });
3294@@ -315,7 +329,7 @@
3295
3296 // Steal the focus
3297 auto second_connection = connect_client(another_name);
3298- auto second_surface = create_surface(second_connection, another_name, sync1);
3299+ auto second_surface = create_window(second_connection, another_name, sync1);
3300
3301 sync2.exec([&]{ invoke_tools([&](WindowManagerTools& tools){ tools.select_active_window(parent_window); }); });
3302
3303@@ -328,7 +342,7 @@
3304 char const* const test_name = __PRETTY_FUNCTION__;
3305 auto const connection = connect_client(test_name);
3306
3307- auto const parent = create_surface(connection, test_name, sync1);
3308+ auto const parent = create_window(connection, test_name, sync1);
3309 auto const input_method = WindowSpec::for_input_method(connection, 50, 50, parent).create_window();
3310
3311 assert_active_window_is(test_name);
3312@@ -347,7 +361,7 @@
3313 char const* const test_name = __PRETTY_FUNCTION__;
3314 auto const connection = connect_client(test_name);
3315
3316- auto const parent = create_surface(connection, test_name, sync1);
3317+ auto const parent = create_window(connection, test_name, sync1);
3318 auto const satellite = WindowSpec::for_satellite(connection, 50, 50, parent).create_window();
3319
3320 assert_active_window_is(test_name);
3321@@ -368,7 +382,7 @@
3322 auto const dialog_name = "dialog";
3323 auto const connection = connect_client(parent_name);
3324
3325- auto const parent = create_surface(connection, parent_name, sync1);
3326+ auto const parent = create_window(connection, parent_name, sync1);
3327 auto const dialog = create_dialog(connection, dialog_name, parent, sync2);
3328
3329 sync1.exec([&]{ mir_window_set_state(dialog, mir_window_state_hidden); });
3330@@ -386,8 +400,8 @@
3331 auto const another_window_name = "another window";
3332 auto const connection = connect_client(parent_name);
3333
3334- auto const parent = create_surface(connection, parent_name, sync1);
3335- auto const another_window = create_surface(connection, another_window_name, sync2);
3336+ auto const parent = create_window(connection, parent_name, sync1);
3337+ auto const another_window = create_window(connection, another_window_name, sync2);
3338 auto const dialog = create_dialog(connection, dialog_name, parent, sync3);
3339
3340 sync1.exec([&]{ mir_window_set_state(dialog, mir_window_state_hidden); });
3341
3342=== added file 'test/client_mediated_gestures.cpp'
3343--- test/client_mediated_gestures.cpp 1970-01-01 00:00:00 +0000
3344+++ test/client_mediated_gestures.cpp 2017-06-20 16:14:05 +0000
3345@@ -0,0 +1,295 @@
3346+/*
3347+ * Copyright © 2017 Canonical Ltd.
3348+ *
3349+ * This program is free software: you can redistribute it and/or modify it
3350+ * under the terms of the GNU General Public License version 3,
3351+ * as published by the Free Software Foundation.
3352+ *
3353+ * This program is distributed in the hope that it will be useful,
3354+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3355+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3356+ * GNU General Public License for more details.
3357+ *
3358+ * You should have received a copy of the GNU General Public License
3359+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3360+ *
3361+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
3362+ */
3363+
3364+#include <mir/client/surface.h>
3365+#include <mir/client/window_spec.h>
3366+
3367+#include <mir_toolkit/mir_window.h>
3368+#include <mir_toolkit/mir_blob.h>
3369+
3370+#include <mir/geometry/displacement.h>
3371+#include <mir/input/input_device_info.h>
3372+#include <mir/input/device_capability.h>
3373+#include <mir/shell/canonical_window_manager.h>
3374+#include <mir/shell/shell.h>
3375+
3376+#include <mir_test_framework/connected_client_with_a_window.h>
3377+#include <mir_test_framework/fake_input_device.h>
3378+#include <mir_test_framework/stub_server_platform_factory.h>
3379+#include <mir/test/event_factory.h>
3380+#include <mir/test/fake_shared.h>
3381+#include <mir/test/signal.h>
3382+
3383+#include <gmock/gmock.h>
3384+#include <gtest/gtest.h>
3385+
3386+#include <linux/input.h>
3387+
3388+#include <atomic>
3389+
3390+using namespace std::chrono_literals;
3391+using namespace mir::geometry;
3392+using namespace testing;
3393+using mir::test::fake_shared;
3394+using mir::test::Signal;
3395+
3396+namespace
3397+{
3398+class Cookie
3399+{
3400+public:
3401+ Cookie() = default;
3402+
3403+ explicit Cookie(MirCookie const* cookie) : self{cookie, deleter} {}
3404+
3405+ operator MirCookie const*() const { return self.get(); }
3406+
3407+ auto get() const -> MirCookie const* { return self.get(); }
3408+
3409+ void reset() { self.reset(); }
3410+
3411+ void reset(MirCookie const* cookie) { self.reset(cookie, deleter); }
3412+
3413+private:
3414+ static void deleter(MirCookie const* cookie) { mir_cookie_release(cookie); }
3415+
3416+ std::shared_ptr<MirCookie const> self;
3417+};
3418+
3419+void mir_cookie_release(Cookie const&) = delete;
3420+
3421+struct MockWindowManager : mir::shell::CanonicalWindowManager
3422+{
3423+ using mir::shell::CanonicalWindowManager::CanonicalWindowManager;
3424+
3425+ MOCK_METHOD3(handle_request_move,
3426+ void(std::shared_ptr<mir::scene::Session> const&, std::shared_ptr<mir::scene::Surface> const&, uint64_t));
3427+};
3428+
3429+struct MouseMoverAndFaker
3430+{
3431+ void start_dragging_mouse()
3432+ {
3433+ using namespace mir::input::synthesis;
3434+ fake_mouse->emit_event(a_button_down_event().of_button(BTN_LEFT));
3435+ }
3436+
3437+ void move_mouse(Displacement const& displacement)
3438+ {
3439+ using mir::input::synthesis::a_pointer_event;
3440+ fake_mouse->emit_event(a_pointer_event().with_movement(displacement.dx.as_int(), displacement.dy.as_int()));
3441+ }
3442+
3443+ void release_mouse()
3444+ {
3445+ using namespace mir::input::synthesis;
3446+ fake_mouse->emit_event(a_button_up_event().of_button(BTN_LEFT));
3447+ }
3448+
3449+private:
3450+ std::unique_ptr<mir_test_framework::FakeInputDevice> fake_mouse{
3451+ mir_test_framework::add_fake_input_device(
3452+ mir::input::InputDeviceInfo{"mouse", "mouse-uid", mir::input::DeviceCapability::pointer})
3453+ };
3454+};
3455+
3456+Rectangle const screen_geometry{{0, 0}, {800, 600}};
3457+auto const receive_event_timeout = 90s;
3458+
3459+struct ClientMediatedUserGestures : mir_test_framework::ConnectedClientWithAWindow,
3460+ MouseMoverAndFaker
3461+{
3462+ void SetUp() override
3463+ {
3464+ initial_display_layout({screen_geometry});
3465+ server.override_the_window_manager_builder([this](mir::shell::FocusController* focus_controller)
3466+ {
3467+ return window_manager =
3468+ std::make_shared<MockWindowManager>(focus_controller, server.the_shell_display_layout());
3469+ });
3470+
3471+ mir_test_framework::ConnectedClientWithAWindow::SetUp();
3472+ mir_window_set_event_handler(window, &window_event_handler, this);
3473+
3474+ paint_window();
3475+
3476+ center_mouse();
3477+ }
3478+
3479+ void TearDown() override
3480+ {
3481+ reset_window_event_handler();
3482+ window_manager.reset();
3483+ surface.reset();
3484+ mir_test_framework::ConnectedClientWithAWindow::TearDown();
3485+ }
3486+
3487+ auto user_initiates_gesture() -> Cookie;
3488+
3489+ std::shared_ptr<MockWindowManager> window_manager;
3490+
3491+private:
3492+ void center_mouse();
3493+ void paint_window();
3494+ void set_window_event_handler(std::function<void(MirEvent const* event)> const& handler);
3495+ void reset_window_event_handler();
3496+ void invoke_window_event_handler(MirEvent const* event)
3497+ {
3498+ std::lock_guard<decltype(window_event_handler_mutex)> lock{window_event_handler_mutex};
3499+ window_event_handler_(event);
3500+ }
3501+
3502+ mir::client::Surface surface;
3503+
3504+ std::mutex window_event_handler_mutex;
3505+ std::function<void(MirEvent const* event)> window_event_handler_ = [](MirEvent const*) {};
3506+
3507+ static void window_event_handler(MirWindow* window, MirEvent const* event, void* context);
3508+};
3509+
3510+void ClientMediatedUserGestures::set_window_event_handler(std::function<void(MirEvent const* event)> const& handler)
3511+{
3512+ std::lock_guard<decltype(window_event_handler_mutex)> lock{window_event_handler_mutex};
3513+ window_event_handler_ = handler;
3514+}
3515+
3516+void ClientMediatedUserGestures::reset_window_event_handler()
3517+{
3518+ std::lock_guard<decltype(window_event_handler_mutex)> lock{window_event_handler_mutex};
3519+ window_event_handler_ = [](MirEvent const*) {};
3520+}
3521+
3522+void ClientMediatedUserGestures::window_event_handler(MirWindow* /*window*/, MirEvent const* event, void* context)
3523+{
3524+ static_cast<ClientMediatedUserGestures*>(context)->invoke_window_event_handler(event);
3525+}
3526+
3527+void ClientMediatedUserGestures::paint_window()
3528+{
3529+ {
3530+ surface = mir::client::Surface{mir_connection_create_render_surface_sync(connection, 42, 42)};
3531+ auto const spec = mir::client::WindowSpec::for_changes(connection);
3532+ mir_window_spec_add_render_surface(spec, surface, 42, 42, 0, 0);
3533+ mir_window_apply_spec(window, spec);
3534+ }
3535+
3536+ Signal have_focus;
3537+
3538+ set_window_event_handler([&](MirEvent const* event)
3539+ {
3540+ if (mir_event_get_type(event) != mir_event_type_window)
3541+ return;
3542+
3543+ auto const window_event = mir_event_get_window_event(event);
3544+ if (mir_window_event_get_attribute(window_event) != mir_window_attrib_focus)
3545+ return;
3546+
3547+ if (mir_window_event_get_attribute_value(window_event))
3548+ have_focus.raise();
3549+ });
3550+
3551+ mir_buffer_stream_swap_buffers_sync(mir_render_surface_get_buffer_stream(surface, 42, 42, mir_pixel_format_argb_8888));
3552+
3553+ EXPECT_THAT(have_focus.wait_for(receive_event_timeout), Eq(true));
3554+
3555+ reset_window_event_handler();
3556+}
3557+
3558+void ClientMediatedUserGestures::center_mouse()
3559+{
3560+ Signal have_mouseover;
3561+
3562+ set_window_event_handler([&](MirEvent const* event)
3563+ {
3564+ if (mir_event_get_type(event) != mir_event_type_input)
3565+ return;
3566+
3567+ auto const input_event = mir_event_get_input_event(event);
3568+
3569+ if (mir_input_event_get_type(input_event) != mir_input_event_type_pointer)
3570+ return;
3571+
3572+ auto const pointer_event = mir_input_event_get_pointer_event(input_event);
3573+
3574+ if (mir_pointer_event_action(pointer_event) != mir_pointer_action_enter)
3575+ return;
3576+
3577+ have_mouseover.raise();
3578+ });
3579+
3580+ move_mouse(0.5 * as_displacement(screen_geometry.size));
3581+
3582+// We miss the "mouseover" occasionally (with valgrind and heavy stress about 1/20).
3583+// But it isn't essential for the test and we've probably waited long enough
3584+// for the mouse-down needed by the test to reach the window.
3585+// EXPECT_THAT(have_mouseover.wait_for(receive_event_timeout), Eq(true));
3586+ have_mouseover.wait_for(receive_event_timeout);
3587+
3588+ reset_window_event_handler();
3589+}
3590+
3591+auto ClientMediatedUserGestures::user_initiates_gesture() -> Cookie
3592+{
3593+ Cookie cookie;
3594+ Signal have_cookie;
3595+
3596+ set_window_event_handler([&](MirEvent const* event)
3597+ {
3598+ if (mir_event_get_type(event) != mir_event_type_input)
3599+ return;
3600+
3601+ auto const input_event = mir_event_get_input_event(event);
3602+
3603+ if (mir_input_event_get_type(input_event) != mir_input_event_type_pointer)
3604+ return;
3605+
3606+ auto const pointer_event = mir_input_event_get_pointer_event(input_event);
3607+
3608+ if (mir_pointer_event_action(pointer_event) != mir_pointer_action_button_down)
3609+ return;
3610+
3611+ cookie = Cookie{mir_input_event_get_cookie(input_event)};
3612+ have_cookie.raise();
3613+ });
3614+
3615+ start_dragging_mouse();
3616+
3617+ EXPECT_THAT(have_cookie.wait_for(receive_event_timeout), Eq(true));
3618+
3619+ reset_window_event_handler();
3620+ return cookie;
3621+}
3622+}
3623+
3624+TEST_F(ClientMediatedUserGestures, when_user_initiates_gesture_client_receives_cookie)
3625+{
3626+ auto const cookie = user_initiates_gesture();
3627+
3628+ EXPECT_THAT(cookie.get(), NotNull());
3629+}
3630+
3631+TEST_F(ClientMediatedUserGestures, when_client_initiates_move_window_manager_handles_request)
3632+{
3633+ auto const cookie = user_initiates_gesture();
3634+ Signal have_request;
3635+ EXPECT_CALL(*window_manager, handle_request_move(_, _, _)).WillOnce(InvokeWithoutArgs([&]{ have_request.raise(); }));
3636+
3637+ mir_window_request_user_move(window, cookie);
3638+
3639+ EXPECT_THAT(have_request.wait_for(receive_event_timeout), Eq(true));
3640+}
3641
3642=== added file 'test/drag_and_drop.cpp'
3643--- test/drag_and_drop.cpp 1970-01-01 00:00:00 +0000
3644+++ test/drag_and_drop.cpp 2017-06-20 16:14:05 +0000
3645@@ -0,0 +1,653 @@
3646+/*
3647+ * Copyright © 2017 Canonical Ltd.
3648+ *
3649+ * This program is free software: you can redistribute it and/or modify it
3650+ * under the terms of the GNU General Public License version 3,
3651+ * as published by the Free Software Foundation.
3652+ *
3653+ * This program is distributed in the hope that it will be useful,
3654+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3655+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3656+ * GNU General Public License for more details.
3657+ *
3658+ * You should have received a copy of the GNU General Public License
3659+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3660+ *
3661+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
3662+ */
3663+
3664+#include <miral/window_management_policy_addendum2.h>
3665+
3666+#include <mir/client/blob.h>
3667+#include <mir/client/cookie.h>
3668+#include <mir/client/surface.h>
3669+#include <mir/client/window.h>
3670+#include <mir/client/window_spec.h>
3671+#include <mir_toolkit/mir_buffer_stream.h>
3672+#include <mir_toolkit/extensions/drag_and_drop.h>
3673+
3674+#include <mir/geometry/displacement.h>
3675+#include <mir/input/input_device_info.h>
3676+#include <mir/input/device_capability.h>
3677+#include <mir/shell/shell.h>
3678+
3679+#include "test_server.h"
3680+#include <mir_test_framework/fake_input_device.h>
3681+#include <mir_test_framework/stub_server_platform_factory.h>
3682+#include <mir/test/event_factory.h>
3683+#include <mir/test/signal.h>
3684+
3685+#include <gmock/gmock.h>
3686+#include <gtest/gtest.h>
3687+
3688+#include <linux/input.h>
3689+#include <uuid/uuid.h>
3690+
3691+#include <boost/throw_exception.hpp>
3692+#include <atomic>
3693+
3694+using namespace std::chrono_literals;
3695+using namespace mir::client;
3696+using namespace mir::geometry;
3697+using namespace testing;
3698+using mir::test::Signal;
3699+
3700+namespace
3701+{
3702+struct MouseMoverAndFaker
3703+{
3704+ void start_dragging_mouse()
3705+ {
3706+ using namespace mir::input::synthesis;
3707+ fake_mouse->emit_event(a_button_down_event().of_button(BTN_LEFT));
3708+ }
3709+
3710+ void move_mouse(Displacement const& displacement)
3711+ {
3712+ using mir::input::synthesis::a_pointer_event;
3713+ fake_mouse->emit_event(a_pointer_event().with_movement(displacement.dx.as_int(), displacement.dy.as_int()));
3714+ }
3715+
3716+ void release_mouse()
3717+ {
3718+ using namespace mir::input::synthesis;
3719+ fake_mouse->emit_event(a_button_up_event().of_button(BTN_LEFT));
3720+ }
3721+
3722+private:
3723+ std::unique_ptr<mir_test_framework::FakeInputDevice> fake_mouse{
3724+ mir_test_framework::add_fake_input_device(
3725+ mir::input::InputDeviceInfo{"mouse", "mouse-uid", mir::input::DeviceCapability::pointer})};
3726+};
3727+
3728+Rectangle const screen_geometry{{0,0}, {800,600}};
3729+auto const receive_event_timeout = 1s; //90s;
3730+
3731+struct ConnectedClientWithAWindow : miral::TestServer
3732+{
3733+ Connection connection;
3734+ Surface surface;
3735+ Window window;
3736+
3737+ void SetUp() override
3738+ {
3739+ miral::TestServer::SetUp();
3740+ connection = connect_client(__func__);
3741+ auto const width = surface_size.width.as_int();
3742+ auto const height = surface_size.height.as_int();
3743+ surface = Surface{mir_connection_create_render_surface_sync(connection, width, height)};
3744+ window = WindowSpec::for_normal_window(connection, width, height)
3745+ .set_name("ConnectedClientWithAWindow")
3746+ .add_surface(surface, width, height, 0, 0)
3747+ .create_window();
3748+ }
3749+
3750+ void TearDown() override
3751+ {
3752+ window.reset();
3753+ surface.reset();
3754+ connection.reset();
3755+ miral::TestServer::TearDown();
3756+ }
3757+
3758+ mir::geometry::Size const surface_size {640, 480};
3759+};
3760+
3761+struct DragAndDrop : ConnectedClientWithAWindow,
3762+ MouseMoverAndFaker
3763+{
3764+ MirDragAndDropV1 const* dnd = nullptr;
3765+
3766+ void SetUp() override
3767+ {
3768+ mir_test_framework::set_next_display_rects(std::unique_ptr<std::vector<Rectangle>>(new std::vector<Rectangle>({screen_geometry})));
3769+
3770+ ConnectedClientWithAWindow::SetUp();
3771+ dnd = mir_drag_and_drop_v1(connection);
3772+ mir_window_set_event_handler(window, &window_event_handler, this);
3773+ if (dnd) dnd->set_start_drag_and_drop_callback(window, &window_dnd_start_handler, this);
3774+
3775+ create_target_window();
3776+
3777+ paint_window(surface, window);
3778+
3779+ center_mouse();
3780+ }
3781+
3782+ void TearDown() override
3783+ {
3784+ reset_window_event_handler(target_window);
3785+ reset_window_event_handler(window);
3786+ target_window.reset();
3787+ target_surface.reset();
3788+ another_connection.reset();
3789+ ConnectedClientWithAWindow::TearDown();
3790+ }
3791+
3792+ auto user_initiates_drag() -> Cookie;
3793+ auto client_requests_drag(Cookie const& cookie) -> Blob;
3794+ auto handle_from_mouse_move() -> Blob;
3795+ auto handle_from_mouse_leave() -> Blob;
3796+ auto handle_from_mouse_enter() -> Blob;
3797+ auto handle_from_mouse_release() -> Blob;
3798+ auto count_of_handles_when_moving_mouse() -> int;
3799+
3800+private:
3801+ auto build_window_manager_policy(miral::WindowManagerTools const& tools) -> std::unique_ptr<TestWindowManagerPolicy> override;
3802+ void center_mouse();
3803+ void paint_window(MirRenderSurface* s, MirWindow* w);
3804+ void set_window_event_handler(MirWindow* window, std::function<void(MirEvent const* event)> const& handler);
3805+ void set_window_dnd_start_handler(MirWindow* window, std::function<void(MirDragAndDropEvent const*)> const& handler);
3806+ void reset_window_event_handler(MirWindow* window);
3807+
3808+ void create_target_window()
3809+ {
3810+ another_connection = connect_client("another_connection");
3811+ auto const height = screen_geometry.size.height.as_int();
3812+ auto const width = screen_geometry.size.width.as_int();
3813+ target_surface = Surface{mir_connection_create_render_surface_sync(another_connection, width,height)};
3814+ target_window = WindowSpec::for_normal_window(another_connection, width, height)
3815+ .set_name("target_window")
3816+ .add_surface(target_surface, width, height, 0, 0)
3817+ .set_event_handler(&window_event_handler, this)
3818+ .create_window();
3819+
3820+ paint_window(target_surface, target_window);
3821+ }
3822+
3823+ void invoke_window_event_handler(MirWindow* window, MirEvent const* event)
3824+ {
3825+ std::lock_guard<decltype(window_event_handler_mutex)> lock{window_event_handler_mutex};
3826+ if (window == this->window) window_event_handler_(event);
3827+ if (window == target_window) target_window_event_handler_(event);
3828+ }
3829+
3830+ void invoke_window_dnd_start_handler(MirWindow* window, MirDragAndDropEvent const* event)
3831+ {
3832+ std::lock_guard<decltype(window_event_handler_mutex)> lock{window_event_handler_mutex};
3833+ if (window == this->window) window_dnd_start_(event);
3834+ }
3835+
3836+ std::mutex window_event_handler_mutex;
3837+ std::function<void(MirDragAndDropEvent const* event)> window_dnd_start_ = [](MirDragAndDropEvent const*) {};
3838+ std::function<void(MirEvent const* event)> window_event_handler_ = [](MirEvent const*) {};
3839+ std::function<void(MirEvent const* event)> target_window_event_handler_ = [](MirEvent const*) {};
3840+
3841+ static void window_event_handler(MirWindow* window, MirEvent const* event, void* context);
3842+ static void window_dnd_start_handler(MirWindow* window, MirDragAndDropEvent const* event, void* context);
3843+
3844+ Connection another_connection;
3845+ Surface target_surface;
3846+ Window target_window;
3847+};
3848+
3849+void DragAndDrop::set_window_event_handler(MirWindow* window, std::function<void(MirEvent const* event)> const& handler)
3850+{
3851+ std::lock_guard<decltype(window_event_handler_mutex)> lock{window_event_handler_mutex};
3852+ if (window == this->window) window_event_handler_ = handler;
3853+ if (window == target_window) target_window_event_handler_ = handler;
3854+}
3855+
3856+void DragAndDrop::set_window_dnd_start_handler(MirWindow* window, std::function<void(MirDragAndDropEvent const*)> const& handler)
3857+{
3858+std::lock_guard<decltype(window_event_handler_mutex)> lock{window_event_handler_mutex};
3859+if (window == this->window) window_dnd_start_ = handler;
3860+}
3861+
3862+
3863+void DragAndDrop::reset_window_event_handler(MirWindow* window)
3864+{
3865+ if (window == this->window) window_event_handler_ = [](MirEvent const*) {};
3866+ if (window == target_window) target_window_event_handler_ = [](MirEvent const*) {};
3867+}
3868+
3869+void DragAndDrop::paint_window(MirRenderSurface* s, MirWindow* w)
3870+{
3871+ Signal have_focus;
3872+
3873+ set_window_event_handler(w, [&](MirEvent const* event)
3874+ {
3875+ if (mir_event_get_type(event) != mir_event_type_window)
3876+ return;
3877+
3878+ auto const window_event = mir_event_get_window_event(event);
3879+ if (mir_window_event_get_attribute(window_event) != mir_window_attrib_focus)
3880+ return;
3881+
3882+ if (mir_window_event_get_attribute_value(window_event))
3883+ have_focus.raise();
3884+ });
3885+
3886+ int width;
3887+ int height;
3888+ mir_render_surface_get_size(s, &width, &height);
3889+ mir_buffer_stream_swap_buffers_sync(
3890+ mir_render_surface_get_buffer_stream(s, width, height, mir_pixel_format_argb_8888));
3891+
3892+ EXPECT_THAT(have_focus.wait_for(receive_event_timeout), Eq(true));
3893+
3894+ reset_window_event_handler(w);
3895+}
3896+
3897+void DragAndDrop::center_mouse()
3898+{
3899+ Signal have_mouseover;
3900+
3901+ set_window_event_handler(window, [&](MirEvent const* event)
3902+ {
3903+ if (mir_event_get_type(event) != mir_event_type_input)
3904+ return;
3905+
3906+ auto const input_event = mir_event_get_input_event(event);
3907+
3908+ if (mir_input_event_get_type(input_event) != mir_input_event_type_pointer)
3909+ return;
3910+
3911+ auto const pointer_event = mir_input_event_get_pointer_event(input_event);
3912+
3913+ if (mir_pointer_event_action(pointer_event) != mir_pointer_action_enter)
3914+ return;
3915+
3916+ have_mouseover.raise();
3917+ });
3918+
3919+ move_mouse(0.5 * as_displacement(screen_geometry.size));
3920+
3921+// We miss the "mouseover" occasionally (with valgrind and heavy stress about 1/20).
3922+// But it isn't essential for the test and we've probably waited long enough
3923+// for the mouse-down needed by the test to reach the window.
3924+// EXPECT_THAT(have_mouseover.wait_for(receive_event_timeout), Eq(true));
3925+ have_mouseover.wait_for(receive_event_timeout);
3926+
3927+ reset_window_event_handler(window);
3928+}
3929+
3930+void DragAndDrop::window_event_handler(MirWindow* window, MirEvent const* event, void* context)
3931+{
3932+ static_cast<DragAndDrop*>(context)->invoke_window_event_handler(window, event);
3933+}
3934+
3935+void DragAndDrop::window_dnd_start_handler(MirWindow* window, MirDragAndDropEvent const* event, void* context)
3936+{
3937+ static_cast<DragAndDrop*>(context)->invoke_window_dnd_start_handler(window, event);
3938+}
3939+
3940+
3941+auto DragAndDrop::user_initiates_drag() -> Cookie
3942+{
3943+ Cookie cookie;
3944+ Signal have_cookie;
3945+
3946+ set_window_event_handler(window, [&](MirEvent const* event)
3947+ {
3948+ if (mir_event_get_type(event) != mir_event_type_input)
3949+ return;
3950+
3951+ auto const input_event = mir_event_get_input_event(event);
3952+
3953+ if (mir_input_event_get_type(input_event) != mir_input_event_type_pointer)
3954+ return;
3955+
3956+ auto const pointer_event = mir_input_event_get_pointer_event(input_event);
3957+
3958+ if (mir_pointer_event_action(pointer_event) != mir_pointer_action_button_down)
3959+ return;
3960+
3961+ cookie = Cookie{mir_input_event_get_cookie(input_event)};
3962+ have_cookie.raise();
3963+ });
3964+
3965+ start_dragging_mouse();
3966+
3967+ EXPECT_THAT(have_cookie.wait_for(receive_event_timeout), Eq(true));
3968+
3969+ reset_window_event_handler(window);
3970+ return cookie;
3971+}
3972+
3973+auto DragAndDrop::client_requests_drag(Cookie const& cookie) -> Blob
3974+{
3975+ Blob blob;
3976+ Signal initiated;
3977+
3978+ set_window_dnd_start_handler(window, [&](MirDragAndDropEvent const* event)
3979+ {
3980+ if (dnd)
3981+ blob.reset(dnd->start_drag_and_drop(event));
3982+
3983+ if (blob)
3984+ initiated.raise();
3985+ });
3986+
3987+ EXPECT_THAT(dnd, Ne(nullptr)) << "No Drag and Drop extension";
3988+
3989+ if (dnd)
3990+ dnd->request_drag_and_drop(window, cookie);
3991+
3992+ EXPECT_TRUE(initiated.wait_for(receive_event_timeout));
3993+
3994+ reset_window_event_handler(window);
3995+ return blob;
3996+}
3997+
3998+auto DragAndDrop::handle_from_mouse_move() -> Blob
3999+{
4000+ Blob blob;
4001+ Signal have_blob;
4002+
4003+ set_window_event_handler(window, [&](MirEvent const* event)
4004+ {
4005+ if (mir_event_get_type(event) != mir_event_type_input)
4006+ return;
4007+
4008+ auto const input_event = mir_event_get_input_event(event);
4009+
4010+ if (mir_input_event_get_type(input_event) != mir_input_event_type_pointer)
4011+ return;
4012+
4013+ auto const pointer_event = mir_input_event_get_pointer_event(input_event);
4014+
4015+ EXPECT_THAT(dnd, Ne(nullptr)) << "No Drag and Drop extension";
4016+
4017+ if (dnd)
4018+ blob.reset(dnd->pointer_drag_and_drop(pointer_event));
4019+
4020+ if (blob)
4021+ have_blob.raise();
4022+ });
4023+
4024+ move_mouse({1,1});
4025+
4026+ EXPECT_TRUE(have_blob.wait_for(receive_event_timeout));
4027+
4028+ reset_window_event_handler(window);
4029+ return blob;
4030+}
4031+
4032+auto DragAndDrop::handle_from_mouse_leave() -> Blob
4033+{
4034+ Blob blob;
4035+ Signal have_blob;
4036+
4037+ set_window_event_handler(window, [&](MirEvent const* event)
4038+ {
4039+ if (mir_event_get_type(event) != mir_event_type_input)
4040+ return;
4041+
4042+ auto const input_event = mir_event_get_input_event(event);
4043+
4044+ if (mir_input_event_get_type(input_event) != mir_input_event_type_pointer)
4045+ return;
4046+
4047+ auto const pointer_event = mir_input_event_get_pointer_event(input_event);
4048+
4049+ if (mir_pointer_event_action(pointer_event) != mir_pointer_action_leave)
4050+ return;
4051+
4052+ EXPECT_THAT(dnd, Ne(nullptr)) << "No Drag and Drop extension";
4053+
4054+ if (dnd)
4055+ blob.reset(dnd->pointer_drag_and_drop(pointer_event));
4056+
4057+ if (blob)
4058+ have_blob.raise();
4059+ });
4060+
4061+ move_mouse({1,1});
4062+ move_mouse(0.5 * as_displacement(surface_size));
4063+
4064+ EXPECT_TRUE(have_blob.wait_for(receive_event_timeout));
4065+
4066+ reset_window_event_handler(window);
4067+ return blob;
4068+}
4069+
4070+auto DragAndDrop::handle_from_mouse_enter() -> Blob
4071+{
4072+ Blob blob;
4073+ Signal have_blob;
4074+
4075+ set_window_event_handler(target_window, [&](MirEvent const* event)
4076+ {
4077+ if (mir_event_get_type(event) != mir_event_type_input)
4078+ return;
4079+
4080+ auto const input_event = mir_event_get_input_event(event);
4081+
4082+ if (mir_input_event_get_type(input_event) != mir_input_event_type_pointer)
4083+ return;
4084+
4085+ auto const pointer_event = mir_input_event_get_pointer_event(input_event);
4086+
4087+ if (mir_pointer_event_action(pointer_event) != mir_pointer_action_enter)
4088+ return;
4089+
4090+ EXPECT_THAT(dnd, Ne(nullptr)) << "No Drag and Drop extension";
4091+
4092+ if (dnd)
4093+ blob.reset(dnd->pointer_drag_and_drop(pointer_event));
4094+
4095+ if (blob)
4096+ have_blob.raise();
4097+ });
4098+
4099+ move_mouse({1,1});
4100+ move_mouse(0.5 * as_displacement(surface_size));
4101+
4102+ EXPECT_TRUE(have_blob.wait_for(receive_event_timeout));
4103+
4104+ reset_window_event_handler(target_window);
4105+ return blob;
4106+}
4107+
4108+auto DragAndDrop::handle_from_mouse_release() -> Blob
4109+{
4110+ Blob blob;
4111+ Signal have_blob;
4112+
4113+ set_window_event_handler(target_window, [&](MirEvent const* event)
4114+ {
4115+ if (mir_event_get_type(event) != mir_event_type_input)
4116+ return;
4117+
4118+ auto const input_event = mir_event_get_input_event(event);
4119+
4120+ if (mir_input_event_get_type(input_event) != mir_input_event_type_pointer)
4121+ return;
4122+
4123+ auto const pointer_event = mir_input_event_get_pointer_event(input_event);
4124+
4125+ if (mir_pointer_event_action(pointer_event) != mir_pointer_action_button_up)
4126+ return;
4127+
4128+ EXPECT_THAT(dnd, Ne(nullptr)) << "No Drag and Drop extension";
4129+
4130+ if (dnd)
4131+ blob.reset(dnd->pointer_drag_and_drop(pointer_event));
4132+
4133+ if (blob)
4134+ have_blob.raise();
4135+ });
4136+
4137+ move_mouse({1,1});
4138+ move_mouse(0.5 * as_displacement(surface_size));
4139+ release_mouse();
4140+
4141+ EXPECT_TRUE(have_blob.wait_for(receive_event_timeout));
4142+
4143+ reset_window_event_handler(target_window);
4144+ return blob;
4145+}
4146+
4147+auto DragAndDrop::count_of_handles_when_moving_mouse() -> int
4148+{
4149+ Signal have_3_events;
4150+ std::atomic<int> events{0};
4151+ std::atomic<int> handles{0};
4152+
4153+ auto counter = [&](MirEvent const* event)
4154+ {
4155+ if (mir_event_get_type(event) != mir_event_type_input)
4156+ return;
4157+
4158+ auto const input_event = mir_event_get_input_event(event);
4159+
4160+ if (mir_input_event_get_type(input_event) != mir_input_event_type_pointer)
4161+ return;
4162+
4163+ auto const pointer_event = mir_input_event_get_pointer_event(input_event);
4164+
4165+ EXPECT_THAT(dnd, Ne(nullptr)) << "No Drag and Drop extension";
4166+
4167+ Blob blob;
4168+ if (dnd)
4169+ blob.reset(dnd->pointer_drag_and_drop(pointer_event));
4170+
4171+ if (blob)
4172+ handles.fetch_add(1);
4173+
4174+ if (events.fetch_add(1) == 2)
4175+ have_3_events.raise();
4176+ };
4177+
4178+ set_window_event_handler(window, counter);
4179+ set_window_event_handler(target_window, counter);
4180+
4181+ start_dragging_mouse();
4182+ move_mouse({1,1});
4183+ release_mouse();
4184+
4185+ EXPECT_TRUE(have_3_events.wait_for(receive_event_timeout));
4186+
4187+ reset_window_event_handler(window);
4188+ reset_window_event_handler(target_window);
4189+ return handles;
4190+}
4191+
4192+auto DragAndDrop::build_window_manager_policy(miral::WindowManagerTools const& tools) -> std::unique_ptr<TestWindowManagerPolicy>
4193+{
4194+ struct DnDWindowManagerPolicy : miral::TestServer::TestWindowManagerPolicy, miral::WindowManagementPolicyAddendum2
4195+ {
4196+ using miral::TestServer::TestWindowManagerPolicy::TestWindowManagerPolicy;
4197+
4198+ void handle_request_drag_and_drop(miral::WindowInfo& window_info) override
4199+ {
4200+ uuid_t uuid;
4201+ uuid_generate(uuid);
4202+ std::vector<uint8_t> const handle{std::begin(uuid), std::end(uuid)};
4203+
4204+ tools.start_drag_and_drop(window_info, handle);
4205+ }
4206+
4207+ void handle_request_move(miral::WindowInfo&, MirInputEvent const*) override {}
4208+ };
4209+
4210+ return std::make_unique<DnDWindowManagerPolicy>(tools, *this);
4211+}
4212+
4213+MATCHER_P(BlobContentEq, p, "")
4214+{
4215+ if (!arg || !p)
4216+ return false;
4217+ if (mir_blob_size(arg) != mir_blob_size(p))
4218+ return false;
4219+ return !memcmp(mir_blob_data(arg), mir_blob_data(p), mir_blob_size(p));
4220+}
4221+}
4222+
4223+TEST_F(DragAndDrop, when_user_initiates_drag_client_receives_cookie)
4224+{
4225+ auto const cookie = user_initiates_drag();
4226+
4227+ EXPECT_THAT(cookie, NotNull());
4228+}
4229+
4230+TEST_F(DragAndDrop, when_client_requests_drags_it_receives_handle)
4231+{
4232+ auto const cookie = user_initiates_drag();
4233+ ASSERT_THAT(cookie, NotNull());
4234+
4235+ auto const handle = client_requests_drag(cookie);
4236+
4237+ EXPECT_THAT(handle, NotNull());
4238+}
4239+
4240+TEST_F(DragAndDrop, during_drag_when_user_moves_mouse_client_receives_handle)
4241+{
4242+ auto const cookie = user_initiates_drag();
4243+ ASSERT_THAT(cookie, NotNull());
4244+ auto const handle_from_request = client_requests_drag(cookie);
4245+
4246+ auto const handle = handle_from_mouse_move();
4247+
4248+ EXPECT_THAT(handle, NotNull());
4249+ EXPECT_THAT(handle, BlobContentEq(handle_from_request));
4250+}
4251+
4252+TEST_F(DragAndDrop, when_drag_moves_from_window_leave_event_contains_handle)
4253+{
4254+ auto const cookie = user_initiates_drag();
4255+ ASSERT_THAT(cookie, NotNull());
4256+ auto const handle_from_request = client_requests_drag(cookie);
4257+
4258+ auto const handle = handle_from_mouse_leave();
4259+
4260+ EXPECT_THAT(handle, NotNull());
4261+ EXPECT_THAT(handle, BlobContentEq(handle_from_request));
4262+}
4263+
4264+TEST_F(DragAndDrop, when_drag_enters_target_window_enter_event_contains_handle)
4265+{
4266+ auto const cookie = user_initiates_drag();
4267+ ASSERT_THAT(cookie, NotNull());
4268+ auto const handle_from_request = client_requests_drag(cookie);
4269+
4270+ auto const handle = handle_from_mouse_enter();
4271+
4272+ EXPECT_THAT(handle, NotNull());
4273+ EXPECT_THAT(handle, BlobContentEq(handle_from_request));
4274+}
4275+
4276+TEST_F(DragAndDrop, when_drag_releases_target_window_release_event_contains_handle)
4277+{
4278+ auto const cookie = user_initiates_drag();
4279+ ASSERT_THAT(cookie, NotNull());
4280+ auto const handle_from_request = client_requests_drag(cookie);
4281+
4282+ auto const handle = handle_from_mouse_release();
4283+
4284+ EXPECT_THAT(handle, NotNull());
4285+ EXPECT_THAT(handle, BlobContentEq(handle_from_request));
4286+}
4287+
4288+TEST_F(DragAndDrop, after_drag_finishes_pointer_events_no_longer_contain_handle)
4289+{
4290+ auto const cookie = user_initiates_drag();
4291+ ASSERT_THAT(cookie, NotNull());
4292+ client_requests_drag(cookie);
4293+ handle_from_mouse_release();
4294+
4295+ invoke_tools([](miral::WindowManagerTools& tools) { tools.end_drag_and_drop(); });
4296+
4297+ EXPECT_THAT(count_of_handles_when_moving_mouse(), Eq(0));
4298+}
4299
4300=== modified file 'test/select_active_window.cpp'
4301--- test/select_active_window.cpp 2017-01-13 18:17:01 +0000
4302+++ test/select_active_window.cpp 2017-06-20 16:14:05 +0000
4303@@ -32,8 +32,6 @@
4304 Rectangle const display_area{{display_left, display_top},
4305 {display_width, display_height}};
4306
4307-auto const null_window = Window{};
4308-
4309 struct SelectActiveWindow : TestWindowManagerTools
4310 {
4311
4312
4313=== modified file 'test/test_server.cpp'
4314--- test/test_server.cpp 2017-03-20 12:28:06 +0000
4315+++ test/test_server.cpp 2017-06-20 16:14:05 +0000
4316@@ -29,9 +29,7 @@
4317 #include <mir/server.h>
4318 #include <mir/version.h>
4319
4320-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 25, 0)
4321 #include <mir_test_framework/headless_display_buffer_compositor_factory.h>
4322-#endif
4323
4324 #include <boost/throw_exception.hpp>
4325
4326@@ -52,7 +50,6 @@
4327 CanonicalWindowManagerPolicy{tools}
4328 {
4329 test_fixture.tools = tools;
4330- test_fixture.policy = this;
4331 }
4332
4333 miral::TestServer::TestServer() :
4334@@ -71,10 +68,6 @@
4335
4336 void miral::TestServer::SetUp()
4337 {
4338-#if MIR_SERVER_VERSION < MIR_VERSION_NUMBER(0, 25, 0)
4339- mtf::set_next_preset_display({}); // Workaround for lp:1611337
4340-#endif
4341-
4342 mir::test::AutoJoinThread t([this]
4343 {
4344 auto init = [this](mir::Server& server)
4345@@ -93,23 +86,17 @@
4346 });
4347 });
4348
4349-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 25, 0)
4350 server.override_the_display_buffer_compositor_factory([]
4351 {
4352 return std::make_shared<mtf::HeadlessDisplayBufferCompositorFactory>();
4353 });
4354-#endif
4355
4356 server.override_the_window_manager_builder([this, &server](msh::FocusController* focus_controller)
4357 -> std::shared_ptr<msh::WindowManager>
4358 {
4359 auto const display_layout = server.the_shell_display_layout();
4360
4361-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 24, 0)
4362 auto const persistent_surface_store = server.the_persistent_surface_store();
4363-#else
4364- std::shared_ptr<mir::shell::PersistentSurfaceStore> const persistent_surface_store;
4365-#endif
4366
4367 auto builder = [this](WindowManagerTools const& tools) -> std::unique_ptr<miral::WindowManagementPolicy>
4368 {
4369
4370=== modified file 'test/test_server.h'
4371--- test/test_server.h 2017-02-14 17:11:07 +0000
4372+++ test/test_server.h 2017-06-20 16:14:05 +0000
4373@@ -69,7 +69,6 @@
4374
4375 private:
4376 WindowManagerTools tools{nullptr};
4377- WindowManagementPolicy* policy{nullptr};
4378 std::weak_ptr<mir::shell::WindowManager> window_manager;
4379 mir::test::AutoJoinThread server_thread;
4380 std::mutex mutex;
4381
4382=== modified file 'test/window_id.cpp'
4383--- test/window_id.cpp 2017-03-03 12:31:47 +0000
4384+++ test/window_id.cpp 2017-06-20 16:14:05 +0000
4385@@ -42,14 +42,13 @@
4386 }
4387 };
4388
4389-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 24, 0)
4390 TEST_F(WindowId, server_can_identify_window_specified_by_client)
4391 {
4392 char const* const test_name = __PRETTY_FUNCTION__;
4393 using namespace mir::client;
4394
4395 auto const connection = connect_client(test_name);
4396- auto const spec = WindowSpec::for_normal_window(connection, 50, 50, mir_pixel_format_argb_8888)
4397+ auto const spec = WindowSpec::for_normal_window(connection, 50, 50)
4398 .set_name(test_name);
4399
4400 Window const surface{spec.create_window()};
4401@@ -71,7 +70,7 @@
4402 using namespace mir::client;
4403
4404 auto const connection = connect_client(test_name);
4405- auto const spec = WindowSpec::for_normal_window(connection, 50, 50, mir_pixel_format_argb_8888)
4406+ auto const spec = WindowSpec::for_normal_window(connection, 50, 50)
4407 .set_name(test_name);
4408
4409 Window const surface{spec.create_window()};
4410@@ -86,46 +85,6 @@
4411 ASSERT_THAT(client_surface_id.c_str(), Eq(id));
4412 });
4413 }
4414-#else
4415-TEST_F(WindowId, server_fails_gracefully_to_identify_window_specified_by_client)
4416-{
4417- char const* const test_name = __PRETTY_FUNCTION__;
4418- using namespace mir::client;
4419-
4420- auto const connection = connect_client(test_name);
4421- auto const spec = WindowSpec::for_normal_window(connection, 50, 50, mir_pixel_format_argb_8888)
4422- .set_name(test_name);
4423-
4424- Window const surface{spec.create_window()};
4425-
4426- mir::client::WindowId client_surface_id{surface};
4427-
4428- invoke_tools([&](miral::WindowManagerTools& tools)
4429- {
4430- EXPECT_THROW(tools.info_for_window_id(client_surface_id.c_str()), std::runtime_error);
4431- });
4432-}
4433-
4434-TEST_F(WindowId, server_fails_gracefully_to_return_id_for_window)
4435-{
4436- char const* const test_name = __PRETTY_FUNCTION__;
4437- using namespace mir::client;
4438-
4439- auto const connection = connect_client(test_name);
4440- auto const spec = WindowSpec::for_normal_window(connection, 50, 50, mir_pixel_format_argb_8888)
4441- .set_name(test_name);
4442-
4443- Window const surface{spec.create_window()};
4444-
4445- mir::client::WindowId client_surface_id{surface};
4446-
4447- invoke_tools([&](miral::WindowManagerTools& tools)
4448- {
4449- auto window = get_first_window(tools);
4450- EXPECT_THROW(tools.id_for_window(window), std::runtime_error);
4451- });
4452-}
4453-#endif
4454
4455 TEST_F(WindowId, server_fails_gracefully_to_identify_window_from_garbage_id)
4456 {
4457@@ -133,8 +92,7 @@
4458 using namespace mir::client;
4459
4460 auto const connection = connect_client(test_name);
4461- auto const spec = WindowSpec::for_normal_window(connection, 50, 50, mir_pixel_format_argb_8888)
4462- .set_name(test_name);
4463+ auto const spec = WindowSpec::for_normal_window(connection, 50, 50).set_name(test_name);
4464
4465 Window const surface{spec.create_window()};
4466
4467
4468=== modified file 'test/window_placement_client_api.cpp'
4469--- test/window_placement_client_api.cpp 2017-02-14 11:49:59 +0000
4470+++ test/window_placement_client_api.cpp 2017-06-20 16:14:05 +0000
4471@@ -16,19 +16,8 @@
4472 * Authored by: Alan Griffiths <alan@octopull.co.uk>
4473 */
4474
4475-#include <mir/version.h>
4476-#include <mir_toolkit/version.h>
4477-
4478-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 25, 0)
4479-#if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 5, 0)
4480-#include <mir_toolkit/events/surface_placement.h>
4481-auto const mir_event_get_window_placement_event = mir_event_get_surface_placement_event;
4482-#else
4483 #include <mir_toolkit/events/window_placement.h>
4484-#endif
4485-#endif
4486
4487-#include <mir/client/detail/mir_forward_compatibility.h>
4488 #include <mir/client/window_spec.h>
4489 #include <mir/client/window.h>
4490
4491@@ -57,7 +46,7 @@
4492 char const* const test_name = __PRETTY_FUNCTION__;
4493
4494 connection = connect_client(test_name);
4495- auto spec = WindowSpec::for_normal_window(connection, 400, 400, mir_pixel_format_argb_8888)
4496+ auto spec = WindowSpec::for_normal_window(connection, 400, 400)
4497 .set_name(test_name);
4498
4499 parent = spec.create_window();
4500@@ -78,12 +67,6 @@
4501 };
4502 }
4503
4504-#if MIR_SERVER_VERSION >= MIR_VERSION_NUMBER(0, 25, 0)
4505-
4506-#if MIR_CLIENT_VERSION == MIR_VERSION_NUMBER(3, 4, 0)
4507-auto const mir_event_type_window_placement = mir_event_type_surface_placement;
4508-#endif
4509-
4510 namespace
4511 {
4512 struct CheckPlacement
4513@@ -137,7 +120,7 @@
4514 CheckPlacement expected{aux_rect.left+(int)aux_rect.width, aux_rect.top, dx, dy};
4515
4516 auto const spec = WindowSpec::
4517- for_menu(connection, dx, dy, mir_pixel_format_argb_8888, parent, &aux_rect, mir_edge_attachment_any)
4518+ for_menu(connection, dx, dy, parent, &aux_rect, mir_edge_attachment_any)
4519 .set_event_handler(&CheckPlacement::callback, &expected)
4520 .set_name(test_name);
4521
4522@@ -156,4 +139,3 @@
4523 spec.apply_to(child);
4524 }
4525 }
4526-#endif
4527
4528=== modified file 'test/window_properties.cpp'
4529--- test/window_properties.cpp 2017-02-21 15:49:58 +0000
4530+++ test/window_properties.cpp 2017-06-20 16:14:05 +0000
4531@@ -18,6 +18,7 @@
4532
4533 #include <miral/window_manager_tools.h>
4534
4535+#include <mir/client/surface.h>
4536 #include <mir/client/window.h>
4537 #include <mir/client/window_spec.h>
4538 #include <mir_toolkit/mir_buffer_stream.h>
4539@@ -45,18 +46,27 @@
4540 {
4541 miral::TestServer::SetUp();
4542 client_connection = connect_client("WindowProperties");
4543+ surface = Surface{mir_connection_create_render_surface_sync(client_connection, 40, 40)};
4544 }
4545
4546 void TearDown() override
4547 {
4548+ surface.reset();
4549 client_connection.reset();
4550 miral::TestServer::TearDown();
4551 }
4552
4553 Connection client_connection;
4554+ Surface surface;
4555
4556 std::unique_ptr<TestWindowManagerPolicy> build_window_manager_policy(WindowManagerTools const& tools) override;
4557
4558+ void paint(Surface const& surface)
4559+ {
4560+ mir_buffer_stream_swap_buffers_sync(
4561+ mir_render_surface_get_buffer_stream(surface, 50, 50, mir_pixel_format_argb_8888));
4562+ }
4563+
4564 mir::test::Signal window_ready;
4565 };
4566
4567@@ -80,12 +90,12 @@
4568
4569 TEST_F(WindowProperties, on_creation_default_shell_chrome_is_normal)
4570 {
4571- auto const window = WindowSpec::for_normal_window(client_connection, 50, 50, mir_pixel_format_argb_8888)
4572- .set_buffer_usage(mir_buffer_usage_software)
4573+ auto const window = WindowSpec::for_normal_window(client_connection, 50, 50)
4574 .set_name(a_window.c_str())
4575+ .add_surface(surface, 50, 50, 0, 0)
4576 .create_window();
4577
4578- mir_buffer_stream_swap_buffers_sync(mir_window_get_buffer_stream(window));
4579+ paint(surface);
4580 ASSERT_TRUE(window_ready.wait_for(400ms));
4581
4582 invoke_tools([&, this](WindowManagerTools& tools)
4583@@ -96,13 +106,13 @@
4584
4585 TEST_F(WindowProperties, on_creation_client_setting_shell_chrome_low_is_seen_by_window_manager)
4586 {
4587- auto const window = WindowSpec::for_normal_window(client_connection, 50, 50, mir_pixel_format_argb_8888)
4588- .set_buffer_usage(mir_buffer_usage_software)
4589+ auto const window = WindowSpec::for_normal_window(client_connection, 50, 50)
4590 .set_name(a_window.c_str())
4591 .set_shell_chrome(mir_shell_chrome_low)
4592+ .add_surface(surface, 50, 50, 0, 0)
4593 .create_window();
4594
4595- mir_buffer_stream_swap_buffers_sync(mir_window_get_buffer_stream(window));
4596+ paint(surface);
4597 ASSERT_TRUE(window_ready.wait_for(400ms));
4598
4599 invoke_tools([&, this](WindowManagerTools& tools)
4600@@ -113,16 +123,17 @@
4601
4602 TEST_F(WindowProperties, after_creation_client_setting_shell_chrome_low_is_seen_by_window_manager)
4603 {
4604- auto const window = WindowSpec::for_normal_window(client_connection, 50, 50, mir_pixel_format_argb_8888)
4605- .set_buffer_usage(mir_buffer_usage_software)
4606+ auto const window = WindowSpec::for_normal_window(client_connection, 50, 50)
4607 .set_name(a_window.c_str())
4608+ .add_surface(surface, 50, 50, 0, 0)
4609 .create_window();
4610
4611 WindowSpec::for_changes(client_connection)
4612 .set_shell_chrome(mir_shell_chrome_low)
4613 .apply_to(window);
4614
4615- mir_buffer_stream_swap_buffers_sync(mir_window_get_buffer_stream(window));
4616+ paint(surface);
4617+
4618 ASSERT_TRUE(window_ready.wait_for(400ms));
4619
4620 invoke_tools([&, this](WindowManagerTools& tools)
4621@@ -133,17 +144,17 @@
4622
4623 TEST_F(WindowProperties, after_creation_client_setting_shell_chrome_normal_is_seen_by_window_manager)
4624 {
4625- auto const window = WindowSpec::for_normal_window(client_connection, 50, 50, mir_pixel_format_argb_8888)
4626- .set_buffer_usage(mir_buffer_usage_software)
4627+ auto const window = WindowSpec::for_normal_window(client_connection, 50, 50)
4628 .set_name(a_window.c_str())
4629 .set_shell_chrome(mir_shell_chrome_low)
4630+ .add_surface(surface, 50, 50, 0, 0)
4631 .create_window();
4632
4633 WindowSpec::for_changes(client_connection)
4634 .set_shell_chrome(mir_shell_chrome_normal)
4635 .apply_to(window);
4636
4637- mir_buffer_stream_swap_buffers_sync(mir_window_get_buffer_stream(window));
4638+ paint(surface);
4639 ASSERT_TRUE(window_ready.wait_for(400ms));
4640
4641 invoke_tools([&, this](WindowManagerTools& tools)
4642
4643=== modified file 'test/workspaces.cpp'
4644--- test/workspaces.cpp 2017-03-30 09:42:17 +0000
4645+++ test/workspaces.cpp 2017-06-20 16:14:05 +0000
4646@@ -19,6 +19,7 @@
4647 #include <miral/workspace_policy.h>
4648 #include <miral/window_manager_tools.h>
4649
4650+#include <mir/client/surface.h>
4651 #include <mir/client/window.h>
4652 #include <mir/client/window_spec.h>
4653 #include <mir_toolkit/mir_buffer_stream.h>
4654@@ -65,57 +66,74 @@
4655 Workspaces& test_fixture;
4656 };
4657
4658+struct TestWindow : Surface, Window
4659+{
4660+ using Surface::operator=;
4661+ using Window::operator=;
4662+};
4663+
4664 struct Workspaces : public miral::TestServer
4665 {
4666- auto create_window(std::string const& name) -> Window
4667+ auto create_window(std::string const& name) -> TestWindow
4668 {
4669- auto const window = WindowSpec::for_normal_window(client_connection, 50, 50, mir_pixel_format_argb_8888)
4670- .set_buffer_usage(mir_buffer_usage_software)
4671+ TestWindow result;
4672+
4673+ result = Surface{mir_connection_create_render_surface_sync(client_connection, 50, 50)};
4674+ result = WindowSpec::for_normal_window(client_connection, 50, 50)
4675 .set_name(name.c_str())
4676+ .add_surface(result, 50, 50, 0, 0)
4677 .create_window();
4678
4679- client_windows[name] = window;
4680- init_window(window);
4681+ client_windows[name] = result;
4682+ init_window(result);
4683
4684- return window;
4685+ return result;
4686 }
4687
4688- void init_window(Window const& window)
4689+ void init_window(TestWindow const& window)
4690 {
4691 mir::test::Signal window_ready;
4692 EXPECT_CALL(policy(), advise_window_ready(_)).WillOnce(InvokeWithoutArgs([&]{ window_ready.raise(); }));
4693
4694- mir_buffer_stream_swap_buffers_sync(mir_window_get_buffer_stream(window));
4695+ mir_buffer_stream_swap_buffers_sync(
4696+ mir_render_surface_get_buffer_stream(window, 50, 50, mir_pixel_format_argb_8888));
4697
4698 EXPECT_TRUE(window_ready.wait_for(1s));
4699 }
4700
4701- auto create_tip(std::string const& name, Window const& parent) -> Window
4702+ auto create_tip(std::string const& name, Window const& parent) -> TestWindow
4703 {
4704+ TestWindow result;
4705+
4706+ result = Surface{mir_connection_create_render_surface_sync(client_connection, 50, 50)};
4707+
4708 MirRectangle aux_rect{10, 10, 10, 10};
4709- auto const window = WindowSpec::for_tip(client_connection, 50, 50, mir_pixel_format_argb_8888, parent,
4710- &aux_rect, mir_edge_attachment_any)
4711- .set_buffer_usage(mir_buffer_usage_software)
4712+ result = WindowSpec::for_tip(client_connection, 50, 50, parent, &aux_rect, mir_edge_attachment_any)
4713 .set_name(name.c_str())
4714+ .add_surface(result, 50, 50, 0, 0)
4715 .create_window();
4716
4717- client_windows[name] = window;
4718- init_window(window);
4719+ client_windows[name] = result;
4720+ init_window(result);
4721
4722- return window;
4723+ return result;
4724 }
4725
4726- auto create_dialog(std::string const& name, Window const& parent) -> Window
4727+ auto create_dialog(std::string const& name, Window const& parent) -> TestWindow
4728 {
4729- auto const window = WindowSpec::for_dialog(client_connection, 50, 50, mir_pixel_format_argb_8888, parent)
4730- .set_buffer_usage(mir_buffer_usage_software)
4731+ TestWindow result;
4732+
4733+ result = Surface{mir_connection_create_render_surface_sync(client_connection, 50, 50)};
4734+
4735+ result = WindowSpec::for_dialog(client_connection, 50, 50, parent)
4736 .set_name(name.c_str())
4737+ .add_surface(result, 50, 50, 0, 0)
4738 .create_window();
4739
4740- client_windows[name] = window;
4741- init_window(window);
4742+ client_windows[name] = result;
4743+ init_window(result);
4744
4745- return window;
4746+ return result;
4747 }
4748
4749 auto create_workspace() -> std::shared_ptr<miral::Workspace>
4750@@ -202,7 +220,7 @@
4751
4752 private:
4753 std::mutex mutable mutex;
4754- std::map<std::string, Window> client_windows;
4755+ std::map<std::string, TestWindow> client_windows;
4756 std::map<std::string, miral::Window> server_windows;
4757 WorkspacesWindowManagerPolicy* the_policy{nullptr};
4758
4759@@ -466,9 +484,11 @@
4760
4761 {
4762 auto const another_app = connect_client("another app");
4763- auto const window = WindowSpec::for_normal_window(another_app, 50, 50, mir_pixel_format_argb_8888)
4764- .set_buffer_usage(mir_buffer_usage_software)
4765+ TestWindow window;
4766+ window = Surface{mir_connection_create_render_surface_sync(another_app, 50, 50)};
4767+ window = WindowSpec::for_normal_window(another_app, 50, 50)
4768 .set_name(a_window.c_str())
4769+ .add_surface(window, 50, 50, 0, 0)
4770 .create_window();
4771
4772 init_window(window);
4773@@ -527,9 +547,11 @@
4774 create_window(another_window);
4775
4776 auto const another_app = connect_client("another app");
4777- auto const window = WindowSpec::for_normal_window(another_app, 50, 50, mir_pixel_format_argb_8888)
4778- .set_buffer_usage(mir_buffer_usage_software)
4779+ TestWindow window;
4780+ window = Surface{mir_connection_create_render_surface_sync(another_app, 50, 50)};
4781+ window = WindowSpec::for_normal_window(another_app, 50, 50)
4782 .set_name(a_window.c_str())
4783+ .add_surface(window, 50, 50, 0, 0)
4784 .create_window();
4785
4786 init_window(window);
4787@@ -590,9 +612,11 @@
4788 create_window(another_window);
4789
4790 auto const another_app = connect_client("another app");
4791- auto const window = WindowSpec::for_normal_window(another_app, 50, 50, mir_pixel_format_argb_8888)
4792- .set_buffer_usage(mir_buffer_usage_software)
4793+ TestWindow window;
4794+ window = Surface{mir_connection_create_render_surface_sync(another_app, 50, 50)};
4795+ window = WindowSpec::for_normal_window(another_app, 50, 50)
4796 .set_name(a_window.c_str())
4797+ .add_surface(window, 50, 50, 0, 0)
4798 .create_window();
4799
4800 init_window(window);

Subscribers

People subscribed via source and target branches