From 8b761e2fec12a500b8c4e5c91274a8e9f53056ae Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 7 Feb 2019 12:02:50 +1000 Subject: [PATCH] fallback: cancel the arbitration timer on device remove When the touch arbitration is reset to ARBITRATION_NOT_ACTIVE, the proximity timer is set for 90ms to avoid erroneous touches (see 2a378beab for the reason). If the device is removed within those 90ms, the timer is never cancelled, leading to an assert on cleanup. Signed-off-by: Peter Hutterer --- src/evdev-fallback.c | 1 + test/test-tablet.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/evdev-fallback.c b/src/evdev-fallback.c index d50b9c54..3fc0187b 100644 --- a/src/evdev-fallback.c +++ b/src/evdev-fallback.c @@ -1171,6 +1171,7 @@ fallback_interface_remove(struct evdev_dispatch *evdev_dispatch) libinput_timer_cancel(&dispatch->debounce.timer); libinput_timer_cancel(&dispatch->debounce.timer_short); + libinput_timer_cancel(&dispatch->arbitration.arbitration_timer); libinput_device_remove_event_listener(&dispatch->tablet_mode.other.listener); diff --git a/test/test-tablet.c b/test/test-tablet.c index d71fa068..bf692f30 100644 --- a/test/test-tablet.c +++ b/test/test-tablet.c @@ -4382,6 +4382,46 @@ START_TEST(touch_arbitration_outside_rect) } END_TEST +START_TEST(touch_arbitration_remove_after) +{ + struct litest_device *dev = litest_current_device(); + enum litest_device_type other; + struct litest_device *finger; + struct libinput *li = dev->libinput; + struct axis_replacement axes[] = { + { ABS_TILT_X, 80 }, + { ABS_TILT_Y, 80 }, + { ABS_DISTANCE, 10 }, + { ABS_PRESSURE, 0 }, + { -1, -1 } + }; + bool is_touchpad; + + other = paired_device(dev); + if (other == LITEST_NO_DEVICE) + return; + + finger = litest_add_device(li, other); + litest_drain_events(li); + + is_touchpad = !libevdev_has_property(finger->evdev, INPUT_PROP_DIRECT); + if (is_touchpad) + return; + + litest_tablet_proximity_in(dev, 50, 50, axes); + litest_drain_events(li); + + litest_touch_down(finger, 0, 70, 70); + litest_drain_events(li); + litest_tablet_proximity_out(dev); + libinput_dispatch(li); + + /* Delete the device immediately after the tablet goes out of prox. + * This merely tests that the arbitration timer gets cleaned up */ + litest_delete_device(finger); +} +END_TEST + START_TEST(touch_arbitration_stop_touch) { struct litest_device *dev = litest_current_device(); @@ -4990,6 +5030,7 @@ TEST_COLLECTION(tablet) litest_add("tablet:touch-arbitration", touch_arbitration_keep_ignoring, LITEST_TABLET, LITEST_ANY); litest_add("tablet:touch-arbitration", touch_arbitration_late_touch_lift, LITEST_TABLET, LITEST_ANY); litest_add("tablet:touch-arbitration", touch_arbitration_outside_rect, LITEST_TABLET | LITEST_DIRECT, LITEST_ANY); + litest_add("tablet:touch-arbitration", touch_arbitration_remove_after, LITEST_TABLET | LITEST_DIRECT, LITEST_ANY); litest_add_for_device("tablet:quirks", huion_static_btn_tool_pen, LITEST_HUION_TABLET); litest_add_for_device("tablet:quirks", huion_static_btn_tool_pen_no_timeout_during_usage, LITEST_HUION_TABLET);