Implement QTest:mouseMove widget overload to send event

We cannot assume that calling QCursor::setCursor results in a mouse move
event, and we can definitely not assume that the previously pressed
button (via QTest::mousePress) will be included in such an event.

Instead, follow the mechanism used in the QWindow-overload to keep track
of the mouse buttons pressed, and make those the buttons pressed in the
mouse move event we generate.

[ChangeLog][QTestLib] QTest::mouseMove no longer moves the mouse cursor
via QCursor::setPos, but instead generates a QEvent::MouseMove. Testing
of code that relies on QCursor::pos needs to be done with explicit calls
to QCursor::setPos.

Change-Id: Ia643bcc999498a0dc93479b77e107b989dfe202d
Reviewed-by: Jason McDonald <macadder1@gmail.com>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
Volker Hilsheimer 2021-10-25 12:34:25 +02:00
parent a887b7750c
commit e2e5f448ca

View File

@ -206,29 +206,36 @@ namespace QTest
stateKey &= static_cast<unsigned int>(Qt::KeyboardModifierMask);
QEvent::Type meType;
Qt::MouseButton meButton;
using namespace QTestPrivate;
switch (action)
{
case MousePress:
qtestMouseButtons.setFlag(button, true);
meType = QEvent::MouseButtonPress;
meButton = button;
break;
case MouseRelease:
qtestMouseButtons.setFlag(button, false);
meType = QEvent::MouseButtonRelease;
meButton = Qt::MouseButton();
break;
case MouseDClick:
qtestMouseButtons.setFlag(button, true);
meType = QEvent::MouseButtonDblClick;
meButton = button;
break;
case MouseMove:
QCursor::setPos(widget->mapToGlobal(pos));
qApp->processEvents();
return;
// ### Qt 7: compatibility with < Qt 6.3, we should not rely on QCursor::setPos
// for generating mouse move events, and code that depends on QCursor::pos should
// be tested using QCursor::setPos explicitly.
if (qtestMouseButtons == Qt::NoButton) {
QCursor::setPos(widget->mapToGlobal(pos));
qApp->processEvents();
return;
}
meType = QEvent::MouseMove;
break;
default:
QTEST_ASSERT(false);
}
QMouseEvent me(meType, pos, widget->mapToGlobal(pos), button, meButton, stateKey, QPointingDevice::primaryPointingDevice());
QMouseEvent me(meType, pos, widget->mapToGlobal(pos), button, qtestMouseButtons, stateKey, QPointingDevice::primaryPointingDevice());
me.setTimestamp(lastMouseTimestamp);
if (action == MouseRelease) // avoid double clicks being generated
lastMouseTimestamp += mouseDoubleClickInterval;