~lukas-kde/miral/shellchrome-windowinfo

« back to all changes in this revision

Viewing changes to miral-qt/src/modules/Unity/Application/sessionmanager.cpp

  • Committer: Larry Price
  • Date: 2016-09-13 16:19:29 UTC
  • mto: (330.4.1 miral)
  • mto: This revision was merged to the branch mainline in revision 352.
  • Revision ID: larry.price@canonical.com-20160913161929-vs9ka1capmljq1es
Removing miral-qt from release branch, updating copyright file, and adding GPL3 license to root dir

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2014-2016 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
 
// Qt
18
 
#include <QGuiApplication>
19
 
 
20
 
// local
21
 
#include "application_manager.h"
22
 
#include "debughelpers.h"
23
 
#include "sessionmanager.h"
24
 
 
25
 
// QPA mirserver
26
 
#include "nativeinterface.h"
27
 
#include "sessionlistener.h"
28
 
#include "logging.h"
29
 
#include "promptsessionlistener.h"
30
 
 
31
 
// mir
32
 
#include <mir/scene/prompt_session.h>
33
 
#include <mir/scene/prompt_session_manager.h>
34
 
#include <mir/report_exception.h>
35
 
 
36
 
namespace ms = mir::scene;
37
 
 
38
 
namespace qtmir {
39
 
 
40
 
SessionManager *SessionManager::the_session_manager = nullptr;
41
 
 
42
 
 
43
 
void connectToSessionListener(SessionManager *manager, SessionListener *listener)
44
 
{
45
 
    QObject::connect(listener, &SessionListener::sessionStarting,
46
 
                     manager, &SessionManager::onSessionStarting);
47
 
    QObject::connect(listener, &SessionListener::sessionStopping,
48
 
                     manager, &SessionManager::onSessionStopping);
49
 
}
50
 
 
51
 
void connectToPromptSessionListener(SessionManager * manager, PromptSessionListener * listener)
52
 
{
53
 
    QObject::connect(listener, &PromptSessionListener::promptSessionStarting,
54
 
                     manager, &SessionManager::onPromptSessionStarting);
55
 
    QObject::connect(listener, &PromptSessionListener::promptSessionStopping,
56
 
                     manager, &SessionManager::onPromptSessionStopping);
57
 
    QObject::connect(listener, &PromptSessionListener::promptProviderAdded,
58
 
                     manager, &SessionManager::onPromptProviderAdded);
59
 
    QObject::connect(listener, &PromptSessionListener::promptProviderRemoved,
60
 
                     manager, &SessionManager::onPromptProviderRemoved);
61
 
}
62
 
 
63
 
SessionManager* SessionManager::singleton()
64
 
try
65
 
{
66
 
    if (!the_session_manager) {
67
 
 
68
 
        NativeInterface *nativeInterface = dynamic_cast<NativeInterface*>(QGuiApplication::platformNativeInterface());
69
 
 
70
 
        if (!nativeInterface) {
71
 
            qCritical("ERROR: Unity.Application QML plugin requires use of the 'mirserver' QPA plugin");
72
 
            QGuiApplication::quit();
73
 
            return nullptr;
74
 
        }
75
 
 
76
 
        SessionListener *sessionListener = static_cast<SessionListener*>(nativeInterface->nativeResourceForIntegration("SessionListener"));
77
 
        PromptSessionListener *promptSessionListener = static_cast<PromptSessionListener*>(nativeInterface->nativeResourceForIntegration("PromptSessionListener"));
78
 
 
79
 
        the_session_manager = new SessionManager(nativeInterface->thePromptSessionManager(), ApplicationManager::singleton());
80
 
 
81
 
        connectToSessionListener(the_session_manager, sessionListener);
82
 
        connectToPromptSessionListener(the_session_manager, promptSessionListener);
83
 
    }
84
 
    return the_session_manager;
85
 
}
86
 
catch (...)
87
 
{
88
 
    // We only call mir::report_exception() here to force linkage against libmirserver.
89
 
    // Unless we force this module to have a link dependency on libmirserver we get
90
 
    // several tests hanging during link loading. I wish I understood why.    alan_g
91
 
    mir::report_exception();
92
 
    throw;
93
 
}
94
 
 
95
 
SessionManager::SessionManager(
96
 
        const std::shared_ptr<mir::scene::PromptSessionManager>& promptSessionManager,
97
 
        ApplicationManager* applicationManager,
98
 
        QObject *parent)
99
 
    : SessionModel(parent)
100
 
    , m_promptSessionManager(promptSessionManager)
101
 
    , m_applicationManager(applicationManager)
102
 
{
103
 
    qCDebug(QTMIR_SESSIONS) << "SessionManager::SessionManager - this=" << this;
104
 
    setObjectName(QStringLiteral("qtmir::SessionManager"));
105
 
}
106
 
 
107
 
SessionManager::~SessionManager()
108
 
{
109
 
    qCDebug(QTMIR_SESSIONS) << "SessionManager::~SessionManager - this=" << this;
110
 
}
111
 
 
112
 
SessionInterface *SessionManager::findSession(const mir::scene::Session* session) const
113
 
{
114
 
    if (!session) return nullptr;
115
 
 
116
 
    for (SessionInterface* child : list()) {
117
 
        if (child->session().get() == session)
118
 
            return child;
119
 
    }
120
 
    return nullptr;
121
 
}
122
 
 
123
 
void SessionManager::onSessionStarting(std::shared_ptr<mir::scene::Session> const& session)
124
 
{
125
 
    qCDebug(QTMIR_SESSIONS) << "SessionManager::onSessionStarting - sessionName=" <<  session->name().c_str();
126
 
 
127
 
    Session* qmlSession = new Session(session, m_promptSessionManager);
128
 
    insert(0, qmlSession);
129
 
 
130
 
    Application* application = m_applicationManager->findApplicationWithSession(session);
131
 
    if (application && application->state() != Application::Running) {
132
 
        application->setSession(qmlSession);
133
 
    }
134
 
    // need to remove if we've destroyed outside
135
 
    connect(qmlSession, &Session::destroyed, this, [&](QObject *item) {
136
 
        auto sessionToRemove = static_cast<Session*>(item);
137
 
        remove(sessionToRemove);
138
 
    });
139
 
 
140
 
    Q_EMIT sessionStarting(qmlSession);
141
 
}
142
 
 
143
 
void SessionManager::onSessionStopping(std::shared_ptr<mir::scene::Session> const& session)
144
 
{
145
 
    qCDebug(QTMIR_SESSIONS) << "SessionManager::onSessionStopping - sessionName=" << session->name().c_str();
146
 
 
147
 
    SessionInterface* qmlSession = findSession(session.get());
148
 
    if (!qmlSession) return;
149
 
 
150
 
    remove(qmlSession);
151
 
 
152
 
    qmlSession->setLive(false);
153
 
    Q_EMIT sessionStopping(qmlSession);
154
 
}
155
 
 
156
 
void SessionManager::onPromptSessionStarting(const std::shared_ptr<ms::PromptSession>& promptSession)
157
 
{
158
 
    qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptSessionStarting - promptSession=" << promptSession.get();
159
 
 
160
 
    std::shared_ptr<mir::scene::Session> appSession = m_promptSessionManager->application_for(promptSession);
161
 
    SessionInterface *qmlAppSession = findSession(appSession.get());
162
 
    if (qmlAppSession) {
163
 
        m_mirPromptToSessionHash[promptSession.get()] = qmlAppSession;
164
 
        qmlAppSession->appendPromptSession(promptSession);
165
 
    } else {
166
 
        qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptSessionStarting - could not find app session for prompt session";
167
 
    }
168
 
}
169
 
 
170
 
void SessionManager::onPromptSessionStopping(const std::shared_ptr<ms::PromptSession>& promptSession)
171
 
{
172
 
    qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptSessionStopping - promptSession=" << promptSession.get();
173
 
 
174
 
    for (SessionInterface *qmlSession : this->list()) {
175
 
        qmlSession->removePromptSession(promptSession);
176
 
    }
177
 
    m_mirPromptToSessionHash.remove(promptSession.get());
178
 
}
179
 
 
180
 
void SessionManager::onPromptProviderAdded(const mir::scene::PromptSession *promptSession,
181
 
                                              const std::shared_ptr<mir::scene::Session> &promptProvider)
182
 
{
183
 
    qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderAdded - promptSession=" << promptSession << " promptProvider=" << promptProvider.get();
184
 
 
185
 
    SessionInterface* qmlAppSession = m_mirPromptToSessionHash.value(promptSession, nullptr);
186
 
    if (!qmlAppSession) {
187
 
        qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderAdded - could not find session item for app session";
188
 
        return;
189
 
    }
190
 
 
191
 
    SessionInterface* qmlPromptProvider = findSession(promptProvider.get());
192
 
    if (!qmlPromptProvider) {
193
 
        qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderAdded - could not find session item for provider session";
194
 
        return;
195
 
    }
196
 
 
197
 
    qmlAppSession->addChildSession(qmlPromptProvider);
198
 
}
199
 
 
200
 
void SessionManager::onPromptProviderRemoved(const mir::scene::PromptSession *promptSession,
201
 
                                                const std::shared_ptr<mir::scene::Session> &promptProvider)
202
 
{
203
 
    qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderRemoved - promptSession=" << promptSession << " promptProvider=" << promptProvider.get();
204
 
 
205
 
    SessionInterface* qmlPromptProvider = findSession(promptProvider.get());
206
 
    if (!qmlPromptProvider) {
207
 
        qCDebug(QTMIR_SESSIONS) << "SessionManager::onPromptProviderAdded - could not find session item for provider session";
208
 
        return;
209
 
    }
210
 
    qmlPromptProvider->setLive(false);
211
 
}
212
 
 
213
 
} // namespace qtmir