libinput: Changes to 'debian-unstable'
debian/patches/fix-lp1696929.patch | 164 +++++++++++++++++++++++++++++++++++++
1 file changed, 164 insertions(+)
New commits:
commit f6ace7b00d8a548927d6aec157e97e28168b9ded
Author: Timo Aaltonen <tjaalton@debian.org>
Date: Thu Dec 14 17:17:37 2017 +0200
git add the patch too
diff --git a/debian/patches/fix-lp1696929.patch b/debian/patches/fix-lp1696929.patch
new file mode 100644
index 0000000..c1b2d9e
--- /dev/null
+++ b/debian/patches/fix-lp1696929.patch
@@ -0,0 +1,164 @@
+Description: touchpad: automatically disable the hysteresis where not required
+ Touchpads that require the hysteresis do not have filtering in the firmware
+ and holding a finger still causes continuous cursor movements. This implies
+ that we get a continuous stream of events with motion data.
+ .
+ If the finger is on the touchpad but we don't see any motion, the finger is
+ stationary and the touchpad firmware does filtering. In that case, we don't
+ need to add a hysteresis on top.
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Reviewed-by: Daniel van Vugt <daniel.van.vugt@canonical.com>
+Origin: upstream, https://cgit.freedesktop.org/wayland/libinput/commit/?id=aaded3d01d9e10e79543c7952aacd393487f9efc
+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1696929
+Bug: https://bugs.freedesktop.org/show_bug.cgi?id=98839
+Last-Update: 2017-12-13
+
+Index: libinput-1.9.3-1ubuntu1/src/evdev-mt-touchpad.c
+===================================================================
+--- libinput-1.9.3-1ubuntu1.orig/src/evdev-mt-touchpad.c
++++ libinput-1.9.3-1ubuntu1/src/evdev-mt-touchpad.c
+@@ -132,21 +132,39 @@ tp_motion_history_push(struct tp_touch *
+ }
+
+ 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)
+ {
+ int x = t->point.x,
+ y = t->point.y;
+
++ if (!tp->hysteresis.enabled)
++ return;
++
+ if (t->history.count == 0) {
+ t->hysteresis_center = t->point;
+ } else {
+ x = evdev_hysteresis(x,
+ t->hysteresis_center.x,
+- tp->hysteresis_margin.x);
++ tp->hysteresis.margin.x);
+ y = evdev_hysteresis(y,
+ t->hysteresis_center.y,
+- tp->hysteresis_margin.y);
++ tp->hysteresis.margin.y);
+ t->hysteresis_center.x = x;
+ t->hysteresis_center.y = y;
+ t->point.x = x;
+@@ -273,6 +291,7 @@ tp_begin_touch(struct tp_dispatch *tp, s
+ t->thumb.first_touch_time = time;
+ t->tap.is_thumb = false;
+ assert(tp->nfingers_down >= 1);
++ tp->hysteresis.last_motion_time = time;
+ }
+
+ /**
+@@ -1531,6 +1550,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);
+@@ -2917,8 +2939,9 @@ tp_init_hysteresis(struct tp_dispatch *t
+
+ res_x = tp->device->abs.absinfo_x->resolution;
+ res_y = tp->device->abs.absinfo_y->resolution;
+- tp->hysteresis_margin.x = res_x/2;
+- tp->hysteresis_margin.y = res_y/2;
++ tp->hysteresis.margin.x = res_x/2;
++ tp->hysteresis.margin.y = res_y/2;
++ tp->hysteresis.enabled = true;
+ }
+
+ static void
+Index: libinput-1.9.3-1ubuntu1/src/evdev-mt-touchpad.h
+===================================================================
+--- libinput-1.9.3-1ubuntu1.orig/src/evdev-mt-touchpad.h
++++ libinput-1.9.3-1ubuntu1/src/evdev-mt-touchpad.h
+@@ -269,7 +269,12 @@ struct tp_dispatch {
+ double orientation_to_angle;
+ } touch_size;
+
+- struct device_coords hysteresis_margin;
++ struct {
++ bool enabled;
++ struct device_coords margin;
++ unsigned int other_event_count;
++ uint64_t last_motion_time;
++ } hysteresis;
+
+ struct {
+ double x_scale_coeff;
+Index: libinput-1.9.3-1ubuntu1/src/evdev.h
+===================================================================
+--- libinput-1.9.3-1ubuntu1.orig/src/evdev.h
++++ libinput-1.9.3-1ubuntu1/src/evdev.h
+@@ -620,6 +620,19 @@ evdev_to_left_handed(struct evdev_device
+ * calculation to do circular hysteresis are nontrivial, especially since
+ * many touchpads have uneven x/y resolutions.
+ *
++ * Given coordinates, 0, 1, 2, ... this is what we return for a margin of 3
++ * and a center of 0:
++ *
++ * Input: 1 2 3 4 5 6 5 4 3 2 1 0 -1
++ * Coord: 0 0 0 1 2 3 3 3 3 3 3 3 2
++ * Center: 0 0 0 1 2 3 3 3 3 3 3 3 2
++ *
++ * Problem: viewed from a stationary finger that starts moving, the
++ * hysteresis margin is M in both directions. Once we start moving
++ * continuously though, the margin is 0 in the movement direction and 2*M to
++ * change direction. That makes the finger less responsive to directional
++ * changes than to the original movement.
++ *
+ * @param in The input coordinate
+ * @param center Current center of the hysteresis
+ * @param margin Hysteresis width (on each side)
+Index: libinput-1.9.3-1ubuntu1/test/litest.c
+===================================================================
+--- libinput-1.9.3-1ubuntu1.orig/test/litest.c
++++ libinput-1.9.3-1ubuntu1/test/litest.c
+@@ -3252,6 +3252,12 @@ litest_timeout_tablet_proxout(void)
+ }
+
+ void
++litest_timeout_hysteresis(void)
++{
++ msleep(90);
++}
++
++void
+ litest_push_event_frame(struct litest_device *dev)
+ {
+ litest_assert(dev->skip_ev_syn >= 0);
+Index: libinput-1.9.3-1ubuntu1/test/litest.h
+===================================================================
+--- libinput-1.9.3-1ubuntu1.orig/test/litest.h
++++ libinput-1.9.3-1ubuntu1/test/litest.h
+@@ -768,6 +768,9 @@ void
+ litest_timeout_tablet_proxout(void);
+
+ void
++litest_timeout_hysteresis(void);
++
++void
+ litest_push_event_frame(struct litest_device *dev);
+
+ void
Reply to: