QMenu: make mousePopupPos a QPointF

QMenuPrivate::mousePopupPos is a QPoint which gets set to
QGuiApplicationPrivate::lastCursorPosition, and only read from
QMenuPrivate::hasMouseMoved to determine if the mouse has moved enough.

When the last mouse position is not known, lastCursorPosition.toPoint()
returns {INT_MAX,INT_MAX} (see c5792dcfd631abb4f9e2b92cd6e88d7e5c373406
for the reasoning). This is extremely prone to overflows. In fact, one
was happening into QMenuPrivate::hasMouseMoved:

  (mousePopupPos - globalPos).manhattanLength()

On the first mouse move the subtraction yields an enormous result which
overflows manhattanLength.

The solution is simple, make mousePopupPos so that these calculations
happen in fp coordinates. The length itself is only used as a threshold
against QApplication::startDragDistance, so its representation doesn't
actually matter.

Pick-to: 6.8
Change-Id: I9c8e30a637de120d086d6f7171725702c205da78
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: David Faure <david.faure@kdab.com>
(cherry picked from commit 7736823500fe8d97bc6d12ffb88001d34d1980bb)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Giuseppe D'Angelo 2025-01-28 03:46:24 +01:00 committed by Qt Cherry-pick Bot
parent ea4a6cfdfa
commit 5adddf6cd9
2 changed files with 4 additions and 2 deletions

View File

@ -2457,8 +2457,10 @@ void QMenuPrivate::popup(const QPoint &p, QAction *atAction, PositionFunction po
return;
}
// Note that QGuiApplicationPrivate::lastCursorPosition isn't a QPointF,
// so these two statements can't be simplified...
const QPoint mouse = QGuiApplicationPrivate::lastCursorPosition.toPoint();
mousePopupPos = mouse;
mousePopupPos = QGuiApplicationPrivate::lastCursorPosition;
const bool snapToMouse = !causedPopup.widget && (QRect(p.x() - 3, p.y() - 3, 6, 6).contains(mouse));
if (adjustToDesktop) {

View File

@ -326,7 +326,7 @@ public:
//selection
static QMenu *mouseDown;
QPoint mousePopupPos;
QPointF mousePopupPos;
QAction *currentAction = nullptr;
#ifdef QT_KEYPAD_NAVIGATION