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 <shawn.rutledge@qt.io>
This commit is contained in:
Thomas Moerschell 2025-01-23 00:18:41 +00:00
parent a66f51fe82
commit 84e09e060b
3 changed files with 27 additions and 5 deletions

View File

@ -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;

View File

@ -9,6 +9,8 @@
#include <QtCore/QPointF>
#include <QtWidgets/QScrollerProperties>
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

View File

@ -7,6 +7,8 @@
#include <QtWidgets/qscroller.h>
#include <QtWidgets/qwidget.h>
#include "private/qscroller_p.h"
#include <QtGui/qevent.h>
#include <QtGui/qpointingdevice.h>
#include <QtGui/qstylehints.h>
@ -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);