From 84e09e060bedd37d8de7cded7e430371e335c029 Mon Sep 17 00:00:00 2001 From: Thomas Moerschell Date: Thu, 23 Jan 2025 00:18:41 +0000 Subject: [PATCH] QScroller: Fix no overshoot behavior Correct previously mixed up parameters to pushSegment(). stopProgress can be set to 1 so stopPos is the only terminating condition. Pick-to: 6.9 6.8 Change-Id: If590555ed08170800b67063aa10e853411180aa3 Reviewed-by: Shawn Rutledge --- src/widgets/util/qscroller.cpp | 7 ++---- src/widgets/util/qscroller.h | 3 +++ .../widgets/util/qscroller/tst_qscroller.cpp | 22 +++++++++++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/widgets/util/qscroller.cpp b/src/widgets/util/qscroller.cpp index 031b7119202..5329c8681da 100644 --- a/src/widgets/util/qscroller.cpp +++ b/src/widgets/util/qscroller.cpp @@ -1309,14 +1309,11 @@ void QScrollerPrivate::createScrollingSegments(qreal v, qreal startPos, qCDebug(lcScroller) << "Overshoot: delta:" << (stopPos - startPos); - qreal stopProgress = progressForValue(sp->scrollingCurve, qAbs((stopPos - startPos) / deltaPos)); - if (!canOvershoot) { - qCDebug(lcScroller) << "Overshoot stopp:" << stopProgress; - - pushSegment(ScrollTypeFlick, deltaTime, stopProgress, startPos, endPos, stopPos, + pushSegment(ScrollTypeFlick, deltaTime, qreal(1), startPos, deltaPos, stopPos, sp->scrollingCurve.type(), orientation); } else { + qreal stopProgress = progressForValue(sp->scrollingCurve, qAbs((stopPos - startPos) / deltaPos)); qreal oDeltaTime = sp->overshootScrollTime; qreal oStopProgress = qMin(stopProgress + oDeltaTime * qreal(0.3) / deltaTime, qreal(1)); qreal oDistance = startPos + deltaPos * sp->scrollingCurve.valueForProgress(oStopProgress) - stopPos; diff --git a/src/widgets/util/qscroller.h b/src/widgets/util/qscroller.h index a9f31218a45..fe926bc50d8 100644 --- a/src/widgets/util/qscroller.h +++ b/src/widgets/util/qscroller.h @@ -9,6 +9,8 @@ #include #include +class tst_QScroller; + QT_REQUIRE_CONFIG(scroller); QT_BEGIN_NAMESPACE @@ -106,6 +108,7 @@ private: Q_DISABLE_COPY(QScroller) Q_DECLARE_PRIVATE(QScroller) + friend class ::tst_QScroller; #ifndef QT_NO_GESTURES friend class QFlickGestureRecognizer; #endif diff --git a/tests/auto/widgets/util/qscroller/tst_qscroller.cpp b/tests/auto/widgets/util/qscroller/tst_qscroller.cpp index 3f94710f2e3..825895f8937 100644 --- a/tests/auto/widgets/util/qscroller/tst_qscroller.cpp +++ b/tests/auto/widgets/util/qscroller/tst_qscroller.cpp @@ -7,6 +7,8 @@ #include #include +#include "private/qscroller_p.h" + #include #include #include @@ -474,6 +476,26 @@ void tst_QScroller::overshoot() QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500)); QCOMPARE(sw->receivedOvershoot, false); + // -- try to scroll with overshoot (always off, slow) + sw->reset(); + sw->scrollArea = QRectF(0, 0, 1000, 1000); + + sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOff)); + s1->setScrollerProperties(sp1); + kineticScrollNoTest(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(200, 0), QPoint(215, 0)); + + // Check that segment parameters are consistent + QScrollerPrivate* priv = s1->d_func(); + QVERIFY(priv->xSegments.size() == 1); + auto& segment = priv->xSegments.head(); + QVERIFY(segment.startPos + segment.deltaPos < segment.stopPos); + + QTRY_COMPARE(s1->state(), QScroller::Inactive); + + QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0)); + QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500)); + QCOMPARE(sw->receivedOvershoot, false); + // -- try to scroll with overshoot (always on but max overshoot = 0) sp1.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 0.0); sp1.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 0.0);