summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2019-10-14 15:58:50 +0200
committerTor Arne Vestbø <tor.arne.vestbo@qt.io>2019-10-19 11:58:35 +0200
commit1b6db1849477be30ef0ca52c288d358b911ea1e4 (patch)
treed158bc3656467c2d66d62e56acc6bb9e39a1d197 /src/gui/kernel
parent2967510213373fa92db94385e3904196637e8df1 (diff)
Propagate application termination requests through QPA
Instead of having each platform plugin deal with application termination in their own weird ways, we now have a QPA API to signal that the system requested the application to terminate. On the QGuiApplication side this results in a Quit event being sent to the application, which triggers the default behavior of closing all app windows, and then finally calling QCoreApplication::quit(). The quit event replaces the misuse of a close event being sent to the application. Close events are documented as being sent to windows. The close events that are sent to individual windows as part of the quit process can be ignored. This will skip the final quit() of the application, and also inform the platform that the quit was not accepted, in case that should be propagated further. In the future the logic for closing windows should be unified between the various approaches in closeAllWindows, shouldQuit, and friends. Change-Id: I0ed7f1c0d3f0bf1a755e1dd4066e1575fc3a28e1 Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/qguiapplication.cpp23
-rw-r--r--src/gui/kernel/qguiapplication_p.h2
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp6
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h3
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h3
5 files changed, 36 insertions, 1 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 13de8af8b5..54f3996b6e 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -1863,7 +1863,20 @@ bool QGuiApplication::event(QEvent *e)
{
if(e->type() == QEvent::LanguageChange) {
setLayoutDirection(qt_detectRTLLanguage()?Qt::RightToLeft:Qt::LeftToRight);
+ } else if (e->type() == QEvent::Quit) {
+ // Close open windows. This is done in order to deliver de-expose
+ // events while the event loop is still running.
+ for (QWindow *topLevelWindow : QGuiApplication::topLevelWindows()) {
+ // Already closed windows will not have a platform window, skip those
+ if (!topLevelWindow->handle())
+ continue;
+ if (!topLevelWindow->close()) {
+ e->ignore();
+ return true;
+ }
+ }
}
+
return QCoreApplication::event(e);
}
@@ -1940,6 +1953,9 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
QWindowSystemInterfacePrivate::ApplicationStateChangedEvent * changeEvent = static_cast<QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *>(e);
QGuiApplicationPrivate::setApplicationState(changeEvent->newState, changeEvent->forcePropagate); }
break;
+ case QWindowSystemInterfacePrivate::ApplicationTermination:
+ QGuiApplicationPrivate::processApplicationTermination(e);
+ break;
case QWindowSystemInterfacePrivate::FlushEvents: {
QWindowSystemInterfacePrivate::FlushEventsEvent *flushEventsEvent = static_cast<QWindowSystemInterfacePrivate::FlushEventsEvent *>(e);
QWindowSystemInterface::deferredFlushWindowSystemEvents(flushEventsEvent->flags); }
@@ -3489,6 +3505,13 @@ bool QGuiApplicationPrivate::tryCloseRemainingWindows(QWindowList processedWindo
return true;
}
+void QGuiApplicationPrivate::processApplicationTermination(QWindowSystemInterfacePrivate::WindowSystemEvent *windowSystemEvent)
+{
+ QEvent event(QEvent::Quit);
+ QGuiApplication::sendSpontaneousEvent(QGuiApplication::instance(), &event);
+ windowSystemEvent->eventAccepted = event.isAccepted();
+}
+
/*!
\since 5.2
\fn Qt::ApplicationState QGuiApplication::applicationState()
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index e28607bad6..26f65b2f16 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -141,6 +141,8 @@ public:
static void processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e);
+ static void processApplicationTermination(QWindowSystemInterfacePrivate::WindowSystemEvent *e);
+
static void updateFilteredScreenOrientation(QScreen *screen);
static void reportScreenOrientationChange(QScreen *screen);
static void processScreenOrientationChange(QWindowSystemInterfacePrivate::ScreenOrientationEvent *e);
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 5f61853a6d..4f1056e906 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -285,6 +285,12 @@ QT_DEFINE_QPA_EVENT_HANDLER(void, handleApplicationStateChanged, Qt::Application
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
}
+QT_DEFINE_QPA_EVENT_HANDLER(bool, handleApplicationTermination)
+{
+ auto *e = new QWindowSystemInterfacePrivate::WindowSystemEvent(QWindowSystemInterfacePrivate::ApplicationTermination);
+ return QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
+}
+
QWindowSystemInterfacePrivate::GeometryChangeEvent::GeometryChangeEvent(QWindow *window, const QRect &newGeometry)
: WindowSystemEvent(GeometryChange)
, window(window)
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index 4a0bc858a9..d5a4ad30d8 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -215,6 +215,9 @@ public:
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
static void handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate = false);
+ template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
+ static bool handleApplicationTermination();
+
#if QT_CONFIG(draganddrop)
#if QT_DEPRECATED_SINCE(5, 11)
QT_DEPRECATED static QPlatformDragQtResponse handleDrag(QWindow *window, const QMimeData *dropData,
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index 55fd181ef0..6e4bce607e 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -99,7 +99,8 @@ public:
ApplicationStateChanged = 0x19,
FlushEvents = 0x20,
WindowScreenChanged = 0x21,
- SafeAreaMarginsChanged = 0x22
+ SafeAreaMarginsChanged = 0x22,
+ ApplicationTermination = 0x23
};
class WindowSystemEvent {