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 Pick-to: 6.10 6.10.0 Change-Id: Id2c402d3121c8a3e6962cfed0afe1e90f5f14b3f Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
5ab3da9daf
commit
a346f6d0f3
|
@ -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)
|
||||
|
|
|
@ -194,6 +194,7 @@ public:
|
|||
|
||||
qreal lastReportedItemDevicePixelRatio;
|
||||
QMetaObject::Connection physicalDpiChangedConnection;
|
||||
std::array<QMetaObject::Connection, 7> connections;
|
||||
|
||||
void updateDirtyNodes();
|
||||
void cleanupNodes();
|
||||
|
|
Loading…
Reference in New Issue