2
* Copyright (C) 2013-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 "mirsurfacemanager.h"
20
#include <QGuiApplication>
21
#include <QMutexLocker>
24
#include "mirsurface.h"
25
#include "sessionmanager.h"
26
#include "application_manager.h"
27
#include "tracepoints.h" // generated from tracepoints.tp
30
#include <debughelpers.h>
33
#include "nativeinterface.h"
34
#include "sessionlistener.h"
36
#include "creationhints.h"
39
#include <mir/scene/surface.h>
42
namespace ms = mir::scene;
46
MirSurfaceManager *MirSurfaceManager::instance = nullptr;
49
void connectToSessionListener(MirSurfaceManager *manager, SessionListener *listener)
51
QObject::connect(listener, &SessionListener::sessionCreatedSurface,
52
manager, &MirSurfaceManager::onSessionCreatedSurface);
53
QObject::connect(listener, &SessionListener::sessionDestroyingSurface,
54
manager, &MirSurfaceManager::onSessionDestroyingSurface);
57
MirSurfaceManager* MirSurfaceManager::singleton()
61
NativeInterface *nativeInterface = dynamic_cast<NativeInterface*>(QGuiApplication::platformNativeInterface());
63
if (!nativeInterface) {
64
qCritical("ERROR: Unity.Application QML plugin requires use of the 'mirserver' QPA plugin");
65
QGuiApplication::quit();
69
SessionListener *sessionListener = static_cast<SessionListener*>(nativeInterface->nativeResourceForIntegration("SessionListener"));
70
mir::shell::Shell *shell = static_cast<mir::shell::Shell*>(nativeInterface->nativeResourceForIntegration("Shell"));
72
instance = new MirSurfaceManager(shell, SessionManager::singleton());
74
connectToSessionListener(instance, sessionListener);
79
MirSurfaceManager::MirSurfaceManager(
80
mir::shell::Shell* shell,
81
SessionManager* sessionManager,
85
, m_sessionManager(sessionManager)
87
qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::MirSurfaceManager - this=" << this;
88
setObjectName(QStringLiteral("qtmir::SurfaceManager"));
91
MirSurfaceManager::~MirSurfaceManager()
93
qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::~MirSurfaceManager - this=" << this;
95
m_mirSurfaceToQmlSurfaceHash.clear();
98
void MirSurfaceManager::onSessionCreatedSurface(const mir::scene::Session *mirSession,
99
const std::shared_ptr<mir::scene::Surface> &surface,
100
const std::shared_ptr<SurfaceObserver> &/*observer*/,
101
const qtmir::CreationHints &creationHints)
103
qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::onSessionCreatedSurface - mirSession=" << mirSession
104
<< "surface=" << surface.get() << "surface.name=" << surface->name().c_str()
105
<< "creationHints=" << creationHints.toString();
107
// SessionInterface* session = m_sessionManager->findSession(mirSession);
108
// auto qmlSurface = new MirSurface(surface, session, m_shell, observer, creationHints);
110
// QMutexLocker lock(&m_mutex);
111
// m_mirSurfaceToQmlSurfaceHash.insert(surface.get(), qmlSurface);
115
// session->registerSurface(qmlSurface);
117
// if (qmlSurface->type() == Mir::InputMethodType) {
118
// m_inputMethodSurface = qmlSurface;
119
// Q_EMIT inputMethodSurfaceChanged();
122
// // Only notify QML of surface creation once it has drawn its first frame.
123
// connect(qmlSurface, &MirSurfaceInterface::firstFrameDrawn, this, [=]() {
124
// tracepoint(qtmir, firstFrameDrawn);
125
// Q_EMIT surfaceCreated(qmlSurface);
128
// // clean up after MirSurface is destroyed
129
// connect(qmlSurface, &QObject::destroyed, this, [&](QObject *obj) {
130
// auto qmlSurface = static_cast<MirSurfaceInterface*>(obj);
132
// QMutexLocker lock(&m_mutex);
133
// m_mirSurfaceToQmlSurfaceHash.remove(m_mirSurfaceToQmlSurfaceHash.key(qmlSurface));
136
// tracepoint(qtmir, surfaceDestroyed);
138
// tracepoint(qtmir, surfaceCreated);
141
void MirSurfaceManager::onSessionDestroyingSurface(const mir::scene::Session *session,
142
const std::shared_ptr<mir::scene::Surface> &surface)
144
qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::onSessionDestroyingSurface - session=" << session
145
<< "surface=" << surface.get() << "surface.name=" << surface->name().c_str();
147
// MirSurfaceInterface* qmlSurface = nullptr;
149
// QMutexLocker lock(&m_mutex);
150
// auto it = m_mirSurfaceToQmlSurfaceHash.find(surface.get());
151
// if (it != m_mirSurfaceToQmlSurfaceHash.end()) {
152
// qmlSurface = it.value();
153
// m_mirSurfaceToQmlSurfaceHash.erase(it);
155
// qCritical() << "MirSurfaceManager::onSessionDestroyingSurface: unable to find MirSurface corresponding"
156
// << "to surface=" << surface.get() << "surface.name=" << surface->name().c_str();
161
// if (qmlSurface->type() == Mir::InputMethodType) {
162
// m_inputMethodSurface = nullptr;
163
// Q_EMIT inputMethodSurfaceChanged();
166
// qmlSurface->setLive(false);
167
// Q_EMIT surfaceDestroyed(qmlSurface);
170
MirSurfaceInterface* MirSurfaceManager::inputMethodSurface() const
172
return m_inputMethodSurface;