From abb84abcd000343db91adbac6689397b1e86efea Mon Sep 17 00:00:00 2001 From: Debian Qt/KDE Maintainers Date: Thu, 29 Sep 2022 09:39:46 +0100 Subject: [PATCH] QQuickLoader: do not incubate if the source arrives after setActive(false) Origin: upstream, https://code.qt.io/cgit/qt/qtdeclarative.git/commit/?id=e78c068700fa74ab Last-Update: 2022-07-01 Otherwise we end up in the crazy place of active being false but item being non-null and forces us to workaround within the apps. Gbp-Pq: Name QQuickLoader-Do-not-incubate-if-the-source-arrives-a.patch --- src/quick/items/qquickloader.cpp | 3 +++ .../data/loader-async-race-rect.qml | 10 ++++++++++ .../qquickloader/data/loader-async-race.qml | 14 ++++++++++++++ .../quick/qquickloader/tst_qquickloader.cpp | 19 +++++++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 tests/auto/quick/qquickloader/data/loader-async-race-rect.qml create mode 100644 tests/auto/quick/qquickloader/data/loader-async-race.qml diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp index cb4f79a3c..7fbe66fdd 100644 --- a/src/quick/items/qquickloader.cpp +++ b/src/quick/items/qquickloader.cpp @@ -737,6 +737,9 @@ void QQuickLoaderPrivate::_q_sourceLoaded() return; } + if (!active) + return; + QQmlContext *creationContext = component->creationContext(); if (!creationContext) creationContext = qmlContext(q); itemContext = new QQmlContext(creationContext); diff --git a/tests/auto/quick/qquickloader/data/loader-async-race-rect.qml b/tests/auto/quick/qquickloader/data/loader-async-race-rect.qml new file mode 100644 index 000000000..a56dcea5a --- /dev/null +++ b/tests/auto/quick/qquickloader/data/loader-async-race-rect.qml @@ -0,0 +1,10 @@ +import QtQuick 2.15 + +Rectangle { + anchors.fill: parent + color: "blue" + Item { + Item { + } + } +} diff --git a/tests/auto/quick/qquickloader/data/loader-async-race.qml b/tests/auto/quick/qquickloader/data/loader-async-race.qml new file mode 100644 index 000000000..8ba625c5c --- /dev/null +++ b/tests/auto/quick/qquickloader/data/loader-async-race.qml @@ -0,0 +1,14 @@ +import QtQuick 2.15 + +Item { + id: root + Component.onCompleted: { + myloader.active = false + } + Loader { + id: myloader + anchors.fill: parent + asynchronous: true + source: "loader-async-race-rect.qml" + } +} diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp index 0f6c811ad..dddacbaa0 100644 --- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp +++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp @@ -132,6 +132,7 @@ private slots: void statusChangeOnlyEmittedOnce(); void setSourceAndCheckStatus(); + void asyncLoaderRace(); }; Q_DECLARE_METATYPE(QList) @@ -1496,6 +1497,24 @@ void tst_QQuickLoader::setSourceAndCheckStatus() QCOMPARE(loader->status(), QQuickLoader::Null); } +void tst_QQuickLoader::asyncLoaderRace() +{ + QQmlApplicationEngine engine; + auto url = testFileUrl("loader-async-race.qml"); + engine.load(url); + auto root = engine.rootObjects().at(0); + QVERIFY(root); + + QQuickLoader *loader = root->findChild(); + QCOMPARE(loader->active(), false); + QCOMPARE(loader->status(), QQuickLoader::Null); + QCOMPARE(loader->item(), nullptr); + + QSignalSpy spy(loader, &QQuickLoader::itemChanged); + QVERIFY(!spy.wait(100)); + QCOMPARE(loader->item(), nullptr); +} + QTEST_MAIN(tst_QQuickLoader) #include "tst_qquickloader.moc" -- 2.30.2