From a3839e8b320e29687fa15ac0b711b1c7d7b7d9cd Mon Sep 17 00:00:00 2001 From: Axel Spoerl Date: Thu, 12 Jun 2025 20:41:31 +0200 Subject: [PATCH] QWindowsScreenManager::removeScreen() - don't leave stale screen behind MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QWindowsScreenManager::removeScreen() read an element from m_screens and removed it. If the removed screen was not the primary screen, QWindowSystemInterface::flushWindowSystemEvents() is called. When removeScreen() is called from handleScreenChanges() in the same class, flushing window events can lead to a re-entry. That is e.g. the case when a RDP connection is closed and the server removes the virtual screen. QWindowScreenManager::removeScreen() removes the platform screen only at the very end, which means that m_screens contains a stale pointer. The re-entry can therefore crash with a double delete. Take the platform screen at the beginning of the method, to make it safe for re-entry. Fixes: QTBUG-135337 Pick-to: 6.8 6.5 Change-Id: Id18a6fb3e72922bcdb62c9e79857b6bb713c0c1b Reviewed-by: Tor Arne Vestbø Reviewed-by: Volker Hilsheimer Reviewed-by: Wladimir Leuschner (cherry picked from commit 3416d28c8b0fa8e5cd6622fc86fe6fc5aae9222b) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 0e0db3eefdfdde8480bf80304056d6e129168bf8) --- src/plugins/platforms/windows/qwindowsscreen.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index 6c86c47caac..ddc1114485e 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -765,7 +765,8 @@ static void moveToVirtualScreen(QWindow *w, const QScreen *newScreen) void QWindowsScreenManager::removeScreen(int index) { qCDebug(lcQpaScreen) << "Removing Monitor:" << m_screens.at(index)->data(); - QScreen *screen = m_screens.at(index)->screen(); + QPlatformScreen *platformScreen = m_screens.takeAt(index); + QScreen *screen = platformScreen->screen(); QScreen *primaryScreen = QGuiApplication::primaryScreen(); // QTBUG-38650: When a screen is disconnected, Windows will automatically // move the Window to another screen. This will trigger a geometry change @@ -791,7 +792,7 @@ void QWindowsScreenManager::removeScreen(int index) if (movedWindowCount) QWindowSystemInterface::flushWindowSystemEvents(); } - QWindowSystemInterface::handleScreenRemoved(m_screens.takeAt(index)); + QWindowSystemInterface::handleScreenRemoved(platformScreen); } /*!