Initialize QLastCursorPosition with a large number rather than infinity

Infinity has caused some problems when the floating-point position gets
converted to QPoint. We are trying to be stricter about overflows now
(cf 1145e1709d1072f7dd45683e9c25a14615603854). And we still have the
QTBUG-40856 fix in place in Qt Quick: on touch release, we pretend that
the mouse moves back to its last-known position. It should not re-visit
infinity in that case.

Why 2^23? Worst case, qreal might be a 32-bit float. If we store 2^24,
x() - 1 in floating-point ought to be accurately computed:
https://en.wikipedia.org/wiki/Single-precision_floating-point_format#IEEE_754_standard:_binary32
But often manhattanLength() is used with mouse positions, so with a
number half as big, that should also be accurately computed, even if
both operands have coordinates of 2^23.

Another way to look at this is we just need to say that the mouse cursor
is initially offscreen, until it moves to a known location. The actual
coordinate doesn't matter, as long as it's very obviously offscreen, no
matter how big the desktop's cluster of screens is.

Amends c5792dcfd631abb4f9e2b92cd6e88d7e5c373406

Fixes: QTBUG-134718
Change-Id: I246865e1ba389503aadbc833a0308b60f9b91d93
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
This commit is contained in:
Shawn Rutledge 2025-03-14 16:59:37 +01:00
parent 7d25a1a0fd
commit 209a2145f9

View File

@ -211,7 +211,9 @@ public:
static Qt::MouseButton mousePressButton;
static struct QLastCursorPosition {
constexpr inline QLastCursorPosition() noexcept : thePoint(qt_inf(), qt_inf()) {}
// Initialize to a far-offscreen position. 2^23 is small enough for accurate arithmetic
// (even manhattanLength()) even when stored in the mantissa of a 32-bit float.
constexpr inline QLastCursorPosition() noexcept : thePoint(1 << 23, 1 << 23) {}
constexpr inline Q_IMPLICIT QLastCursorPosition(QPointF p) noexcept : thePoint(p) {}
constexpr inline Q_IMPLICIT operator QPointF() const noexcept { return thePoint; }
constexpr inline qreal x() const noexcept{ return thePoint.x(); }