Merge lp:~alan-griffiths/qtmir/introducing-QtmirWindowManagementPolicy into lp:qtmir

Proposed by Alan Griffiths
Status: Rejected
Rejected by: Alan Griffiths
Proposed branch: lp:~alan-griffiths/qtmir/introducing-QtmirWindowManagementPolicy
Merge into: lp:qtmir
Prerequisite: lp:~alan-griffiths/qtmir/import-WindowManagement-code-from-Mir-examples
Diff against target: 601 lines (+309/-135)
5 files modified
src/platforms/mirserver/CMakeLists.txt (+18/-5)
src/platforms/mirserver/mirserver.cpp (+5/-3)
src/platforms/mirserver/mirwindowmanager.cpp (+242/-122)
src/platforms/mirserver/mirwindowmanager.h (+23/-4)
tests/mirserver/WindowManager/window_manager.cpp (+21/-1)
To merge this branch: bzr merge lp:~alan-griffiths/qtmir/introducing-QtmirWindowManagementPolicy
Reviewer Review Type Date Requested Status
Unity8 CI Bot (community) continuous-integration Needs Fixing
PS Jenkins bot (community) continuous-integration Needs Fixing
Daniel d'Andrada (community) Abstain
Review via email: mp+278736@code.launchpad.net

Commit message

Wire up the draft Window Management framework to a (currently trivial) QtmirWindowManagementPolicy

Description of the change

Wire up the draft Window Management framework to a (currently trivial) QtmirWindowManagementPolicy

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

"""
void QtmirWindowManagementPolicy::generate_decorations_for(
"""

Why would Mir or even QtMir have anything to do with window decorations?

review: Needs Information
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

Don't think this approach is top-down enough. Looks too disconnected with unity8's/QML "reality". It should probably start in unity8, changing the mock implementations of the interfaces it use to talk to QtMir and the interfaces themselves (Unity.Application presently). Once you have something that makes sense over there then you move down to QtMir to write the real implementation of it. Then you propose the unity8, unity-api and qtmir branches in tandem.

Afterall, if I got the plan right, the idea is that QtMir provides unity8 with a tree of surfaces which unity8 them wraps or syncs with QML items in the QML scene.

Otherwise you run the risk of laboring something in QtMir just to find out later that it's unusable in practice, up in unity8.

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

> """
> void QtmirWindowManagementPolicy::generate_decorations_for(
> """
>
> Why would Mir or even QtMir have anything to do with window decorations?

If as you suggest QtMir does not have anything to do with window decorations this function can keep the proposed null implementation. However, other clients of Mir *do* work with decorations. E.g. mir_demo_server and mir_proving_server draw titlebars.

Alternatively, we can come up with a more general approach then we can change the code here and port it back to Mir.

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

On 27/11/2015 08:18, Alan Griffiths wrote:
>> """
>> void QtmirWindowManagementPolicy::generate_decorations_for(
>> """
>>
>> Why would Mir or even QtMir have anything to do with window decorations?
> If as you suggest QtMir does not have anything to do with window decorations this function can keep the proposed null implementation. However, other clients of Mir *do* work with decorations. E.g. mir_demo_server and mir_proving_server draw titlebars.
>
> Alternatively, we can come up with a more general approach then we can change the code here and port it back to Mir.

But those barebones pure Mir+OpenGL are not very realistic examples of
shell implementations (apart from, maybe, some dumb kiosks or the like).
Any minimally complex shell will likely use a toolkit to help out with
animations etc. And they most likely have their own scene
implementation, like Qt/QML.

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

> But those barebones pure Mir+OpenGL are not very realistic examples of
> shell implementations (apart from, maybe, some dumb kiosks or the like).
> Any minimally complex shell will likely use a toolkit to help out with
> animations etc. And they most likely have their own scene
> implementation, like Qt/QML.

There are a lot of "dumb kiosks" about and that's a valid usecase for Mir (possibly with only S/W rendering).

While I understand these scenarios are of little interest to Unity8, the cost of supporting them is small: a vtab entry for this trivial function (which doesn't even need to be exposed by qtmir).

Revision history for this message
Daniel d'Andrada (dandrader) :
review: Abstain
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:419
https://unity8-jenkins.ubuntu.com/job/lp-qtmir-1-ci/7/
Executed test runs:

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:420
https://unity8-jenkins.ubuntu.com/job/lp-qtmir-1-ci/19/
Executed test runs:

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

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
421. By Alan Griffiths

Resolve merge better

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

FAILED: Continuous integration, rev:421
https://unity8-jenkins.ubuntu.com/job/lp-qtmir-1-ci/20/
Executed test runs:

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

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:422
https://unity8-jenkins.ubuntu.com/job/lp-qtmir-1-ci/27/
Executed test runs:

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

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
423. By Alan Griffiths

Rather brutal merge\ lp:qtmir

424. By Alan Griffiths

TODO{arg} comments to flage stuff that needs sorting

425. By Alan Griffiths

Refactor to get all of the state and most of the logic out of MirWindowManagerImpl

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

> """
> void QtmirWindowManagementPolicy::generate_decorations_for(
> """
>
> Why would Mir or even QtMir have anything to do with window decorations?

Having thought about this some more - the need for this customization point in the Mir examples comes from the rather inelegant way that surfaces get constructed.

It's far from trivial to clean up without breaking downstream code, but getting everything to use a common structure (so as to deprecate legacy mechanisms) will help.

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

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

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

review: Approve (continuous-integration)
426. By Alan Griffiths

merge lp:qtmir and resolve conflicts

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

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

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

review: Approve (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)

Unmerged revisions

426. By Alan Griffiths

merge lp:qtmir and resolve conflicts

425. By Alan Griffiths

Refactor to get all of the state and most of the logic out of MirWindowManagerImpl

424. By Alan Griffiths

TODO{arg} comments to flage stuff that needs sorting

423. By Alan Griffiths

Rather brutal merge\ lp:qtmir

422. By Alan Griffiths

merge lp:~alan-griffiths/qtmir/import-WindowManagement-code-from-Mir-examples/

421. By Alan Griffiths

Resolve merge better

420. By Alan Griffiths

merge lp:~alan-griffiths/qtmir/import-WindowManagement-code-from-Mir-examples

419. By Alan Griffiths

Introducing QtmirWindowManagementPolicy

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/platforms/mirserver/CMakeLists.txt'
2--- src/platforms/mirserver/CMakeLists.txt 2016-03-10 09:28:57 +0000
3+++ src/platforms/mirserver/CMakeLists.txt 2016-03-14 09:55:02 +0000
4@@ -17,11 +17,23 @@
5 list(APPEND QT5_PLATFORMSUPPORT_INCLUDE_DIRS ${newitem})
6 endforeach(item ${Qt5Gui_PRIVATE_INCLUDE_DIRS})
7
8+# Use the local copy of the work-in-progress Window Management code.
9+# (Will remove this once Mir support is published.)
10+set(QTMIR_USE_WINDOW_MANAGEMENT_WIP on)
11+
12 include_directories(
13- ${CMAKE_SOURCE_DIR}/src/common
14-
15 ${MIRCOMMON_INCLUDE_DIRS}
16 ${MIRSERVER_INCLUDE_DIRS}
17+)
18+
19+if (QTMIR_USE_WINDOW_MANAGEMENT_WIP)
20+add_subdirectory(wm-wip)
21+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/wm-wip)
22+endif()
23+
24+include_directories(
25+ ${CMAKE_SOURCE_DIR}/src/common
26+
27 ${MIRRENDERERGLDEV_INCLUDE_DIRS}
28
29 ${URL_DISPATCHER_INCLUDE_DIRS}
30@@ -36,8 +48,6 @@
31 ${APPLICATION_API_INCLUDE_DIRS}
32 )
33
34-add_subdirectory(wm-wip)
35-
36 # We have to remove -pedantic for tracepoints.c
37 string (REPLACE " -pedantic " " " CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
38 # Needed to compile tracepoints in C99 mode.
39@@ -82,9 +92,12 @@
40 ${MIRSERVER_QPA_PLUGIN_SRC}
41 )
42
43+if (QTMIR_USE_WINDOW_MANAGEMENT_WIP)
44+target_link_libraries(qpa-mirserver experimentalwindowmanager)
45+endif()
46+
47 target_link_libraries(
48 qpa-mirserver
49-
50 ${MIRSERVER_LDFLAGS}
51 ${MIRCLIENT_LDFLAGS}
52 ${URL_DISPATCHER_LDFLAGS}
53
54=== modified file 'src/platforms/mirserver/mirserver.cpp'
55--- src/platforms/mirserver/mirserver.cpp 2016-02-15 17:18:08 +0000
56+++ src/platforms/mirserver/mirserver.cpp 2016-03-14 09:55:02 +0000
57@@ -107,11 +107,13 @@
58 return std::make_shared<MirServerStatusListener>();
59 });
60
61- override_the_window_manager_builder([this](mir::shell::FocusController*)
62+ override_the_window_manager_builder([this](mir::shell::FocusController* focus_controller)
63 -> std::shared_ptr<mir::shell::WindowManager>
64 {
65- auto windowManager = MirWindowManager::create(the_shell_display_layout(),
66- std::static_pointer_cast<::SessionListener>(the_session_listener()));
67+ std::shared_ptr<MirWindowManager> const windowManager{MirWindowManager::create(focus_controller,
68+ the_shell_display_layout(),
69+ std::static_pointer_cast<::SessionListener>(the_session_listener()))};
70+
71 m_windowManager = windowManager;
72 return windowManager;
73 });
74
75=== modified file 'src/platforms/mirserver/mirwindowmanager.cpp'
76--- src/platforms/mirserver/mirwindowmanager.cpp 2016-02-11 11:58:16 +0000
77+++ src/platforms/mirserver/mirwindowmanager.cpp 2016-03-14 09:55:02 +0000
78@@ -1,5 +1,5 @@
79 /*
80- * Copyright (C) 2015 Canonical, Ltd.
81+ * Copyright (C) 2015-2016 Canonical, Ltd.
82 *
83 * This program is free software: you can redistribute it and/or modify it under
84 * the terms of the GNU Lesser General Public License version 3, as published by
85@@ -24,36 +24,49 @@
86 #include <mir/scene/surface_creation_parameters.h>
87 #include <mir/scene/surface.h>
88 #include <mir/shell/display_layout.h>
89+#include <mir/shell/surface_ready_observer.h>
90+
91+#include "server_example_basic_window_manager.h"
92
93 #include <QMutexLocker>
94
95+namespace me = mir::examples;
96+namespace mf = mir::frontend;
97 namespace ms = mir::scene;
98+namespace msh = mir::shell;
99+using namespace mir::geometry;
100
101 namespace
102 {
103-class MirWindowManagerImpl : public MirWindowManager
104+class QtmirWindowManagementPolicy : public me::WindowManagementPolicy
105 {
106 public:
107
108- MirWindowManagerImpl(const std::shared_ptr<mir::shell::DisplayLayout> &displayLayout,
109- std::shared_ptr<::SessionListener> sessionListener);
110-
111- void add_session(std::shared_ptr<mir::scene::Session> const& session) override;
112-
113- void remove_session(std::shared_ptr<mir::scene::Session> const& session) override;
114-
115- mir::frontend::SurfaceId add_surface(
116- std::shared_ptr<mir::scene::Session> const& session,
117- mir::scene::SurfaceCreationParameters const& params,
118- std::function<mir::frontend::SurfaceId(std::shared_ptr<mir::scene::Session> const& session, mir::scene::SurfaceCreationParameters const& params)> const& build) override;
119-
120- void remove_surface(
121- std::shared_ptr<mir::scene::Session> const& session,
122- std::weak_ptr<mir::scene::Surface> const& surface) override;
123-
124- void add_display(mir::geometry::Rectangle const& area) override;
125-
126- void remove_display(mir::geometry::Rectangle const& area) override;
127+ explicit QtmirWindowManagementPolicy(
128+ me::WindowManagerTools* const tools,
129+ std::shared_ptr<msh::DisplayLayout> const& display_layout,
130+ std::shared_ptr<::SessionListener> const& session_listener,
131+ qtmir::WindowManagementAdvisor* advisor);
132+
133+ void handle_session_info_updated(SessionInfoMap& session_info, Rectangles const& displays) override;
134+
135+ void handle_displays_updated(SessionInfoMap& session_info, Rectangles const& displays) override;
136+
137+ auto handle_place_new_surface(
138+ std::shared_ptr<ms::Session> const& session,
139+ ms::SurfaceCreationParameters const& request_parameters)
140+ -> ms::SurfaceCreationParameters override;
141+
142+ void handle_new_surface(std::shared_ptr<ms::Session> const& session, std::shared_ptr<ms::Surface> const& surface) override;
143+
144+ void handle_modify_surface(
145+ std::shared_ptr<ms::Session> const& session,
146+ std::shared_ptr<ms::Surface> const& surface,
147+ msh::SurfaceSpecification const& modifications) override;
148+
149+ void handle_delete_surface(std::shared_ptr<ms::Session> const& session, std::weak_ptr<ms::Surface> const& surface) override;
150+
151+ int handle_set_state(std::shared_ptr<ms::Surface> const& surface, MirSurfaceState value) override;
152
153 bool handle_keyboard_event(MirKeyboardEvent const* event) override;
154
155@@ -61,132 +74,165 @@
156
157 bool handle_pointer_event(MirPointerEvent const* event) override;
158
159- int set_surface_attribute(
160- std::shared_ptr<mir::scene::Session> const& session,
161- std::shared_ptr<mir::scene::Surface> const& surface,
162- MirSurfaceAttrib attrib,
163- int value) override;
164-
165 void handle_raise_surface(
166+ std::shared_ptr<ms::Session> const& session,
167+ std::shared_ptr<ms::Surface> const& surface) override;
168+
169+ void generate_decorations_for(
170+ std::shared_ptr<ms::Session> const& session,
171+ std::shared_ptr<ms::Surface> const& surface,
172+ SurfaceInfoMap& surface_map,
173+ std::function<mir::frontend::SurfaceId(std::shared_ptr<ms::Session> const& session, ms::SurfaceCreationParameters const& params)> const& build) override;
174+
175+private:
176+ static const int modifier_mask =
177+ mir_input_event_modifier_alt |
178+ mir_input_event_modifier_shift |
179+ mir_input_event_modifier_sym |
180+ mir_input_event_modifier_ctrl |
181+ mir_input_event_modifier_meta;
182+
183+ me::WindowManagerTools* const tools;
184+ std::shared_ptr<msh::DisplayLayout> const display_layout;
185+ std::shared_ptr<::SessionListener> const session_listener;
186+ qtmir::WindowManagementAdvisor* const advisor;
187+};
188+
189+template <typename Target>
190+inline Target implicit_cast(Target target) { return target; }
191+
192+// TODO This is likely not the best place to implement WindowManagementAdvisor
193+// but it works for now, and avoids re-plumbing the MirWindowManager Q_SIGNAL
194+class MirWindowManagerImpl : public MirWindowManager,
195+ public me::WindowManagerBuilder<QtmirWindowManagementPolicy>,
196+ qtmir::WindowManagementAdvisor
197+{
198+public:
199+
200+ template <typename... PolicyArgs>
201+ MirWindowManagerImpl(msh::FocusController* focus_controller, PolicyArgs&&... policy_args) :
202+ me::WindowManagerBuilder<QtmirWindowManagementPolicy>(
203+ focus_controller,
204+ std::forward<PolicyArgs>(policy_args)...,
205+ implicit_cast<qtmir::WindowManagementAdvisor*>(this))
206+ {
207+ }
208+
209+private:
210+ mir::scene::SurfaceCreationParameters proposePlacementForNewSurface(
211+ mir::scene::SurfaceCreationParameters const &params,
212 std::shared_ptr<mir::scene::Session> const& session,
213- std::shared_ptr<mir::scene::Surface> const& surface,
214- uint64_t timestamp) override;
215-
216- void modify_surface(
217- const std::shared_ptr<mir::scene::Session>&,
218- const std::shared_ptr<mir::scene::Surface>& surface,
219- const mir::shell::SurfaceSpecification& modifications) override;
220-
221-private:
222- std::shared_ptr<mir::shell::DisplayLayout> const m_displayLayout;
223- std::shared_ptr<::SessionListener> m_sessionListener;
224+ mir::shell::DisplayLayout &displayLayout,
225+ ::SessionListener &sessionListener) override;
226 };
227
228 }
229
230-MirWindowManagerImpl::MirWindowManagerImpl(const std::shared_ptr<mir::shell::DisplayLayout> &displayLayout,
231- std::shared_ptr<::SessionListener> sessionListener) :
232- m_displayLayout{displayLayout},
233- m_sessionListener(sessionListener)
234-{
235- qCDebug(QTMIR_MIR_MESSAGES) << "MirWindowManagerImpl::MirWindowManagerImpl";
236-}
237-
238-void MirWindowManagerImpl::add_session(std::shared_ptr<ms::Session> const& /*session*/)
239-{
240-}
241-
242-void MirWindowManagerImpl::remove_session(std::shared_ptr<ms::Session> const& /*session*/)
243-{
244-}
245-
246-mir::frontend::SurfaceId MirWindowManagerImpl::add_surface(
247- std::shared_ptr<ms::Session> const& session,
248- ms::SurfaceCreationParameters const& requestParameters,
249- std::function<mir::frontend::SurfaceId(std::shared_ptr<ms::Session> const& session, ms::SurfaceCreationParameters const& params)> const& build)
250-{
251+mir::scene::SurfaceCreationParameters MirWindowManagerImpl::proposePlacementForNewSurface(
252+ mir::scene::SurfaceCreationParameters const &request_parameters,
253+ std::shared_ptr<mir::scene::Session> const& session,
254+ mir::shell::DisplayLayout &displayLayout,
255+ ::SessionListener &sessionListener)
256+{
257+ auto placedParameters = request_parameters;
258+
259 tracepoint(qtmirserver, surfacePlacementStart);
260
261- m_sessionListener->surfaceAboutToBeCreated(*session.get(), qtmir::SizeHints(requestParameters));
262+ sessionListener.surfaceAboutToBeCreated(*session.get(), qtmir::SizeHints(request_parameters));
263
264 QSize initialSize;
265 // can be connected to via Qt::BlockingQueuedConnection to alter surface initial size
266 {
267- int surfaceType = requestParameters.type.is_set() ? requestParameters.type.value() : -1;
268+ int surfaceType = request_parameters.type.is_set() ? request_parameters.type.value() : -1;
269 Q_EMIT sessionAboutToCreateSurface(session, surfaceType, initialSize);
270 }
271- ms::SurfaceCreationParameters placedParameters = requestParameters;
272
273 if (initialSize.isValid()) {
274 placedParameters.size.width = mir::geometry::Width(initialSize.width());
275 placedParameters.size.height = mir::geometry::Height(initialSize.height());
276 } else {
277 qCWarning(QTMIR_MIR_MESSAGES) << "MirWindowManagerImpl::add_surface(): didn't get a initial surface"
278- " size from shell. Falling back to fullscreen placement";
279+ " size from shell. Falling back to fullscreen placement";
280 // This is bad. Fallback to fullscreen
281- mir::geometry::Rectangle rect{requestParameters.top_left, requestParameters.size};
282- m_displayLayout->size_to_output(rect);
283+ mir::geometry::Rectangle rect{request_parameters.top_left, request_parameters.size};
284+ displayLayout.size_to_output(rect);
285 placedParameters.size = rect.size;
286 }
287
288-
289- qCDebug(QTMIR_MIR_MESSAGES) << "MirWindowManagerImpl::add_surface(): size requested ("
290- << requestParameters.size.width.as_int() << "," << requestParameters.size.height.as_int() << ") and placed ("
291+ qCDebug(QTMIR_MIR_MESSAGES) << "CanonicalWindowManagerPolicy::handle_place_new_surface(): size requested ("
292+ << request_parameters.size.width.as_int() << "," << request_parameters.size.height.as_int() << ") and placed ("
293 << placedParameters.size.width.as_int() << "," << placedParameters.size.height.as_int() << ")";
294
295 tracepoint(qtmirserver, surfacePlacementEnd);
296
297- return build(session, placedParameters);
298-}
299-
300-void MirWindowManagerImpl::remove_surface(
301- std::shared_ptr<ms::Session> const& /*session*/,
302- std::weak_ptr<ms::Surface> const& /*surface*/)
303-{
304-}
305-
306-void MirWindowManagerImpl::add_display(mir::geometry::Rectangle const& /*area*/)
307-{
308-}
309-
310-void MirWindowManagerImpl::remove_display(mir::geometry::Rectangle const& /*area*/)
311-{
312-}
313-
314-bool MirWindowManagerImpl::handle_keyboard_event(MirKeyboardEvent const* /*event*/)
315-{
316- return false;
317-}
318-
319-bool MirWindowManagerImpl::handle_touch_event(MirTouchEvent const* /*event*/)
320-{
321- return false;
322-}
323-
324-bool MirWindowManagerImpl::handle_pointer_event(MirPointerEvent const* /*event*/)
325-{
326- return false;
327-}
328-
329-void MirWindowManagerImpl::handle_raise_surface(
330- std::shared_ptr<mir::scene::Session> const& /*session*/,
331- std::shared_ptr<mir::scene::Surface> const& /*surface*/,
332- uint64_t /*timestamp*/)
333-{
334-}
335-
336-int MirWindowManagerImpl::set_surface_attribute(
337+ return placedParameters;
338+}
339+
340+std::unique_ptr<MirWindowManager> MirWindowManager::create(
341+ msh::FocusController* focus_controller,
342+ const std::shared_ptr<msh::DisplayLayout> &displayLayout,
343+ const std::shared_ptr<::SessionListener> &sessionListener)
344+{
345+ return std::make_unique<MirWindowManagerImpl>(focus_controller, displayLayout, sessionListener);
346+}
347+
348+QtmirWindowManagementPolicy::QtmirWindowManagementPolicy(
349+ me::WindowManagerTools* const tools,
350+ std::shared_ptr<msh::DisplayLayout> const& display_layout,
351+ std::shared_ptr<::SessionListener> const& session_listener,
352+ qtmir::WindowManagementAdvisor* advisor) :
353+ tools(tools),
354+ display_layout(display_layout),
355+ session_listener(session_listener),
356+ advisor(advisor)
357+{
358+}
359+
360+void QtmirWindowManagementPolicy::handle_session_info_updated(SessionInfoMap& /*session_info*/, Rectangles const& /*displays*/)
361+{
362+}
363+
364+void QtmirWindowManagementPolicy::handle_displays_updated(SessionInfoMap& /*session_info*/, Rectangles const& /*displays*/)
365+{
366+}
367+
368+auto QtmirWindowManagementPolicy::handle_place_new_surface(
369+ std::shared_ptr<ms::Session> const& session,
370+ ms::SurfaceCreationParameters const& parameters)
371+-> ms::SurfaceCreationParameters
372+{
373+ return advisor->proposePlacementForNewSurface(parameters, session, *display_layout, *session_listener);
374+}
375+
376+void QtmirWindowManagementPolicy::handle_new_surface(std::shared_ptr<ms::Session> const& session, std::shared_ptr<ms::Surface> const& surface)
377+{
378+ auto& surface_info = tools->info_for(surface);
379+ if (auto const parent = surface_info.parent.lock())
380+ {
381+ tools->info_for(parent).children.push_back(surface);
382+ }
383+
384+ tools->info_for(session).surfaces.push_back(surface);
385+
386+ if (surface_info.can_be_active())
387+ {
388+ surface->add_observer(
389+ std::make_shared<msh::SurfaceReadyObserver>(
390+ [this](
391+ std::shared_ptr<ms::Session> const& /*session*/,
392+ std::shared_ptr<ms::Surface> const& /*surface*/)
393+ {
394+ // TODO select_active_surface(surface);
395+ },
396+ session,
397+ surface));
398+ }
399+}
400+
401+void QtmirWindowManagementPolicy::handle_modify_surface(
402 std::shared_ptr<ms::Session> const& /*session*/,
403 std::shared_ptr<ms::Surface> const& surface,
404- MirSurfaceAttrib attrib,
405- int value)
406-{
407- return surface->configure(attrib, value);
408-}
409-
410-void MirWindowManagerImpl::modify_surface(const std::shared_ptr<mir::scene::Session>&,
411- const std::shared_ptr<mir::scene::Surface>& surface,
412- const mir::shell::SurfaceSpecification& modifications)
413+ msh::SurfaceSpecification const& modifications)
414 {
415 if (modifications.name.is_set()) {
416 surface->rename(modifications.name.value());
417@@ -199,9 +245,83 @@
418 }
419 }
420
421-std::shared_ptr<MirWindowManager> MirWindowManager::create(
422- const std::shared_ptr<mir::shell::DisplayLayout> &displayLayout,
423- std::shared_ptr<::SessionListener> sessionListener)
424-{
425- return std::make_shared<MirWindowManagerImpl>(displayLayout, sessionListener);
426+void QtmirWindowManagementPolicy::handle_delete_surface(std::shared_ptr<ms::Session> const& session, std::weak_ptr<ms::Surface> const& surface)
427+{
428+ auto& info = tools->info_for(surface);
429+
430+ if (auto const parent = info.parent.lock())
431+ {
432+ auto& siblings = tools->info_for(parent).children;
433+
434+ for (auto i = begin(siblings); i != end(siblings); ++i)
435+ {
436+ if (surface.lock() == i->lock())
437+ {
438+ siblings.erase(i);
439+ break;
440+ }
441+ }
442+ }
443+
444+ session->destroy_surface(surface);
445+
446+ if (info.titlebar)
447+ {
448+ session->destroy_surface(info.titlebar_id);
449+ tools->forget(info.titlebar);
450+ }
451+
452+ auto& surfaces = tools->info_for(session).surfaces;
453+
454+ for (auto i = begin(surfaces); i != end(surfaces); ++i)
455+ {
456+ if (surface.lock() == i->lock())
457+ {
458+ surfaces.erase(i);
459+ break;
460+ }
461+ }
462+
463+ if (surfaces.empty() && session == tools->focused_session())
464+ {
465+// active_surface_.reset();
466+ tools->focus_next_session();
467+// select_active_surface(tools->focused_surface());
468+ }
469+}
470+
471+int QtmirWindowManagementPolicy::handle_set_state(std::shared_ptr<ms::Surface> const& surface, MirSurfaceState value)
472+{
473+ auto& info = tools->info_for(surface);
474+ return info.state = value;
475+}
476+
477+bool QtmirWindowManagementPolicy::handle_keyboard_event(MirKeyboardEvent const* /*event*/)
478+{
479+ return false;
480+}
481+
482+bool QtmirWindowManagementPolicy::handle_touch_event(MirTouchEvent const* /*event*/)
483+{
484+ return false;
485+}
486+
487+bool QtmirWindowManagementPolicy::handle_pointer_event(MirPointerEvent const* /*event*/)
488+{
489+ return false;
490+}
491+
492+void QtmirWindowManagementPolicy::handle_raise_surface(
493+ std::shared_ptr<ms::Session> const& /*session*/,
494+ std::shared_ptr<ms::Surface> const& /*surface*/)
495+{
496+
497+}
498+
499+void QtmirWindowManagementPolicy::generate_decorations_for(
500+ std::shared_ptr<ms::Session> const& /*session*/,
501+ std::shared_ptr<ms::Surface> const& /*surface*/,
502+ SurfaceInfoMap& /*surface_map*/,
503+ std::function<mir::frontend::SurfaceId(std::shared_ptr<ms::Session> const& session, ms::SurfaceCreationParameters const& params)> const& /*build*/)
504+{
505 }
506
507=== modified file 'src/platforms/mirserver/mirwindowmanager.h'
508--- src/platforms/mirserver/mirwindowmanager.h 2016-02-15 17:18:08 +0000
509+++ src/platforms/mirserver/mirwindowmanager.h 2016-03-14 09:55:02 +0000
510@@ -1,5 +1,5 @@
511 /*
512- * Copyright (C) 2015 Canonical, Ltd.
513+ * Copyright (C) 2015-2016 Canonical, Ltd.
514 *
515 * This program is free software: you can redistribute it and/or modify it under
516 * the terms of the GNU Lesser General Public License version 3, as published by
517@@ -31,14 +31,33 @@
518 }
519 }
520
521-class MirWindowManager : public QObject, public mir::shell::WindowManager
522+namespace qtmir
523+{
524+class WindowManagementAdvisor
525+{
526+public:
527+ virtual mir::scene::SurfaceCreationParameters proposePlacementForNewSurface(
528+ mir::scene::SurfaceCreationParameters const &params,
529+ std::shared_ptr<mir::scene::Session> const& session,
530+ mir::shell::DisplayLayout &displayLayout,
531+ ::SessionListener &sessionListener) = 0;
532+
533+ WindowManagementAdvisor() = default;
534+ virtual ~WindowManagementAdvisor() = default;
535+ WindowManagementAdvisor(WindowManagementAdvisor const&) = delete;
536+ WindowManagementAdvisor& operator=(WindowManagementAdvisor const&) = delete;
537+};
538+}
539+
540+class MirWindowManager : public QObject, public virtual mir::shell::WindowManager
541 {
542 Q_OBJECT
543
544 public:
545- static std::shared_ptr<MirWindowManager> create(
546+ static std::unique_ptr<MirWindowManager> create(
547+ mir::shell::FocusController* focus_controller,
548 const std::shared_ptr<mir::shell::DisplayLayout> &displayLayout,
549- std::shared_ptr<::SessionListener> sessionListener);
550+ std::shared_ptr<::SessionListener> const& sessionListener);
551
552 Q_SIGNALS:
553 // requires Qt::BlockingQueuedConnection!!
554
555=== modified file 'tests/mirserver/WindowManager/window_manager.cpp'
556--- tests/mirserver/WindowManager/window_manager.cpp 2016-02-11 11:58:16 +0000
557+++ tests/mirserver/WindowManager/window_manager.cpp 2016-03-14 09:55:02 +0000
558@@ -22,6 +22,7 @@
559 #include <mir/events/event_builders.h>
560 #include <mir/scene/surface_creation_parameters.h>
561 #include <mir/shell/display_layout.h>
562+#include <mir/shell/focus_controller.h>
563
564 #include "gtest/gtest.h"
565 #include "gmock/gmock.h"
566@@ -54,15 +55,34 @@
567 MOCK_CONST_METHOD1(surface, std::shared_ptr<ms::Surface> (mir::frontend::SurfaceId surface));
568 };
569
570+struct StubFocusController : msh::FocusController
571+{
572+public:
573+ void focus_next_session() override {}
574+
575+ std::shared_ptr<ms::Session> focused_session() const override { return {}; }
576+
577+ void set_focus_to(
578+ std::shared_ptr<ms::Session> const& /*focus_session*/,
579+ std::shared_ptr<ms::Surface> const& /*focus_surface*/) override {}
580+
581+ std::shared_ptr<ms::Surface> focused_surface() const override { return {}; }
582+
583+ std::shared_ptr<ms::Surface> surface_at(Point /*cursor*/) const override { return {}; }
584+
585+ void raise(msh::SurfaceSet const& /*surfaces*/) override {}
586+};
587+
588 struct WindowManager : Test
589 {
590 const std::shared_ptr<MockDisplayLayout> mock_display_layout =
591 std::make_shared<NiceMock<MockDisplayLayout>>();
592
593+ StubFocusController focus_controller;
594 std::shared_ptr<SessionListener> sessionListener = std::make_shared<SessionListener>();
595
596 const std::shared_ptr<MirWindowManager> window_manager =
597- MirWindowManager::create(mock_display_layout, sessionListener);
598+ MirWindowManager::create(&focus_controller, mock_display_layout, sessionListener);
599
600 const Rectangle arbitrary_display{{0, 0}, {97, 101}};
601 const std::shared_ptr<MockSession> arbitrary_session = std::make_shared<NiceMock<MockSession>>();

Subscribers

People subscribed via source and target branches