From 416fa44d80b0f2c53b652ddfa35dd4a156a65c65 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 7 Sep 2016 08:18:33 +1000 Subject: [PATCH] touchpad: require at least 3 events before enabling trackpoint palm detection Some trackpoints, notably the one on the Lenovo T460s have a tendency to send the odd event even when they're not actually used. Trackpoint events trigger palm detection (see 0210f1fee193) and thus effectively disable the touchpad, causing the touchpad to appear nonresponsive. Fix this by requiring at least 3 events from a trackpoint before palm detection is enabled. For normal use it's hard enough to trigger a single event anyway so this should not affect the normal use-case. https://bugzilla.redhat.com/show_bug.cgi?id=1364850 Signed-off-by: Peter Hutterer Reviewed-by: Hans de Goede --- src/evdev-mt-touchpad.c | 9 ++++++++- src/evdev-mt-touchpad.h | 1 + test/trackpoint.c | 26 ++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index 2354061c..38b638b5 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -1305,6 +1305,7 @@ tp_trackpoint_timeout(uint64_t now, void *data) tp_tap_resume(tp, now); tp->palm.trackpoint_active = false; + tp->palm.trackpoint_event_count = 0; } static void @@ -1317,6 +1318,13 @@ tp_trackpoint_event(uint64_t time, struct libinput_event *event, void *data) if (event->type == LIBINPUT_EVENT_POINTER_BUTTON) return; + tp->palm.trackpoint_last_event_time = time; + tp->palm.trackpoint_event_count++; + + /* Require at least three events before enabling palm detection */ + if (tp->palm.trackpoint_event_count < 3) + return; + if (!tp->palm.trackpoint_active) { tp_edge_scroll_stop_events(tp, time); tp_gesture_cancel(tp, time); @@ -1324,7 +1332,6 @@ tp_trackpoint_event(uint64_t time, struct libinput_event *event, void *data) tp->palm.trackpoint_active = true; } - tp->palm.trackpoint_last_event_time = time; libinput_timer_set(&tp->palm.trackpoint_timer, time + DEFAULT_TRACKPOINT_ACTIVITY_TIMEOUT); } diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h index de9bdb5f..f4ad0907 100644 --- a/src/evdev-mt-touchpad.h +++ b/src/evdev-mt-touchpad.h @@ -341,6 +341,7 @@ struct tp_dispatch { struct libinput_event_listener trackpoint_listener; struct libinput_timer trackpoint_timer; uint64_t trackpoint_last_event_time; + uint32_t trackpoint_event_count; bool monitor_trackpoint; } palm; diff --git a/test/trackpoint.c b/test/trackpoint.c index b92b994d..e9ba0271 100644 --- a/test/trackpoint.c +++ b/test/trackpoint.c @@ -349,6 +349,31 @@ START_TEST(trackpoint_palmdetect_resume_touch) } END_TEST +START_TEST(trackpoint_palmdetect_require_min_events) +{ + struct litest_device *trackpoint = litest_current_device(); + struct litest_device *touchpad; + struct libinput *li = trackpoint->libinput; + + touchpad = litest_add_device(li, LITEST_SYNAPTICS_I2C); + litest_drain_events(li); + + /* A single event does not trigger palm detection */ + litest_event(trackpoint, EV_REL, REL_X, 1); + litest_event(trackpoint, EV_REL, REL_Y, 1); + litest_event(trackpoint, EV_SYN, SYN_REPORT, 0); + libinput_dispatch(li); + litest_drain_events(li); + + litest_touch_down(touchpad, 0, 30, 30); + litest_touch_move_to(touchpad, 0, 30, 30, 80, 80, 10, 1); + litest_touch_up(touchpad, 0); + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); + + litest_delete_device(touchpad); +} +END_TEST + void litest_setup_tests_trackpoint(void) { @@ -362,4 +387,5 @@ litest_setup_tests_trackpoint(void) litest_add("trackpoint:palmdetect", trackpoint_palmdetect, LITEST_POINTINGSTICK, LITEST_ANY); litest_add("trackpoint:palmdetect", trackpoint_palmdetect_resume_touch, LITEST_POINTINGSTICK, LITEST_ANY); + litest_add("trackpoint:palmdetect", trackpoint_palmdetect_require_min_events, LITEST_POINTINGSTICK, LITEST_ANY); }