diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2022-07-27 17:09:34 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2022-09-02 00:40:26 +0000 |
commit | 3c0ab1326ec50a636cc442e788e79042edda9c51 (patch) | |
tree | f245899776865d466baa74b8e09b1c127b6bffdc | |
parent | c54ffcccd1eb9d4f87b04d2911eaf4351ef10953 (diff) |
Integrate property binding evaluation fix from qtbase
This is basically the same as QTBUG-105204, only with the QML engine
being involved.
Fixes: QTBUG-104982
Change-Id: I5afaadedcd7af41198702a8f2331703b4f6ef2e7
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit 2879c7c3411955b1d4f795436f803abd960c176d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/qml/qml/qqmlpropertybinding.cpp | 8 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/data/qpropertyBindingNoQPropertyCapture.qml | 19 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 23 |
3 files changed, 47 insertions, 3 deletions
diff --git a/src/qml/qml/qqmlpropertybinding.cpp b/src/qml/qml/qqmlpropertybinding.cpp index d55f1021f2..24fd48ffae 100644 --- a/src/qml/qml/qqmlpropertybinding.cpp +++ b/src/qml/qml/qqmlpropertybinding.cpp @@ -131,7 +131,8 @@ QUntypedPropertyBinding QQmlPropertyBinding::createFromBoundFunction(const QQmlP void QQmlPropertyBindingJS::expressionChanged() { - if (!asBinding()->propertyDataPtr) + auto binding = asBinding(); + if (!binding->propertyDataPtr) return; const auto currentTag = m_error.tag(); if (currentTag == InEvaluationLoop) { @@ -151,8 +152,9 @@ void QQmlPropertyBindingJS::expressionChanged() return; } m_error.setTag(InEvaluationLoop); - asBinding()->evaluateRecursive(); - asBinding()->notifyRecursive(); + PendingBindingObserverList bindingObservers; + binding->evaluateRecursive(bindingObservers); + binding->notifyNonRecursive(bindingObservers); m_error.setTag(NoTag); } diff --git a/tests/auto/qml/qqmlecmascript/data/qpropertyBindingNoQPropertyCapture.qml b/tests/auto/qml/qqmlecmascript/data/qpropertyBindingNoQPropertyCapture.qml new file mode 100644 index 0000000000..d3a151efe3 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/qpropertyBindingNoQPropertyCapture.qml @@ -0,0 +1,19 @@ +import QtQuick + +Item { + objectName: "redRectangle" + id: redRectangle + + property bool b: false + function toggle() { b = !b } + width: b ? 600 : 500 + + Item { + id: blueRectangle + objectName: "blueRectangle" + // width: b ? (100 + redRectangle.width / 2) : 25 + width: b ? redRectangle.width : 25 + } + + property int blueRectangleWidth: blueRectangle.width +} diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 87995b0aca..5904b540ed 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -292,6 +292,7 @@ private slots: void bindingBoundFunctions(); void qpropertyAndQtBinding(); void qpropertyBindingReplacement(); + void qpropertyBindingNoQPropertyCapture(); void deleteRootObjectInCreation(); void onDestruction(); void onDestructionViaGC(); @@ -7722,6 +7723,28 @@ void tst_qqmlecmascript::qpropertyBindingReplacement() QCOMPARE(root->objectName(), u"overwritten"_s); } +void tst_qqmlecmascript::qpropertyBindingNoQPropertyCapture() +{ + + QQmlEngine engine; + QQmlComponent comp(&engine, testFileUrl("qpropertyBindingNoQPropertyCapture.qml")); + std::unique_ptr<QObject> root(comp.create()); + QVERIFY2(root, qPrintable(comp.errorString())); + auto redRectangle = root.get(); + + QQmlProperty blueRectangleWidth(redRectangle, "blueRectangleWidth", &engine); + + auto toggle = [&](){ + QMetaObject::invokeMethod(root.get(), "toggle"); + }; + + QCOMPARE(blueRectangleWidth.read().toInt(), 25); + toggle(); + QCOMPARE(blueRectangleWidth.read().toInt(), 600); + toggle(); + QCOMPARE(blueRectangleWidth.read().toInt(), 25); +} + void tst_qqmlecmascript::deleteRootObjectInCreation() { QQmlEngine engine; |