Merge lp:~alan-griffiths/miral/move-WM-logic-into-BasicWindowManager into lp:miral

Proposed by Alan Griffiths on 2016-06-03
Status: Merged
Approved by: Alan Griffiths on 2016-06-06
Approved revision: 199
Merged at revision: 185
Proposed branch: lp:~alan-griffiths/miral/move-WM-logic-into-BasicWindowManager
Merge into: lp:miral
Prerequisite: lp:~alan-griffiths/miral/clarify-WindowManagementPolicy-interface
Diff against target: 1916 lines (+827/-597)
17 files modified
include/miral/canonical_window_manager.h (+34/-32)
include/miral/window.h (+0/-6)
include/miral/window_management_policy.h (+6/-2)
include/miral/window_manager_tools.h (+5/-1)
miral-kiosk/kiosk_window_manager.cpp (+33/-8)
miral-kiosk/kiosk_window_manager.h (+2/-2)
miral-shell/CMakeLists.txt (+1/-2)
miral-shell/shell_main.cpp (+9/-7)
miral-shell/tiling_window_manager.cpp (+34/-14)
miral-shell/tiling_window_manager.h (+3/-1)
miral-shell/titlebar_window_manager.cpp (+208/-0)
miral-shell/titlebar_window_manager.h (+51/-0)
miral/CMakeLists.txt (+1/-0)
miral/basic_window_manager.cpp (+377/-2)
miral/basic_window_manager.h (+9/-2)
miral/canonical_window_manager.cpp (+54/-492)
miral/window.cpp (+0/-26)
To merge this branch: bzr merge lp:~alan-griffiths/miral/move-WM-logic-into-BasicWindowManager
Reviewer Review Type Date Requested Status
Mir development team 2016-06-03 Pending
Review via email: mp+296439@code.launchpad.net

Commit Message

Put most of the default window management logic into BasicWindowManager and provide a default CanonicalWindowManagerPolicy in libmiral

Description of the Change

Put most of the default window management logic into BasicWindowManager and provide a default CanonicalWindowManagerPolicy in libmiral

To post a comment you must log in.
200. By Alan Griffiths on 2016-06-03

merge :parent

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== renamed file 'miral-shell/canonical_window_manager.h' => 'include/miral/canonical_window_manager.h'
2--- miral-shell/canonical_window_manager.h 2016-06-03 15:11:50 +0000
3+++ include/miral/canonical_window_manager.h 2016-06-03 15:27:17 +0000
4@@ -16,10 +16,8 @@
5 * Authored By: Alan Griffiths <alan@octopull.co.uk>
6 */
7
8-#ifndef MIRAL_SHELL_CANONICAL_WINDOW_MANAGER_H_
9-#define MIRAL_SHELL_CANONICAL_WINDOW_MANAGER_H_
10-
11-#include "spinner/splash.h"
12+#ifndef MIRAL_CANONICAL_WINDOW_MANAGER_H_
13+#define MIRAL_CANONICAL_WINDOW_MANAGER_H_
14
15 #include <miral/window.h>
16 #include <miral/window_management_policy.h>
17@@ -29,6 +27,8 @@
18 #include <atomic>
19 #include <set>
20
21+namespace miral
22+{
23 using namespace mir::geometry;
24
25 // Based on "Mir and Unity: Surfaces, input, and displays (v0.3)"
26@@ -41,32 +41,36 @@
27 // o Maximize/restore current window (to display height): Shift-F11
28 // o Maximize/restore current window (to display width): Ctrl-F11
29 // o client requests to maximize, vertically maximize & restore
30-class CanonicalWindowManagerPolicy : public miral::WindowManagementPolicy
31+class CanonicalWindowManagerPolicy : public WindowManagementPolicy
32 {
33 public:
34
35- explicit CanonicalWindowManagerPolicy(miral::WindowManagerTools* const tools, SpinnerSplash const& spinner);
36+ explicit CanonicalWindowManagerPolicy(WindowManagerTools* const tools);
37
38 auto place_new_surface(
39- miral::ApplicationInfo const& app_info,
40- miral::WindowSpecification const& request_parameters)
41- -> miral::WindowSpecification override;
42-
43- void handle_app_info_updated(Rectangles const& displays) override;
44- void handle_displays_updated(Rectangles const& displays) override;
45- void advise_new_window(miral::WindowInfo& window_info) override;
46- void handle_window_ready(miral::WindowInfo& window_info) override;
47- void handle_modify_window(miral::WindowInfo& window_info, miral::WindowSpecification const& modifications) override;
48- void advise_delete_window(miral::WindowInfo const& window_info) override;
49+ ApplicationInfo const& app_info,
50+ WindowSpecification const& request_parameters)
51+ -> WindowSpecification override;
52+
53+ void handle_window_ready(WindowInfo& window_info) override;
54+ void handle_modify_window(WindowInfo& window_info, WindowSpecification const& modifications) override;
55+ void handle_raise_window(WindowInfo& window_info) override;
56+
57 bool handle_keyboard_event(MirKeyboardEvent const* event) override;
58 bool handle_touch_event(MirTouchEvent const* event) override;
59 bool handle_pointer_event(MirPointerEvent const* event) override;
60- void handle_raise_window(miral::WindowInfo& window_info) override;
61-
62- void advise_focus_lost(miral::WindowInfo const& info) override;
63- void advise_focus_gained(miral::WindowInfo const& info) override;
64-
65-private:
66+
67+ void advise_new_window(WindowInfo& window_info) override;
68+ void advise_focus_lost(WindowInfo const& info) override;
69+ void advise_focus_gained(WindowInfo const& info) override;
70+ void advise_state_change(WindowInfo const& window_info, MirSurfaceState state) override;
71+ void advise_resize(WindowInfo const& window_info, Size const& new_size) override;
72+ void advise_delete_window(WindowInfo const& window_info) override;
73+
74+ void handle_app_info_updated(Rectangles const& displays) override;
75+ void handle_displays_updated(Rectangles const& displays) override;
76+
77+protected:
78 static const int modifier_mask =
79 mir_input_event_modifier_alt |
80 mir_input_event_modifier_shift |
81@@ -74,30 +78,28 @@
82 mir_input_event_modifier_ctrl |
83 mir_input_event_modifier_meta;
84
85+private:
86 void drag(Point cursor);
87 void click(Point cursor);
88 bool resize(Point cursor);
89 void toggle(MirSurfaceState state);
90
91
92- bool resize(miral::Window const& window, Point cursor, Point old_cursor);
93-
94- void apply_resize(miral::WindowInfo& window_info, Point new_pos, Size new_size) const;
95- void apply_set_state(miral::WindowInfo& window_info, MirSurfaceState value);
96- void generate_decorations_for(miral::WindowInfo& window_info);
97-
98- miral::WindowManagerTools* const tools;
99- SpinnerSplash const spinner;
100+ bool resize(Window const& window, Point cursor, Point old_cursor);
101+
102+ WindowManagerTools* const tools;
103
104 Rectangle display_area;
105 Point old_cursor{};
106- using FullscreenSurfaces = std::set<miral::Window>;
107+ using FullscreenSurfaces = std::set<Window>;
108
109 FullscreenSurfaces fullscreen_surfaces;
110
111 bool resizing = false;
112 bool left_resize = false;
113 bool top_resize = false;
114+
115 };
116+}
117
118-#endif /* MIRAL_SHELL_CANONICAL_WINDOW_MANAGER_H_ */
119+#endif /* MIRAL_CANONICAL_WINDOW_MANAGER_H_ */
120
121=== modified file 'include/miral/window.h'
122--- include/miral/window.h 2016-04-22 08:54:29 +0000
123+++ include/miral/window.h 2016-06-03 15:27:17 +0000
124@@ -53,7 +53,6 @@
125 auto input_area_contains(mir::geometry::Point const& point) const -> bool;
126 auto application() const -> Application;
127
128-
129 void configure_streams(std::vector<StreamSpecification> const& config);
130
131 // Indicates that the Window isn't null
132@@ -63,13 +62,8 @@
133 void resize(mir::geometry::Size const& size);
134 void show();
135 void hide();
136- void rename(std::string const& name);
137 void move_to(mir::geometry::Point top_left);
138- void set_input_region(std::vector<mir::geometry::Rectangle> const& input_rectangles);
139 void set_state(MirSurfaceState state);
140- void set_type(MirSurfaceType type);
141-
142- void reset();
143
144 void request_client_surface_close() const;
145
146
147=== modified file 'include/miral/window_management_policy.h'
148--- include/miral/window_management_policy.h 2016-06-03 09:06:20 +0000
149+++ include/miral/window_management_policy.h 2016-06-03 15:27:17 +0000
150@@ -29,6 +29,8 @@
151 struct ApplicationInfo;
152 struct WindowInfo;
153
154+using namespace mir::geometry;
155+
156 /// The interface through which the policy invoked.
157 class WindowManagementPolicy
158 {
159@@ -61,14 +63,16 @@
160 virtual void advise_new_window(WindowInfo& window_info) = 0;
161 virtual void advise_focus_lost(WindowInfo const& info) = 0;
162 virtual void advise_focus_gained(WindowInfo const& info) = 0;
163+ virtual void advise_state_change(WindowInfo const& window_info, MirSurfaceState state) = 0;
164+ virtual void advise_resize(WindowInfo const& window_info, Size const& new_size) = 0;
165 virtual void advise_delete_window(WindowInfo const& window_info) = 0;
166 /** @} */
167
168 /** @name Changes to the applications or displays
169 * \todo these are very course grained and should probably be replaced
170 * @{ */
171- virtual void handle_app_info_updated(mir::geometry::Rectangles const& displays) = 0;
172- virtual void handle_displays_updated(mir::geometry::Rectangles const& displays) = 0;
173+ virtual void handle_app_info_updated(Rectangles const& displays) = 0;
174+ virtual void handle_displays_updated(Rectangles const& displays) = 0;
175 /** @} */
176
177 virtual ~WindowManagementPolicy() = default;
178
179=== modified file 'include/miral/window_manager_tools.h'
180--- include/miral/window_manager_tools.h 2016-06-02 16:53:17 +0000
181+++ include/miral/window_manager_tools.h 2016-06-03 15:27:17 +0000
182@@ -20,6 +20,7 @@
183 #define MIRAL_WINDOW_MANAGER_TOOLS_H
184
185 #include "miral/application.h"
186+#include "window_info.h"
187
188 #include <mir/geometry/displacement.h>
189
190@@ -67,7 +68,10 @@
191 virtual auto active_display() -> mir::geometry::Rectangle const = 0;
192 virtual void destroy(Window& window) = 0;
193 virtual void raise_tree(Window const& root) = 0;
194- virtual void move_tree(WindowInfo& root, mir::geometry::Displacement movement) = 0;
195+ virtual void modify_window(WindowInfo& window_info, WindowSpecification const& modifications) = 0;
196+ virtual void place_and_size(WindowInfo& window_info, Point const& new_pos, Size const& new_size) = 0;
197+ virtual void set_state(WindowInfo& window_info, MirSurfaceState value) = 0;
198+
199 virtual void size_to_output(mir::geometry::Rectangle& rect) = 0;
200 virtual bool place_in_output(int id, mir::geometry::Rectangle& rect) = 0;
201 /** @} */
202
203=== modified file 'miral-kiosk/kiosk_window_manager.cpp'
204--- miral-kiosk/kiosk_window_manager.cpp 2016-06-03 09:06:20 +0000
205+++ miral-kiosk/kiosk_window_manager.cpp 2016-06-03 15:27:17 +0000
206@@ -123,8 +123,26 @@
207 miral::WindowInfo& window_info,
208 miral::WindowSpecification const& modifications)
209 {
210- if (modifications.name().is_set())
211- window_info.window().rename(modifications.name().value());
212+ auto mods = modifications;
213+
214+ // filter out changes we don't want the client making
215+ mods.top_left().consume();
216+ mods.size().consume();
217+ mods.output_id().consume();
218+ mods.state().consume();
219+ mods.preferred_orientation().consume();
220+ mods.edge_attachment().consume();
221+ mods.min_width().consume();
222+ mods.min_height().consume();
223+ mods.max_width().consume();
224+ mods.max_height().consume();
225+ mods.width_inc().consume();
226+ mods.height_inc().consume();
227+ mods.min_aspect().consume();
228+ mods.max_aspect().consume();
229+ mods.parent().consume();
230+
231+ tools->modify_window(window_info, mods);
232 }
233
234 void KioskWindowManagerPolicy::advise_delete_window(WindowInfo const& /*window_info*/)
235@@ -177,6 +195,8 @@
236
237 Point const cursor{total_x/count, total_y/count};
238
239+ tools->select_active_window(tools->window_at(cursor));
240+
241 return false;
242 }
243
244@@ -196,8 +216,10 @@
245 return false;
246 }
247
248-void KioskWindowManagerPolicy::raise_splash_session() const
249+void KioskWindowManagerPolicy::advise_focus_gained(WindowInfo const& info)
250 {
251+ tools->raise_tree(info.window());
252+
253 if (auto session = splash.session().lock())
254 {
255 auto const& app_info = tools->info_for(session);
256@@ -207,11 +229,14 @@
257 }
258 }
259
260-void KioskWindowManagerPolicy::advise_focus_gained(WindowInfo const& info)
261-{
262- tools->raise_tree(info.window());
263-}
264-
265 void KioskWindowManagerPolicy::advise_focus_lost(WindowInfo const& /*info*/)
266 {
267 }
268+
269+void KioskWindowManagerPolicy::advise_state_change(WindowInfo const& /*window_info*/, MirSurfaceState /*state*/)
270+{
271+}
272+
273+void KioskWindowManagerPolicy::advise_resize(WindowInfo const& /*window_info*/, Size const& /*new_size*/)
274+{
275+}
276
277=== modified file 'miral-kiosk/kiosk_window_manager.h'
278--- miral-kiosk/kiosk_window_manager.h 2016-06-03 09:06:20 +0000
279+++ miral-kiosk/kiosk_window_manager.h 2016-06-03 15:27:17 +0000
280@@ -58,6 +58,8 @@
281 void advise_focus_lost(miral::WindowInfo const& info) override;
282
283 void advise_focus_gained(miral::WindowInfo const& info) override;
284+ void advise_state_change(miral::WindowInfo const& window_info, MirSurfaceState state) override;
285+ void advise_resize(miral::WindowInfo const& window_info, Size const& new_size) override;
286
287 private:
288 static const int modifier_mask =
289@@ -67,8 +69,6 @@
290 mir_input_event_modifier_ctrl |
291 mir_input_event_modifier_meta;
292
293- void raise_splash_session() const;
294-
295 miral::WindowManagerTools* const tools;
296
297 SwSplash const splash;
298
299=== modified file 'miral-shell/CMakeLists.txt'
300--- miral-shell/CMakeLists.txt 2016-04-16 23:13:59 +0000
301+++ miral-shell/CMakeLists.txt 2016-06-03 15:27:17 +0000
302@@ -12,9 +12,8 @@
303
304 add_executable(miral-shell
305 shell_main.cpp
306- canonical_window_manager.cpp canonical_window_manager.h
307 tiling_window_manager.cpp tiling_window_manager.h
308-)
309+ titlebar_window_manager.cpp titlebar_window_manager.h)
310
311 target_link_libraries(miral-shell
312 miral-spinner
313
314=== modified file 'miral-shell/shell_main.cpp'
315--- miral-shell/shell_main.cpp 2016-04-15 16:43:27 +0000
316+++ miral-shell/shell_main.cpp 2016-06-03 15:27:17 +0000
317@@ -17,14 +17,15 @@
318 */
319
320 #include "tiling_window_manager.h"
321-#include "canonical_window_manager.h"
322+#include "titlebar_window_manager.h"
323 #include "spinner/splash.h"
324
325-#include "miral/display_configuration_option.h"
326-#include "miral/runner.h"
327-#include "miral/window_management_options.h"
328-#include "miral/quit_on_ctrl_alt_bksp.h"
329-#include "miral/startup_internal_client.h"
330+#include <miral/canonical_window_manager.h>
331+#include <miral/display_configuration_option.h>
332+#include <miral/runner.h>
333+#include <miral/window_management_options.h>
334+#include <miral/quit_on_ctrl_alt_bksp.h>
335+#include <miral/startup_internal_client.h>
336
337 int main(int argc, char const* argv[])
338 {
339@@ -36,7 +37,8 @@
340 {
341 WindowManagerOptions
342 {
343- add_window_manager_policy<CanonicalWindowManagerPolicy>("canonical", spinner),
344+ add_window_manager_policy<TitlebarWindowManagerPolicy>("titlebar", spinner),
345+ add_window_manager_policy<CanonicalWindowManagerPolicy>("canonical"),
346 add_window_manager_policy<TilingWindowManagerPolicy>("tiling"),
347 },
348 display_configuration_options,
349
350=== modified file 'miral-shell/tiling_window_manager.cpp'
351--- miral-shell/tiling_window_manager.cpp 2016-06-03 09:06:20 +0000
352+++ miral-shell/tiling_window_manager.cpp 2016-06-03 15:27:17 +0000
353@@ -161,14 +161,29 @@
354 miral::WindowInfo& window_info,
355 miral::WindowSpecification const& modifications)
356 {
357- if (modifications.name().is_set())
358- window_info.window().rename(modifications.name().value());
359-
360- if (modifications.state().is_set())
361+ auto mods = modifications;
362+
363+ // filter out changes we don't want the client making
364+ mods.top_left().consume();
365+ mods.size().consume();
366+ mods.output_id().consume();
367+ mods.edge_attachment().consume();
368+ mods.min_width().consume();
369+ mods.min_height().consume();
370+ mods.max_width().consume();
371+ mods.max_height().consume();
372+ mods.width_inc().consume();
373+ mods.height_inc().consume();
374+ mods.min_aspect().consume();
375+ mods.max_aspect().consume();
376+
377+ if (mods.state().is_set())
378 {
379- auto state = transform_set_state(window_info, modifications.state().value());
380+ auto state = transform_set_state(window_info, mods.state().consume());
381 window_info.window().set_state(state);
382 }
383+
384+ tools->modify_window(window_info, mods);
385 }
386
387 void TilingWindowManagerPolicy::advise_delete_window(WindowInfo const& /*window_info*/)
388@@ -462,15 +477,10 @@
389
390 void TilingWindowManagerPolicy::update_surfaces(ApplicationInfo& info, Rectangle const& old_tile, Rectangle const& new_tile)
391 {
392- auto displacement = new_tile.top_left - old_tile.top_left;
393-
394 for (auto& window : info.windows())
395 {
396 if (window)
397 {
398- auto const old_pos = window.top_left();
399- window.move_to(old_pos + displacement);
400-
401 fit_to_new_tile(window, old_tile, new_tile);
402 }
403 }
404@@ -488,17 +498,18 @@
405
406 void TilingWindowManagerPolicy::fit_to_new_tile(miral::Window& window, Rectangle const& old_tile, Rectangle const& new_tile)
407 {
408- auto const displacement = window.top_left() - new_tile.top_left;
409+ auto const new_pos = window.top_left() + (new_tile.top_left - old_tile.top_left);
410+ auto const offset = new_pos - new_tile.top_left;
411
412 // For now just scale if was filling width/height of tile
413 auto const old_size = window.size();
414 auto const scaled_width = old_size.width == old_tile.size.width ? new_tile.size.width : old_size.width;
415 auto const scaled_height = old_size.height == old_tile.size.height ? new_tile.size.height : old_size.height;
416
417- auto width = std::min(new_tile.size.width.as_int()-displacement.dx.as_int(), scaled_width.as_int());
418- auto height = std::min(new_tile.size.height.as_int()-displacement.dy.as_int(), scaled_height.as_int());
419+ auto width = std::min(new_tile.size.width.as_int()-offset.dx.as_int(), scaled_width.as_int());
420+ auto height = std::min(new_tile.size.height.as_int()-offset.dy.as_int(), scaled_height.as_int());
421
422- window.resize({width, height});
423+ tools->place_and_size(tools->info_for(window), new_pos, {width, height});
424 }
425
426 void TilingWindowManagerPolicy::drag(WindowInfo& window_info, Point to, Point from, Rectangle bounds)
427@@ -580,3 +591,12 @@
428 void TilingWindowManagerPolicy::advise_focus_lost(WindowInfo const& /*info*/)
429 {
430 }
431+
432+void TilingWindowManagerPolicy::advise_state_change(WindowInfo const& /*window_info*/, MirSurfaceState /*state*/)
433+{
434+}
435+
436+void TilingWindowManagerPolicy::advise_resize(WindowInfo const& /*window_info*/, Size const& /*new_size*/)
437+{
438+}
439+
440
441=== modified file 'miral-shell/tiling_window_manager.h'
442--- miral-shell/tiling_window_manager.h 2016-06-03 15:11:50 +0000
443+++ miral-shell/tiling_window_manager.h 2016-06-03 15:27:17 +0000
444@@ -59,6 +59,8 @@
445
446 void advise_focus_lost(miral::WindowInfo const& info) override;
447 void advise_focus_gained(miral::WindowInfo const& info) override;
448+ void advise_state_change(miral::WindowInfo const& window_info, MirSurfaceState state) override;
449+ void advise_resize(miral::WindowInfo const& window_info, Size const& new_size) override;
450
451 private:
452 static const int modifier_mask =
453@@ -81,7 +83,7 @@
454 auto transform_set_state(miral::WindowInfo& window_info, MirSurfaceState value) -> MirSurfaceState;
455
456 static void clip_to_tile(miral::WindowSpecification& parameters, Rectangle const& tile);
457- static void fit_to_new_tile(miral::Window& window, Rectangle const& old_tile, Rectangle const& new_tile);
458+ void fit_to_new_tile(miral::Window& window, Rectangle const& old_tile, Rectangle const& new_tile);
459 static void resize(miral::Window window, Point cursor, Point old_cursor, Rectangle bounds);
460 static void constrained_move(miral::Window window, Displacement& movement, Rectangle const& bounds);
461
462
463=== added file 'miral-shell/titlebar_window_manager.cpp'
464--- miral-shell/titlebar_window_manager.cpp 1970-01-01 00:00:00 +0000
465+++ miral-shell/titlebar_window_manager.cpp 2016-06-03 15:27:17 +0000
466@@ -0,0 +1,208 @@
467+/*
468+ * Copyright © 2016 Canonical Ltd.
469+ *
470+ * This program is free software: you can redistribute it and/or modify it
471+ * under the terms of the GNU General Public License version 3,
472+ * as published by the Free Software Foundation.
473+ *
474+ * This program is distributed in the hope that it will be useful,
475+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
476+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
477+ * GNU General Public License for more details.
478+ *
479+ * You should have received a copy of the GNU General Public License
480+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
481+ *
482+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
483+ */
484+
485+#include "titlebar_window_manager.h"
486+#include "titlebar/canonical_window_management_policy_data.h"
487+
488+#include <miral/application_info.h>
489+#include <miral/window_info.h>
490+#include <miral/window_manager_tools.h>
491+
492+using namespace miral;
493+
494+namespace
495+{
496+int const title_bar_height = 10;
497+Size titlebar_size_for_window(Size window_size)
498+{
499+ return {window_size.width, Height{title_bar_height}};
500+}
501+
502+Point titlebar_position_for_window(Point window_position)
503+{
504+ return {
505+ window_position.x,
506+ window_position.y - DeltaY(title_bar_height)
507+ };
508+}
509+}
510+
511+TitlebarWindowManagerPolicy::TitlebarWindowManagerPolicy(WindowManagerTools* const tools, SpinnerSplash const& spinner) :
512+ CanonicalWindowManagerPolicy(tools),
513+ tools(tools),
514+ spinner{spinner}
515+{
516+}
517+
518+bool TitlebarWindowManagerPolicy::handle_pointer_event(MirPointerEvent const* event)
519+{
520+ auto consumes_event = CanonicalWindowManagerPolicy::handle_pointer_event(event);
521+
522+ auto const action = mir_pointer_event_action(event);
523+ auto const modifiers = mir_pointer_event_modifiers(event) & modifier_mask;
524+ Point const cursor{
525+ mir_pointer_event_axis_value(event, mir_pointer_axis_x),
526+ mir_pointer_event_axis_value(event, mir_pointer_axis_y)};
527+
528+
529+ if (!consumes_event && action == mir_pointer_action_motion && !modifiers)
530+ {
531+ if (mir_pointer_event_button_state(event, mir_pointer_button_primary))
532+ {
533+ // TODO this is a rather roundabout way to detect a titlebar
534+ if (auto const possible_titlebar = tools->window_at(old_cursor))
535+ {
536+ if (auto const parent = tools->info_for(possible_titlebar).parent())
537+ {
538+ if (auto const& parent_userdata =
539+ std::static_pointer_cast<CanonicalWindowManagementPolicyData>(tools->info_for(parent).userdata()))
540+ {
541+ if (possible_titlebar == parent_userdata->window)
542+ {
543+ if (auto const target = tools->window_at(old_cursor))
544+ {
545+ tools->select_active_window(target);
546+ tools->drag_active_window(cursor - old_cursor);
547+ }
548+ consumes_event = true;
549+ }
550+ }
551+ }
552+ }
553+ }
554+ }
555+
556+ old_cursor = cursor;
557+ return consumes_event;
558+}
559+
560+
561+void TitlebarWindowManagerPolicy::advise_new_window(WindowInfo& window_info)
562+{
563+ CanonicalWindowManagerPolicy::advise_new_window(window_info);
564+
565+ if (!window_info.needs_titlebar(window_info.type()))
566+ return;
567+
568+ Window const& window = window_info.window();
569+
570+ auto format = mir_pixel_format_xrgb_8888;
571+ WindowSpecification params;
572+ params.size() = titlebar_size_for_window(window.size());
573+ params.name() = "decoration";
574+ params.pixel_format() = format;
575+ params.buffer_usage() = WindowSpecification::BufferUsage::software;
576+ params.top_left() = titlebar_position_for_window(window.top_left());
577+ params.type() = mir_surface_type_gloss;
578+
579+ auto& titlebar_info = tools->build_window(window.application(), params);
580+ titlebar_info.window().set_alpha(0.9);
581+ titlebar_info.parent(window);
582+
583+ auto data = std::make_shared<CanonicalWindowManagementPolicyData>(titlebar_info.window());
584+ window_info.userdata(data);
585+ window_info.add_child(titlebar_info.window());
586+}
587+
588+void TitlebarWindowManagerPolicy::advise_focus_lost(WindowInfo const& info)
589+{
590+ CanonicalWindowManagerPolicy::advise_focus_lost(info);
591+
592+ if (auto const titlebar = std::static_pointer_cast<CanonicalWindowManagementPolicyData>(info.userdata()))
593+ {
594+ titlebar->paint_titlebar(0x3F);
595+ }
596+}
597+
598+void TitlebarWindowManagerPolicy::advise_focus_gained(WindowInfo const& info)
599+{
600+ CanonicalWindowManagerPolicy::advise_focus_gained(info);
601+
602+ if (auto const titlebar = std::static_pointer_cast<CanonicalWindowManagementPolicyData>(info.userdata()))
603+ {
604+ titlebar->paint_titlebar(0xFF);
605+ }
606+
607+ // Frig to force the spinner to the top
608+ if (auto const spinner_session = spinner.session())
609+ {
610+ auto const& spinner_info = tools->info_for(spinner_session);
611+
612+ if (spinner_info.windows().size() > 0)
613+ tools->raise_tree(spinner_info.windows()[0]);
614+ }
615+}
616+
617+void TitlebarWindowManagerPolicy::advise_state_change(WindowInfo const& window_info, MirSurfaceState state)
618+{
619+ CanonicalWindowManagerPolicy::advise_state_change(window_info, state);
620+
621+ if (auto const titlebar = std::static_pointer_cast<CanonicalWindowManagementPolicyData>(window_info.userdata()))
622+ {
623+ switch (state)
624+ {
625+ case mir_surface_state_restored:
626+ titlebar->window.resize(titlebar_size_for_window(window_info.restore_rect().size));
627+ titlebar->window.show();
628+ break;
629+
630+ case mir_surface_state_maximized:
631+ case mir_surface_state_vertmaximized:
632+ case mir_surface_state_hidden:
633+ case mir_surface_state_minimized:
634+ titlebar->window.hide();
635+ break;
636+
637+ case mir_surface_state_horizmaximized:
638+ titlebar->window.resize(titlebar_size_for_window({display_area.size.width, window_info.restore_rect().size.height}));
639+ titlebar->window.show();
640+ break;
641+
642+ case mir_surface_state_fullscreen:
643+ default:
644+ break;
645+ }
646+ }
647+}
648+
649+void TitlebarWindowManagerPolicy::advise_resize(WindowInfo const& window_info, Size const& new_size)
650+{
651+ CanonicalWindowManagerPolicy::advise_resize(window_info, new_size);
652+
653+ if (auto const titlebar = std::static_pointer_cast<CanonicalWindowManagementPolicyData>(window_info.userdata()))
654+ {
655+ titlebar->window.resize({new_size.width, Height{title_bar_height}});
656+ }
657+}
658+
659+void TitlebarWindowManagerPolicy::advise_delete_window(WindowInfo const& window_info)
660+{
661+ CanonicalWindowManagerPolicy::advise_delete_window(window_info);
662+
663+ if (auto const titlebar = std::static_pointer_cast<CanonicalWindowManagementPolicyData>(window_info.userdata()))
664+ {
665+ tools->destroy(titlebar->window);
666+ }
667+}
668+
669+void TitlebarWindowManagerPolicy::handle_displays_updated(Rectangles const& displays)
670+{
671+ CanonicalWindowManagerPolicy::handle_displays_updated(displays);
672+
673+ display_area = displays.bounding_rectangle();
674+}
675
676=== added file 'miral-shell/titlebar_window_manager.h'
677--- miral-shell/titlebar_window_manager.h 1970-01-01 00:00:00 +0000
678+++ miral-shell/titlebar_window_manager.h 2016-06-03 15:27:17 +0000
679@@ -0,0 +1,51 @@
680+/*
681+ * Copyright © 2016 Canonical Ltd.
682+ *
683+ * This program is free software: you can redistribute it and/or modify it
684+ * under the terms of the GNU General Public License version 3,
685+ * as published by the Free Software Foundation.
686+ *
687+ * This program is distributed in the hope that it will be useful,
688+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
689+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
690+ * GNU General Public License for more details.
691+ *
692+ * You should have received a copy of the GNU General Public License
693+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
694+ *
695+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
696+ */
697+
698+#ifndef MIRAL_SHELL_TITLEBAR_WINDOW_MANAGER_H
699+#define MIRAL_SHELL_TITLEBAR_WINDOW_MANAGER_H
700+
701+#include "spinner/splash.h"
702+
703+#include <miral/canonical_window_manager.h>
704+
705+using namespace mir::geometry;
706+
707+class TitlebarWindowManagerPolicy : public miral::CanonicalWindowManagerPolicy
708+{
709+public:
710+ TitlebarWindowManagerPolicy(miral::WindowManagerTools* const tools, SpinnerSplash const& spinner);
711+
712+ bool handle_pointer_event(MirPointerEvent const* event) override;
713+
714+ void advise_new_window(miral::WindowInfo& window_info) override;
715+ void advise_focus_lost(miral::WindowInfo const& info) override;
716+ void advise_focus_gained(miral::WindowInfo const& info) override;
717+ void advise_state_change(miral::WindowInfo const& window_info, MirSurfaceState state) override;
718+ void advise_resize(miral::WindowInfo const& window_info, Size const& new_size) override;
719+ void advise_delete_window(miral::WindowInfo const& window_info) override;
720+
721+ void handle_displays_updated(Rectangles const& displays) override;
722+private:
723+ miral::WindowManagerTools* const tools;
724+ SpinnerSplash const spinner;
725+
726+ Rectangle display_area;
727+ Point old_cursor{};
728+};
729+
730+#endif //MIRAL_SHELL_TITLEBAR_WINDOW_MANAGER_H
731
732=== modified file 'miral/CMakeLists.txt'
733--- miral/CMakeLists.txt 2016-05-20 11:14:40 +0000
734+++ miral/CMakeLists.txt 2016-06-03 15:27:17 +0000
735@@ -5,6 +5,7 @@
736 add_library(miral SHARED
737 application.cpp ${CMAKE_SOURCE_DIR}/include/miral/application.h
738 application_info.cpp ${CMAKE_SOURCE_DIR}/include/miral/application_info.h
739+ canonical_window_manager.cpp ${CMAKE_SOURCE_DIR}/include/miral/canonical_window_manager.h
740 runner.cpp ${CMAKE_SOURCE_DIR}/include/miral/runner.h
741 display_configuration_option.cpp ${CMAKE_SOURCE_DIR}/include/miral/display_configuration_option.h
742 quit_on_ctrl_alt_bksp.cpp ${CMAKE_SOURCE_DIR}/include/miral/quit_on_ctrl_alt_bksp.h
743
744=== modified file 'miral/basic_window_manager.cpp'
745--- miral/basic_window_manager.cpp 2016-06-03 09:06:20 +0000
746+++ miral/basic_window_manager.cpp 2016-06-03 15:27:17 +0000
747@@ -29,6 +29,11 @@
748
749 using namespace mir;
750
751+namespace
752+{
753+int const title_bar_height = 10;
754+}
755+
756 miral::BasicWindowManager::BasicWindowManager(
757 shell::FocusController* focus_controller,
758 std::shared_ptr<shell::DisplayLayout> const& display_layout,
759@@ -91,7 +96,9 @@
760 };
761
762 auto& session_info = info_for(session);
763- auto& window_info = build_window(session, policy->place_new_surface(session_info, params));
764+
765+ auto default_placement = place_new_surface(session_info, params);
766+ auto& window_info = build_window(session, policy->place_new_surface(session_info, default_placement));
767
768 auto const window = window_info.window();
769
770@@ -461,6 +468,219 @@
771 move_tree(info_for(child), movement);
772 }
773
774+void miral::BasicWindowManager::modify_window(WindowInfo& window_info, WindowSpecification const& modifications)
775+{
776+ auto window_info_tmp = window_info;
777+
778+#define COPY_IF_SET(field)\
779+ if (modifications.field().is_set())\
780+ window_info_tmp.field(modifications.field().value())
781+
782+ COPY_IF_SET(type);
783+ COPY_IF_SET(min_width);
784+ COPY_IF_SET(min_height);
785+ COPY_IF_SET(max_width);
786+ COPY_IF_SET(max_height);
787+ COPY_IF_SET(width_inc);
788+ COPY_IF_SET(height_inc);
789+ COPY_IF_SET(min_aspect);
790+ COPY_IF_SET(max_aspect);
791+ COPY_IF_SET(output_id);
792+ COPY_IF_SET(preferred_orientation);
793+
794+#undef COPY_IF_SET
795+
796+ if (modifications.parent().is_set())
797+ window_info_tmp.parent(info_for(modifications.parent().value()).window());
798+
799+ if (window_info.type() != window_info_tmp.type())
800+ {
801+ auto const new_type = window_info_tmp.type();
802+
803+ if (!window_info.can_morph_to(new_type))
804+ {
805+ throw std::runtime_error("Unsupported window type change");
806+ }
807+
808+ if (window_info_tmp.must_not_have_parent())
809+ {
810+ if (modifications.parent().is_set())
811+ throw std::runtime_error("Target window type does not support parent");
812+
813+ window_info_tmp.parent({});
814+ }
815+ else if (window_info_tmp.must_have_parent())
816+ {
817+ if (!window_info_tmp.parent())
818+ throw std::runtime_error("Target window type requires parent");
819+ }
820+ }
821+
822+ std::swap(window_info_tmp, window_info);
823+
824+ auto& window = window_info.window();
825+
826+ if (window_info.type() != window_info_tmp.type())
827+ std::shared_ptr<scene::Surface>(window)->configure(mir_surface_attrib_type, window_info.type());
828+
829+ if (window_info.parent() != window_info_tmp.parent())
830+ {
831+ if (window_info_tmp.parent())
832+ {
833+ auto& parent_info = info_for(window_info_tmp.parent());
834+ parent_info.remove_child(window);
835+ }
836+
837+ if (window_info.parent())
838+ {
839+ auto& parent_info = info_for(window_info.parent());
840+ parent_info.add_child(window);
841+ }
842+ }
843+
844+ if (modifications.name().is_set())
845+ std::shared_ptr<scene::Surface>(window)->rename(modifications.name().value());
846+
847+ if (modifications.streams().is_set())
848+ window.configure_streams(modifications.streams().value());
849+
850+ if (modifications.input_shape().is_set())
851+ std::shared_ptr<scene::Surface>(window)->set_input_region(modifications.input_shape().value());
852+
853+ if (modifications.size().is_set())
854+ {
855+ Point new_pos = window.top_left();
856+ Size new_size = modifications.size().value();
857+
858+ window_info.constrain_resize(new_pos, new_size);
859+ place_and_size(window_info, new_pos, new_size);
860+ }
861+ else if (modifications.min_width().is_set() || modifications.min_height().is_set() ||
862+ modifications.max_width().is_set() || modifications.max_height().is_set() ||
863+ modifications.width_inc().is_set() || modifications.height_inc().is_set())
864+ {
865+ Point new_pos = window.top_left();
866+ Size new_size = window.size();
867+
868+ window_info.constrain_resize(new_pos, new_size);
869+ place_and_size(window_info, new_pos, new_size);
870+ }
871+
872+ if (modifications.state().is_set())
873+ {
874+ set_state(window_info, modifications.state().value());
875+ }
876+}
877+
878+void miral::BasicWindowManager::place_and_size(WindowInfo& root, Point const& new_pos, Size const& new_size)
879+{
880+ policy->advise_resize(root, new_size);
881+ root.window().resize(new_size);
882+ move_tree(root, new_pos - root.window().top_left());
883+}
884+
885+void miral::BasicWindowManager::set_state(miral::WindowInfo& window_info, MirSurfaceState value)
886+{
887+ switch (value)
888+ {
889+ case mir_surface_state_restored:
890+ case mir_surface_state_maximized:
891+ case mir_surface_state_vertmaximized:
892+ case mir_surface_state_horizmaximized:
893+ case mir_surface_state_fullscreen:
894+ case mir_surface_state_hidden:
895+ case mir_surface_state_minimized:
896+ break;
897+
898+ default:
899+ window_info.window().set_state(window_info.state());
900+ return;
901+ }
902+
903+ if (window_info.state() == mir_surface_state_restored)
904+ {
905+ window_info.restore_rect({window_info.window().top_left(), window_info.window().size()});
906+ }
907+
908+ if (window_info.state() != mir_surface_state_fullscreen)
909+ {
910+ window_info.output_id({});
911+ }
912+
913+ if (window_info.state() == value)
914+ {
915+ return;
916+ }
917+
918+ auto const old_pos = window_info.window().top_left();
919+ Displacement movement;
920+
921+ policy->advise_state_change(window_info, value);
922+
923+ auto const display_area = displays.bounding_rectangle();
924+
925+ switch (value)
926+ {
927+ case mir_surface_state_restored:
928+ movement = window_info.restore_rect().top_left - old_pos;
929+ window_info.window().resize(window_info.restore_rect().size);
930+ break;
931+
932+ case mir_surface_state_maximized:
933+ movement = display_area.top_left - old_pos;
934+ window_info.window().resize(display_area.size);
935+ break;
936+
937+ case mir_surface_state_horizmaximized:
938+ movement = Point{display_area.top_left.x, window_info.restore_rect().top_left.y} - old_pos;
939+ window_info.window().resize({display_area.size.width, window_info.restore_rect().size.height});
940+ break;
941+
942+ case mir_surface_state_vertmaximized:
943+ movement = Point{window_info.restore_rect().top_left.x, display_area.top_left.y} - old_pos;
944+ window_info.window().resize({window_info.restore_rect().size.width, display_area.size.height});
945+ break;
946+
947+ case mir_surface_state_fullscreen:
948+ {
949+ Rectangle rect{old_pos, window_info.window().size()};
950+
951+ if (window_info.has_output_id())
952+ {
953+ place_in_output(window_info.output_id(), rect);
954+ }
955+ else
956+ {
957+ size_to_output(rect);
958+ }
959+
960+ movement = rect.top_left - old_pos;
961+ window_info.window().resize(rect.size);
962+ break;
963+ }
964+
965+ case mir_surface_state_hidden:
966+ case mir_surface_state_minimized:
967+ window_info.window().hide();
968+ window_info.state(value);
969+ window_info.window().set_state(window_info.state());
970+ return;
971+
972+ default:
973+ break;
974+ }
975+
976+ move_tree(window_info, movement);
977+
978+ window_info.state(value);
979+
980+ if (window_info.is_visible())
981+ window_info.window().show();
982+
983+ window_info.window().set_state(window_info.state());
984+}
985+
986+
987 void miral::BasicWindowManager::update_event_timestamp(MirKeyboardEvent const* kev)
988 {
989 auto iev = mir_keyboard_event_input_event(kev);
990@@ -601,4 +821,159 @@
991 });
992
993 return new_focus;
994-}
995\ No newline at end of file
996+}
997+
998+auto miral::BasicWindowManager::place_new_surface(
999+ ApplicationInfo const& app_info,
1000+ WindowSpecification const& request_parameters)
1001+-> WindowSpecification
1002+{
1003+ auto parameters = request_parameters;
1004+ auto surf_type = parameters.type().is_set() ? parameters.type().value() : mir_surface_type_normal;
1005+ bool const needs_titlebar = WindowInfo::needs_titlebar(surf_type);
1006+
1007+ if (needs_titlebar)
1008+ parameters.size() = Size{parameters.size().value().width, parameters.size().value().height + DeltaY{title_bar_height}};
1009+
1010+ if (!parameters.state().is_set())
1011+ parameters.state() = mir_surface_state_restored;
1012+
1013+ auto const active_display_area = active_display();
1014+
1015+ auto const width = parameters.size().value().width.as_int();
1016+ auto const height = parameters.size().value().height.as_int();
1017+
1018+ bool positioned = false;
1019+
1020+ bool const has_parent{parameters.parent().is_set() && parameters.parent().value().lock()};
1021+
1022+ if (parameters.output_id().is_set() && parameters.output_id().value() != 0)
1023+ {
1024+ Rectangle rect{parameters.top_left().value(), parameters.size().value()};
1025+ place_in_output(parameters.output_id().value(), rect);
1026+ parameters.top_left() = rect.top_left;
1027+ parameters.size() = rect.size;
1028+ parameters.state() = mir_surface_state_fullscreen;
1029+ positioned = true;
1030+ }
1031+ else if (!has_parent) // No parent => client can't suggest positioning
1032+ {
1033+ if (app_info.windows().size() > 0)
1034+ {
1035+ if (auto const default_window = app_info.windows()[0])
1036+ {
1037+ static Displacement const offset{title_bar_height, title_bar_height};
1038+
1039+ parameters.top_left() = default_window.top_left() + offset;
1040+
1041+ Rectangle display_for_app{default_window.top_left(), default_window.size()};
1042+
1043+ size_to_output(display_for_app);
1044+
1045+ positioned = display_for_app.overlaps(Rectangle{parameters.top_left().value(), parameters.size().value()});
1046+ }
1047+ }
1048+ }
1049+
1050+ if (has_parent && parameters.aux_rect().is_set() && parameters.edge_attachment().is_set())
1051+ {
1052+ auto parent = info_for(parameters.parent().value()).window();
1053+
1054+ auto const edge_attachment = parameters.edge_attachment().value();
1055+ auto const aux_rect = parameters.aux_rect().value();
1056+ auto const parent_top_left = parent.top_left();
1057+ auto const top_left = aux_rect.top_left -Point{} + parent_top_left;
1058+ auto const top_right= aux_rect.top_right() -Point{} + parent_top_left;
1059+ auto const bot_left = aux_rect.bottom_left()-Point{} + parent_top_left;
1060+
1061+ if (edge_attachment & mir_edge_attachment_vertical)
1062+ {
1063+ if (active_display_area.contains(top_right + Displacement{width, height}))
1064+ {
1065+ parameters.top_left() = top_right;
1066+ positioned = true;
1067+ }
1068+ else if (active_display_area.contains(top_left + Displacement{-width, height}))
1069+ {
1070+ parameters.top_left() = top_left + Displacement{-width, 0};
1071+ positioned = true;
1072+ }
1073+ }
1074+
1075+ if (edge_attachment & mir_edge_attachment_horizontal)
1076+ {
1077+ if (active_display_area.contains(bot_left + Displacement{width, height}))
1078+ {
1079+ parameters.top_left() = bot_left;
1080+ positioned = true;
1081+ }
1082+ else if (active_display_area.contains(top_left + Displacement{width, -height}))
1083+ {
1084+ parameters.top_left() = top_left + Displacement{0, -height};
1085+ positioned = true;
1086+ }
1087+ }
1088+ }
1089+ else if (has_parent)
1090+ {
1091+ auto parent = info_for(parameters.parent().value()).window();
1092+ // o Otherwise, if the dialog is not the same as any previous dialog for the
1093+ // same parent window, and/or it does not have user-customized position:
1094+ // o It should be optically centered relative to its parent, unless this
1095+ // would overlap or cover the title bar of the parent.
1096+ // o Otherwise, it should be cascaded vertically (but not horizontally)
1097+ // relative to its parent, unless, this would cause at least part of
1098+ // it to extend into shell space.
1099+ auto const parent_top_left = parent.top_left();
1100+ auto const centred = parent_top_left
1101+ + 0.5*(as_displacement(parent.size()) - as_displacement(parameters.size().value()))
1102+ - DeltaY{(parent.size().height.as_int()-height)/6};
1103+
1104+ parameters.top_left() = centred;
1105+ positioned = true;
1106+ }
1107+
1108+ if (!positioned)
1109+ {
1110+ auto centred = active_display_area.top_left
1111+ + 0.5*(as_displacement(active_display_area.size) - as_displacement(parameters.size().value()))
1112+ - DeltaY{(active_display_area.size.height.as_int()-height)/6};
1113+
1114+ switch (parameters.state().value())
1115+ {
1116+ case mir_surface_state_fullscreen:
1117+ case mir_surface_state_maximized:
1118+ parameters.top_left() = active_display_area.top_left;
1119+ parameters.size() = active_display_area.size;
1120+ break;
1121+
1122+ case mir_surface_state_vertmaximized:
1123+ centred.y = active_display_area.top_left.y;
1124+ parameters.top_left() = centred;
1125+ parameters.size() = Size{parameters.size().value().width, active_display_area.size.height};
1126+ break;
1127+
1128+ case mir_surface_state_horizmaximized:
1129+ centred.x = active_display_area.top_left.x;
1130+ parameters.top_left() = centred;
1131+ parameters.size() = Size{active_display_area.size.width, parameters.size().value().height};
1132+ break;
1133+
1134+ default:
1135+ parameters.top_left() = centred;
1136+ }
1137+
1138+ auto const display_area = displays.bounding_rectangle();
1139+
1140+ if (parameters.top_left().value().y < display_area.top_left.y)
1141+ parameters.top_left() = Point{parameters.top_left().value().x, display_area.top_left.y};
1142+ }
1143+
1144+ if (parameters.state().value() != mir_surface_state_fullscreen && needs_titlebar)
1145+ {
1146+ parameters.top_left() = Point{parameters.top_left().value().x, parameters.top_left().value().y + DeltaY{title_bar_height}};
1147+ parameters.size() = Size{parameters.size().value().width, parameters.size().value().height - DeltaY{title_bar_height}};
1148+ }
1149+
1150+ return parameters;
1151+}
1152
1153=== modified file 'miral/basic_window_manager.h'
1154--- miral/basic_window_manager.h 2016-06-02 16:53:17 +0000
1155+++ miral/basic_window_manager.h 2016-06-03 15:27:17 +0000
1156@@ -38,7 +38,6 @@
1157 namespace shell { class DisplayLayout; }
1158 }
1159
1160-/// This is based on mir/examples, but intended to move to miral after building the necessary abstractions
1161 namespace miral
1162 {
1163 using mir::shell::SurfaceSet;
1164@@ -132,7 +131,11 @@
1165
1166 void raise_tree(Window const& root) override;
1167
1168- void move_tree(miral::WindowInfo& root, mir::geometry::Displacement movement) override;
1169+ void modify_window(WindowInfo& window_info, WindowSpecification const& modifications) override;
1170+
1171+ void place_and_size(WindowInfo& root, Point const& new_pos, Size const& new_size) override;
1172+
1173+ void set_state(miral::WindowInfo& window_info, MirSurfaceState value) override;
1174
1175 void size_to_output(mir::geometry::Rectangle& rect) override;
1176
1177@@ -164,6 +167,10 @@
1178 void update_event_timestamp(MirTouchEvent const* tev);
1179
1180 auto can_activate_window_for_session(miral::Application const& session) -> bool;
1181+
1182+ auto place_new_surface(ApplicationInfo const& app_info, WindowSpecification const& request_parameters)
1183+ -> WindowSpecification;
1184+ void move_tree(miral::WindowInfo& root, mir::geometry::Displacement movement);
1185 };
1186 }
1187
1188
1189=== renamed file 'miral-shell/canonical_window_manager.cpp' => 'miral/canonical_window_manager.cpp'
1190--- miral-shell/canonical_window_manager.cpp 2016-06-03 09:06:20 +0000
1191+++ miral/canonical_window_manager.cpp 2016-06-03 15:27:17 +0000
1192@@ -16,56 +16,36 @@
1193 * Authored By: Alan Griffiths <alan@octopull.co.uk>
1194 */
1195
1196-#include "canonical_window_manager.h"
1197-#include "titlebar/canonical_window_management_policy_data.h"
1198-#include "spinner/splash.h"
1199+#include "miral/canonical_window_manager.h"
1200
1201-#include <miral/application_info.h>
1202-#include <miral/window_info.h>
1203-#include <miral/window_manager_tools.h>
1204+#include "miral/application_info.h"
1205+#include "miral/window_info.h"
1206+#include "miral/window_manager_tools.h"
1207
1208 #include <linux/input.h>
1209 #include <algorithm>
1210 #include <csignal>
1211
1212 namespace ms = mir::scene;
1213-using namespace miral;
1214
1215 // Based on "Mir and Unity: Surfaces, input, and displays (v0.3)"
1216
1217-namespace
1218-{
1219-int const title_bar_height = 10;
1220-Size titlebar_size_for_window(Size window_size)
1221-{
1222- return {window_size.width, Height{title_bar_height}};
1223-}
1224-
1225-Point titlebar_position_for_window(Point window_position)
1226-{
1227- return {
1228- window_position.x,
1229- window_position.y - DeltaY(title_bar_height)
1230- };
1231-}
1232-}
1233-
1234-CanonicalWindowManagerPolicy::CanonicalWindowManagerPolicy(WindowManagerTools* const tools, SpinnerSplash const& spinner) :
1235- tools{tools}, spinner{spinner}
1236-{
1237-}
1238-
1239-void CanonicalWindowManagerPolicy::click(Point cursor)
1240+miral::CanonicalWindowManagerPolicy::CanonicalWindowManagerPolicy(WindowManagerTools* const tools) :
1241+ tools{tools}
1242+{
1243+}
1244+
1245+void miral::CanonicalWindowManagerPolicy::click(Point cursor)
1246 {
1247 if (auto const window = tools->window_at(cursor))
1248 tools->select_active_window(window);
1249 }
1250
1251-void CanonicalWindowManagerPolicy::handle_app_info_updated(Rectangles const& /*displays*/)
1252+void miral::CanonicalWindowManagerPolicy::handle_app_info_updated(Rectangles const& /*displays*/)
1253 {
1254 }
1255
1256-void CanonicalWindowManagerPolicy::handle_displays_updated(Rectangles const& displays)
1257+void miral::CanonicalWindowManagerPolicy::handle_displays_updated(Rectangles const& displays)
1258 {
1259 display_area = displays.bounding_rectangle();
1260
1261@@ -73,17 +53,16 @@
1262 {
1263 if (window)
1264 {
1265- auto const& info = tools->info_for(window);
1266+ auto& info = tools->info_for(window);
1267 Rectangle rect{window.top_left(), window.size()};
1268
1269 tools->place_in_output(info.output_id(), rect);
1270- window.move_to(rect.top_left);
1271- window.resize(rect.size);
1272+ tools->place_and_size(info, rect.top_left, rect.size);
1273 }
1274 }
1275 }
1276
1277-bool CanonicalWindowManagerPolicy::resize(Point cursor)
1278+bool miral::CanonicalWindowManagerPolicy::resize(Point cursor)
1279 {
1280 if (!resizing)
1281 tools->select_active_window(tools->window_at(old_cursor));
1282@@ -91,423 +70,38 @@
1283 }
1284
1285
1286-auto CanonicalWindowManagerPolicy::place_new_surface(
1287- miral::ApplicationInfo const& app_info,
1288+auto miral::CanonicalWindowManagerPolicy::place_new_surface(
1289+ miral::ApplicationInfo const& /*app_info*/,
1290 miral::WindowSpecification const& request_parameters)
1291 -> miral::WindowSpecification
1292 {
1293- auto parameters = request_parameters;
1294- auto surf_type = parameters.type().is_set() ? parameters.type().value() : mir_surface_type_normal;
1295- bool const needs_titlebar = WindowInfo::needs_titlebar(surf_type);
1296-
1297- if (needs_titlebar)
1298- parameters.size() = Size{parameters.size().value().width, parameters.size().value().height + DeltaY{title_bar_height}};
1299-
1300- if (!parameters.state().is_set())
1301- parameters.state() = mir_surface_state_restored;
1302-
1303- auto const active_display = tools->active_display();
1304-
1305- auto const width = parameters.size().value().width.as_int();
1306- auto const height = parameters.size().value().height.as_int();
1307-
1308- bool positioned = false;
1309-
1310- bool const has_parent{parameters.parent().is_set() && parameters.parent().value().lock()};
1311-
1312- if (parameters.output_id().is_set() && parameters.output_id().value() != 0)
1313- {
1314- Rectangle rect{parameters.top_left().value(), parameters.size().value()};
1315- tools->place_in_output(parameters.output_id().value(), rect);
1316- parameters.top_left() = rect.top_left;
1317- parameters.size() = rect.size;
1318- parameters.state() = mir_surface_state_fullscreen;
1319- positioned = true;
1320- }
1321- else if (!has_parent) // No parent => client can't suggest positioning
1322- {
1323- if (app_info.windows().size() > 0)
1324- {
1325- if (auto const default_window = app_info.windows()[0])
1326- {
1327- static Displacement const offset{title_bar_height, title_bar_height};
1328-
1329- parameters.top_left() = default_window.top_left() + offset;
1330-
1331- Rectangle display_for_app{default_window.top_left(), default_window.size()};
1332-
1333- tools->size_to_output(display_for_app);
1334-
1335- positioned = display_for_app.overlaps(Rectangle{parameters.top_left().value(), parameters.size().value()});
1336- }
1337- }
1338- }
1339-
1340- if (has_parent && parameters.aux_rect().is_set() && parameters.edge_attachment().is_set())
1341- {
1342- auto parent = tools->info_for(parameters.parent().value()).window();
1343-
1344- auto const edge_attachment = parameters.edge_attachment().value();
1345- auto const aux_rect = parameters.aux_rect().value();
1346- auto const parent_top_left = parent.top_left();
1347- auto const top_left = aux_rect.top_left -Point{} + parent_top_left;
1348- auto const top_right= aux_rect.top_right() -Point{} + parent_top_left;
1349- auto const bot_left = aux_rect.bottom_left()-Point{} + parent_top_left;
1350-
1351- if (edge_attachment & mir_edge_attachment_vertical)
1352- {
1353- if (active_display.contains(top_right + Displacement{width, height}))
1354- {
1355- parameters.top_left() = top_right;
1356- positioned = true;
1357- }
1358- else if (active_display.contains(top_left + Displacement{-width, height}))
1359- {
1360- parameters.top_left() = top_left + Displacement{-width, 0};
1361- positioned = true;
1362- }
1363- }
1364-
1365- if (edge_attachment & mir_edge_attachment_horizontal)
1366- {
1367- if (active_display.contains(bot_left + Displacement{width, height}))
1368- {
1369- parameters.top_left() = bot_left;
1370- positioned = true;
1371- }
1372- else if (active_display.contains(top_left + Displacement{width, -height}))
1373- {
1374- parameters.top_left() = top_left + Displacement{0, -height};
1375- positioned = true;
1376- }
1377- }
1378- }
1379- else if (has_parent)
1380- {
1381- auto parent = tools->info_for(parameters.parent().value()).window();
1382- // o Otherwise, if the dialog is not the same as any previous dialog for the
1383- // same parent window, and/or it does not have user-customized position:
1384- // o It should be optically centered relative to its parent, unless this
1385- // would overlap or cover the title bar of the parent.
1386- // o Otherwise, it should be cascaded vertically (but not horizontally)
1387- // relative to its parent, unless, this would cause at least part of
1388- // it to extend into shell space.
1389- auto const parent_top_left = parent.top_left();
1390- auto const centred = parent_top_left
1391- + 0.5*(as_displacement(parent.size()) - as_displacement(parameters.size().value()))
1392- - DeltaY{(parent.size().height.as_int()-height)/6};
1393-
1394- parameters.top_left() = centred;
1395- positioned = true;
1396- }
1397-
1398- if (!positioned)
1399- {
1400- auto centred = active_display.top_left
1401- + 0.5*(as_displacement(active_display.size) - as_displacement(parameters.size().value()))
1402- - DeltaY{(active_display.size.height.as_int()-height)/6};
1403-
1404- switch (parameters.state().value())
1405- {
1406- case mir_surface_state_fullscreen:
1407- case mir_surface_state_maximized:
1408- parameters.top_left() = active_display.top_left;
1409- parameters.size() = active_display.size;
1410- break;
1411-
1412- case mir_surface_state_vertmaximized:
1413- centred.y = active_display.top_left.y;
1414- parameters.top_left() = centred;
1415- parameters.size() = Size{parameters.size().value().width, active_display.size.height};
1416- break;
1417-
1418- case mir_surface_state_horizmaximized:
1419- centred.x = active_display.top_left.x;
1420- parameters.top_left() = centred;
1421- parameters.size() = Size{active_display.size.width, parameters.size().value().height};
1422- break;
1423-
1424- default:
1425- parameters.top_left() = centred;
1426- }
1427-
1428- if (parameters.top_left().value().y < display_area.top_left.y)
1429- parameters.top_left() = Point{parameters.top_left().value().x, display_area.top_left.y};
1430- }
1431-
1432- if (parameters.state().value() != mir_surface_state_fullscreen && needs_titlebar)
1433- {
1434- parameters.top_left() = Point{parameters.top_left().value().x, parameters.top_left().value().y + DeltaY{title_bar_height}};
1435- parameters.size() = Size{parameters.size().value().width, parameters.size().value().height - DeltaY{title_bar_height}};
1436- }
1437-
1438- return parameters;
1439-}
1440-
1441-void CanonicalWindowManagerPolicy::generate_decorations_for(WindowInfo& window_info)
1442-{
1443- Window const& window = window_info.window();
1444-
1445- if (!window_info.needs_titlebar(window_info.type()))
1446- return;
1447-
1448- auto format = mir_pixel_format_xrgb_8888;
1449- WindowSpecification params;
1450- params.size() = titlebar_size_for_window(window.size());
1451- params.name() = "decoration";
1452- params.pixel_format() = format;
1453- params.buffer_usage() = WindowSpecification::BufferUsage::software;
1454- params.top_left() = titlebar_position_for_window(window.top_left());
1455- params.type() = mir_surface_type_gloss;
1456-
1457- auto& titlebar_info = tools->build_window(window.application(), params);
1458- titlebar_info.window().set_alpha(0.9);
1459- titlebar_info.parent(window);
1460-
1461- auto data = std::make_shared<CanonicalWindowManagementPolicyData>(titlebar_info.window());
1462- window_info.userdata(data);
1463- window_info.add_child(titlebar_info.window());
1464-}
1465-
1466-void CanonicalWindowManagerPolicy::advise_new_window(WindowInfo& window_info)
1467+ return request_parameters;
1468+}
1469+
1470+void miral::CanonicalWindowManagerPolicy::advise_new_window(WindowInfo& window_info)
1471 {
1472 if (window_info.state() == mir_surface_state_fullscreen)
1473 fullscreen_surfaces.insert(window_info.window());
1474-
1475- generate_decorations_for(window_info);
1476 }
1477
1478-void CanonicalWindowManagerPolicy::handle_window_ready(WindowInfo& window_info)
1479+void miral::CanonicalWindowManagerPolicy::handle_window_ready(WindowInfo& window_info)
1480 {
1481 tools->select_active_window(window_info.window());
1482 }
1483
1484-void CanonicalWindowManagerPolicy::handle_modify_window(
1485+void miral::CanonicalWindowManagerPolicy::handle_modify_window(
1486 WindowInfo& window_info,
1487 WindowSpecification const& modifications)
1488 {
1489- auto window_info_tmp = window_info;
1490-
1491-#define COPY_IF_SET(field)\
1492- if (modifications.field().is_set())\
1493- window_info_tmp.field(modifications.field().value())
1494-
1495- COPY_IF_SET(type);
1496- COPY_IF_SET(min_width);
1497- COPY_IF_SET(min_height);
1498- COPY_IF_SET(max_width);
1499- COPY_IF_SET(max_height);
1500- COPY_IF_SET(width_inc);
1501- COPY_IF_SET(height_inc);
1502- COPY_IF_SET(min_aspect);
1503- COPY_IF_SET(max_aspect);
1504- COPY_IF_SET(output_id);
1505- COPY_IF_SET(preferred_orientation);
1506-
1507-#undef COPY_IF_SET
1508-
1509- if (modifications.parent().is_set())
1510- window_info_tmp.parent(tools->info_for(modifications.parent().value()).window());
1511-
1512- if (window_info.type() != window_info_tmp.type())
1513- {
1514- auto const new_type = window_info_tmp.type();
1515-
1516- if (!window_info.can_morph_to(new_type))
1517- {
1518- throw std::runtime_error("Unsupported window type change");
1519- }
1520-
1521- if (window_info_tmp.must_not_have_parent())
1522- {
1523- if (modifications.parent().is_set())
1524- throw std::runtime_error("Target window type does not support parent");
1525-
1526- window_info_tmp.parent({});
1527- }
1528- else if (window_info_tmp.must_have_parent())
1529- {
1530- if (!window_info_tmp.parent())
1531- throw std::runtime_error("Target window type requires parent");
1532- }
1533- }
1534-
1535- std::swap(window_info_tmp, window_info);
1536-
1537- auto& window = window_info.window();
1538-
1539- if (window_info.type() != window_info_tmp.type())
1540- window.set_type(window_info.type());
1541-
1542- if (window_info.parent() != window_info_tmp.parent())
1543- {
1544- if (window_info_tmp.parent())
1545- {
1546- auto& parent_info = tools->info_for(window_info_tmp.parent());
1547- parent_info.remove_child(window);
1548- }
1549-
1550- if (window_info.parent())
1551- {
1552- auto& parent_info = tools->info_for(window_info.parent());
1553- parent_info.add_child(window);
1554- }
1555- }
1556-
1557- if (modifications.name().is_set())
1558- window.rename(modifications.name().value());
1559-
1560- if (modifications.streams().is_set())
1561- window.configure_streams(modifications.streams().value());
1562-
1563- if (modifications.input_shape().is_set())
1564- window.set_input_region(modifications.input_shape().value());
1565-
1566- if (modifications.size().is_set())
1567- {
1568- apply_resize(window_info, window.top_left(), modifications.size().value());
1569- }
1570- else if (modifications.min_width().is_set() || modifications.min_height().is_set() ||
1571- modifications.max_width().is_set() || modifications.max_height().is_set() ||
1572- modifications.width_inc().is_set() || modifications.height_inc().is_set())
1573- {
1574- apply_resize(window_info, window.top_left(), window.size());
1575- }
1576-
1577- if (modifications.state().is_set())
1578- apply_set_state(window_info, modifications.state().value());
1579+ tools->modify_window(window_info, modifications);
1580 }
1581
1582-void CanonicalWindowManagerPolicy::advise_delete_window(WindowInfo const& window_info)
1583+void miral::CanonicalWindowManagerPolicy::advise_delete_window(WindowInfo const& window_info)
1584 {
1585 fullscreen_surfaces.erase(window_info.window());
1586-
1587- if (auto const titlebar = std::static_pointer_cast<CanonicalWindowManagementPolicyData>(window_info.userdata()))
1588- {
1589- tools->destroy(titlebar->window);
1590- }
1591-}
1592-
1593-void CanonicalWindowManagerPolicy::apply_set_state(WindowInfo& window_info, MirSurfaceState value)
1594-{
1595- switch (value)
1596- {
1597- case mir_surface_state_restored:
1598- case mir_surface_state_maximized:
1599- case mir_surface_state_vertmaximized:
1600- case mir_surface_state_horizmaximized:
1601- case mir_surface_state_fullscreen:
1602- case mir_surface_state_hidden:
1603- case mir_surface_state_minimized:
1604- break;
1605-
1606- default:
1607- window_info.window().set_state(window_info.state());
1608- return;
1609- }
1610-
1611- if (window_info.state() == mir_surface_state_restored)
1612- {
1613- window_info.restore_rect({window_info.window().top_left(), window_info.window().size()});
1614- }
1615-
1616- if (window_info.state() != mir_surface_state_fullscreen)
1617- {
1618- window_info.output_id({});
1619- fullscreen_surfaces.erase(window_info.window());
1620- }
1621- else
1622- {
1623- fullscreen_surfaces.insert(window_info.window());
1624- }
1625-
1626- if (window_info.state() == value)
1627- {
1628- return;
1629- }
1630-
1631- auto const old_pos = window_info.window().top_left();
1632- Displacement movement;
1633-
1634- switch (value)
1635- {
1636- case mir_surface_state_restored:
1637- movement = window_info.restore_rect().top_left - old_pos;
1638- window_info.window().resize(window_info.restore_rect().size);
1639- if (auto const titlebar = std::static_pointer_cast<CanonicalWindowManagementPolicyData>(window_info.userdata()))
1640- {
1641- titlebar->window.resize(titlebar_size_for_window(window_info.restore_rect().size));
1642- titlebar->window.show();
1643- }
1644- break;
1645-
1646- case mir_surface_state_maximized:
1647- movement = display_area.top_left - old_pos;
1648- window_info.window().resize(display_area.size);
1649- if (auto const titlebar = std::static_pointer_cast<CanonicalWindowManagementPolicyData>(window_info.userdata()))
1650- titlebar->window.hide();
1651- break;
1652-
1653- case mir_surface_state_horizmaximized:
1654- movement = Point{display_area.top_left.x, window_info.restore_rect().top_left.y} - old_pos;
1655- window_info.window().resize({display_area.size.width, window_info.restore_rect().size.height});
1656- if (auto const titlebar = std::static_pointer_cast<CanonicalWindowManagementPolicyData>(window_info.userdata()))
1657- {
1658- titlebar->window.resize(titlebar_size_for_window({display_area.size.width, window_info.restore_rect().size.height}));
1659- titlebar->window.show();
1660- }
1661- break;
1662-
1663- case mir_surface_state_vertmaximized:
1664- movement = Point{window_info.restore_rect().top_left.x, display_area.top_left.y} - old_pos;
1665- window_info.window().resize({window_info.restore_rect().size.width, display_area.size.height});
1666- if (auto const titlebar = std::static_pointer_cast<CanonicalWindowManagementPolicyData>(window_info.userdata()))
1667- titlebar->window.hide();
1668- break;
1669-
1670- case mir_surface_state_fullscreen:
1671- {
1672- Rectangle rect{old_pos, window_info.window().size()};
1673-
1674- if (window_info.has_output_id())
1675- {
1676- tools->place_in_output(window_info.output_id(), rect);
1677- }
1678- else
1679- {
1680- tools->size_to_output(rect);
1681- }
1682-
1683- movement = rect.top_left - old_pos;
1684- window_info.window().resize(rect.size);
1685- break;
1686- }
1687-
1688- case mir_surface_state_hidden:
1689- case mir_surface_state_minimized:
1690- if (auto const titlebar = std::static_pointer_cast<CanonicalWindowManagementPolicyData>(window_info.userdata()))
1691- titlebar->window.hide();
1692- window_info.window().hide();
1693- window_info.state(value);
1694- window_info.window().set_state(window_info.state());
1695- return;
1696-
1697- default:
1698- break;
1699- }
1700-
1701- tools->move_tree(window_info, movement);
1702-
1703- window_info.state(value);
1704-
1705- if (window_info.is_visible())
1706- window_info.window().show();
1707-
1708- window_info.window().set_state(window_info.state());
1709- return;
1710-}
1711-
1712-void CanonicalWindowManagerPolicy::drag(Point cursor)
1713+}
1714+
1715+void miral::CanonicalWindowManagerPolicy::drag(Point cursor)
1716 {
1717 if (auto const target = tools->window_at(old_cursor))
1718 {
1719@@ -516,12 +110,12 @@
1720 }
1721 }
1722
1723-void CanonicalWindowManagerPolicy::handle_raise_window(WindowInfo& window_info)
1724+void miral::CanonicalWindowManagerPolicy::handle_raise_window(WindowInfo& window_info)
1725 {
1726 tools->select_active_window(window_info.window());
1727 }
1728
1729-bool CanonicalWindowManagerPolicy::handle_keyboard_event(MirKeyboardEvent const* event)
1730+bool miral::CanonicalWindowManagerPolicy::handle_keyboard_event(MirKeyboardEvent const* event)
1731 {
1732 auto const action = mir_keyboard_event_action(event);
1733 auto const scan_code = mir_keyboard_event_scan_code(event);
1734@@ -585,7 +179,7 @@
1735 return false;
1736 }
1737
1738-bool CanonicalWindowManagerPolicy::handle_touch_event(MirTouchEvent const* event)
1739+bool miral::CanonicalWindowManagerPolicy::handle_touch_event(MirTouchEvent const* event)
1740 {
1741 auto const count = mir_touch_event_point_count(event);
1742
1743@@ -642,7 +236,7 @@
1744 return consumes_event;
1745 }
1746
1747-bool CanonicalWindowManagerPolicy::handle_pointer_event(MirPointerEvent const* event)
1748+bool miral::CanonicalWindowManagerPolicy::handle_pointer_event(MirPointerEvent const* event)
1749 {
1750 auto const action = mir_pointer_event_action(event);
1751 auto const modifiers = mir_pointer_event_modifiers(event) & modifier_mask;
1752@@ -672,35 +266,13 @@
1753 consumes_event = true;
1754 }
1755 }
1756- else if (action == mir_pointer_action_motion && !modifiers)
1757- {
1758- if (mir_pointer_event_button_state(event, mir_pointer_button_primary))
1759- {
1760- // TODO this is a rather roundabout way to detect a titlebar
1761- if (auto const possible_titlebar = tools->window_at(old_cursor))
1762- {
1763- if (auto const parent = tools->info_for(possible_titlebar).parent())
1764- {
1765- if (auto const& parent_userdata =
1766- std::static_pointer_cast<CanonicalWindowManagementPolicyData>(tools->info_for(parent).userdata()))
1767- {
1768- if (possible_titlebar == parent_userdata->window)
1769- {
1770- drag(cursor);
1771- consumes_event = true;
1772- }
1773- }
1774- }
1775- }
1776- }
1777- }
1778
1779 resizing = resize_event;
1780 old_cursor = cursor;
1781 return consumes_event;
1782 }
1783
1784-void CanonicalWindowManagerPolicy::toggle(MirSurfaceState state)
1785+void miral::CanonicalWindowManagerPolicy::toggle(MirSurfaceState state)
1786 {
1787 if (auto const window = tools->active_window())
1788 {
1789@@ -709,34 +281,20 @@
1790 if (info.state() == state)
1791 state = mir_surface_state_restored;
1792
1793- apply_set_state(info, state);
1794+ tools->set_state(info, state);
1795 }
1796 }
1797
1798-void CanonicalWindowManagerPolicy::advise_focus_gained(WindowInfo const& info)
1799+void miral::CanonicalWindowManagerPolicy::advise_focus_gained(WindowInfo const& info)
1800 {
1801 tools->raise_tree(info.window());
1802-
1803- if (auto const titlebar = std::static_pointer_cast<CanonicalWindowManagementPolicyData>(info.userdata()))
1804- titlebar->paint_titlebar(0xFF);
1805-
1806- // Frig to force the spinner to the top
1807- if (auto const spinner_session = spinner.session())
1808- {
1809- auto const& spinner_info = tools->info_for(spinner_session);
1810-
1811- if (spinner_info.windows().size() > 0)
1812- tools->raise_tree(spinner_info.windows()[0]);
1813- }
1814 }
1815
1816-void CanonicalWindowManagerPolicy::advise_focus_lost(WindowInfo const& info)
1817+void miral::CanonicalWindowManagerPolicy::advise_focus_lost(WindowInfo const& /*info*/)
1818 {
1819- if (auto const titlebar = std::static_pointer_cast<CanonicalWindowManagementPolicyData>(info.userdata()))
1820- titlebar->paint_titlebar(0x3F);
1821 }
1822
1823-bool CanonicalWindowManagerPolicy::resize(Window const& window, Point cursor, Point old_cursor)
1824+bool miral::CanonicalWindowManagerPolicy::resize(Window const& window, Point cursor, Point old_cursor)
1825 {
1826 if (!window)
1827 return false;
1828@@ -794,20 +352,24 @@
1829 Size new_size{new_width, new_height};
1830 Point new_pos = top_left + left_resize*delta.dx + top_resize*delta.dy;
1831
1832- apply_resize(window_info, new_pos, new_size);
1833+ window_info.constrain_resize(new_pos, new_size);
1834+ tools->place_and_size(window_info, new_pos, new_size);
1835
1836 return true;
1837 }
1838
1839-void CanonicalWindowManagerPolicy::apply_resize(WindowInfo& window_info, Point new_pos, Size new_size) const
1840-{
1841- window_info.constrain_resize(new_pos, new_size);
1842-
1843- if (auto const titlebar = std::static_pointer_cast<CanonicalWindowManagementPolicyData>(window_info.userdata()))
1844- titlebar->window.resize({new_size.width, Height{title_bar_height}});
1845-
1846- window_info.window().resize(new_size);
1847-
1848- tools->move_tree(window_info, new_pos - window_info.window().top_left());
1849-}
1850-
1851+void miral::CanonicalWindowManagerPolicy::advise_state_change(WindowInfo const& window_info, MirSurfaceState state)
1852+{
1853+ if (state != mir_surface_state_fullscreen)
1854+ {
1855+ fullscreen_surfaces.erase(window_info.window());
1856+ }
1857+ else
1858+ {
1859+ fullscreen_surfaces.insert(window_info.window());
1860+ }
1861+}
1862+
1863+void miral::CanonicalWindowManagerPolicy::advise_resize(WindowInfo const& /*window_info*/, Size const& /*new_size*/)
1864+{
1865+}
1866
1867=== modified file 'miral/window.cpp'
1868--- miral/window.cpp 2016-04-29 13:34:54 +0000
1869+++ miral/window.cpp 2016-06-03 15:27:17 +0000
1870@@ -91,11 +91,6 @@
1871 surface->hide();
1872 }
1873
1874-void miral::Window::reset()
1875-{
1876- self.reset();
1877-}
1878-
1879 void miral::Window::set_state(MirSurfaceState state)
1880 {
1881 if (!self) return;
1882@@ -103,13 +98,6 @@
1883 surface->configure(mir_surface_attrib_state, state);
1884 }
1885
1886-void miral::Window::set_type(MirSurfaceType type)
1887-{
1888- if (!self) return;
1889- if (auto const surface = self->surface.lock())
1890- surface->configure(mir_surface_attrib_type, type);
1891-}
1892-
1893 void miral::Window::move_to(mir::geometry::Point top_left)
1894 {
1895 if (!self) return;
1896@@ -200,20 +188,6 @@
1897 }
1898 }
1899
1900-void miral::Window::set_input_region(std::vector<mir::geometry::Rectangle> const& input_rectangles)
1901-{
1902- if (!self) return;
1903- if (auto const surface = self->surface.lock())
1904- surface->set_input_region(input_rectangles);
1905-}
1906-
1907-void miral::Window::rename(std::string const& name)
1908-{
1909- if (!self) return;
1910- if (auto const surface = self->surface.lock())
1911- surface->rename(name);
1912-}
1913-
1914 bool miral::operator==(Window const& lhs, Window const& rhs)
1915 {
1916 return lhs.self == rhs.self;

Subscribers

People subscribed via source and target branches