From eaa0e37506ef2e8db794ca1c941c1812da084de7 Mon Sep 17 00:00:00 2001 From: David Redondo Date: Wed, 18 Feb 2026 17:36:09 +0100 Subject: [PATCH] Don't deliver events for removed devices The action of the device might trigger changes in the eis implementation that might lead to it removing the device. Dont deliver such events which the eis implementation might not expect. --- src/libeis-device.c | 6 ++++++ test/test-eis.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/src/libeis-device.c b/src/libeis-device.c index a2345fb..a99ed79 100644 --- a/src/libeis-device.c +++ b/src/libeis-device.c @@ -1078,6 +1078,12 @@ eis_device_remove(struct eis_device *device) list_remove(&event->link); eis_event_unref(event); } + list_for_each_safe(event, &(eis_device_get_context(device)->event_queue), link) { + if (event->device == device) { + list_remove(&event->link); + eis_event_unref(event); + } + } device->state = EIS_DEVICE_STATE_DEAD; eis_client_unregister_object(client, &device->proto_object); diff --git a/test/test-eis.c b/test/test-eis.c index 40829ad..1d116bf 100644 --- a/test/test-eis.c +++ b/test/test-eis.c @@ -749,3 +749,44 @@ MUNIT_TEST(eistest_ignore_EPIPE) return MUNIT_OK; } + +MUNIT_TEST(test_no_events_for_removed_device) +{ + _unref_(peck) *peck = peck_new(); + + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_HANDLE_BIND_SEAT); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_HANDLE_START_EMULATING); + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER); + peck_disable_eis_behavior(peck, PECK_EIS_BEHAVIOR_HANDLE_FRAME); + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_ADDED); + peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_RESUMED); + peck_dispatch_until_stable(peck); + + with_server(peck) { + struct eis_device *device = peck_eis_get_default_pointer(peck); + eis_device_resume(device); + } + + peck_dispatch_until_stable(peck); + + with_client(peck) { + struct ei_device *pointer = peck_ei_get_default_pointer(peck); + ei_device_pointer_motion(pointer, 1, 1); + ei_device_frame(pointer, ei_now(ei)); + } + + peck_dispatch_until_stable(peck); + + /* Pausing multiple times should only trigger one event */ + with_server(peck) { + struct eis_device *device = peck_eis_get_default_pointer(peck); + _unref_(eis_event) *motion = peck_eis_next_event(eis, EIS_EVENT_POINTER_MOTION); + eis_device_remove(device); + peck_assert_no_eis_events(eis); + + } + + return MUNIT_OK; +}