diff options
-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; } |