diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2022-04-12 17:50:07 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2022-08-10 23:48:33 +0200 |
commit | 5be302fa9b3bacc9247eb4a6c65eb03eafe11c3f (patch) | |
tree | c25d1451bd351408674834f833959db6d29b84da | |
parent | 13d6adac3812b8c1fd78b9833f0fe5b1346d0427 (diff) |
QQuickControlPrivate::resizeBackground: preserve geometry binding
When resizing the background, use setSize instead of setWidth and
setHeight to reduce the number of geometryChange calls when both width
and height get resized.
Additionally, setSize preserves bindings, which fixes the linked bug: We
would resize the background even when we have binding on height/width,
which would later overwrite the value again. With the porting to
bindable properties, the setWidth/Height calls would have destroyed that
binding. setSize avoids that issue.
Lastly, do not even attempt to overwrite the binding when we detect that
it exists.
Fixes: QTBUG-102136
Change-Id: I16a99fd9f7d56f84b423b477d373e265e39d4094
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
(cherry picked from commit cda435941ee0a8e5d0d9491d337e89a6982f2e0d)
Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io>
3 files changed, 70 insertions, 2 deletions
diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index 346eb8fba0..e0d2740519 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -348,15 +348,26 @@ void QQuickControlPrivate::resizeBackground() resizingBackground = true; QQuickItemPrivate *p = QQuickItemPrivate::get(background); + bool changeWidth = false; + bool changeHeight = false; if (((!p->widthValid() || !extra.isAllocated() || !extra->hasBackgroundWidth) && qFuzzyIsNull(background->x())) || (extra.isAllocated() && (extra->hasLeftInset || extra->hasRightInset))) { background->setX(getLeftInset()); - background->setWidth(width - getLeftInset() - getRightInset()); + changeWidth = !p->width.hasBinding(); } if (((!p->heightValid() || !extra.isAllocated() || !extra->hasBackgroundHeight) && qFuzzyIsNull(background->y())) || (extra.isAllocated() && (extra->hasTopInset || extra->hasBottomInset))) { background->setY(getTopInset()); - background->setHeight(height - getTopInset() - getBottomInset()); + changeHeight = !p->height.hasBinding(); + } + if (changeHeight || changeWidth) { + auto newWidth = changeWidth ? + width.valueBypassingBindings() - getLeftInset() - getRightInset() : + p->width.valueBypassingBindings(); + auto newHeight = changeHeight ? + height.valueBypassingBindings() - getTopInset() - getBottomInset() : + p->height.valueBypassingBindings(); + background->setSize({newWidth, newHeight}); } resizingBackground = false; diff --git a/tests/auto/quickcontrols2/qquickcontrol/data/resizeBackgroundKeepsBindings.qml b/tests/auto/quickcontrols2/qquickcontrol/data/resizeBackgroundKeepsBindings.qml new file mode 100644 index 0000000000..9a6a159990 --- /dev/null +++ b/tests/auto/quickcontrols2/qquickcontrol/data/resizeBackgroundKeepsBindings.qml @@ -0,0 +1,42 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 + +ApplicationWindow { + width: 640 + height: 80 + visible: true + + Slider { + id: control + value: 0.5 + anchors.fill: parent + + background: Rectangle { + id: background + x: control.leftPadding + y: control.topPadding + control.availableHeight / 2 - height / 2 + implicitHeight: 4 + width: control.availableWidth + height: implicitHeight + radius: 2 + color: "#bdbebf" + + Rectangle { + width: control.visualPosition * parent.width + height: parent.height + color: "#21be2b" + radius: 2 + } + } + + handle: Rectangle { + x: control.leftPadding + control.visualPosition * (control.availableWidth - width) + y: control.topPadding + control.availableHeight / 2 - height / 2 + implicitWidth: 26 + implicitHeight: 26 + radius: 13 + color: control.pressed ? "#f0f0f0" : "#f6f6f6" + border.color: "#bdbebf" + } + } +} diff --git a/tests/auto/quickcontrols2/qquickcontrol/tst_qquickcontrol.cpp b/tests/auto/quickcontrols2/qquickcontrol/tst_qquickcontrol.cpp index 9086d958b0..ca6183e41d 100644 --- a/tests/auto/quickcontrols2/qquickcontrol/tst_qquickcontrol.cpp +++ b/tests/auto/quickcontrols2/qquickcontrol/tst_qquickcontrol.cpp @@ -23,6 +23,7 @@ private slots: void initTestCase() override; void flickable(); void fractionalFontSize(); + void resizeBackgroundKeepsBindings(); private: QScopedPointer<QPointingDevice> touchDevice; @@ -91,6 +92,20 @@ void tst_QQuickControl::fractionalFontSize() "The QQuickText::contentWidth() doesn't match the layout's preferred text width"); } +void tst_QQuickControl::resizeBackgroundKeepsBindings() +{ + QQuickApplicationHelper helper(this, QStringLiteral("resizeBackgroundKeepsBindings.qml")); + QQuickWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + auto ctxt = qmlContext(window); + QVERIFY(ctxt); + auto background = qobject_cast<QQuickItem *>(ctxt->objectForName("background")); + QVERIFY(background); + QCOMPARE(background->height(), 4); + QVERIFY(background->bindableHeight().hasBinding()); +} + QTEST_QUICKCONTROLS_MAIN(tst_QQuickControl) #include "tst_qquickcontrol.moc" |