diff options
author | Gerry Boland <gerry.boland@canonical.com> | 2015-05-01 14:31:30 +0100 |
---|---|---|
committer | Gerry Boland <gerry.boland@canonical.com> | 2015-05-01 14:31:30 +0100 |
commit | c55b26f96ce02b6811f4ca86d950ddabb3d529f7 (patch) | |
tree | d310c8696f7e38e57d8f991d607ce89f0686bb7f | |
parent | b9e9716a8d7e3cc8e38e58d94622eed5a68cc302 (diff) |
[qpa] have QMirServer own the MirServer instance. Clean up the QMirServer API with view of making it public API
-rw-r--r-- | demos/qml-demo-shell/qml-demo-shell.qml | 15 | ||||
-rw-r--r-- | src/platforms/mirserver/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/platforms/mirserver/display.cpp | 7 | ||||
-rw-r--r-- | src/platforms/mirserver/display.h | 10 | ||||
-rw-r--r-- | src/platforms/mirserver/miropenglcontext.cpp | 5 | ||||
-rw-r--r-- | src/platforms/mirserver/miropenglcontext.h | 1 | ||||
-rw-r--r-- | src/platforms/mirserver/mirserverintegration.cpp | 46 | ||||
-rw-r--r-- | src/platforms/mirserver/mirserverintegration.h | 5 | ||||
-rw-r--r-- | src/platforms/mirserver/nativeinterface.cpp | 21 | ||||
-rw-r--r-- | src/platforms/mirserver/nativeinterface.h | 4 | ||||
-rw-r--r-- | src/platforms/mirserver/qmirserver.cpp | 110 | ||||
-rw-r--r-- | src/platforms/mirserver/qmirserver.h | 58 | ||||
-rw-r--r-- | src/platforms/mirserver/qmirserver_p.cpp | 58 | ||||
-rw-r--r-- | src/platforms/mirserver/qmirserver_p.h | 67 |
14 files changed, 260 insertions, 148 deletions
diff --git a/demos/qml-demo-shell/qml-demo-shell.qml b/demos/qml-demo-shell/qml-demo-shell.qml index 2a620e3..f8ed58a 100644 --- a/demos/qml-demo-shell/qml-demo-shell.qml +++ b/demos/qml-demo-shell/qml-demo-shell.qml @@ -110,6 +110,21 @@ Rectangle { y: point.y } + Rectangle { + width: 60 + height: 40 + color: "red" + anchors { right: parent.right; bottom: parent.bottom } + Text { + anchors.centerIn: parent + text: "Quit" + } + MouseArea { + anchors.fill: parent + onClicked: Qt.quit() + } + } + Connections { target: SurfaceManager onSurfaceCreated: { diff --git a/src/platforms/mirserver/CMakeLists.txt b/src/platforms/mirserver/CMakeLists.txt index 0815d3d..eb807f8 100644 --- a/src/platforms/mirserver/CMakeLists.txt +++ b/src/platforms/mirserver/CMakeLists.txt @@ -42,6 +42,7 @@ set(MIRSERVER_QPA_PLUGIN_SRC qteventfeeder.cpp plugin.cpp qmirserver.cpp + qmirserver_p.cpp sessionauthorizer.cpp sessionlistener.cpp surfaceobserver.cpp diff --git a/src/platforms/mirserver/display.cpp b/src/platforms/mirserver/display.cpp index 70a6b15..538f921 100644 --- a/src/platforms/mirserver/display.cpp +++ b/src/platforms/mirserver/display.cpp @@ -23,17 +23,14 @@ #include <mir/graphics/display.h> #include <mir/graphics/display_configuration.h> -#include <QDebug> namespace mg = mir::graphics; // TODO: Listen for display changes and update the list accordingly -Display::Display(const QSharedPointer<MirServer> &server, QObject *parent) - : QObject(parent) - , m_mirServer(server) +Display::Display(const QSharedPointer<MirServer> &server) { - std::shared_ptr<mir::graphics::DisplayConfiguration> displayConfig = m_mirServer->the_display()->configuration(); + std::shared_ptr<mir::graphics::DisplayConfiguration> displayConfig = server->the_display()->configuration(); displayConfig->for_each_output([this](mg::DisplayConfigurationOutput const& output) { if (output.used) { diff --git a/src/platforms/mirserver/display.h b/src/platforms/mirserver/display.h index 21c7767..f84a820 100644 --- a/src/platforms/mirserver/display.h +++ b/src/platforms/mirserver/display.h @@ -19,23 +19,21 @@ #ifndef DISPLAY_H #define DISPLAY_H -#include <QObject> +#include <QSharedPointer> #include <qpa/qplatformscreen.h> class MirServer; -class Display : public QObject +class Display { - Q_OBJECT public: - Display(const QSharedPointer<MirServer> &server, QObject *parent = 0); - ~Display(); + Display(const QSharedPointer<MirServer> &server); + virtual ~Display(); QList<QPlatformScreen *> screens() const { return m_screens; } private: QList<QPlatformScreen *> m_screens; - const QSharedPointer<MirServer> m_mirServer; }; #endif // DISPLAY_H diff --git a/src/platforms/mirserver/miropenglcontext.cpp b/src/platforms/mirserver/miropenglcontext.cpp index cf5ef9d..cb84666 100644 --- a/src/platforms/mirserver/miropenglcontext.cpp +++ b/src/platforms/mirserver/miropenglcontext.cpp @@ -36,12 +36,11 @@ // (i.e. individual display output buffers) to use as a common base context. MirOpenGLContext::MirOpenGLContext(const QSharedPointer<MirServer> &server, const QSurfaceFormat &format) - : m_mirServer(server) #if GL_DEBUG - , m_logger(new QOpenGLDebugLogger(this)) + : m_logger(new QOpenGLDebugLogger(this)) #endif { - std::shared_ptr<mir::graphics::Display> display = m_mirServer->the_display(); + std::shared_ptr<mir::graphics::Display> display = server->the_display(); // create a temporary GL context to fetch the EGL display and config, so Qt can determine the surface format std::unique_ptr<mir::graphics::GLContext> mirContext = display->create_gl_context(); diff --git a/src/platforms/mirserver/miropenglcontext.h b/src/platforms/mirserver/miropenglcontext.h index e09a992..de3ec9c 100644 --- a/src/platforms/mirserver/miropenglcontext.h +++ b/src/platforms/mirserver/miropenglcontext.h @@ -52,7 +52,6 @@ public: #endif private: - const QSharedPointer<MirServer> m_mirServer; QSurfaceFormat m_format; #if GL_DEBUG QOpenGLDebugLogger *m_logger; diff --git a/src/platforms/mirserver/mirserverintegration.cpp b/src/platforms/mirserver/mirserverintegration.cpp index 14e7033..95b50e8 100644 --- a/src/platforms/mirserver/mirserverintegration.cpp +++ b/src/platforms/mirserver/mirserverintegration.cpp @@ -30,7 +30,6 @@ #include <qpa/qwindowsysteminterface.h> #include <QCoreApplication> -#include <QStringList> #include <QOpenGLContext> #if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) @@ -41,10 +40,6 @@ // Mir #include <mir/graphics/display.h> -#include <mir/graphics/display_buffer.h> - -// std -#include <csignal> // local #include "clipboard.h" @@ -66,37 +61,22 @@ MirServerIntegration::MirServerIntegration() #if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) , m_eventDispatcher(createUnixEventDispatcher()) #endif + , m_mirServer(new QMirServer(QCoreApplication::arguments())) , m_display(nullptr) - , m_qmirServer(nullptr) , m_nativeInterface(nullptr) , m_clipboard(new Clipboard) { - // Start Mir server only once Qt has initialized its event dispatcher, see initialize() - - QStringList args = QCoreApplication::arguments(); - // convert arguments back into argc-argv form that Mir wants - char **argv; - argv = new char*[args.size() + 1]; - for (int i = 0; i < args.size(); i++) { - argv[i] = new char[strlen(args.at(i).toStdString().c_str())+1]; - memcpy(argv[i], args.at(i).toStdString().c_str(), strlen(args.at(i).toStdString().c_str())+1); - } - argv[args.size()] = '\0'; - // For access to sensors, qtmir uses qtubuntu-sensors. qtubuntu-sensors reads the // UBUNTU_PLATFORM_API_BACKEND variable to decide if to load a valid sensor backend or not. // For it to function we need to ensure a valid backend has been specified if (qEnvironmentVariableIsEmpty("UBUNTU_PLATFORM_API_BACKEND")) { - if (qgetenv("DESKTOP_SESSION").contains("mir")) { + if (qgetenv("DESKTOP_SESSION").contains("mir") || !qEnvironmentVariableIsSet("ANDROID_DATA")) { qputenv("UBUNTU_PLATFORM_API_BACKEND", "desktop_mirclient"); } else { qputenv("UBUNTU_PLATFORM_API_BACKEND", "touch_mirclient"); } } - m_mirServer = QSharedPointer<MirServer>( - new MirServer(args.length(), const_cast<const char**>(argv))); - #if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) QGuiApplicationPrivate::instance()->setEventDispatcher(eventDispatcher_); initialize(); @@ -109,7 +89,6 @@ MirServerIntegration::~MirServerIntegration() { delete m_nativeInterface; delete m_display; - delete m_qmirServer; } bool MirServerIntegration::hasCapability(QPlatformIntegration::Capability cap) const @@ -135,11 +114,14 @@ QPlatformWindow *MirServerIntegration::createPlatformWindow(QWindow *window) con DisplayWindow* displayWindow = nullptr; - m_mirServer->the_display()->for_each_display_buffer( - [&](mg::DisplayBuffer& buffer) { - // FIXME(gerry) this will go very bad for >1 display buffer - displayWindow = new DisplayWindow(window, &buffer); - }); + auto const mirServer = m_mirServer->mirServer().lock(); + if (mirServer) { + mirServer->the_display()->for_each_display_buffer( + [&](mg::DisplayBuffer& buffer) { + // FIXME(gerry) this will go very bad for >1 display buffer + displayWindow = new DisplayWindow(window, &buffer); + }); + } if (!displayWindow) return nullptr; @@ -157,7 +139,7 @@ QPlatformBackingStore *MirServerIntegration::createPlatformBackingStore(QWindow QPlatformOpenGLContext *MirServerIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { qDebug() << "createPlatformOpenGLContext" << context; - return new MirOpenGLContext(m_mirServer, context->format()); + return new MirOpenGLContext(m_mirServer->mirServer(), context->format()); } #if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) @@ -170,10 +152,10 @@ QAbstractEventDispatcher *MirServerIntegration::createEventDispatcher() const void MirServerIntegration::initialize() { // Creates instance of and start the Mir server in a separate thread - m_qmirServer = new QMirServer(m_mirServer); + m_mirServer->run(); - m_display = new Display(m_mirServer); - m_nativeInterface = new NativeInterface(m_mirServer); + m_display = new Display(m_mirServer->mirServer()); + m_nativeInterface = new NativeInterface(m_mirServer->mirServer()); for (QPlatformScreen *screen : m_display->screens()) screenAdded(screen); diff --git a/src/platforms/mirserver/mirserverintegration.h b/src/platforms/mirserver/mirserverintegration.h index 37e0dc0..efcdb2f 100644 --- a/src/platforms/mirserver/mirserverintegration.h +++ b/src/platforms/mirserver/mirserverintegration.h @@ -69,8 +69,6 @@ public: QPlatformNativeInterface *nativeInterface() const override; private: - QSharedPointer<MirServer> m_mirServer; - QScopedPointer<QPlatformAccessibility> m_accessibility; QScopedPointer<QPlatformFontDatabase> m_fontDb; QScopedPointer<QPlatformServices> m_services; @@ -78,8 +76,9 @@ private: QScopedPointer<QAbstractEventDispatcher> m_eventDispatcher; #endif + QScopedPointer<QMirServer> m_mirServer; + Display *m_display; - QMirServer *m_qmirServer; NativeInterface *m_nativeInterface; QPlatformInputContext* m_inputContext; QScopedPointer<qtmir::Clipboard> m_clipboard; diff --git a/src/platforms/mirserver/nativeinterface.cpp b/src/platforms/mirserver/nativeinterface.cpp index b013345..e6c77d7 100644 --- a/src/platforms/mirserver/nativeinterface.cpp +++ b/src/platforms/mirserver/nativeinterface.cpp @@ -18,7 +18,7 @@ #include "nativeinterface.h" -NativeInterface::NativeInterface(const QSharedPointer<MirServer> &server) +NativeInterface::NativeInterface(const QWeakPointer<MirServer> &server) : m_mirServer(server) { } @@ -27,14 +27,17 @@ void *NativeInterface::nativeResourceForIntegration(const QByteArray &resource) { void *result = nullptr; - if (resource == "SessionAuthorizer") - result = m_mirServer->sessionAuthorizer(); - else if (resource == "Shell") - result = m_mirServer->shell(); - else if (resource == "SessionListener") - result = m_mirServer->sessionListener(); - else if (resource == "PromptSessionListener") - result = m_mirServer->promptSessionListener(); + auto const server = m_mirServer.lock(); + if (server) { + if (resource == "SessionAuthorizer") + result = server->sessionAuthorizer(); + else if (resource == "Shell") + result = server->shell(); + else if (resource == "SessionListener") + result = server->sessionListener(); + else if (resource == "PromptSessionListener") + result = server->promptSessionListener(); + } return result; } diff --git a/src/platforms/mirserver/nativeinterface.h b/src/platforms/mirserver/nativeinterface.h index 5a5c377..d3bf316 100644 --- a/src/platforms/mirserver/nativeinterface.h +++ b/src/platforms/mirserver/nativeinterface.h @@ -29,11 +29,11 @@ class NativeInterface : public QPlatformNativeInterface { public: - NativeInterface(const QSharedPointer<MirServer> &); + NativeInterface(const QWeakPointer<MirServer> &); virtual void *nativeResourceForIntegration(const QByteArray &resource); - QSharedPointer<MirServer> m_mirServer; + QWeakPointer<MirServer> m_mirServer; }; #endif // NATIVEINTEGRATION_H diff --git a/src/platforms/mirserver/qmirserver.cpp b/src/platforms/mirserver/qmirserver.cpp index 4af86f7..d946f2d 100644 --- a/src/platforms/mirserver/qmirserver.cpp +++ b/src/platforms/mirserver/qmirserver.cpp @@ -17,82 +17,102 @@ // Qt #include <QObject> #include <QCoreApplication> +#include <QMetaMethod> #include <QDebug> -#include <mir/main_loop.h> - // local +#include "mirserver.h" #include "qmirserver.h" +#include "qmirserver_p.h" -void MirServerWorker::run() +QMirServer::QMirServer(const QStringList &arguments, QObject *parent) + : QObject(parent) + , d_ptr(new QMirServerPrivate()) { - auto const main_loop = server->the_main_loop(); - // By enqueuing the notification code in the main loop, we are - // ensuring that the server has really and fully started before - // leaving wait_for_startup(). - main_loop->enqueue( - this, - [&] - { - std::lock_guard<std::mutex> lock(mutex); - mir_running = true; - started_cv.notify_one(); - }); - - server->run(); - Q_EMIT stopped(); + Q_D(QMirServer); + + // convert arguments back into argc-argv form that Mir wants + int argc = arguments.size(); + char **argv = new char*[argc + 1]; + for (int i = 0; i < argc; i++) { + argv[i] = new char[strlen(arguments.at(i).toStdString().c_str())+1]; + memcpy(argv[i], arguments.at(i).toStdString().c_str(), strlen(arguments.at(i).toStdString().c_str())+1); + } + argv[argc] = '\0'; + + d->server = QSharedPointer<MirServer>(new MirServer(argc, const_cast<const char**>(argv))); + + d->serverWorker = new MirServerWorker(d->server); + d->serverWorker->moveToThread(&d->serverThread); + + connect(this, &QMirServer::runServer, d->serverWorker, &MirServerWorker::run); + connect(this, &QMirServer::stopServer, d->serverWorker, &MirServerWorker::stop); + + connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, + d->serverWorker, &MirServerWorker::stop, Qt::DirectConnection); // see FIXME in MirServerWorker + connect(d->serverWorker, &MirServerWorker::stopped, this, &QMirServer::serverStopped, Qt::DirectConnection); } -bool MirServerWorker::wait_for_mir_startup() +QMirServer::~QMirServer() { - std::unique_lock<decltype(mutex)> lock(mutex); - started_cv.wait_for(lock, std::chrono::seconds{10}, [&]{ return mir_running; }); - return mir_running; + stop(); } -QMirServer::QMirServer(const QSharedPointer<MirServer> &server, QObject *parent) - : QObject(parent) - , m_mirServer(new MirServerWorker(server)) +bool QMirServer::run() { - m_mirServer->moveToThread(&m_mirThread); - - connect(this, &QMirServer::run, m_mirServer, &MirServerWorker::run); - connect(this, &QMirServer::stop, m_mirServer, &MirServerWorker::stop); + Q_D(QMirServer); - connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &QMirServer::shutDownMirServer); - connect(m_mirServer, &MirServerWorker::stopped, this, &QMirServer::shutDownQApplication, Qt::DirectConnection); // since no event loop + d->serverThread.start(QThread::TimeCriticalPriority); + Q_EMIT runServer(); - m_mirThread.start(QThread::TimeCriticalPriority); - Q_EMIT run(); - - if (!m_mirServer->wait_for_mir_startup()) + if (!d->serverWorker->waitForMirStartup()) { qCritical() << "ERROR: QMirServer - Mir failed to start"; QCoreApplication::quit(); + return false; } + + return true; } -QMirServer::~QMirServer() +bool QMirServer::stop() { - shutDownMirServer(); + Q_D(QMirServer); + + if (d->serverThread.isRunning()) { + Q_EMIT stopServer(); + if (!d->serverThread.wait(10000)) { + // do something to indicate fail during shutdown + qCritical() << "ERROR: QMirServer - Mir failed to shut down correctly, terminating it"; + d->serverThread.terminate(); + return false; + } + } + return true; } -void QMirServer::shutDownMirServer() +bool QMirServer::isRunning() const { - if (m_mirThread.isRunning()) { - m_mirServer->stop(); - m_mirThread.wait(); - } + Q_D(const QMirServer); + return d->serverThread.isRunning(); } -void QMirServer::shutDownQApplication() +void QMirServer::serverStopped() { - if (m_mirThread.isRunning()) - m_mirThread.quit(); + Q_D(QMirServer); + + if (d->serverThread.isRunning()) + d->serverThread.quit(); // if unexpected mir server stop, better quit the QApplication if (!QCoreApplication::closingDown()) { QCoreApplication::quit(); } } + +QWeakPointer<MirServer> QMirServer::mirServer() const +{ + Q_D(const QMirServer); + return d->server.toWeakRef(); +} diff --git a/src/platforms/mirserver/qmirserver.h b/src/platforms/mirserver/qmirserver.h index be74149..4008a80 100644 --- a/src/platforms/mirserver/qmirserver.h +++ b/src/platforms/mirserver/qmirserver.h @@ -19,63 +19,37 @@ // Qt #include <QObject> -#include <QThread> -#include <QSharedPointer> +#include <QWeakPointer> -// local -#include "mirserver.h" +class QMirServerPrivate; +class MirServer; -#include <condition_variable> -#include <mutex> - -// Wrap mir::Server with QObject, so it can be controlled via QThread -class MirServerWorker : public QObject +class QMirServer: public QObject { Q_OBJECT public: - MirServerWorker(const QSharedPointer<MirServer> &server) - : server(server) - {} - - bool wait_for_mir_startup(); - -Q_SIGNALS: - void stopped(); - -public Q_SLOTS: - void run(); - void stop() { server->stop(); } - -private: - std::mutex mutex; - std::condition_variable started_cv; - bool mir_running{false}; + QMirServer(const QStringList &arguments, QObject* parent=0); + virtual ~QMirServer(); - const QSharedPointer<MirServer> server; -}; + bool run(); + Q_SLOT bool stop(); + bool isRunning() const; + QWeakPointer<MirServer> mirServer() const; -class QMirServer: public QObject -{ - Q_OBJECT +protected: + QMirServerPrivate * const d_ptr; -public: - QMirServer(const QSharedPointer<MirServer> &config, QObject* parent=0); - ~QMirServer(); + Q_SLOT void serverStopped(); Q_SIGNALS: - void run(); - void stop(); - -protected Q_SLOTS: - void shutDownMirServer(); - void shutDownQApplication(); + void runServer(); + void stopServer(); private: - QThread m_mirThread; - MirServerWorker *m_mirServer; Q_DISABLE_COPY(QMirServer) + Q_DECLARE_PRIVATE(QMirServer) }; #endif // QMIRSERVER_H diff --git a/src/platforms/mirserver/qmirserver_p.cpp b/src/platforms/mirserver/qmirserver_p.cpp new file mode 100644 index 0000000..444ec93 --- /dev/null +++ b/src/platforms/mirserver/qmirserver_p.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2015 Canonical, Ltd. + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 3, as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +// Mir +#include <mir/main_loop.h> + +#include "qmirserver_p.h" + + +/* FIXME: QThread by default starts an event loop, which is required for correct signal/slot + * messaging between threads. However below you'll see that the mir server run() method + * blocks, which blocks the event loop for this thread too. Therefore while mir is running + * the queued signal/slot mechanism does not work. As workaround, need to use direct call to + * stop the server. + */ +void MirServerWorker::run() +{ + auto const main_loop = server->the_main_loop(); + // By enqueuing the notification code in the main loop, we are + // ensuring that the server has really and fully started before + // leaving wait_for_startup(). + main_loop->enqueue( + this, + [&] + { + std::lock_guard<std::mutex> lock(mutex); + mir_running = true; + started_cv.notify_one(); + }); + + server->run(); // blocks until Mir server stopped + Q_EMIT stopped(); +} + +void MirServerWorker::stop() +{ + server->stop(); +} + +bool MirServerWorker::waitForMirStartup() +{ + std::unique_lock<decltype(mutex)> lock(mutex); + started_cv.wait_for(lock, std::chrono::seconds{10}, [&]{ return mir_running; }); + return mir_running; +} diff --git a/src/platforms/mirserver/qmirserver_p.h b/src/platforms/mirserver/qmirserver_p.h new file mode 100644 index 0000000..0d824a8 --- /dev/null +++ b/src/platforms/mirserver/qmirserver_p.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2015 Canonical, Ltd. + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 3, as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef QMIRSERVER_P_H +#define QMIRSERVER_P_H + +#include <QThread> +#include <QSharedPointer> + +// std +#include <condition_variable> +#include <mutex> + +#include "mirserver.h" + +class QMirServer; +class MirServerWorker; + +struct QMirServerPrivate +{ + QSharedPointer<MirServer> server; + QThread serverThread; + MirServerWorker *serverWorker; +}; + + +// Wraps mir::Server with QObject, so it can be controlled via QThread +class MirServerWorker : public QObject +{ + Q_OBJECT + +public: + MirServerWorker(const QSharedPointer<MirServer> &server) + : server(server) + {} + + bool waitForMirStartup(); + +Q_SIGNALS: + void stopped(); + +public Q_SLOTS: + void run(); + void stop(); + +private: + std::mutex mutex; + std::condition_variable started_cv; + bool mir_running{false}; + + const QSharedPointer<MirServer> server; +}; + +#endif // QMIRSERVER_P_H |