Make it possible to check the accepted state of touch events in tests

QTouchEventSequence simulates a QPA touch event, potentially containing
multiple points. (Despite the name, it only calls qt_handleTouchEvent()
once, so it cannot really send a sequence of events; however, one event
can contain multiple touchpoints.) Delivery is synchronous, and we keep
return values through the QWindowSystemInterface::handleTouchEvent()
template functions; so the remaining step is to return a bool from
qt_handleTouchEvent(), so that we can return a bool from commit().
This allows tests to see the same perspective as a platform plugin can:
check whether the event was accepted or not, after delivery is complete.
Some tests in Qt Quick need to start doing that, to enforce correct
behavior in QQuickDeliveryAgent.

[ChangeLog][QtTestLib] QTouchEventSequence::commit() now returns a bool
so that tests can check whether the event was accepted during delivery.

Pick-to: 6.4
Task-number: QTBUG-104656
Change-Id: I9cf87909a3f847dedbdeca257013e309ac19cf0d
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Shawn Rutledge 2022-06-30 08:49:48 +02:00
parent 0d5d914dbf
commit e1f25b1c8d
6 changed files with 29 additions and 19 deletions

View File

@ -92,17 +92,19 @@ QTouchEventSequence& QTouchEventSequence::stationary(int touchId)
return *this;
}
void QTouchEventSequence::commit(bool processEvents)
bool QTouchEventSequence::commit(bool processEvents)
{
if (points.isEmpty())
return;
return false;
QThread::msleep(1);
bool ret = false;
if (targetWindow)
qt_handleTouchEvent(targetWindow, device, points.values());
ret = qt_handleTouchEvent(targetWindow, device, points.values());
if (processEvents)
QCoreApplication::processEvents();
previousPoints = points;
points.clear();
return ret;
}
QTouchEventSequence::QTouchEventSequence(QWindow *window, QPointingDevice *aDevice, bool autoCommit)

View File

@ -12,7 +12,7 @@ QT_BEGIN_NAMESPACE
class QWindow;
Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, const QPointingDevice *device,
Q_GUI_EXPORT bool qt_handleTouchEvent(QWindow *w, const QPointingDevice *device,
const QList<QEventPoint> &points,
Qt::KeyboardModifiers mods = Qt::NoModifier);
@ -33,7 +33,7 @@ public:
QTouchEventSequence& release(int touchId, const QPoint &pt, QWindow *window = nullptr);
virtual QTouchEventSequence& stationary(int touchId);
virtual void commit(bool processEvents = true);
virtual bool commit(bool processEvents = true);
protected:
QTouchEventSequence(QWindow *window, QPointingDevice *aDevice, bool autoCommit);

View File

@ -1203,11 +1203,11 @@ namespace QTest
}
}
Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *window, const QPointingDevice *device,
Q_GUI_EXPORT bool qt_handleTouchEvent(QWindow *window, const QPointingDevice *device,
const QList<QEventPoint> &points,
Qt::KeyboardModifiers mods = Qt::NoModifier)
{
QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(window, device,
return QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(window, device,
QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window), mods);
}

View File

@ -1640,15 +1640,21 @@
*/
/*!
\fn void QTest::QTouchEventSequence::commit(bool processEvents)
\fn bool QTest::QTouchEventSequence::commit(bool processEvents)
Commits this sequence of touch events to the event system. Normally there is no need to call this
function because it is called from the destructor. However, if autoCommit is disabled, the events
only get committed upon explicitly calling this function.
Commits this touch event to the event system, and returns whether it was
accepted after delivery.
In special cases tests may want to disable the processing of the events. This can be achieved by
setting \a processEvents to false. This results in merely queuing the events, the event loop will
not be forced to process them.
Normally there is no need to call this function because it is called from
the destructor. However, if autoCommit is disabled, the events only get
committed upon explicitly calling this function. Another reason to call it
explicitly is to check the return value.
In special cases, tests may want to disable the processing of the event.
This can be achieved by setting \a processEvents to false. This results in
merely queuing the event: the event loop will not be forced to process it.
Returns whether the event was accepted after delivery.
*/
/*!

View File

@ -115,20 +115,22 @@ QTouchEventWidgetSequence& QTouchEventWidgetSequence::stationary(int touchId)
return *this;
}
void QTouchEventWidgetSequence::commit(bool processEvents)
bool QTouchEventWidgetSequence::commit(bool processEvents)
{
bool ret = false;
if (points.isEmpty())
return;
return ret;
QThread::msleep(1);
if (targetWindow) {
qt_handleTouchEvent(targetWindow, device, points.values());
ret = qt_handleTouchEvent(targetWindow, device, points.values());
} else if (targetWidget) {
qt_handleTouchEvent(targetWidget->windowHandle(), device, points.values());
ret = qt_handleTouchEvent(targetWidget->windowHandle(), device, points.values());
}
if (processEvents)
QCoreApplication::processEvents();
previousPoints = points;
points.clear();
return ret;
}
QTest::QTouchEventWidgetSequence::QTouchEventWidgetSequence(QWidget *widget, QPointingDevice *aDevice, bool autoCommit)

View File

@ -26,7 +26,7 @@ public:
QTouchEventWidgetSequence& release(int touchId, const QPoint &pt, QWidget *widget = nullptr);
QTouchEventWidgetSequence& stationary(int touchId) override;
void commit(bool processEvents = true) override;
bool commit(bool processEvents = true) override;
private:
QTouchEventWidgetSequence(QWidget *widget, QPointingDevice *aDevice, bool autoCommit);