QGuiApplication: send TouchCancel when touch is interrupted by popup

QQuickWindow depends on maintaining state of known touch points
between events, so it needs to be notified when it will not be
receiving the corresponding release event for one or more.
This temporary fix needs to be reverted when we have a proper
event forwarding solution.

Task-number: QTBUG-37371

Change-Id: I5dc40af6feac425be8103c1586f8ebe3a6aad20d
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@digia.com>
bb10
Shawn Rutledge 2014-03-11 22:10:05 +01:00 committed by The Qt Project
parent 584088f200
commit efcfa0b252
2 changed files with 63 additions and 0 deletions

View File

@ -2294,6 +2294,18 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
if (w->d_func()->blockedByModalWindow) {
// a modal window is blocking this window, don't allow touch events through
// QTBUG-37371 temporary fix; TODO: revisit in 5.4 when we have a forwarding solution
if (eventType == QEvent::TouchEnd) {
// but don't leave dangling state: e.g.
// QQuickWindowPrivate::itemForTouchPointId needs to be cleared.
QTouchEvent touchEvent(QEvent::TouchCancel,
e->device,
e->modifiers);
touchEvent.setTimestamp(e->timestamp);
touchEvent.setWindow(w);
QGuiApplication::sendSpontaneousEvent(w, &touchEvent);
}
continue;
}

View File

@ -71,6 +71,7 @@ private slots:
void mouseToTouchLoop();
void touchCancel();
void touchCancelWithTouchToMouse();
void touchInterruptedByPopup();
void orientation();
void sizes();
void close();
@ -772,6 +773,56 @@ void tst_QWindow::touchCancelWithTouchToMouse()
QTRY_COMPARE(window.mouseReleaseButton, 0);
}
void tst_QWindow::touchInterruptedByPopup()
{
InputTestWindow window;
window.setGeometry(80, 80, 200, 200);
window.show();
QVERIFY(QTest::qWaitForWindowExposed(&window));
QList<QWindowSystemInterface::TouchPoint> points;
QWindowSystemInterface::TouchPoint tp1;
tp1.id = 1;
// Start a touch.
tp1.state = Qt::TouchPointPressed;
tp1.area = QRect(10, 10, 4, 4);
points << tp1;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
QCoreApplication::processEvents();
QTRY_COMPARE(window.touchEventType, QEvent::TouchBegin);
QTRY_COMPARE(window.touchPressedCount, 1);
// Launch a popup window
InputTestWindow popup;
popup.setFlags(Qt::Popup);
popup.setModality(Qt::WindowModal);
popup.setWidth(160);
popup.setHeight(160);
popup.setTransientParent(&window);
popup.show();
QVERIFY(QTest::qWaitForWindowExposed(&popup));
// Send a move -> will not be delivered to the original window
// (TODO verify where it is forwarded, after we've defined that)
QTRY_COMPARE(window.touchMovedCount, 0);
points[0].state = Qt::TouchPointMoved;
tp1.area.adjust(2, 2, 2, 2);
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
QCoreApplication::processEvents();
QTRY_COMPARE(window.touchMovedCount, 0);
// Send a touch end -> will not be delivered to the original window
QTRY_COMPARE(window.touchReleasedCount, 0);
points[0].state = Qt::TouchPointReleased;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
QCoreApplication::processEvents();
QTRY_COMPARE(window.touchReleasedCount, 0);
// Due to temporary fix for QTBUG-37371: the original window should receive a TouchCancel
QTRY_COMPARE(window.touchEventType, QEvent::TouchCancel);
}
void tst_QWindow::orientation()
{
qRegisterMetaType<Qt::ScreenOrientation>("Qt::ScreenOrientation");