aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorIvan Tkachenko <me@ratijas.tk>2023-09-02 14:16:41 +0300
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-09-05 17:03:29 +0000
commit51277900f3de7a3b9faaa9223f23cdaac935490b (patch)
tree12f8a8cadf64cba7245e7c56daa6699d8c590884 /src
parentf02735d4514149b0c297e1e2c2f7060c2fdd4e96 (diff)
ScrollBar: Fix visualSize being stuck without change signal
Fixes a bug that visualSizeChanged signal won't be emitted when needed, causing listeners such as binding expression being stuck with an old value without updates. This has caused a visual glitch with scrollbars in KDE: they appear incorrectly sized initially, but fix themselves as soon as scrolling starts. Needless to say, we don't use overshoot on desktops, but that feature is also plagued by this bug. Solution is to (1) don't assign new d->size before measuring visualArea, and (2) don't reassign oldVisualArea, because it would override visual size with an updated data, losing information needed for visualAreaChange to determine whether to emit signal or not. To optimize and avoid double-signals for visual position, existing setPosition() method was factored out into a new private method with an optional signal suppression flag. See also: https://bugs.kde.org/show_bug.cgi?id=473241 Change-Id: Id0482e5b90e08e1bb31367efe86f4a9cc046c4f6 Reviewed-by: Oliver Eftevaag <oliver.eftevaag@qt.io> (cherry picked from commit 470cc1a600ef5364fd7bee0f3f0b822ba95bab35) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src')
-rw-r--r--src/quicktemplates/qquickscrollbar.cpp29
-rw-r--r--src/quicktemplates/qquickscrollbar_p_p.h1
2 files changed, 18 insertions, 12 deletions
diff --git a/src/quicktemplates/qquickscrollbar.cpp b/src/quicktemplates/qquickscrollbar.cpp
index e99887f940..6e167a9314 100644
--- a/src/quicktemplates/qquickscrollbar.cpp
+++ b/src/quicktemplates/qquickscrollbar.cpp
@@ -409,13 +409,11 @@ void QQuickScrollBar::setSize(qreal size)
size = qBound(0.0, size, 1.0);
if (qFuzzyCompare(d->size, size))
return;
- d->size = size;
- auto oldVisualArea = d->visualArea();
- d->size = qBound(0.0, size, 1.0);
+ const auto oldVisualArea = d->visualArea();
+ d->size = size;
if (d->size + d->position > 1.0) {
- setPosition(1.0 - d->size);
- oldVisualArea = d->visualArea();
+ d->setPosition(1.0 - d->size, false);
}
if (isComponentComplete())
@@ -450,15 +448,22 @@ qreal QQuickScrollBar::position() const
void QQuickScrollBar::setPosition(qreal position)
{
Q_D(QQuickScrollBar);
- if (!qt_is_finite(position) || qFuzzyCompare(d->position, position))
+ d->setPosition(position);
+}
+
+void QQuickScrollBarPrivate::setPosition(qreal newPosition, bool notifyVisualChange)
+{
+ Q_Q(QQuickScrollBar);
+ if (!qt_is_finite(newPosition) || qFuzzyCompare(position, newPosition))
return;
- auto oldVisualArea = d->visualArea();
- d->position = position;
- if (isComponentComplete())
- d->resizeContent();
- emit positionChanged();
- d->visualAreaChange(d->visualArea(), oldVisualArea);
+ auto oldVisualArea = visualArea();
+ position = newPosition;
+ if (q->isComponentComplete())
+ resizeContent();
+ emit q->positionChanged();
+ if (notifyVisualChange)
+ visualAreaChange(visualArea(), oldVisualArea);
}
/*!
diff --git a/src/quicktemplates/qquickscrollbar_p_p.h b/src/quicktemplates/qquickscrollbar_p_p.h
index cad54882d2..2a834ce71e 100644
--- a/src/quicktemplates/qquickscrollbar_p_p.h
+++ b/src/quicktemplates/qquickscrollbar_p_p.h
@@ -45,6 +45,7 @@ public:
qreal logicalPosition(qreal position) const;
+ void setPosition(qreal position, bool notifyVisualChange = true);
qreal snapPosition(qreal position) const;
qreal positionAt(const QPointF &point) const;
void setInteractive(bool interactive);