diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index c25f67faf83..8131c314d75 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -125,6 +125,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -142,7 +143,7 @@ Q_GUI_EXPORT bool qt_is_gui_used = true; Qt::MouseButtons QGuiApplicationPrivate::mouse_buttons = Qt::NoButton; Qt::KeyboardModifiers QGuiApplicationPrivate::modifier_buttons = Qt::NoModifier; -QPointF QGuiApplicationPrivate::lastCursorPosition(qt_inf(), qt_inf()); +QGuiApplicationPrivate::QLastCursorPosition QGuiApplicationPrivate::lastCursorPosition; QWindow *QGuiApplicationPrivate::currentMouseWindow = nullptr; @@ -704,7 +705,7 @@ QGuiApplication::~QGuiApplication() QGuiApplicationPrivate::desktopFileName = nullptr; QGuiApplicationPrivate::mouse_buttons = Qt::NoButton; QGuiApplicationPrivate::modifier_buttons = Qt::NoModifier; - QGuiApplicationPrivate::lastCursorPosition = {qreal(qInf()), qreal(qInf())}; + QGuiApplicationPrivate::lastCursorPosition.reset(); QGuiApplicationPrivate::currentMousePressWindow = QGuiApplicationPrivate::currentMouseWindow = nullptr; QGuiApplicationPrivate::applicationState = Qt::ApplicationInactive; QGuiApplicationPrivate::currentDragWindow = nullptr; @@ -4140,6 +4141,14 @@ QPixmap QGuiApplicationPrivate::getPixmapCursor(Qt::CursorShape cshape) return QPixmap(); } +QPoint QGuiApplicationPrivate::QLastCursorPosition::toPoint() const noexcept +{ + // Guard against the default initialization of qInf() (avoid UB or SIGFPE in conversion). + if (Q_UNLIKELY(qIsInf(thePoint.x()))) + return QPoint(std::numeric_limits::max(), std::numeric_limits::max()); + return thePoint.toPoint(); +} + void QGuiApplicationPrivate::notifyThemeChanged() { updatePalette(); diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 5845d983745..a6c48c2baef 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -61,6 +61,7 @@ #include #include +#include #include #include @@ -225,7 +226,19 @@ public: virtual bool popupActive() { return false; } static Qt::MouseButton mousePressButton; - static QPointF lastCursorPosition; + static struct QLastCursorPosition { + constexpr inline QLastCursorPosition() noexcept : thePoint(qt_inf(), qt_inf()) {} + 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(); } + constexpr inline qreal y() const noexcept{ return thePoint.y(); } + Q_GUI_EXPORT QPoint toPoint() const noexcept; + + constexpr void reset() noexcept { *this = QLastCursorPosition{}; } + + private: + QPointF thePoint; + } lastCursorPosition; static QWindow *currentMouseWindow; static QWindow *currentMousePressWindow; static Qt::ApplicationState applicationState; diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 1501407a42d..066c8b552f5 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -413,7 +413,7 @@ void QWidgetWindow::handleEnterLeaveEvent(QEvent *event) QWindowSystemInterfacePrivate::EnterEvent *systemEvent = static_cast (QWindowSystemInterfacePrivate::peekWindowSystemEvent(QWindowSystemInterfacePrivate::Enter)); - const QPointF globalPosF = systemEvent ? systemEvent->globalPos : QGuiApplicationPrivate::lastCursorPosition; + const QPointF globalPosF = systemEvent ? systemEvent->globalPos : QPointF(QGuiApplicationPrivate::lastCursorPosition); if (systemEvent) { if (QWidgetWindow *enterWindow = qobject_cast(systemEvent->enter)) {