diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index a3e243b3..44bc9780 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -131,6 +131,21 @@ tp_motion_history_push(struct tp_touch *t) t->history.index = motion_index; } +static inline void +tp_maybe_disable_hysteresis(struct tp_dispatch *tp, uint64_t time) +{ + /* If the finger is down for 80ms without seeing motion events, + the firmware filters and we don't need a software hysteresis */ + if (time - tp->hysteresis.last_motion_time > ms2us(80)) { + tp->hysteresis.enabled = false; + evdev_log_debug(tp->device, "hysteresis disabled\n"); + return; + } + + if (tp->queued & TOUCHPAD_EVENT_MOTION) + tp->hysteresis.last_motion_time = time; +} + static inline void tp_motion_hysteresis(struct tp_dispatch *tp, struct tp_touch *t) @@ -276,6 +291,7 @@ tp_begin_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time) t->thumb.first_touch_time = time; t->tap.is_thumb = false; assert(tp->nfingers_down >= 1); + tp->hysteresis.last_motion_time = time; } /** @@ -1529,6 +1545,9 @@ static void tp_handle_state(struct tp_dispatch *tp, uint64_t time) { + if (tp->hysteresis.enabled) + tp_maybe_disable_hysteresis(tp, time); + tp_process_state(tp, time); tp_post_events(tp, time); tp_post_process_state(tp, time); diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h index ab4bcde1..cb87b3ff 100644 --- a/src/evdev-mt-touchpad.h +++ b/src/evdev-mt-touchpad.h @@ -272,6 +272,8 @@ struct tp_dispatch { struct { bool enabled; struct device_coords margin; + unsigned int other_event_count; + uint64_t last_motion_time; } hysteresis; struct { diff --git a/test/litest.c b/test/litest.c index d34bd3c5..1fd5a6e9 100644 --- a/test/litest.c +++ b/test/litest.c @@ -3223,6 +3223,12 @@ litest_timeout_tablet_proxout(void) msleep(70); } +void +litest_timeout_hysteresis(void) +{ + msleep(90); +} + void litest_push_event_frame(struct litest_device *dev) { diff --git a/test/litest.h b/test/litest.h index 53d8153d..d6d5c82c 100644 --- a/test/litest.h +++ b/test/litest.h @@ -766,6 +766,9 @@ litest_timeout_trackpoint(void); void litest_timeout_tablet_proxout(void); +void +litest_timeout_hysteresis(void); + void litest_push_event_frame(struct litest_device *dev);