diff options
author | Tor Arne Vestbø <[email protected]> | 2022-09-09 16:41:49 +0200 |
---|---|---|
committer | Tor Arne Vestbø <[email protected]> | 2023-03-28 17:31:17 +0200 |
commit | 3a2277cb634dd394b4245d2f7f26b8b5357b806f (patch) | |
tree | 9b68168abb5d54dbe8e0f13185a2c0a49efc6f0c | |
parent | 2187936978c93e73c86119e8ef99625e9f2b4109 (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.cpp | 6 | ||||
-rw-r--r-- | src/gui/kernel/qscreen.cpp | 40 | ||||
-rw-r--r-- | src/gui/kernel/qwindowsysteminterface.cpp | 46 |
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; } |