~mir-team/qtmir/trunk

« back to all changes in this revision

Viewing changes to src/modules/Unity/Application/mirsurfacemanager.cpp

  • Committer: Bileto Bot
  • Author(s): Albert Astals Cid, Gerry Boland
  • Date: 2017-03-20 21:15:13 UTC
  • mfrom: (606.4.12 make_sure_surface_not_null)
  • Revision ID: ci-train-bot@canonical.com-20170320211513-z7v3z0ldes3gtcc0
Check for find() result not being null before using it

We do it in onWindowReady, onWindowMoved, onWindowFocusChanged, etc so no reason to not do it in onWindowRemoved

Approved by: Lukáš Tinkl, Unity8 CI Bot

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2013-2015 Canonical, Ltd.
3
 
 *
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.
7
 
 *
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.
12
 
 *
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/>.
15
 
 */
16
 
 
17
 
#include "mirsurfacemanager.h"
18
 
 
19
 
// Qt
20
 
#include <QGuiApplication>
21
 
#include <QMutexLocker>
22
 
 
23
 
// local
24
 
#include "mirsurface.h"
25
 
#include "sessionmanager.h"
26
 
#include "application_manager.h"
27
 
#include "tracepoints.h" // generated from tracepoints.tp
28
 
 
29
 
// common
30
 
#include <debughelpers.h>
31
 
 
32
 
// QPA mirserver
33
 
#include "nativeinterface.h"
34
 
#include "mirserver.h"
35
 
#include "sessionlistener.h"
36
 
#include "logging.h"
37
 
 
38
 
Q_LOGGING_CATEGORY(QTMIR_SURFACES, "qtmir.surfaces")
39
 
 
40
 
namespace ms = mir::scene;
41
 
 
42
 
namespace qtmir {
43
 
 
44
 
MirSurfaceManager *MirSurfaceManager::instance = nullptr;
45
 
 
46
 
 
47
 
void connectToSessionListener(MirSurfaceManager *manager, SessionListener *listener)
48
 
{
49
 
    QObject::connect(listener, &SessionListener::sessionCreatedSurface,
50
 
                     manager, &MirSurfaceManager::onSessionCreatedSurface);
51
 
    QObject::connect(listener, &SessionListener::sessionDestroyingSurface,
52
 
                     manager, &MirSurfaceManager::onSessionDestroyingSurface);
53
 
}
54
 
 
55
 
MirSurfaceManager* MirSurfaceManager::singleton()
56
 
{
57
 
    if (!instance) {
58
 
 
59
 
        NativeInterface *nativeInterface = dynamic_cast<NativeInterface*>(QGuiApplication::platformNativeInterface());
60
 
 
61
 
        if (!nativeInterface) {
62
 
            qCritical("ERROR: Unity.Application QML plugin requires use of the 'mirserver' QPA plugin");
63
 
            QGuiApplication::quit();
64
 
            return nullptr;
65
 
        }
66
 
 
67
 
        SessionListener *sessionListener = static_cast<SessionListener*>(nativeInterface->nativeResourceForIntegration("SessionListener"));
68
 
        MirShell *shell = static_cast<MirShell*>(nativeInterface->nativeResourceForIntegration("Shell"));
69
 
 
70
 
        instance = new MirSurfaceManager(nativeInterface->m_mirServer, shell, SessionManager::singleton());
71
 
 
72
 
        connectToSessionListener(instance, sessionListener);
73
 
    }
74
 
    return instance;
75
 
}
76
 
 
77
 
MirSurfaceManager::MirSurfaceManager(
78
 
        const QSharedPointer<MirServer>& mirServer,
79
 
        MirShell *shell,
80
 
        SessionManager* sessionManager,
81
 
        QObject *parent)
82
 
    : QObject(parent)
83
 
    , m_mirServer(mirServer)
84
 
    , m_shell(shell)
85
 
    , m_sessionManager(sessionManager)
86
 
{
87
 
    qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::MirSurfaceManager - this=" << this;
88
 
    setObjectName("qtmir::SurfaceManager");
89
 
}
90
 
 
91
 
MirSurfaceManager::~MirSurfaceManager()
92
 
{
93
 
    qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::~MirSurfaceManager - this=" << this;
94
 
 
95
 
    m_mirSurfaceToQmlSurfaceHash.clear();
96
 
}
97
 
 
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
 
{
102
 
    qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::onSessionCreatedSurface - mirSession=" << mirSession
103
 
                            << "surface=" << surface.get() << "surface.name=" << surface->name().c_str();
104
 
 
105
 
    SessionInterface* session = m_sessionManager->findSession(mirSession);
106
 
    auto qmlSurface = new MirSurface(surface, session, m_shell, observer);
107
 
    {
108
 
        QMutexLocker lock(&m_mutex);
109
 
        m_mirSurfaceToQmlSurfaceHash.insert(surface.get(), qmlSurface);
110
 
    }
111
 
 
112
 
    if (session)
113
 
        session->registerSurface(qmlSurface);
114
 
 
115
 
    // Only notify QML of surface creation once it has drawn its first frame.
116
 
    connect(qmlSurface, &MirSurfaceInterface::firstFrameDrawn, this, [=]() {
117
 
        tracepoint(qtmir, firstFrameDrawn);
118
 
        Q_EMIT surfaceCreated(qmlSurface);
119
 
    });
120
 
 
121
 
    // clean up after MirSurface is destroyed
122
 
    connect(qmlSurface, &QObject::destroyed, this, [&](QObject *obj) {
123
 
        auto qmlSurface = static_cast<MirSurfaceInterface*>(obj);
124
 
        {
125
 
            QMutexLocker lock(&m_mutex);
126
 
            m_mirSurfaceToQmlSurfaceHash.remove(m_mirSurfaceToQmlSurfaceHash.key(qmlSurface));
127
 
        }
128
 
 
129
 
        tracepoint(qtmir, surfaceDestroyed);
130
 
    });
131
 
    tracepoint(qtmir, surfaceCreated);
132
 
}
133
 
 
134
 
void MirSurfaceManager::onSessionDestroyingSurface(const mir::scene::Session *session,
135
 
                                                   const std::shared_ptr<mir::scene::Surface> &surface)
136
 
{
137
 
    qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::onSessionDestroyingSurface - session=" << session
138
 
                            << "surface=" << surface.get() << "surface.name=" << surface->name().c_str();
139
 
 
140
 
    MirSurfaceInterface* qmlSurface = nullptr;
141
 
    {
142
 
        QMutexLocker lock(&m_mutex);
143
 
        auto it = m_mirSurfaceToQmlSurfaceHash.find(surface.get());
144
 
        if (it != m_mirSurfaceToQmlSurfaceHash.end()) {
145
 
 
146
 
            qmlSurface = it.value();
147
 
 
148
 
            m_mirSurfaceToQmlSurfaceHash.erase(it);
149
 
        } else {
150
 
            qCritical() << "MirSurfaceManager::onSessionDestroyingSurface: unable to find MirSurface corresponding"
151
 
                        << "to surface=" << surface.get() << "surface.name=" << surface->name().c_str();
152
 
            return;
153
 
        }
154
 
    }
155
 
 
156
 
    qmlSurface->setLive(false);
157
 
    Q_EMIT surfaceDestroyed(qmlSurface);
158
 
}
159
 
 
160
 
} // namespace qtmir