diff options
| author | Morten Sørvig <morten.sorvig@qt.io> | 2026-09-01 16:10:47 +0200 |
|---|---|---|
| committer | Morten Sørvig <morten.sorvig@qt.io> | 2026-09-21 11:01:30 +0000 |
| commit | fbe7fa601343a50ef08f698db4a233687cadd681 (patch) | |
| tree | 678367f4a2aa8087be34027a0a978cdb07e9cec2 | |
| parent | 87fe30c622af28b1fcf4a6de873b6504f7c85fe9 (diff) | |
QQuickMultiPointTouchArea: ignore sub-pixel noise at the drag threshold
updateTouchData() detects a grab gesture once a touch point has moved more
than QStyleHints::startDragDistance(). tst_QQuickMultiPointTouchArea::mouseGestureStarted
enforces this with a test which expects a move of +dragThreshold not to start
a drag and a further +1 to do so
However, at fractional scale factors the computed delta can end up having
floating point rounding errors due to scaling round-trips between native
and device independent coordinates. This would cause a mouseGestureStarted
test failure when updateTouchData() decided that startDragDistance + (~1e-13)
was larger than startDragDistance and start a drag.
Fix this by replacing the operator > based comparison with one that checks
for floating point rounding errors using qFuzzyCompare() as well.
Task-number: QTBUG-146901
Change-Id: I8da3894cd2c922a59e0aec3a2a16f81b9d03e4bd
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
| -rw-r--r-- | src/quick/items/qquickmultipointtoucharea.cpp | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp index 1865409de7..d36eebebda 100644 --- a/src/quick/items/qquickmultipointtoucharea.cpp +++ b/src/quick/items/qquickmultipointtoucharea.cpp @@ -659,14 +659,23 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event, RemapEventPoints if (!_stealMouse /* !ignoring gesture*/) { bool offerGrab = false; const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); + + // overThreshold test predicate which does not consider deltas with floating + // point rounding residuals to be over the threshld. Required for test stability + // at fractional scale factors where scaling may introduce rounding errors. + const auto overThreshold = [dragThreshold](qreal delta) { + return qAbs(delta) > dragThreshold + && !qFuzzyCompare(qAbs(delta), qreal(dragThreshold)); + }; + for (const QEventPoint &p : std::as_const(touchPoints)) { if (p.state() == QEventPoint::State::Released) continue; const QPointF currentPos = mapFromScene(p.scenePosition()); const QPointF startPos = mapFromScene(p.scenePressPosition()); - if (qAbs(currentPos.x() - startPos.x()) > dragThreshold) + if (overThreshold(currentPos.x() - startPos.x())) offerGrab = true; - else if (qAbs(currentPos.y() - startPos.y()) > dragThreshold) + else if (overThreshold(currentPos.y() - startPos.y())) offerGrab = true; if (offerGrab) break; |
