2
* Copyright (C) 2015-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 "mirwindowmanager.h"
19
#include "surfaceobserver.h"
20
#include "tracepoints.h" // generated from tracepoints.tp
22
#include <mir/geometry/rectangle.h>
23
#include <mir/scene/session.h>
24
#include <mir/scene/surface_creation_parameters.h>
25
#include <mir/scene/surface.h>
26
#include <mir/shell/display_layout.h>
28
#include <QMutexLocker>
30
namespace ms = mir::scene;
34
class MirWindowManagerImpl : public MirWindowManager
38
MirWindowManagerImpl(const std::shared_ptr<mir::shell::DisplayLayout> &displayLayout,
39
std::shared_ptr<::SessionListener> sessionListener);
41
void add_session(std::shared_ptr<mir::scene::Session> const& session) override;
43
void remove_session(std::shared_ptr<mir::scene::Session> const& session) override;
45
mir::frontend::SurfaceId add_surface(
46
std::shared_ptr<mir::scene::Session> const& session,
47
mir::scene::SurfaceCreationParameters const& params,
48
std::function<mir::frontend::SurfaceId(std::shared_ptr<mir::scene::Session> const& session, mir::scene::SurfaceCreationParameters const& params)> const& build) override;
51
std::shared_ptr<mir::scene::Session> const& session,
52
std::weak_ptr<mir::scene::Surface> const& surface) override;
54
void add_display(mir::geometry::Rectangle const& area) override;
56
void remove_display(mir::geometry::Rectangle const& area) override;
58
bool handle_keyboard_event(MirKeyboardEvent const* event) override;
60
bool handle_touch_event(MirTouchEvent const* event) override;
62
bool handle_pointer_event(MirPointerEvent const* event) override;
64
int set_surface_attribute(
65
std::shared_ptr<mir::scene::Session> const& session,
66
std::shared_ptr<mir::scene::Surface> const& surface,
67
MirSurfaceAttrib attrib,
70
void handle_raise_surface(
71
std::shared_ptr<mir::scene::Session> const& session,
72
std::shared_ptr<mir::scene::Surface> const& surface,
73
uint64_t timestamp) override;
76
const std::shared_ptr<mir::scene::Session>&,
77
const std::shared_ptr<mir::scene::Surface>& surface,
78
const mir::shell::SurfaceSpecification& modifications) override;
81
std::shared_ptr<mir::shell::DisplayLayout> const m_displayLayout;
82
std::shared_ptr<::SessionListener> m_sessionListener;
87
MirWindowManagerImpl::MirWindowManagerImpl(const std::shared_ptr<mir::shell::DisplayLayout> &displayLayout,
88
std::shared_ptr<::SessionListener> sessionListener) :
89
m_displayLayout{displayLayout},
90
m_sessionListener(sessionListener)
92
qCDebug(QTMIR_MIR_MESSAGES) << "MirWindowManagerImpl::MirWindowManagerImpl";
95
void MirWindowManagerImpl::add_session(std::shared_ptr<ms::Session> const& /*session*/)
99
void MirWindowManagerImpl::remove_session(std::shared_ptr<ms::Session> const& /*session*/)
103
mir::frontend::SurfaceId MirWindowManagerImpl::add_surface(
104
std::shared_ptr<ms::Session> const& session,
105
ms::SurfaceCreationParameters const& requestParameters,
106
std::function<mir::frontend::SurfaceId(std::shared_ptr<ms::Session> const& session, ms::SurfaceCreationParameters const& params)> const& build)
108
tracepoint(qtmirserver, surfacePlacementStart);
110
m_sessionListener->surfaceAboutToBeCreated(*session.get(), qtmir::CreationHints(requestParameters));
113
// can be connected to via Qt::BlockingQueuedConnection to alter surface initial size
115
int surfaceType = requestParameters.type.is_set() ? requestParameters.type.value() : -1;
116
Q_EMIT sessionAboutToCreateSurface(session, surfaceType, initialSize);
118
ms::SurfaceCreationParameters placedParameters = requestParameters;
120
if (initialSize.isValid()) {
121
placedParameters.size.width = mir::geometry::Width(initialSize.width());
122
placedParameters.size.height = mir::geometry::Height(initialSize.height());
124
qCWarning(QTMIR_MIR_MESSAGES) << "MirWindowManagerImpl::add_surface(): didn't get a initial surface"
125
" size from shell. Falling back to fullscreen placement";
126
// This is bad. Fallback to fullscreen
127
mir::geometry::Rectangle rect{requestParameters.top_left, requestParameters.size};
128
m_displayLayout->size_to_output(rect);
129
placedParameters.size = rect.size;
133
qCDebug(QTMIR_MIR_MESSAGES) << "MirWindowManagerImpl::add_surface(): size requested ("
134
<< requestParameters.size.width.as_int() << "," << requestParameters.size.height.as_int() << ") and placed ("
135
<< placedParameters.size.width.as_int() << "," << placedParameters.size.height.as_int() << ")";
137
tracepoint(qtmirserver, surfacePlacementEnd);
139
auto const result = build(session, placedParameters);
140
auto const surface = session->surface(result);
145
void MirWindowManagerImpl::remove_surface(
146
std::shared_ptr<ms::Session> const& session,
147
std::weak_ptr<ms::Surface> const& surface)
149
// Called when the client releases the surface, usually is response to a surface->close()
151
// Just destroy straight away as we already have code to gracefully handle surfaces being
152
// detroyed out of the blue (set the QML Surface::live to false and so on).
153
session->destroy_surface(surface);
156
void MirWindowManagerImpl::add_display(mir::geometry::Rectangle const& /*area*/)
160
void MirWindowManagerImpl::remove_display(mir::geometry::Rectangle const& /*area*/)
164
bool MirWindowManagerImpl::handle_keyboard_event(MirKeyboardEvent const* /*event*/)
169
bool MirWindowManagerImpl::handle_touch_event(MirTouchEvent const* /*event*/)
174
bool MirWindowManagerImpl::handle_pointer_event(MirPointerEvent const* /*event*/)
179
void MirWindowManagerImpl::handle_raise_surface(
180
std::shared_ptr<mir::scene::Session> const& /*session*/,
181
std::shared_ptr<mir::scene::Surface> const& /*surface*/,
182
uint64_t /*timestamp*/)
186
int MirWindowManagerImpl::set_surface_attribute(
187
std::shared_ptr<ms::Session> const& /*session*/,
188
std::shared_ptr<ms::Surface> const& surface,
189
MirSurfaceAttrib attrib,
192
return surface->configure(attrib, value);
195
void MirWindowManagerImpl::modify_surface(const std::shared_ptr<mir::scene::Session>&,
196
const std::shared_ptr<mir::scene::Surface>& surface,
197
const mir::shell::SurfaceSpecification& modifications)
199
QMutexLocker(&SurfaceObserver::mutex);
200
SurfaceObserver *observer = SurfaceObserver::observerForSurface(surface.get());
202
observer->notifySurfaceModifications(modifications);
205
if (modifications.name.is_set()) {
206
surface->rename(modifications.name.value());
210
std::shared_ptr<MirWindowManager> MirWindowManager::create(
211
const std::shared_ptr<mir::shell::DisplayLayout> &displayLayout,
212
std::shared_ptr<::SessionListener> sessionListener)
214
return std::make_shared<MirWindowManagerImpl>(displayLayout, sessionListener);