summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Arne Vestbø <[email protected]>2022-09-09 16:41:49 +0200
committerTor Arne Vestbø <[email protected]>2023-03-28 17:31:17 +0200
commit3a2277cb634dd394b4245d2f7f26b8b5357b806f (patch)
tree9b68168abb5d54dbe8e0f13185a2c0a49efc6f0c
parent2187936978c93e73c86119e8ef99625e9f2b4109 (diff)
Align QWindowSystemInterface::handleScreenAdded() and handleScreenRemoved()
Having the logic of handleScreenRemoved() inside the QScreen destructor was making it harder to follow the flow of adding and removing screens. As screen management should always go though the QWSI functions, we keep the logic there. Change-Id: I456e77eb8fc10feae7b1f9994b25c9534ea4e430 Reviewed-by: Volker Hilsheimer <[email protected]>
-rw-r--r--src/gui/kernel/qplatformscreen.cpp6
-rw-r--r--src/gui/kernel/qscreen.cpp40
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp46
3 files changed, 47 insertions, 45 deletions
diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp
index 9e038b4032a..1b1631bf3fb 100644
--- a/src/gui/kernel/qplatformscreen.cpp
+++ b/src/gui/kernel/qplatformscreen.cpp
@@ -25,10 +25,8 @@ QPlatformScreen::QPlatformScreen()
QPlatformScreen::~QPlatformScreen()
{
Q_D(QPlatformScreen);
- if (d->screen) {
- qWarning("Manually deleting a QPlatformScreen. Call QWindowSystemInterface::handleScreenRemoved instead.");
- delete d->screen;
- }
+ Q_ASSERT_X(!d->screen, "QPlatformScreen",
+ "QPlatformScreens should be removed via QWindowSystemInterface::handleScreenRemoved()");
}
/*!
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
index d4e94a98a1e..abf8c4569c0 100644
--- a/src/gui/kernel/qscreen.cpp
+++ b/src/gui/kernel/qscreen.cpp
@@ -66,45 +66,13 @@ void QScreenPrivate::updateGeometry()
/*!
Destroys the screen.
+
+ \internal
*/
QScreen::~QScreen()
{
- // Remove screen
- const bool wasPrimary = QGuiApplication::primaryScreen() == this;
- QGuiApplicationPrivate::screen_list.removeOne(this);
- QGuiApplicationPrivate::resetCachedDevicePixelRatio();
-
- if (!qGuiApp)
- return;
-
- QScreen *newPrimaryScreen = QGuiApplication::primaryScreen();
- if (wasPrimary && newPrimaryScreen)
- emit qGuiApp->primaryScreenChanged(newPrimaryScreen);
-
- // Allow clients to manage windows that are affected by the screen going
- // away, before we fall back to moving them to the primary screen.
- emit qApp->screenRemoved(this);
-
- if (QGuiApplication::closingDown())
- return;
-
- bool movingFromVirtualSibling = newPrimaryScreen
- && newPrimaryScreen->handle()->virtualSiblings().contains(handle());
-
- // Move any leftover windows to the primary screen
- const auto allWindows = QGuiApplication::allWindows();
- for (QWindow *window : allWindows) {
- if (!window->isTopLevel() || window->screen() != this)
- continue;
-
- const bool wasVisible = window->isVisible();
- window->setScreen(newPrimaryScreen);
-
- // Re-show window if moved from a virtual sibling screen. Otherwise
- // leave it up to the application developer to show the window.
- if (movingFromVirtualSibling)
- window->setVisible(wasVisible);
- }
+ Q_ASSERT_X(!QGuiApplicationPrivate::screen_list.contains(this), "QScreen",
+ "QScreens should be removed via QWindowSystemInterface::handleScreenRemoved()");
}
/*!
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 00343fef665..6b9fcd2947a 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -738,9 +738,9 @@ QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchCancelEvent, QWindow *window, ulong
The screen should be deleted by calling QWindowSystemInterface::handleScreenRemoved().
*/
-void QWindowSystemInterface::handleScreenAdded(QPlatformScreen *ps, bool isPrimary)
+void QWindowSystemInterface::handleScreenAdded(QPlatformScreen *platformScreen, bool isPrimary)
{
- QScreen *screen = new QScreen(ps);
+ QScreen *screen = new QScreen(platformScreen);
if (isPrimary)
QGuiApplicationPrivate::screen_list.prepend(screen);
@@ -767,9 +767,45 @@ void QWindowSystemInterface::handleScreenAdded(QPlatformScreen *ps, bool isPrima
*/
void QWindowSystemInterface::handleScreenRemoved(QPlatformScreen *platformScreen)
{
- // Important to keep this order since the QSceen doesn't own the platform screen.
- // The QScreen destructor will take care changing the primary screen, so no need here.
- delete platformScreen->screen();
+ QScreen *screen = platformScreen->screen();
+
+ // Remove screen
+ const bool wasPrimary = QGuiApplication::primaryScreen() == screen;
+ QGuiApplicationPrivate::screen_list.removeOne(screen);
+ QGuiApplicationPrivate::resetCachedDevicePixelRatio();
+
+ if (qGuiApp) {
+ QScreen *newPrimaryScreen = QGuiApplication::primaryScreen();
+ if (wasPrimary && newPrimaryScreen)
+ emit qGuiApp->primaryScreenChanged(newPrimaryScreen);
+
+ // Allow clients to manage windows that are affected by the screen going
+ // away, before we fall back to moving them to the primary screen.
+ emit qApp->screenRemoved(screen);
+
+ if (!QGuiApplication::closingDown()) {
+ bool movingFromVirtualSibling = newPrimaryScreen
+ && newPrimaryScreen->handle()->virtualSiblings().contains(platformScreen);
+
+ // Move any leftover windows to the primary screen
+ const auto allWindows = QGuiApplication::allWindows();
+ for (QWindow *window : allWindows) {
+ if (!window->isTopLevel() || window->screen() != screen)
+ continue;
+
+ const bool wasVisible = window->isVisible();
+ window->setScreen(newPrimaryScreen);
+
+ // Re-show window if moved from a virtual sibling screen. Otherwise
+ // leave it up to the application developer to show the window.
+ if (movingFromVirtualSibling)
+ window->setVisible(wasVisible);
+ }
+ }
+ }
+
+ // Important to keep this order since the QSceen doesn't own the platform screen
+ delete screen;
delete platformScreen;
}