From 69f9783d3cd4faca95f1ff9c613d8952f71762a7 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 1 Jul 2015 09:31:21 +1000 Subject: [PATCH] Improve trackpoint->touchpad transition responsiveness (#1233844) --- ...ackpoint-timer-stuff-into-the-palm-s.patch | 125 ++++++++++++++++++ ...s-set-touch-palm.time-on-touch-begin.patch | 37 ++++++ ...-trackpoint-palm-detection-responsiv.patch | 121 +++++++++++++++++ ...-trackpoint-palm-detection-on-small-.patch | 95 +++++++++++++ libinput.spec | 11 +- 5 files changed, 388 insertions(+), 1 deletion(-) create mode 100644 0001-touchpad-move-trackpoint-timer-stuff-into-the-palm-s.patch create mode 100644 0002-touchpad-always-set-touch-palm.time-on-touch-begin.patch create mode 100644 0003-touchpad-improve-trackpoint-palm-detection-responsiv.patch create mode 100644 0004-touchpad-disable-trackpoint-palm-detection-on-small-.patch diff --git a/0001-touchpad-move-trackpoint-timer-stuff-into-the-palm-s.patch b/0001-touchpad-move-trackpoint-timer-stuff-into-the-palm-s.patch new file mode 100644 index 0000000..db15ed2 --- /dev/null +++ b/0001-touchpad-move-trackpoint-timer-stuff-into-the-palm-s.patch @@ -0,0 +1,125 @@ +From 2684b234e0d58029f01c3e944fa355dfa2e04137 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Wed, 24 Jun 2015 11:22:29 +1000 +Subject: [PATCH libinput 1/4] touchpad: move trackpoint timer stuff into the + palm struct + +No functional changes, just rearranging where it fits better. + +Signed-off-by: Peter Hutterer +Reviewed-by: Hans de Goede +--- + src/evdev-mt-touchpad.c | 20 ++++++++++---------- + src/evdev-mt-touchpad.h | 10 +++++----- + 2 files changed, 15 insertions(+), 15 deletions(-) + +diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c +index e4a6480..9dc5a0e 100644 +--- a/src/evdev-mt-touchpad.c ++++ b/src/evdev-mt-touchpad.c +@@ -762,7 +762,7 @@ tp_post_events(struct tp_dispatch *tp, uint64_t time) + filter_motion |= tp_post_button_events(tp, time); + + if (filter_motion || +- tp->sendevents.trackpoint_active || ++ tp->palm.trackpoint_active || + tp->dwt.keyboard_active) { + tp_edge_scroll_stop_events(tp, time); + tp_gesture_stop(tp, time); +@@ -812,12 +812,12 @@ tp_interface_process(struct evdev_dispatch *dispatch, + static void + tp_remove_sendevents(struct tp_dispatch *tp) + { +- libinput_timer_cancel(&tp->sendevents.trackpoint_timer); ++ libinput_timer_cancel(&tp->palm.trackpoint_timer); + libinput_timer_cancel(&tp->dwt.keyboard_timer); + + if (tp->buttons.trackpoint) + libinput_device_remove_event_listener( +- &tp->sendevents.trackpoint_listener); ++ &tp->palm.trackpoint_listener); + + if (tp->dwt.keyboard) + libinput_device_remove_event_listener( +@@ -928,7 +928,7 @@ tp_trackpoint_timeout(uint64_t now, void *data) + struct tp_dispatch *tp = data; + + tp_tap_resume(tp, now); +- tp->sendevents.trackpoint_active = false; ++ tp->palm.trackpoint_active = false; + } + + static void +@@ -941,14 +941,14 @@ tp_trackpoint_event(uint64_t time, struct libinput_event *event, void *data) + if (event->type == LIBINPUT_EVENT_POINTER_BUTTON) + return; + +- if (!tp->sendevents.trackpoint_active) { ++ if (!tp->palm.trackpoint_active) { + tp_edge_scroll_stop_events(tp, time); + tp_gesture_stop(tp, time); + tp_tap_suspend(tp, time); +- tp->sendevents.trackpoint_active = true; ++ tp->palm.trackpoint_active = true; + } + +- libinput_timer_set(&tp->sendevents.trackpoint_timer, ++ libinput_timer_set(&tp->palm.trackpoint_timer, + time + DEFAULT_TRACKPOINT_ACTIVITY_TIMEOUT); + } + +@@ -1080,7 +1080,7 @@ tp_interface_device_added(struct evdev_device *device, + tp->buttons.active_is_topbutton = false; + tp->buttons.trackpoint = added_device; + libinput_device_add_event_listener(&added_device->base, +- &tp->sendevents.trackpoint_listener, ++ &tp->palm.trackpoint_listener, + tp_trackpoint_event, tp); + } + +@@ -1121,7 +1121,7 @@ tp_interface_device_removed(struct evdev_device *device, + tp->buttons.active_is_topbutton = false; + } + libinput_device_remove_event_listener( +- &tp->sendevents.trackpoint_listener); ++ &tp->palm.trackpoint_listener); + tp->buttons.trackpoint = NULL; + } + +@@ -1434,7 +1434,7 @@ static int + tp_init_sendevents(struct tp_dispatch *tp, + struct evdev_device *device) + { +- libinput_timer_init(&tp->sendevents.trackpoint_timer, ++ libinput_timer_init(&tp->palm.trackpoint_timer, + tp_libinput_context(tp), + tp_trackpoint_timeout, tp); + +diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h +index 08c1732..3b5cff5 100644 +--- a/src/evdev-mt-touchpad.h ++++ b/src/evdev-mt-touchpad.h +@@ -275,15 +275,15 @@ struct tp_dispatch { + int32_t right_edge; /* in device coordinates */ + int32_t left_edge; /* in device coordinates */ + int32_t vert_center; /* in device coordinates */ +- } palm; +- +- struct { +- struct libinput_device_config_send_events config; +- enum libinput_config_send_events_mode current_mode; + + bool trackpoint_active; + struct libinput_event_listener trackpoint_listener; + struct libinput_timer trackpoint_timer; ++ } palm; ++ ++ struct { ++ struct libinput_device_config_send_events config; ++ enum libinput_config_send_events_mode current_mode; + } sendevents; + + struct { +-- +2.4.3 + diff --git a/0002-touchpad-always-set-touch-palm.time-on-touch-begin.patch b/0002-touchpad-always-set-touch-palm.time-on-touch-begin.patch new file mode 100644 index 0000000..05b6649 --- /dev/null +++ b/0002-touchpad-always-set-touch-palm.time-on-touch-begin.patch @@ -0,0 +1,37 @@ +From dca83c9edcba574482ac1a93759b196344dc7a87 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Wed, 24 Jun 2015 10:57:07 +1000 +Subject: [PATCH libinput 2/4] touchpad: always set touch->palm.time on touch + begin + +We will use this outside of DWT, so set it unconditionally on touch begin. + +Signed-off-by: Peter Hutterer +Reviewed-by: Hans de Goede +--- + src/evdev-mt-touchpad.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c +index 9dc5a0e..877e667 100644 +--- a/src/evdev-mt-touchpad.c ++++ b/src/evdev-mt-touchpad.c +@@ -211,6 +211,7 @@ tp_begin_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time) + t->state = TOUCH_BEGIN; + t->millis = time; + tp->nfingers_down++; ++ t->palm.time = time; + assert(tp->nfingers_down >= 1); + } + +@@ -491,7 +492,6 @@ tp_palm_detect_dwt(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time) + if (tp->dwt.keyboard_active && + t->state == TOUCH_BEGIN) { + t->palm.state = PALM_TYPING; +- t->palm.time = time; + t->palm.first = t->point; + return 1; + } else if (!tp->dwt.keyboard_active && +-- +2.4.3 + diff --git a/0003-touchpad-improve-trackpoint-palm-detection-responsiv.patch b/0003-touchpad-improve-trackpoint-palm-detection-responsiv.patch new file mode 100644 index 0000000..b49d82b --- /dev/null +++ b/0003-touchpad-improve-trackpoint-palm-detection-responsiv.patch @@ -0,0 +1,121 @@ +From b715f96e1c7457015f048ea76026e3360c27f3f9 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Tue, 23 Jun 2015 15:36:05 +1000 +Subject: [PATCH libinput 3/4] touchpad: improve trackpoint palm detection + responsiveness + +The touchpad is disabled for 500ms after a trackpoint event to avoid +erroneous palm touches. This is currently refreshed on every trackpoint event +and thus forces a delay of 500ms when switching between the two. + +Instead, reduce the timeout to 300ms but ignore any touches started while the +trackpoint was active (i.e. before the last trackpoint event). A touch started +after the last event is released once the timeout expires. + +This is the same logic used for disable-while-typing. + +https://bugzilla.redhat.com/show_bug.cgi?id=1233844 + +Signed-off-by: Peter Hutterer +Reviewed-by: Hans de Goede +--- + src/evdev-mt-touchpad.c | 34 ++++++++++++++++++++++++++++++++-- + src/evdev-mt-touchpad.h | 2 ++ + 2 files changed, 34 insertions(+), 2 deletions(-) + +diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c +index 877e667..fa7d06b 100644 +--- a/src/evdev-mt-touchpad.c ++++ b/src/evdev-mt-touchpad.c +@@ -34,7 +34,7 @@ + * TP_MAGIC_SLOWDOWN in filter.c */ + #define DEFAULT_ACCEL_NUMERATOR 3000.0 + #define DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR 700.0 +-#define DEFAULT_TRACKPOINT_ACTIVITY_TIMEOUT 500 /* ms */ ++#define DEFAULT_TRACKPOINT_ACTIVITY_TIMEOUT 300 /* ms */ + #define DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_1 200 /* ms */ + #define DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_2 500 /* ms */ + #define FAKE_FINGER_OVERFLOW (1 << 7) +@@ -515,6 +515,31 @@ tp_palm_detect_dwt(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time) + return 0; + } + ++static int ++tp_palm_detect_trackpoint(struct tp_dispatch *tp, ++ struct tp_touch *t, ++ uint64_t time) ++{ ++ if (t->palm.state == PALM_NONE && ++ t->state == TOUCH_BEGIN && ++ tp->palm.trackpoint_active) { ++ t->palm.state = PALM_TRACKPOINT; ++ return 1; ++ } else if (t->palm.state == PALM_TRACKPOINT && ++ t->state == TOUCH_UPDATE && ++ !tp->palm.trackpoint_active) { ++ ++ if (t->palm.time == 0 || ++ t->palm.time > tp->palm.trackpoint_last_event_time) { ++ t->palm.state = PALM_NONE; ++ log_debug(tp_libinput_context(tp), ++ "palm: touch released, timeout after trackpoint\n"); ++ } ++ } ++ ++ return 0; ++} ++ + static void + tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time) + { +@@ -526,6 +551,9 @@ tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time) + if (tp_palm_detect_dwt(tp, t, time)) + goto out; + ++ if (tp_palm_detect_trackpoint(tp, t, time)) ++ goto out; ++ + /* If labelled a touch as palm, we unlabel as palm when + we move out of the palm edge zone within the timeout, provided + the direction is within 45 degrees of the horizontal. +@@ -568,7 +596,8 @@ tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time) + out: + log_debug(tp_libinput_context(tp), + "palm: palm detected (%s)\n", +- t->palm.state == PALM_EDGE ? "edge" : "typing"); ++ t->palm.state == PALM_EDGE ? "edge" : ++ t->palm.state == PALM_TYPING ? "typing" : "trackpoint"); + } + + static void +@@ -948,6 +977,7 @@ 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 3b5cff5..dcf6319 100644 +--- a/src/evdev-mt-touchpad.h ++++ b/src/evdev-mt-touchpad.h +@@ -64,6 +64,7 @@ enum touch_palm_state { + PALM_NONE = 0, + PALM_EDGE, + PALM_TYPING, ++ PALM_TRACKPOINT, + }; + + enum button_event { +@@ -279,6 +280,7 @@ struct tp_dispatch { + bool trackpoint_active; + struct libinput_event_listener trackpoint_listener; + struct libinput_timer trackpoint_timer; ++ uint64_t trackpoint_last_event_time; + } palm; + + struct { +-- +2.4.3 + diff --git a/0004-touchpad-disable-trackpoint-palm-detection-on-small-.patch b/0004-touchpad-disable-trackpoint-palm-detection-on-small-.patch new file mode 100644 index 0000000..fff8d5f --- /dev/null +++ b/0004-touchpad-disable-trackpoint-palm-detection-on-small-.patch @@ -0,0 +1,95 @@ +From 7fe0a040794bf09c71e08ff3fbdae0a2a94039bd Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Wed, 24 Jun 2015 11:41:47 +1000 +Subject: [PATCH libinput 4/4] touchpad: disable trackpoint palm detection on + small touchpads + +Tested on three laptops here, Lenovo T61, X220 and an HP EliteBook (?), all +with small touchpads. It's hard to have a hand position where the palm touches +the touchpad while using the trackpoint. So we might as well save us the +effort of monitoring events and enabling/disabling it on demand. + +As a side-effect this fixes 1233844, but that's more a coincidence. +https://bugzilla.redhat.com/show_bug.cgi?id=1233844 + +Signed-off-by: Peter Hutterer +Reviewed-by: Hans de Goede +--- + src/evdev-mt-touchpad.c | 20 ++++++++++++++------ + src/evdev-mt-touchpad.h | 1 + + 2 files changed, 15 insertions(+), 6 deletions(-) + +diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c +index fa7d06b..163226e 100644 +--- a/src/evdev-mt-touchpad.c ++++ b/src/evdev-mt-touchpad.c +@@ -520,6 +520,9 @@ tp_palm_detect_trackpoint(struct tp_dispatch *tp, + struct tp_touch *t, + uint64_t time) + { ++ if (!tp->palm.monitor_trackpoint) ++ return 0; ++ + if (t->palm.state == PALM_NONE && + t->state == TOUCH_BEGIN && + tp->palm.trackpoint_active) { +@@ -844,7 +847,8 @@ tp_remove_sendevents(struct tp_dispatch *tp) + libinput_timer_cancel(&tp->palm.trackpoint_timer); + libinput_timer_cancel(&tp->dwt.keyboard_timer); + +- if (tp->buttons.trackpoint) ++ if (tp->buttons.trackpoint && ++ tp->palm.monitor_trackpoint) + libinput_device_remove_event_listener( + &tp->palm.trackpoint_listener); + +@@ -1109,9 +1113,10 @@ tp_interface_device_added(struct evdev_device *device, + /* Don't send any pending releases to the new trackpoint */ + tp->buttons.active_is_topbutton = false; + tp->buttons.trackpoint = added_device; +- libinput_device_add_event_listener(&added_device->base, +- &tp->palm.trackpoint_listener, +- tp_trackpoint_event, tp); ++ if (tp->palm.monitor_trackpoint) ++ libinput_device_add_event_listener(&added_device->base, ++ &tp->palm.trackpoint_listener, ++ tp_trackpoint_event, tp); + } + + if (added_device->tags & EVDEV_TAG_KEYBOARD && +@@ -1150,8 +1155,9 @@ tp_interface_device_removed(struct evdev_device *device, + tp->buttons.active = 0; + tp->buttons.active_is_topbutton = false; + } +- libinput_device_remove_event_listener( +- &tp->palm.trackpoint_listener); ++ if (tp->palm.monitor_trackpoint) ++ libinput_device_remove_event_listener( ++ &tp->palm.trackpoint_listener); + tp->buttons.trackpoint = NULL; + } + +@@ -1457,6 +1463,8 @@ tp_init_palmdetect(struct tp_dispatch *tp, + tp->palm.left_edge = device->abs.absinfo_x->minimum + width * 0.05; + tp->palm.vert_center = device->abs.absinfo_y->minimum + height/2; + ++ tp->palm.monitor_trackpoint = true; ++ + return 0; + } + +diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h +index dcf6319..6462dda 100644 +--- a/src/evdev-mt-touchpad.h ++++ b/src/evdev-mt-touchpad.h +@@ -281,6 +281,7 @@ struct tp_dispatch { + struct libinput_event_listener trackpoint_listener; + struct libinput_timer trackpoint_timer; + uint64_t trackpoint_last_event_time; ++ bool monitor_trackpoint; + } palm; + + struct { +-- +2.4.3 + diff --git a/libinput.spec b/libinput.spec index 58055d6..a825295 100644 --- a/libinput.spec +++ b/libinput.spec @@ -5,7 +5,7 @@ Name: libinput Version: 0.18.0 -Release: 4%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist} +Release: 5%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist} Summary: Input device library License: MIT @@ -34,6 +34,12 @@ Patch10: 0007-Drop-motion-normalization-of-unaccelerated-deltas.patch Patch11: 0008-filter-pass-the-DPI-to-the-acceleration-filter.patch Patch12: 0009-filter-add-a-custom-low-dpi-acceleration.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1233844 +Patch13: 0001-touchpad-move-trackpoint-timer-stuff-into-the-palm-s.patch +Patch14: 0002-touchpad-always-set-touch-palm.time-on-touch-begin.patch +Patch15: 0003-touchpad-improve-trackpoint-palm-detection-responsiv.patch +Patch16: 0004-touchpad-disable-trackpoint-palm-detection-on-small-.patch + BuildRequires: git BuildRequires: autoconf automake libtool pkgconfig BuildRequires: libevdev-devel @@ -110,6 +116,9 @@ find $RPM_BUILD_ROOT -name '*.la' -delete %changelog +* Wed Jul 01 2015 Peter Hutterer 0.18.0-5 +- Improve trackpoint->touchpad transition responsiveness (#1233844) + * Mon Jun 29 2015 Peter Hutterer 0.18.0-4 - Steepen deceleration curve to get better 1:1 movement on slow speeds (#1231304)