Skip to content

Commit

Permalink
Plumb application quit through platform plugin
Browse files Browse the repository at this point in the history
If we have a platform plugin we ask the platform to quit, and if
not we fall back to the base implementation of QCoreApplication
that sends Quit events directly.

This allows the platform to involve the rest of the system in the
process. The platform will then come back with a spontaneous quit
via QWSI::handleApplicationTermination(), which will then send
the corresponding Quit even from QGuiApplication like normal.

Task-number: QTBUG-45262
Task-number: QTBUG-33235
Task-number: QTBUG-72013
Task-number: QTBUG-59782
Change-Id: I0000aaf7192e4b905933c5da0e53901c6c88f26a
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
  • Loading branch information
torarnv committed Sep 14, 2020
1 parent cc570ce commit 0c02f13
Show file tree
Hide file tree
Showing 11 changed files with 45 additions and 7 deletions.
13 changes: 10 additions & 3 deletions src/corelib/kernel/qcoreapplication.cpp
Expand Up @@ -1975,11 +1975,18 @@ void QCoreApplication::quit()
if (!self)
return;

if (QThread::currentThread() == self->d_func()->mainThread()) {
self->d_func()->quit();
}

void QCoreApplicationPrivate::quit()
{
Q_Q(QCoreApplication);

if (QThread::currentThread() == mainThread()) {
QEvent quitEvent(QEvent::Quit);
QCoreApplication::sendEvent(self, &quitEvent);
QCoreApplication::sendEvent(q, &quitEvent);
} else {
QCoreApplication::postEvent(self, new QEvent(QEvent::Quit));
QCoreApplication::postEvent(q, new QEvent(QEvent::Quit));
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/corelib/kernel/qcoreapplication_p.h
Expand Up @@ -135,6 +135,8 @@ class Q_CORE_EXPORT QCoreApplicationPrivate
virtual bool shouldQuit() {
return true;
}

virtual void quit();
void maybeQuit();

static QBasicAtomicPointer<QThread> theMainThread;
Expand Down
8 changes: 8 additions & 0 deletions src/gui/kernel/qguiapplication.cpp
Expand Up @@ -3641,6 +3641,14 @@ bool QGuiApplicationPrivate::shouldQuitInternal(const QWindowList &processedWind
return true;
}

void QGuiApplicationPrivate::quit()
{
if (auto *platformIntegration = QGuiApplicationPrivate::platformIntegration())
platformIntegration->quit();
else
QCoreApplicationPrivate::quit();
}

void QGuiApplicationPrivate::processApplicationTermination(QWindowSystemInterfacePrivate::WindowSystemEvent *windowSystemEvent)
{
QEvent event(QEvent::Quit);
Expand Down
1 change: 1 addition & 0 deletions src/gui/kernel/qguiapplication_p.h
Expand Up @@ -105,6 +105,7 @@ class Q_GUI_EXPORT QGuiApplicationPrivate : public QCoreApplicationPrivate
void addQtOptions(QList<QCommandLineOption> *options) override;
#endif
virtual bool shouldQuit() override;
void quit() override;

bool shouldQuitInternal(const QWindowList &processedWindows);

Expand Down
14 changes: 14 additions & 0 deletions src/gui/kernel/qplatformintegration.cpp
Expand Up @@ -529,6 +529,20 @@ void QPlatformIntegration::beep() const
{
}

/*!
\since 6.0
Asks the platform to terminate the application.
Overrides should ensure there's a callback into the QWSI
function handleApplicationTermination so that the quit can
be propagated to QtGui and the application.
*/
void QPlatformIntegration::quit() const
{
QWindowSystemInterface::handleApplicationTermination<QWindowSystemInterface::SynchronousDelivery>();
}

#ifndef QT_NO_OPENGL
/*!
Platform integration function for querying the OpenGL implementation type.
Expand Down
1 change: 1 addition & 0 deletions src/gui/kernel/qplatformintegration.h
Expand Up @@ -220,6 +220,7 @@ class Q_GUI_EXPORT QPlatformIntegration
virtual void setApplicationIcon(const QIcon &icon) const;

virtual void beep() const;
virtual void quit() const;

#if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC)
virtual QPlatformVulkanInstance *createPlatformVulkanInstance(QVulkanInstance *instance) const;
Expand Down
4 changes: 0 additions & 4 deletions src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
Expand Up @@ -92,10 +92,6 @@
#include <qpa/qwindowsysteminterface.h>
#include <qwindowdefs.h>

QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaApplication, "qt.qpa.application");
QT_END_NAMESPACE

QT_USE_NAMESPACE

@implementation QCocoaApplicationDelegate {
Expand Down
1 change: 1 addition & 0 deletions src/plugins/platforms/cocoa/qcocoahelpers.h
Expand Up @@ -72,6 +72,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcQpaWindow)
Q_DECLARE_LOGGING_CATEGORY(lcQpaDrawing)
Q_DECLARE_LOGGING_CATEGORY(lcQpaMouse)
Q_DECLARE_LOGGING_CATEGORY(lcQpaScreen)
Q_DECLARE_LOGGING_CATEGORY(lcQpaApplication)

class QPixmap;
class QString;
Expand Down
1 change: 1 addition & 0 deletions src/plugins/platforms/cocoa/qcocoahelpers.mm
Expand Up @@ -59,6 +59,7 @@
Q_LOGGING_CATEGORY(lcQpaDrawing, "qt.qpa.drawing");
Q_LOGGING_CATEGORY(lcQpaMouse, "qt.qpa.input.mouse", QtCriticalMsg);
Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen", QtCriticalMsg);
Q_LOGGING_CATEGORY(lcQpaApplication, "qt.qpa.application");

//
// Conversion Functions
Expand Down
1 change: 1 addition & 0 deletions src/plugins/platforms/cocoa/qcocoaintegration.h
Expand Up @@ -132,6 +132,7 @@ class QCocoaIntegration : public QObject, public QPlatformIntegration
void setApplicationIcon(const QIcon &icon) const override;

void beep() const override;
void quit() const override;

void closePopups(QWindow *forWindow = nullptr);

Expand Down
6 changes: 6 additions & 0 deletions src/plugins/platforms/cocoa/qcocoaintegration.mm
Expand Up @@ -488,6 +488,12 @@ QSurfaceFormat format() const override
NSBeep();
}

void QCocoaIntegration::quit() const
{
qCDebug(lcQpaApplication) << "Terminating application";
[NSApp terminate:nil];
}

void QCocoaIntegration::closePopups(QWindow *forWindow)
{
for (auto it = m_popupWindowStack.begin(); it != m_popupWindowStack.end();) {
Expand Down

0 comments on commit 0c02f13

Please sign in to comment.