aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2022-02-07 15:48:30 +0100
committerFabian Kosmale <fabian.kosmale@qt.io>2022-02-10 21:41:53 +0100
commit1b65829d3ab342230eb13493cefce0cd6c93ed79 (patch)
tree4f49de38f233b4ad45cd440deb93486335fbd50c /tests
parent1f4b5760031bc0d2e090e0f76237a9477cebc65d (diff)
Correctly handle QQuickState::when
64c1fbe96c68b1286a70242ff4922be140128cb2 fixed that one could not assign a constant value to QQuickState::when. However, as alluded to by a comment in QQState's code, this caused state oscillation, breaking clean transitions between two states. The reason for this issue is that as soon as once of the when condition changes, we check the when condition of all states. However, in the case of logically exclusive cases we can run into the issue that the binding of the second state has not been re-evaluated yet. Thus, we might end up with all states being false, even though the second one becomes true immediately afterwards. To avoid this issue, we force the reevaluation of the binding. However, instead of doing this by using a QQmlBinding property (with all the tooling and runtime issues that it would entail), we keep using a normal property. We then ask the engine for the binding, and if it exists, we reevaluate it to obtain the current value. Fixes: QTBUG-86695 Change-Id: Id10a3549935794b93b29450b0f5dfb6d1df691a1 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> (cherry picked from commit a8c729d83979fb0b9939044d246e73b1d578e65b) Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/quick/qquickstates/data/noStateOsciallation.qml22
-rw-r--r--tests/auto/quick/qquickstates/tst_qquickstates.cpp15
2 files changed, 37 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickstates/data/noStateOsciallation.qml b/tests/auto/quick/qquickstates/data/noStateOsciallation.qml
new file mode 100644
index 0000000000..f0d7aeeb6d
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/noStateOsciallation.qml
@@ -0,0 +1,22 @@
+import QtQuick 2.15
+
+Item {
+ id: root
+ property int number: 2
+ property int stateChangeCounter: 0
+
+ Item {
+ id: item
+ onStateChanged: ++stateChangeCounter
+ states: [
+ State {
+ name: "n1"
+ when: root.number === 1
+ },
+ State {
+ name: "n2"
+ when: root.number === 2
+ }
+ ]
+ }
+}
diff --git a/tests/auto/quick/qquickstates/tst_qquickstates.cpp b/tests/auto/quick/qquickstates/tst_qquickstates.cpp
index 849522454f..aa55b42935 100644
--- a/tests/auto/quick/qquickstates/tst_qquickstates.cpp
+++ b/tests/auto/quick/qquickstates/tst_qquickstates.cpp
@@ -188,6 +188,7 @@ private slots:
void revertListMemoryLeak();
void duplicateStateName();
void trivialWhen();
+ void noStateOsciallation();
void parentChangeCorrectReversal();
void revertNullObjectBinding();
};
@@ -1733,6 +1734,20 @@ void tst_qquickstates::trivialWhen()
QVERIFY(c.create());
}
+void tst_qquickstates::noStateOsciallation()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("noStateOsciallation.qml"));
+ QScopedPointer<QObject> root {component.create()};
+ QVERIFY(root);
+ // set to 1 on initial transition from "" to "n2"
+ QCOMPARE(root->property("stateChangeCounter").toInt(), 1);
+ root->setProperty("number", 1);
+ // setting number to 1 changes directly from "n2" to "n1"
+ // without any intermediate transition to ""
+ QCOMPARE(root->property("stateChangeCounter").toInt(), 2);
+}
+
void tst_qquickstates::parentChangeCorrectReversal()
{
QQmlEngine engine;