aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Faure <david.faure@kdab.com>2025-09-15 20:13:23 +0200
committerJani Heikkinen <jani.heikkinen@qt.io>2025-09-17 06:14:08 +0000
commit830d021459c9ce358b0ff3b8dc5da0bf5203962a (patch)
tree4046c9707f57cb886c7e190190656c39afd0e416
parent4816b7750a4c51e487936b18b313316943e75d49 (diff)
QQuickWindow: disconnect incoming signals in dtor to avoid assert
qtbase commit 92a65fdac69d7773b114584f1637946622cf4f72 changed what happened when deleting a QWindow with child windows: they are now deleted earlier, from ~QWindow rather than from ~QObject. As a consequence, if the deletion of the child window triggers any signal (such as QSGRenderContext::invalidated), the parent window now receives it (while before, the code in ~QObject would disconnect the parent window from all senders). Fixed by explicit disconnects, using a std::array of QMetaObject::Connections, like in QSortFilterProxyModel for instance. Task-number: QTBUG-140170 Change-Id: Id2c402d3121c8a3e6962cfed0afe1e90f5f14b3f Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> (cherry picked from commit a346f6d0f3a26b134060b8d3f9e008a8e08353b9) Reviewed-by: Akseli Salovaara <akseli.salovaara@qt.io>
-rw-r--r--src/quick/items/qquickwindow.cpp19
-rw-r--r--src/quick/items/qquickwindow_p.h1
2 files changed, 13 insertions, 7 deletions
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 60c4c1633e..f1b131e7e9 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -817,14 +817,16 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control)
animationController.reset(new QQuickAnimatorController(q));
- QObject::connect(context, &QSGRenderContext::initialized, q, &QQuickWindow::sceneGraphInitialized, Qt::DirectConnection);
- QObject::connect(context, &QSGRenderContext::invalidated, q, &QQuickWindow::sceneGraphInvalidated, Qt::DirectConnection);
- QObject::connect(context, &QSGRenderContext::invalidated, q, &QQuickWindow::cleanupSceneGraph, Qt::DirectConnection);
+ connections = {
+ QObject::connect(context, &QSGRenderContext::initialized, q, &QQuickWindow::sceneGraphInitialized, Qt::DirectConnection),
+ QObject::connect(context, &QSGRenderContext::invalidated, q, &QQuickWindow::sceneGraphInvalidated, Qt::DirectConnection),
+ QObject::connect(context, &QSGRenderContext::invalidated, q, &QQuickWindow::cleanupSceneGraph, Qt::DirectConnection),
- QObject::connect(q, &QQuickWindow::focusObjectChanged, q, &QQuickWindow::activeFocusItemChanged);
- QObject::connect(q, &QQuickWindow::screenChanged, q, &QQuickWindow::handleScreenChanged);
- QObject::connect(qApp, &QGuiApplication::applicationStateChanged, q, &QQuickWindow::handleApplicationStateChanged);
- QObject::connect(q, &QQuickWindow::frameSwapped, q, &QQuickWindow::runJobsAfterSwap, Qt::DirectConnection);
+ QObject::connect(q, &QQuickWindow::focusObjectChanged, q, &QQuickWindow::activeFocusItemChanged),
+ QObject::connect(q, &QQuickWindow::screenChanged, q, &QQuickWindow::handleScreenChanged),
+ QObject::connect(qApp, &QGuiApplication::applicationStateChanged, q, &QQuickWindow::handleApplicationStateChanged),
+ QObject::connect(q, &QQuickWindow::frameSwapped, q, &QQuickWindow::runJobsAfterSwap, Qt::DirectConnection),
+ };
if (QQmlInspectorService *service = QQmlDebugConnector::service<QQmlInspectorService>())
service->addWindow(q);
@@ -1213,6 +1215,9 @@ QQuickWindow::~QQuickWindow()
// have their destructors loaded while they the library is still
// loaded into memory.
QQuickPixmap::purgeCache();
+
+ for (const QMetaObject::Connection &connection : d->connections)
+ disconnect(connection);
}
#if QT_CONFIG(quick_shadereffect)
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index f4769a8c7f..8da8b0b6c0 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -194,6 +194,7 @@ public:
qreal lastReportedItemDevicePixelRatio;
QMetaObject::Connection physicalDpiChangedConnection;
+ std::array<QMetaObject::Connection, 7> connections;
void updateDirtyNodes();
void cleanupNodes();