diff options
| author | David Faure <david.faure@kdab.com> | 2025-09-15 20:13:23 +0200 |
|---|---|---|
| committer | Jani Heikkinen <jani.heikkinen@qt.io> | 2025-09-17 06:14:08 +0000 |
| commit | 830d021459c9ce358b0ff3b8dc5da0bf5203962a (patch) | |
| tree | 4046c9707f57cb886c7e190190656c39afd0e416 | |
| parent | 4816b7750a4c51e487936b18b313316943e75d49 (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.cpp | 19 | ||||
| -rw-r--r-- | src/quick/items/qquickwindow_p.h | 1 |
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(); |
