mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2025-12-30 10:40:09 +01:00
eis: end any ongoing touch in response to touch_end
Even if the client is no longer emulating (and we're not queuing an event) our local touch must be ended. Otherwise our touch will live on forever, despite the client thinking it has ended properly. This can't be triggered with libei because we can't send touch events while not emulating and the only way to get into this state is pausing the device - which already resets the state. But let's add a test case anyway, in the hope that one day it picks up a bug.
This commit is contained in:
parent
c21bdbe036
commit
8d6d23e84d
2 changed files with 98 additions and 4 deletions
|
|
@ -749,8 +749,10 @@ client_msg_touch_up(struct eis_touchscreen *touchscreen, uint32_t touchid)
|
|||
"Touch up event for non-touch device");
|
||||
}
|
||||
|
||||
if (device->state == EIS_DEVICE_STATE_EMULATING) {
|
||||
if (release_touch(device, touchid))
|
||||
/* End the touch locally even if we're not emulating, but
|
||||
* silently ignore touch end/cancel for non-existing touches */
|
||||
if (release_touch(device, touchid)) {
|
||||
if (device->state == EIS_DEVICE_STATE_EMULATING)
|
||||
eis_queue_touch_up_event(device, touchid);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -776,8 +778,10 @@ client_msg_touch_cancel(struct eis_touchscreen *touchscreen, uint32_t touchid)
|
|||
"Touch cancel event for touchscreen version v1");
|
||||
}
|
||||
|
||||
if (device->state == EIS_DEVICE_STATE_EMULATING) {
|
||||
if (release_touch(device, touchid))
|
||||
/* End the touch locally even if we're not emulating, but
|
||||
* silently ignore touch end/cancel for non-existing touches */
|
||||
if (release_touch(device, touchid)) {
|
||||
if (device->state == EIS_DEVICE_STATE_EMULATING)
|
||||
eis_queue_touch_cancel_event(device, touchid);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1523,6 +1523,96 @@ MUNIT_TEST(test_ei_device_multitouch)
|
|||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(test_ei_device_touch_up_after_paused)
|
||||
{
|
||||
_unref_(peck) *peck = peck_new();
|
||||
_unref_(ei_device) *device = NULL;
|
||||
_unref_(eis_device) *eis_device = NULL;
|
||||
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_TOUCH);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTODEVICES);
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
_unref_(ei_touch) *t1 = NULL;
|
||||
_unref_(ei_touch) *t2 = NULL;
|
||||
|
||||
with_client(peck) {
|
||||
device = ei_device_ref(peck_ei_get_default_touch(peck));
|
||||
t1 = ei_device_touch_new(device);
|
||||
t2 = ei_device_touch_new(device);
|
||||
ei_touch_down(t1, 1, 2);
|
||||
ei_touch_down(t2, 3, 4);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_server(peck) {
|
||||
_unref_(eis_event) *down1 = peck_eis_touch_down(eis, 1, 2);
|
||||
_unref_(eis_event) *down2 = peck_eis_touch_down(eis, 3, 4);
|
||||
|
||||
peck_assert_no_eis_events(eis); /* drain the frame */
|
||||
|
||||
eis_device = eis_device_ref(eis_event_get_device(down1));
|
||||
eis_device_pause(eis_device);
|
||||
}
|
||||
|
||||
/* No ei dispatch here */
|
||||
peck_dispatch_eis(peck);
|
||||
|
||||
with_client(peck) {
|
||||
/* These events will arrive when the device is paused and
|
||||
* are discarded by EIS */
|
||||
ei_touch_up(t1);
|
||||
ei_touch_up(t2);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_touch_unref(t1);
|
||||
ei_touch_unref(t2);
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_client(peck) {
|
||||
_unref_(ei_event) *pause = peck_ei_next_event(ei, EI_EVENT_DEVICE_PAUSED);
|
||||
}
|
||||
|
||||
with_server(peck) {
|
||||
/* touch up and empty frame were discarded */
|
||||
peck_assert_no_eis_events(eis);
|
||||
eis_device_resume(eis_device);
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_client(peck) {
|
||||
ei_device_start_emulating(device, 123);
|
||||
|
||||
/* The C API doesn't allow us to set a touch id
|
||||
* so we can't really test for the correct behavior.
|
||||
* All we can do is exercise most of the code by creating
|
||||
* new touches and hope.
|
||||
*/
|
||||
t1 = ei_device_touch_new(device);
|
||||
t2 = ei_device_touch_new(device);
|
||||
ei_touch_down(t1, 1, 2);
|
||||
ei_touch_down(t2, 3, 4);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_server(peck) {
|
||||
_unref_(eis_event) *down1 = peck_eis_touch_down(eis, 1, 2);
|
||||
_unref_(eis_event) *down2 = peck_eis_touch_down(eis, 3, 4);
|
||||
peck_assert_no_eis_events(eis); /* drain the frame */
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
#if HAVE_MEMFD_CREATE
|
||||
MUNIT_TEST(test_ei_keymap_invalid)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue