Add a QHoverEvent ctor taking global mouse position; deprecate the other
The QSinglePointEvent ctor assumes that the given globalPos is correct, so it was wrong that the QHoverEvent ctor passed along a local position as global. It's better to require globalPos as an argument; and in fact it seems that everywhere we construct a QHoverEvent, global position is available, or possible to get by transformation (which is better than resorting to QCursor::pos()). Also, don't convert to QPoint: pointer events have qreal resolution and there's no reason to truncate them. Fixes: QTBUG-100324 Change-Id: I919455da36265988d3d149eb97563c9ed0d2c660 Pick-to: 6.3 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
5c6f8b2c67
commit
0a64a044b6
@ -1068,6 +1068,27 @@ Qt::MouseEventFlags QMouseEvent::flags() const
|
||||
The \a type parameter must be QEvent::HoverEnter,
|
||||
QEvent::HoverLeave, or QEvent::HoverMove.
|
||||
|
||||
The \a pos is the current mouse cursor's position relative to the
|
||||
receiving widget, \a oldPos is its previous such position, and
|
||||
\a globalPos is the mouse position in absolute coordinates.
|
||||
\a modifiers hold the state of all keyboard modifiers at the time
|
||||
of the event.
|
||||
*/
|
||||
QHoverEvent::QHoverEvent(Type type, const QPointF &pos, const QPointF &globalPos, const QPointF &oldPos,
|
||||
Qt::KeyboardModifiers modifiers, const QPointingDevice *device)
|
||||
: QSinglePointEvent(type, device, pos, pos, globalPos, Qt::NoButton, Qt::NoButton, modifiers), m_oldPos(oldPos)
|
||||
{
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(6, 3)
|
||||
/*!
|
||||
\deprecated [6.3] Use the other constructor instead (global position is required).
|
||||
|
||||
Constructs a hover event object originating from \a device.
|
||||
|
||||
The \a type parameter must be QEvent::HoverEnter,
|
||||
QEvent::HoverLeave, or QEvent::HoverMove.
|
||||
|
||||
The \a pos is the current mouse cursor's position relative to the
|
||||
receiving widget, while \a oldPos is its previous such position.
|
||||
\a modifiers hold the state of all keyboard modifiers at the time
|
||||
@ -1078,6 +1099,7 @@ QHoverEvent::QHoverEvent(Type type, const QPointF &pos, const QPointF &oldPos,
|
||||
: QSinglePointEvent(type, device, pos, pos, pos, Qt::NoButton, Qt::NoButton, modifiers), m_oldPos(oldPos)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
@ -281,9 +281,15 @@ class Q_GUI_EXPORT QHoverEvent : public QSinglePointEvent
|
||||
{
|
||||
Q_EVENT_DISABLE_COPY(QHoverEvent);
|
||||
public:
|
||||
QHoverEvent(Type type, const QPointF &pos, const QPointF &globalPos, const QPointF &oldPos,
|
||||
Qt::KeyboardModifiers modifiers = Qt::NoModifier,
|
||||
const QPointingDevice *device = QPointingDevice::primaryPointingDevice());
|
||||
#if QT_DEPRECATED_SINCE(6, 3)
|
||||
QT_DEPRECATED_VERSION_X_6_3("Use the other constructor")
|
||||
QHoverEvent(Type type, const QPointF &pos, const QPointF &oldPos,
|
||||
Qt::KeyboardModifiers modifiers = Qt::NoModifier,
|
||||
const QPointingDevice *device = QPointingDevice::primaryPointingDevice());
|
||||
#endif
|
||||
~QHoverEvent();
|
||||
|
||||
QHoverEvent *clone() const override { return new QHoverEvent(*this); }
|
||||
|
@ -2073,7 +2073,7 @@ void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave, con
|
||||
if (w->testAttribute(Qt::WA_Hover) &&
|
||||
(!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
|
||||
Q_ASSERT(instance());
|
||||
QHoverEvent he(QEvent::HoverLeave, QPoint(-1, -1), w->mapFromGlobal(QApplicationPrivate::instance()->hoverGlobalPos),
|
||||
QHoverEvent he(QEvent::HoverLeave, QPointF(-1, -1), globalPosF, w->mapFromGlobal(globalPosF),
|
||||
QGuiApplication::keyboardModifiers());
|
||||
qApp->d_func()->notify_helper(w, &he);
|
||||
}
|
||||
@ -2081,19 +2081,19 @@ void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave, con
|
||||
}
|
||||
if (!enterList.isEmpty()) {
|
||||
// Guard against QGuiApplicationPrivate::lastCursorPosition initialized to qInf(), qInf().
|
||||
const QPoint globalPos = qIsInf(globalPosF.x())
|
||||
? QPoint(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)
|
||||
: globalPosF.toPoint();
|
||||
const QPoint windowPos = qAsConst(enterList).back()->window()->mapFromGlobal(globalPos);
|
||||
const QPointF globalPos = qIsInf(globalPosF.x())
|
||||
? QPointF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)
|
||||
: globalPosF;
|
||||
const QPointF windowPos = qAsConst(enterList).back()->window()->mapFromGlobal(globalPos);
|
||||
for (auto it = enterList.crbegin(), end = enterList.crend(); it != end; ++it) {
|
||||
auto *w = *it;
|
||||
if (!QApplication::activeModalWidget() || QApplicationPrivate::tryModalHelper(w, nullptr)) {
|
||||
const QPointF localPos = w->mapFromGlobal(globalPos);
|
||||
QEnterEvent enterEvent(localPos, windowPos, globalPosF);
|
||||
QEnterEvent enterEvent(localPos, windowPos, globalPos);
|
||||
QCoreApplication::sendEvent(w, &enterEvent);
|
||||
if (w->testAttribute(Qt::WA_Hover) &&
|
||||
(!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
|
||||
QHoverEvent he(QEvent::HoverEnter, localPos, QPoint(-1, -1),
|
||||
QHoverEvent he(QEvent::HoverEnter, localPos, QPointF(-1, -1), globalPos,
|
||||
QGuiApplication::keyboardModifiers());
|
||||
qApp->d_func()->notify_helper(w, &he);
|
||||
}
|
||||
@ -2843,11 +2843,11 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
|
||||
|
||||
w = static_cast<QWidget *>(receiver);
|
||||
relpos = mouse->position().toPoint();
|
||||
QPoint diff = relpos - w->mapFromGlobal(d->hoverGlobalPos);
|
||||
QPoint diff = relpos - w->mapFromGlobal(mouse->globalPosition().toPoint());
|
||||
while (w) {
|
||||
if (w->testAttribute(Qt::WA_Hover) &&
|
||||
(!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
|
||||
QHoverEvent he(QEvent::HoverMove, relpos, relpos - diff, mouse->modifiers());
|
||||
QHoverEvent he(QEvent::HoverMove, relpos, mouse->globalPosition(), relpos - diff, mouse->modifiers());
|
||||
d->notify_helper(w, &he);
|
||||
}
|
||||
if (w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
|
||||
|
@ -1511,11 +1511,11 @@ void tst_QHeaderView::testEvent()
|
||||
void protected_QHeaderView::testEvent()
|
||||
{
|
||||
// No crashy please
|
||||
QHoverEvent enterEvent(QEvent::HoverEnter, QPoint(), QPoint());
|
||||
QHoverEvent enterEvent(QEvent::HoverEnter, QPoint(), QPoint(), QPoint());
|
||||
event(&enterEvent);
|
||||
QHoverEvent eventLeave(QEvent::HoverLeave, QPoint(), QPoint());
|
||||
QHoverEvent eventLeave(QEvent::HoverLeave, QPoint(), QPoint(), QPoint());
|
||||
event(&eventLeave);
|
||||
QHoverEvent eventMove(QEvent::HoverMove, QPoint(), QPoint());
|
||||
QHoverEvent eventMove(QEvent::HoverMove, QPoint(), QPoint(), QPoint());
|
||||
event(&eventMove);
|
||||
}
|
||||
|
||||
|
@ -1859,11 +1859,11 @@ void tst_QMainWindow::setCursor()
|
||||
QVERIFY(QTest::qWaitForWindowActive(&mw));
|
||||
QCOMPARE(cur.shape(), mw.cursor().shape());
|
||||
|
||||
QHoverEvent enterE(QEvent::HoverEnter, QPoint(10,10), QPoint());
|
||||
QHoverEvent enterE(QEvent::HoverEnter, QPoint(10,10), QPoint(), QPoint());
|
||||
mw.event(&enterE);
|
||||
QCOMPARE(cur.shape(), mw.cursor().shape());
|
||||
|
||||
QHoverEvent leaveE(QEvent::HoverLeave, QPoint(), QPoint());
|
||||
QHoverEvent leaveE(QEvent::HoverLeave, QPoint(), QPoint(), QPoint());
|
||||
mw.event(&leaveE);
|
||||
QCOMPARE(cur.shape(), mw.cursor().shape());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user