aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Eftevaag <oliver.eftevaag@qt.io>2022-01-04 14:14:56 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-03-07 21:36:18 +0000
commitad3c2b52560f88a085a3729761c9b5baf86ce40a (patch)
treef0261fb99fd3601acf2c569bba6f9bed8652c813
parentfbb728494692d64a7d6a3a89a8e34c0b3496e9fb (diff)
QQuickScrollBar: ensure '0 ≤ size ≤ 1' and '0 ≤ minimumSize ≤ 1'
It doesn't make sense for these properties to be negative or larger than 1.0. The size property is meant to be the size of the scrollbar relative to the scroll area size, either horizontally or vertically, and should be in the value range 0 ≤ x ≤ 1, where 1 means that it covers the whole scrollbar area, and 0, meaning it's invisible. This property can be set from qml, or by QQuickFlickable with a scrollbar assigned to the Scrollbar.vertical or Scrollbar.horizontal properties. The minimumSize property can be set by the qml user, to force the scrollbar to be larger than the Flickable size / contentSize ratio. It makes sense to force the 0 ≤ x ≤ 1 constraint for this property's value as well. amends ef69623648f6f5ef5ab10dd9dee72f044334d53d As an additional sanity check, I've added a qt_is_finite() check for all qreal properties as well, just to prevent our API users from accidentally setting a property to an invalid floating point value. Change-Id: I9f2880333483bf584986801d6b7204fea8d66e58 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io> (cherry picked from commit 0e4444a74a4259ec0871ec95d3804a0bbaf3b30f) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/quicktemplates2/qquickscrollbar.cpp17
-rw-r--r--tests/auto/quickcontrols2/controls/data/tst_scrollbar.qml34
2 files changed, 43 insertions, 8 deletions
diff --git a/src/quicktemplates2/qquickscrollbar.cpp b/src/quicktemplates2/qquickscrollbar.cpp
index f20805a8f0..14d4e3a86f 100644
--- a/src/quicktemplates2/qquickscrollbar.cpp
+++ b/src/quicktemplates2/qquickscrollbar.cpp
@@ -165,7 +165,8 @@ static const QQuickItemPrivate::ChangeTypes verticalChangeTypes = changeTypes |
QQuickScrollBarPrivate::VisualArea QQuickScrollBarPrivate::visualArea() const
{
qreal visualPos = position;
- if (minimumSize > size)
+
+ if (minimumSize > size && size != 1.0)
visualPos = position / (1.0 - size) * (1.0 - minimumSize);
qreal visualSize = qBound<qreal>(0, qMax(size, minimumSize) + qMin<qreal>(0, visualPos),
@@ -178,7 +179,7 @@ QQuickScrollBarPrivate::VisualArea QQuickScrollBarPrivate::visualArea() const
qreal QQuickScrollBarPrivate::logicalPosition(qreal position) const
{
- if (minimumSize > size)
+ if (minimumSize > size && minimumSize != 1.0)
return position * (1.0 - size) / (1.0 - minimumSize);
return position;
}
@@ -434,11 +435,11 @@ qreal QQuickScrollBar::size() const
void QQuickScrollBar::setSize(qreal size)
{
Q_D(QQuickScrollBar);
- if (qFuzzyCompare(d->size, size))
+ if (!qt_is_finite(size) || qFuzzyCompare(d->size, size))
return;
auto oldVisualArea = d->visualArea();
- d->size = size;
+ d->size = qBound(0.0, size, 1.0);
if (isComponentComplete())
d->resizeContent();
emit sizeChanged();
@@ -466,7 +467,7 @@ qreal QQuickScrollBar::position() const
void QQuickScrollBar::setPosition(qreal position)
{
Q_D(QQuickScrollBar);
- if (qFuzzyCompare(d->position, position))
+ if (!qt_is_finite(position) || qFuzzyCompare(d->position, position))
return;
auto oldVisualArea = d->visualArea();
@@ -493,7 +494,7 @@ qreal QQuickScrollBar::stepSize() const
void QQuickScrollBar::setStepSize(qreal step)
{
Q_D(QQuickScrollBar);
- if (qFuzzyCompare(d->stepSize, step))
+ if (!qt_is_finite(step) || qFuzzyCompare(d->stepSize, step))
return;
d->stepSize = step;
@@ -737,11 +738,11 @@ qreal QQuickScrollBar::minimumSize() const
void QQuickScrollBar::setMinimumSize(qreal minimumSize)
{
Q_D(QQuickScrollBar);
- if (qFuzzyCompare(d->minimumSize, minimumSize))
+ if (!qt_is_finite(minimumSize) || qFuzzyCompare(d->minimumSize, minimumSize))
return;
auto oldVisualArea = d->visualArea();
- d->minimumSize = minimumSize;
+ d->minimumSize = qBound(0.0, minimumSize, 1.0);
if (isComponentComplete())
d->resizeContent();
emit minimumSizeChanged();
diff --git a/tests/auto/quickcontrols2/controls/data/tst_scrollbar.qml b/tests/auto/quickcontrols2/controls/data/tst_scrollbar.qml
index d49658762c..d453f017e7 100644
--- a/tests/auto/quickcontrols2/controls/data/tst_scrollbar.qml
+++ b/tests/auto/quickcontrols2/controls/data/tst_scrollbar.qml
@@ -964,4 +964,38 @@ TestCase {
compare(vertical.visualPosition, 0.2)
compare(vertical.contentItem.y, vertical.topPadding + 0.2 * vertical.availableHeight)
}
+
+ function test_setting_invalid_property_values() {
+ var control = createTemporaryObject(scrollBar, testCase, {size: 2.0, minimumSize: -1.0})
+ verify(control)
+
+ // check that the values are within the expected range
+ compare(control.size, 1.0)
+ compare(control.minimumSize, 0)
+
+ control.minimumSize = 2.0
+ compare(control.minimumSize, 1.0)
+
+ // test if setting NaN is prevented
+ control.size = NaN
+ control.minimumSize = NaN
+ compare(control.size, 1.0)
+ compare(control.minimumSize, 1.0)
+
+
+ // test if setting float infinity is prevented
+ control.size = Number.POSITIVE_INFINITY
+ control.minimumSize = Number.POSITIVE_INFINITY
+ compare(control.size, 1.0)
+ compare(control.minimumSize, 1.0)
+
+ let oldPosition = control.position;
+ let oldStepSize = control.stepSize;
+
+ control.position = NaN;
+ control.stepSize = NaN;
+
+ compare(oldPosition, control.position)
+ compare(oldStepSize, control.stepSize)
+ }
}