Skip to content

Commit bd75b60

Browse files
ulfhermannqtQt Cherry-pick Bot
authored andcommitted
QQmlProperty: Reset the binding bit when removing a null binding
If we remove a binding we don't want any later code to restore it. This works quite well if the binding we remove already exists. removeFromObject() resets the binding bit and that settles it. However, if the binding doesn't exist yet, we so far didn't reset the bit and when the binding appeared we would still add it to the object. That was quite wrong. Pick-to: 6.7 6.5 6.2 Fixes: QTBUG-124553 Change-Id: I58c115d78b3701ad4e8837772261a9154b971dbb Reviewed-by: Fabian Kosmale <[email protected]> (cherry picked from commit c9d7620) Reviewed-by: Qt Cherry-pick Bot <[email protected]>
1 parent 84c3ca6 commit bd75b60

File tree

4 files changed

+54
-6
lines changed

4 files changed

+54
-6
lines changed

src/qml/qml/qqmlproperty.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -843,17 +843,21 @@ static void removeOldBinding(QObject *object, QQmlPropertyIndex index, QQmlPrope
843843
oldBinding = data->bindings;
844844

845845
while (oldBinding && (oldBinding->targetPropertyIndex().coreIndex() != coreIndex ||
846-
oldBinding->targetPropertyIndex().hasValueTypeIndex()))
846+
oldBinding->targetPropertyIndex().hasValueTypeIndex())) {
847847
oldBinding = oldBinding->nextBinding();
848+
}
848849

849-
if (!oldBinding)
850-
return;
851-
852-
if (valueTypeIndex != -1 && oldBinding->kind() == QQmlAbstractBinding::ValueTypeProxy)
850+
if (valueTypeIndex != -1
851+
&& oldBinding
852+
&& oldBinding->kind() == QQmlAbstractBinding::ValueTypeProxy) {
853853
oldBinding = static_cast<QQmlValueTypeProxyBinding *>(oldBinding.data())->binding(index);
854+
}
854855

855-
if (!oldBinding)
856+
if (!oldBinding) {
857+
// Clear the binding bit so that the binding doesn't appear later for any reason
858+
data->clearBindingBit(coreIndex);
856859
return;
860+
}
857861

858862
if (!(flags & QQmlPropertyPrivate::DontEnable))
859863
oldBinding->setEnabled(false, {});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import QtQml 2.15
2+
3+
SimpleWidget {
4+
width: 20
5+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import QtQuick 2.15
2+
3+
Item {
4+
id: outer
5+
6+
property real innerWidth: 0
7+
8+
Item {
9+
id: inner
10+
width: style.width
11+
onWidthChanged: outer.innerWidth = width
12+
}
13+
14+
width: inner.width
15+
16+
onWidthChanged: {
17+
if (width !== inner.width)
18+
inner.width = width // overwrite binding
19+
}
20+
21+
QtObject {
22+
id: style
23+
property int width: 50
24+
}
25+
}

tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,8 @@ private slots:
464464
void nestedVectors();
465465
void optimizedSequenceShift();
466466

467+
void overrideInnerBinding();
468+
467469
private:
468470
QQmlEngine engine;
469471
QStringList defaultImportPathList;
@@ -8980,6 +8982,18 @@ void tst_qqmllanguage::optimizedSequenceShift()
89808982
QCOMPARE(one.toInt(), 1);
89818983
}
89828984

8985+
void tst_qqmllanguage::overrideInnerBinding()
8986+
{
8987+
QQmlEngine e;
8988+
QQmlComponent c(&e, testFileUrl("BindingOverrider.qml"));
8989+
QVERIFY2(c.isReady(), qPrintable(c.errorString()));
8990+
QScopedPointer<QObject> o(c.create());
8991+
QVERIFY(!o.isNull());
8992+
8993+
QCOMPARE(o->property("width").toReal(), 20.0);
8994+
QCOMPARE(o->property("innerWidth").toReal(), 20.0);
8995+
}
8996+
89838997
QTEST_MAIN(tst_qqmllanguage)
89848998

89858999
#include "tst_qqmllanguage.moc"

0 commit comments

Comments
 (0)