Don't send a mouse move when we just need to do a synthetic enter/leave
[ChangeLog][QtWidgets] QApplication no longer sends a mouse move event to the entered widget if it sends synthetic enter and leave events. Task-number: QTBUG-67736 Change-Id: I75daaffd53f1ddc2bc4d7df67382cbc22d3eb6fc Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
parent
c8625a3e67
commit
8e5f6e3bed
@ -2624,7 +2624,7 @@ QWidget *QApplicationPrivate::pickMouseReceiver(QWidget *candidate, const QPoint
|
|||||||
bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
|
bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
|
||||||
QWidget *alienWidget, QWidget *nativeWidget,
|
QWidget *alienWidget, QWidget *nativeWidget,
|
||||||
QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
|
QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
|
||||||
bool spontaneous)
|
bool spontaneous, bool onlyDispatchEnterLeave)
|
||||||
{
|
{
|
||||||
Q_ASSERT(receiver);
|
Q_ASSERT(receiver);
|
||||||
Q_ASSERT(event);
|
Q_ASSERT(event);
|
||||||
@ -2685,11 +2685,17 @@ bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
|
|||||||
// We need this quard in case someone opens a modal dialog / popup. If that's the case
|
// We need this quard in case someone opens a modal dialog / popup. If that's the case
|
||||||
// leaveAfterRelease is set to null, but we shall not update lastMouseReceiver.
|
// leaveAfterRelease is set to null, but we shall not update lastMouseReceiver.
|
||||||
const bool wasLeaveAfterRelease = leaveAfterRelease != 0;
|
const bool wasLeaveAfterRelease = leaveAfterRelease != 0;
|
||||||
bool result;
|
bool result = true;
|
||||||
if (spontaneous)
|
// This code is used for sending the synthetic enter/leave events for cases where it is needed
|
||||||
result = QApplication::sendSpontaneousEvent(receiver, event);
|
// due to other events causing the widget under the mouse to change. However in those cases
|
||||||
else
|
// we do not want to send the mouse event associated with this call, so this enables us to
|
||||||
result = QApplication::sendEvent(receiver, event);
|
// not send the unneeded mouse event
|
||||||
|
if (!onlyDispatchEnterLeave) {
|
||||||
|
if (spontaneous)
|
||||||
|
result = QApplication::sendSpontaneousEvent(receiver, event);
|
||||||
|
else
|
||||||
|
result = QApplication::sendEvent(receiver, event);
|
||||||
|
}
|
||||||
|
|
||||||
if (!graphicsWidget && leaveAfterRelease && event->type() == QEvent::MouseButtonRelease
|
if (!graphicsWidget && leaveAfterRelease && event->type() == QEvent::MouseButtonRelease
|
||||||
&& !event->buttons() && QWidget::mouseGrabber() != leaveAfterRelease) {
|
&& !event->buttons() && QWidget::mouseGrabber() != leaveAfterRelease) {
|
||||||
@ -2764,9 +2770,10 @@ void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget)
|
|||||||
if (widget->data->in_destructor && qt_button_down == widget)
|
if (widget->data->in_destructor && qt_button_down == widget)
|
||||||
qt_button_down = 0;
|
qt_button_down = 0;
|
||||||
|
|
||||||
// Send enter/leave events followed by a mouse move on the entered widget.
|
// A mouse move is not actually sent, but we utilize the sendMouseEvent() call to send the
|
||||||
|
// enter/leave events as appropriate
|
||||||
QMouseEvent e(QEvent::MouseMove, pos, windowPos, globalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
|
QMouseEvent e(QEvent::MouseMove, pos, windowPos, globalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
|
||||||
sendMouseEvent(widgetUnderCursor, &e, widgetUnderCursor, tlw, &qt_button_down, qt_last_mouse_receiver);
|
sendMouseEvent(widgetUnderCursor, &e, widgetUnderCursor, tlw, &qt_button_down, qt_last_mouse_receiver, true, true);
|
||||||
#else // !QT_NO_CURSOR
|
#else // !QT_NO_CURSOR
|
||||||
Q_UNUSED(widget);
|
Q_UNUSED(widget);
|
||||||
#endif // QT_NO_CURSOR
|
#endif // QT_NO_CURSOR
|
||||||
|
@ -226,7 +226,7 @@ public:
|
|||||||
QWidget *buttonDown, QWidget *alienWidget);
|
QWidget *buttonDown, QWidget *alienWidget);
|
||||||
static bool sendMouseEvent(QWidget *receiver, QMouseEvent *event, QWidget *alienWidget,
|
static bool sendMouseEvent(QWidget *receiver, QMouseEvent *event, QWidget *alienWidget,
|
||||||
QWidget *native, QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
|
QWidget *native, QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
|
||||||
bool spontaneous = true);
|
bool spontaneous = true, bool onlyDispatchEnterLeave = false);
|
||||||
void sendSyntheticEnterLeave(QWidget *widget);
|
void sendSyntheticEnterLeave(QWidget *widget);
|
||||||
|
|
||||||
static QWindow *windowForWidget(const QWidget *widget)
|
static QWindow *windowForWidget(const QWidget *widget)
|
||||||
|
@ -9120,7 +9120,8 @@ void tst_QWidget::taskQTBUG_4055_sendSyntheticEnterLeave()
|
|||||||
void mouseMoveEvent(QMouseEvent *event)
|
void mouseMoveEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
QCOMPARE(event->button(), Qt::NoButton);
|
QCOMPARE(event->button(), Qt::NoButton);
|
||||||
QCOMPARE(event->buttons(), Qt::MouseButtons(Qt::NoButton));
|
QCOMPARE(event->buttons(), QApplication::mouseButtons());
|
||||||
|
QCOMPARE(event->modifiers(), QApplication::keyboardModifiers());
|
||||||
++numMouseMoveEvents;
|
++numMouseMoveEvents;
|
||||||
}
|
}
|
||||||
void reset() { numEnterEvents = numMouseMoveEvents = 0; }
|
void reset() { numEnterEvents = numMouseMoveEvents = 0; }
|
||||||
@ -9154,11 +9155,11 @@ void tst_QWidget::taskQTBUG_4055_sendSyntheticEnterLeave()
|
|||||||
child.setMouseTracking(true);
|
child.setMouseTracking(true);
|
||||||
child.show();
|
child.show();
|
||||||
|
|
||||||
// Make sure the child gets enter event and mouse move event.
|
// Make sure the child gets enter event.
|
||||||
// Note that we verify event->button() and event->buttons()
|
// Note that we verify event->button() and event->buttons()
|
||||||
// in SELChild::mouseMoveEvent().
|
// in SELChild::mouseMoveEvent().
|
||||||
QTRY_COMPARE(child.numEnterEvents, 1);
|
QTRY_COMPARE(child.numEnterEvents, 1);
|
||||||
QCOMPARE(child.numMouseMoveEvents, 1);
|
QCOMPARE(child.numMouseMoveEvents, 0);
|
||||||
|
|
||||||
// Sending synthetic enter/leave trough the parent's mousePressEvent handler.
|
// Sending synthetic enter/leave trough the parent's mousePressEvent handler.
|
||||||
parent.child = &child;
|
parent.child = &child;
|
||||||
@ -9167,10 +9168,19 @@ void tst_QWidget::taskQTBUG_4055_sendSyntheticEnterLeave()
|
|||||||
child.reset();
|
child.reset();
|
||||||
QTest::mouseClick(&parent, Qt::LeftButton);
|
QTest::mouseClick(&parent, Qt::LeftButton);
|
||||||
|
|
||||||
// Make sure the child gets enter event and one mouse move event.
|
// Make sure the child gets enter event.
|
||||||
QTRY_COMPARE(child.numEnterEvents, 1);
|
QTRY_COMPARE(child.numEnterEvents, 1);
|
||||||
QCOMPARE(child.numMouseMoveEvents, 1);
|
QCOMPARE(child.numMouseMoveEvents, 0);
|
||||||
|
|
||||||
|
child.hide();
|
||||||
|
child.reset();
|
||||||
|
QTest::keyPress(&parent, Qt::Key_Shift);
|
||||||
|
QTest::mouseClick(&parent, Qt::LeftButton);
|
||||||
|
|
||||||
|
// Make sure the child gets enter event
|
||||||
|
QTRY_COMPARE(child.numEnterEvents, 1);
|
||||||
|
QCOMPARE(child.numMouseMoveEvents, 0);
|
||||||
|
QTest::keyRelease(&child, Qt::Key_Shift);
|
||||||
child.hide();
|
child.hide();
|
||||||
child.reset();
|
child.reset();
|
||||||
child.setMouseTracking(false);
|
child.setMouseTracking(false);
|
||||||
|
Loading…
Reference in New Issue
Block a user