fallback: cancel the arbitration timer on device remove
authorPeter Hutterer <peter.hutterer@who-t.net>
Thu, 7 Feb 2019 02:02:50 +0000 (12:02 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Mon, 11 Feb 2019 03:46:31 +0000 (13:46 +1000)
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 <peter.hutterer@who-t.net>
src/evdev-fallback.c
test/test-tablet.c

index d50b9c54d5c2f46cbe40de153a220680d6083a68..3fc0187baca3029f60deb5af6fa08c33a657a18f 100644 (file)
@@ -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);
 
index d71fa0684aa2f120ecd7ae00c88217cf88c76069..bf692f3000637842016b1decfcd3c6e5cb763597 100644 (file)
@@ -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);