summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Shaw <andy.shaw@qt.io>2017-12-05 08:46:37 +0100
committerAndy Shaw <andy.shaw@qt.io>2018-04-18 08:19:41 +0000
commit8e5f6e3bed6e123cc603f12d785c47eeee495f94 (patch)
treec746e90c3820ec89272f72e18992d26aeed08ea0
parentc8625a3e67b23b346c4f64c22ac8cfca362e1211 (diff)
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>
-rw-r--r--src/widgets/kernel/qapplication.cpp23
-rw-r--r--src/widgets/kernel/qapplication_p.h2
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp20
3 files changed, 31 insertions, 14 deletions
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index c9933aff8a..8e9ce286de 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -2624,7 +2624,7 @@ QWidget *QApplicationPrivate::pickMouseReceiver(QWidget *candidate, const QPoint
bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
QWidget *alienWidget, QWidget *nativeWidget,
QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
- bool spontaneous)
+ bool spontaneous, bool onlyDispatchEnterLeave)
{
Q_ASSERT(receiver);
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
// leaveAfterRelease is set to null, but we shall not update lastMouseReceiver.
const bool wasLeaveAfterRelease = leaveAfterRelease != 0;
- bool result;
- if (spontaneous)
- result = QApplication::sendSpontaneousEvent(receiver, event);
- else
- result = QApplication::sendEvent(receiver, event);
+ bool result = true;
+ // This code is used for sending the synthetic enter/leave events for cases where it is needed
+ // due to other events causing the widget under the mouse to change. However in those cases
+ // we do not want to send the mouse event associated with this call, so this enables us to
+ // 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
&& !event->buttons() && QWidget::mouseGrabber() != leaveAfterRelease) {
@@ -2764,9 +2770,10 @@ void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget)
if (widget->data->in_destructor && qt_button_down == widget)
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);
- 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
Q_UNUSED(widget);
#endif // QT_NO_CURSOR
diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h
index 019fad3fc3..21ba47caa3 100644
--- a/src/widgets/kernel/qapplication_p.h
+++ b/src/widgets/kernel/qapplication_p.h
@@ -226,7 +226,7 @@ public:
QWidget *buttonDown, QWidget *alienWidget);
static bool sendMouseEvent(QWidget *receiver, QMouseEvent *event, QWidget *alienWidget,
QWidget *native, QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
- bool spontaneous = true);
+ bool spontaneous = true, bool onlyDispatchEnterLeave = false);
void sendSyntheticEnterLeave(QWidget *widget);
static QWindow *windowForWidget(const QWidget *widget)
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index 823a52ce70..e1c4019fba 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -9120,7 +9120,8 @@ void tst_QWidget::taskQTBUG_4055_sendSyntheticEnterLeave()
void mouseMoveEvent(QMouseEvent *event)
{
QCOMPARE(event->button(), Qt::NoButton);
- QCOMPARE(event->buttons(), Qt::MouseButtons(Qt::NoButton));
+ QCOMPARE(event->buttons(), QApplication::mouseButtons());
+ QCOMPARE(event->modifiers(), QApplication::keyboardModifiers());
++numMouseMoveEvents;
}
void reset() { numEnterEvents = numMouseMoveEvents = 0; }
@@ -9154,11 +9155,11 @@ void tst_QWidget::taskQTBUG_4055_sendSyntheticEnterLeave()
child.setMouseTracking(true);
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()
// in SELChild::mouseMoveEvent().
QTRY_COMPARE(child.numEnterEvents, 1);
- QCOMPARE(child.numMouseMoveEvents, 1);
+ QCOMPARE(child.numMouseMoveEvents, 0);
// Sending synthetic enter/leave trough the parent's mousePressEvent handler.
parent.child = &child;
@@ -9167,10 +9168,19 @@ void tst_QWidget::taskQTBUG_4055_sendSyntheticEnterLeave()
child.reset();
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);
- 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.reset();
child.setMouseTracking(false);