2
* Copyright (C) 2016 Canonical, Ltd.
4
* This program is free software: you can redistribute it and/or modify it under
5
* the terms of the GNU Lesser General Public License version 3, as published by
6
* the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful, but WITHOUT
9
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10
* SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
* Lesser General Public License for more details.
13
* You should have received a copy of the GNU Lesser General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
#include "windowmanagementpolicy.h"
19
#include "screensmodel.h"
21
#include "miral/window_manager_tools.h"
22
#include "miral/window_specification.h"
24
#include <mir/scene/surface.h>
27
WindowManagementPolicy::WindowManagementPolicy(const miral::WindowManagerTools &tools,
28
qtmir::WindowModelNotifier &windowModel,
29
qtmir::WindowController &windowController,
30
const QSharedPointer<ScreensModel> screensModel)
31
: CanonicalWindowManagerPolicy(tools)
33
, m_windowModel(windowModel)
34
, m_eventFeeder(new QtEventFeeder(screensModel))
36
windowController.setPolicy(this);
39
/* Following are hooks to allow custom policy be imposed */
40
miral::WindowSpecification WindowManagementPolicy::place_new_surface(
41
const miral::ApplicationInfo &app_info,
42
const miral::WindowSpecification &request_parameters)
44
auto parameters = CanonicalWindowManagerPolicy::place_new_surface(app_info, request_parameters);
45
qDebug() << "Place surface" << parameters.top_left().value().x.as_int();
49
void WindowManagementPolicy::handle_window_ready(miral::WindowInfo &windowInfo)
51
qDebug("Window Ready");
52
CanonicalWindowManagerPolicy::handle_window_ready(windowInfo);
55
void WindowManagementPolicy::handle_modify_window(
56
miral::WindowInfo &windowInfo,
57
const miral::WindowSpecification &modifications)
59
qDebug("Window Modified!");
60
CanonicalWindowManagerPolicy::handle_modify_window(windowInfo, modifications);
63
void WindowManagementPolicy::handle_raise_window(miral::WindowInfo &windowInfo)
65
qDebug("Window Raise");
66
CanonicalWindowManagerPolicy::handle_raise_window(windowInfo);
69
/* Handle input events - here just inject them into Qt event loop for later processing */
70
bool WindowManagementPolicy::handle_keyboard_event(const MirKeyboardEvent *event)
72
m_eventFeeder->dispatchKey(event);
76
bool WindowManagementPolicy::handle_touch_event(const MirTouchEvent *event)
78
m_eventFeeder->dispatchTouch(event);
82
bool WindowManagementPolicy::handle_pointer_event(const MirPointerEvent *event)
84
m_eventFeeder->dispatchPointer(event);
88
void WindowManagementPolicy::advise_new_window(const miral::WindowInfo &windowInfo)
90
// TODO: attach surface observer here
91
std::string persistentId = m_tools.id_for_window(windowInfo.window());
93
m_windowModel.addWindow(windowInfo, persistentId);
96
void WindowManagementPolicy::advise_delete_window(const miral::WindowInfo &windowInfo)
98
m_windowModel.removeWindow(windowInfo);
101
void WindowManagementPolicy::advise_raise(const std::vector<miral::Window> &windows)
103
m_windowModel.raiseWindows(windows);
106
void WindowManagementPolicy::advise_new_app(miral::ApplicationInfo &/*application*/)
111
void WindowManagementPolicy::advise_delete_app(const miral::ApplicationInfo &/*application*/)
113
qDebug("Delete App");
116
void WindowManagementPolicy::advise_state_change(const miral::WindowInfo &/*windowInfo*/, MirSurfaceState /*state*/)
118
qDebug("Window State Change");
121
void WindowManagementPolicy::advise_move_to(const miral::WindowInfo &windowInfo, Point topLeft)
123
qDebug("Window Moved to (%d, %d)", topLeft.x.as_int(), topLeft.y.as_int());
124
m_windowModel.moveWindow(windowInfo, topLeft);
127
void WindowManagementPolicy::advise_resize(const miral::WindowInfo &windowInfo, const Size &newSize)
129
qDebug("Window Resized to %dx%d", newSize.width.as_int(), newSize.height.as_int());
130
m_windowModel.resizeWindow(windowInfo, newSize);
133
void WindowManagementPolicy::advise_focus_lost(const miral::WindowInfo &windowInfo)
135
m_windowModel.focusWindow(windowInfo, false);
138
void WindowManagementPolicy::advise_focus_gained(const miral::WindowInfo &windowInfo)
140
// update Qt model ASAP, before applying Mir policy
141
m_windowModel.focusWindow(windowInfo, true);
143
CanonicalWindowManagerPolicy::advise_focus_gained(windowInfo);
146
void WindowManagementPolicy::advise_begin()
151
void WindowManagementPolicy::advise_end()
156
/* Following methods all called from the Qt GUI thread to deliver events to clients */
157
void WindowManagementPolicy::deliver_keyboard_event(const MirKeyboardEvent *event,
158
const miral::Window &window)
160
m_tools.invoke_under_lock([&window, this]() {
161
m_tools.select_active_window(window);
163
auto e = reinterpret_cast<MirEvent const*>(event); // naughty
165
if (auto surface = std::weak_ptr<mir::scene::Surface>(window).lock()) {
170
void WindowManagementPolicy::deliver_touch_event(const MirTouchEvent *event,
171
const miral::Window &window)
173
m_tools.invoke_under_lock([&window, this]() {
174
m_tools.select_active_window(window);
176
auto e = reinterpret_cast<MirEvent const*>(event); // naughty
178
if (auto surface = std::weak_ptr<mir::scene::Surface>(window).lock()) {
183
void WindowManagementPolicy::deliver_pointer_event(const MirPointerEvent *event,
184
const miral::Window &window)
186
// Prevent mouse hover events causing window focus to change
187
if (mir_pointer_event_action(event) == mir_pointer_action_button_down) {
188
m_tools.invoke_under_lock([&window, this]() {
189
m_tools.select_active_window(window);
192
auto e = reinterpret_cast<MirEvent const*>(event); // naughty
194
if (auto surface = std::weak_ptr<mir::scene::Surface>(window).lock()) {
199
/* Methods to allow Shell to request changes to the window stack. Called from the Qt GUI thread */
200
void WindowManagementPolicy::focus(const miral::Window &window)
202
m_tools.invoke_under_lock([&window, this]() {
203
m_tools.select_active_window(window);
207
void WindowManagementPolicy::resize(const miral::Window &window, const Size size)
209
miral::WindowSpecification modifications;
210
modifications.size() = size;
211
m_tools.invoke_under_lock([&window, &modifications, this]() {
212
m_tools.modify_window(m_tools.info_for(window), modifications);
216
void WindowManagementPolicy::move(const miral::Window &window, const Point topLeft)
218
miral::WindowSpecification modifications;
219
modifications.top_left() = topLeft;
220
m_tools.invoke_under_lock([&window, &modifications, this]() {
221
m_tools.modify_window(m_tools.info_for(window), modifications);
225
void WindowManagementPolicy::ask_client_to_close(const miral::Window &window)
227
m_tools.invoke_under_lock([&window, this]() {
228
m_tools.ask_client_to_close(window);