diff options
-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 | 12 | ||||
-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 | 59 | ||||
-rw-r--r-- | src/platforms/mirserver/mirserverintegration.h | 7 | ||||
-rw-r--r-- | src/platforms/mirserver/nativeinterface.cpp | 23 | ||||
-rw-r--r-- | src/platforms/mirserver/nativeinterface.h | 6 | ||||
-rw-r--r-- | src/platforms/mirserver/qmirserver.cpp | 101 | ||||
-rw-r--r-- | src/platforms/mirserver/qmirserver.h | 60 | ||||
-rw-r--r-- | src/platforms/mirserver/qmirserver_p.cpp | 53 | ||||
-rw-r--r-- | src/platforms/mirserver/qmirserver_p.h | 67 |
14 files changed, 252 insertions, 165 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 a47cb1a..60abe20 100644 --- a/src/platforms/mirserver/CMakeLists.txt +++ b/src/platforms/mirserver/CMakeLists.txt @@ -44,6 +44,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..7228f6e 100644 --- a/src/platforms/mirserver/display.cpp +++ b/src/platforms/mirserver/display.cpp @@ -23,18 +23,13 @@ #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 std::shared_ptr<mir::graphics::DisplayConfiguration> &displayConfig) { - std::shared_ptr<mir::graphics::DisplayConfiguration> displayConfig = m_mirServer->the_display()->configuration(); - displayConfig->for_each_output([this](mg::DisplayConfigurationOutput const& output) { if (output.used) { auto screen = new Screen(output); diff --git a/src/platforms/mirserver/display.h b/src/platforms/mirserver/display.h index 21c7767..bc77381 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 <qpa/qplatformscreen.h> +#include <memory> -class MirServer; +namespace mir { namespace graphics { class DisplayConfiguration; }} -class Display : public QObject +class Display { - Q_OBJECT public: - Display(const QSharedPointer<MirServer> &server, QObject *parent = 0); - ~Display(); + Display(const std::shared_ptr<mir::graphics::DisplayConfiguration> &displayConfig); + 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 2292831..ad33caa 100644 --- a/src/platforms/mirserver/mirserverintegration.cpp +++ b/src/platforms/mirserver/mirserverintegration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2014 Canonical, Ltd. + * Copyright (C) 2013-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 @@ -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,7 @@ // Mir #include <mir/graphics/display.h> -#include <mir/graphics/display_buffer.h> - -// std -#include <csignal> +#include <mir/graphics/display_configuration.h> // local #include "clipboard.h" @@ -66,36 +62,25 @@ 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 Mir shuts down, quit. + QObject::connect(m_mirServer.data(), &QMirServer::stopped, + QCoreApplication::instance(), &QCoreApplication::quit); #if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) QGuiApplicationPrivate::instance()->setEventDispatcher(eventDispatcher_); @@ -109,7 +94,6 @@ MirServerIntegration::~MirServerIntegration() { delete m_nativeInterface; delete m_display; - delete m_qmirServer; } bool MirServerIntegration::hasCapability(QPlatformIntegration::Capability cap) const @@ -135,18 +119,21 @@ QPlatformWindow *MirServerIntegration::createPlatformWindow(QWindow *window) con DisplayWindow* displayWindow = nullptr; + auto const mirServer = m_mirServer->mirServer().lock(); mg::DisplayBuffer* first_buffer{nullptr}; mg::DisplaySyncGroup* first_group{nullptr}; - m_mirServer->the_display()->for_each_display_sync_group([&](mg::DisplaySyncGroup &group) { - if (!first_group) { - first_group = &group; - } - group.for_each_display_buffer([&](mg::DisplayBuffer &buffer) { - if (!first_buffer) { - first_buffer = &buffer; + if (mirServer) { + mirServer->the_display()->for_each_display_sync_group([&](mg::DisplaySyncGroup &group) { + if (!first_group) { + first_group = &group; } + group.for_each_display_buffer([&](mg::DisplayBuffer &buffer) { + if (!first_buffer) { + first_buffer = &buffer; + } + }); }); - }); + } // FIXME(gerry) this will go very bad for >1 display buffer if (first_group && first_buffer) @@ -168,7 +155,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) @@ -181,10 +168,12 @@ 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); + if (!m_mirServer->start()) { + exit(2); + } - m_display = new Display(m_mirServer); - m_nativeInterface = new NativeInterface(m_mirServer); + m_display = new Display(m_mirServer->mirServer().data()->the_display()->configuration()); + 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..a02405e 100644 --- a/src/platforms/mirserver/mirserverintegration.h +++ b/src/platforms/mirserver/mirserverintegration.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2014 Canonical, Ltd. + * Copyright (C) 2013-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 @@ -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..6cc4c0d 100644 --- a/src/platforms/mirserver/nativeinterface.cpp +++ b/src/platforms/mirserver/nativeinterface.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Canonical, Ltd. + * Copyright (C) 2013-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 @@ -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..da97663 100644 --- a/src/platforms/mirserver/nativeinterface.h +++ b/src/platforms/mirserver/nativeinterface.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Canonical, Ltd. + * Copyright (C) 2013-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 @@ -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 f28393a..c7dc580 100644 --- a/src/platforms/mirserver/qmirserver.cpp +++ b/src/platforms/mirserver/qmirserver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Canonical, Ltd. + * Copyright (C) 2013-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 @@ -19,80 +19,77 @@ #include <QCoreApplication> #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->serverThread = new MirServerThread(d->server); + + connect(d->serverThread, &MirServerThread::stopped, this, &QMirServer::stopped); } -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::start() { - m_mirServer->moveToThread(&m_mirThread); + Q_D(QMirServer); - connect(this, &QMirServer::run, m_mirServer, &MirServerWorker::run); - connect(this, &QMirServer::stop, m_mirServer, &MirServerWorker::stop); + d->serverThread->start(QThread::TimeCriticalPriority); - connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &QMirServer::shutDownMirServer); - connect(m_mirServer, &MirServerWorker::stopped, this, &QMirServer::shutDownQApplication, Qt::DirectConnection); // since no event loop - - m_mirThread.start(QThread::TimeCriticalPriority); - Q_EMIT run(); - - if (!m_mirServer->wait_for_mir_startup()) + if (!d->serverThread->waitForMirStartup()) { qCritical() << "ERROR: QMirServer - Mir failed to start"; - exit(2); + return false; } -} -QMirServer::~QMirServer() -{ - shutDownMirServer(); + Q_EMIT started(); + return true; } -void QMirServer::shutDownMirServer() +void QMirServer::stop() { - if (m_mirThread.isRunning()) { - m_mirServer->stop(); - m_mirThread.wait(); + Q_D(QMirServer); + + if (d->serverThread->isRunning()) { + d->serverThread->stop(); + 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(); + } } } -void QMirServer::shutDownQApplication() +bool QMirServer::isRunning() const { - if (m_mirThread.isRunning()) - m_mirThread.quit(); + Q_D(const QMirServer); + return d->serverThread->isRunning(); +} - // 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..ecb943b 100644 --- a/src/platforms/mirserver/qmirserver.h +++ b/src/platforms/mirserver/qmirserver.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Canonical, Ltd. + * Copyright (C) 2013-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 @@ -19,63 +19,35 @@ // 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(); + QMirServer(const QStringList &arguments, QObject* parent=0); + virtual ~QMirServer(); -Q_SIGNALS: - void stopped(); + bool start(); + Q_SLOT void stop(); + bool isRunning() const; -public Q_SLOTS: - void run(); - void stop() { server->stop(); } - -private: - std::mutex mutex; - std::condition_variable started_cv; - bool mir_running{false}; - - const QSharedPointer<MirServer> server; -}; - - -class QMirServer: public QObject -{ - Q_OBJECT - -public: - QMirServer(const QSharedPointer<MirServer> &config, QObject* parent=0); - ~QMirServer(); + QWeakPointer<MirServer> mirServer() const; Q_SIGNALS: - void run(); - void stop(); + void started(); + void stopped(); -protected Q_SLOTS: - void shutDownMirServer(); - void shutDownQApplication(); +protected: + QMirServerPrivate * const d_ptr; 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..d784a46 --- /dev/null +++ b/src/platforms/mirserver/qmirserver_p.cpp @@ -0,0 +1,53 @@ +/* + * 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> + +// local +#include "qmirserver_p.h" + + +void MirServerThread::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 MirServerThread::stop() +{ + server->stop(); +} + +bool MirServerThread::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..6e86d8d --- /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 + +// Qt +#include <QThread> +#include <QSharedPointer> + +// std +#include <condition_variable> +#include <mutex> + +// local +#include "mirserver.h" + +class QMirServer; +class MirServerThread; + +struct QMirServerPrivate +{ + QSharedPointer<MirServer> server; + MirServerThread *serverThread; +}; + + +class MirServerThread : public QThread +{ + Q_OBJECT + +public: + MirServerThread(const QSharedPointer<MirServer> &server) + : server(server) + {} + + bool waitForMirStartup(); + +Q_SIGNALS: + void stopped(); + +public Q_SLOTS: + void run() override; + void stop(); + +private: + std::mutex mutex; + std::condition_variable started_cv; + bool mir_running{false}; + + const QSharedPointer<MirServer> server; +}; + +#endif // QMIRSERVER_P_H |