Client: clear focus on touch cancel

When we get a touch_cancel event all touches should be treated as
lifted.

The next frame call focus is set, with no pending touch points but
without having gone through touch_up. We call mPendingTouchPoints.last()
without guards even though it is potentially now empty.

Change-Id: I3719f9507c5d397d8641692271d878076b7c23b8
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Liang Qi <liang.qi@qt.io>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
This commit is contained in:
David Edmundson 2022-08-05 15:00:31 +01:00
parent 42b9e035d5
commit 9631d9f27a
4 changed files with 39 additions and 0 deletions

View File

@ -1412,6 +1412,7 @@ void QWaylandInputDevice::Touch::touch_cancel()
if (touchExt)
touchExt->touchCanceled();
mFocus = nullptr;
QWindowSystemInterface::handleTouchCancelEvent(nullptr, mParent->mTouchDevice);
}

View File

@ -50,6 +50,7 @@ private slots:
void multiTouch();
void multiTouchUpAndMotionFrame();
void tapAndMoveInSameFrame();
void cancelTouch();
};
void tst_seat::bindsToSeat()
@ -633,5 +634,34 @@ void tst_seat::tapAndMoveInSameFrame()
QTRY_COMPARE(window.m_events.last().touchPoints.first().state(), QEventPoint::State::Released);
}
void tst_seat::cancelTouch()
{
TouchWindow window;
QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial);
exec([=] {
auto *t = touch();
auto *c = client();
t->sendDown(xdgToplevel()->surface(), {32, 32}, 1);
t->sendFrame(c);
t->sendCancel(c);
t->sendFrame(c);
});
QTRY_VERIFY(!window.m_events.empty());
{
auto e = window.m_events.takeFirst();
QCOMPARE(e.type, QEvent::TouchBegin);
QCOMPARE(e.touchPointStates, QEventPoint::State::Pressed);
QCOMPARE(e.touchPoints.length(), 1);
QCOMPARE(e.touchPoints.first().position(), QPointF(32-window.frameMargins().left(), 32-window.frameMargins().top()));
}
{
auto e = window.m_events.takeFirst();
QCOMPARE(e.type, QEvent::TouchCancel);
QCOMPARE(e.touchPoints.length(), 0);
}
}
QCOMPOSITOR_TEST_MAIN(tst_seat)
#include "tst_seat.moc"

View File

@ -493,6 +493,13 @@ void Touch::sendFrame(wl_client *client)
send_frame(r->handle);
}
void Touch::sendCancel(wl_client *client)
{
const auto touchResources = resourceMap().values(client);
for (auto *r : touchResources)
send_cancel(r->handle);
}
uint Keyboard::sendEnter(Surface *surface)
{
auto serial = m_seat->m_compositor->nextSerial();

View File

@ -379,6 +379,7 @@ public:
uint sendUp(wl_client *client, int id);
void sendMotion(wl_client *client, const QPointF &position, int id);
void sendFrame(wl_client *client);
void sendCancel(wl_client *client);
Seat *m_seat = nullptr;
};