[libinput] Add the new touchpad pointer acceleration code

Peter Hutterer whot at fedoraproject.org
Wed Jul 2 04:32:59 UTC 2014


commit 6988264f9fa12c549b2b0345b5344580bf037a94
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jul 2 14:29:01 2014 +1000

    Add the new touchpad pointer acceleration code

 ...itch-to-smooth-simple-acceleration-code-f.patch |  181 ++++++++++++++++++++
 libinput.spec                                      |    9 +-
 2 files changed, 188 insertions(+), 2 deletions(-)
---
diff --git a/0001-touchpad-Switch-to-smooth-simple-acceleration-code-f.patch b/0001-touchpad-Switch-to-smooth-simple-acceleration-code-f.patch
new file mode 100644
index 0000000..924ed44
--- /dev/null
+++ b/0001-touchpad-Switch-to-smooth-simple-acceleration-code-f.patch
@@ -0,0 +1,181 @@
+From ffa7f2c8313e7c119e3c99203a30d583760f14e7 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Tue, 1 Jul 2014 14:53:18 +0200
+Subject: [PATCH libinput] touchpad: Switch to smooth simple acceleration code
+ from filter.c
+
+The old touchpad accel code was clamping touchpad acceleration between
+0.2 and 0.4, and on the test devices I have the constant_factor ended up
+such that in practice the accel was almost always 0.2, so rather than having
+a velocity based acceleration curve, in essence it was just always using an
+acceleration of 0.2 .
+
+This commit introduces actual velocity based acceleration based on the
+recently added smooth simple acceleration code from filter.c .
+
+Before feeding motion events to filter.c, they first get adjusted for touchpad
+resolution. For touchpads where the driver does not provide resolution info,
+scale based on the diagonal-size in units instead.
+
+While at it rename tp_init_accel's dispatch parameter from touchpad to tp
+to be consistent with all other functions.
+
+Since the acceleration is also used for scrolling also adjust the scroll
+start threshold for these changes.
+
+Note that switching to the smooth simple accel code, as an added bonus gives
+the tp code an accel profile with a threshold and a speed parameter, which
+is exactly what is needed for the upcoming configuration interface support.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
+Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
+---
+ src/evdev-mt-touchpad.c | 78 +++++++++++++++++--------------------------------
+ src/evdev-mt-touchpad.h |  4 ---
+ 2 files changed, 26 insertions(+), 56 deletions(-)
+
+diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
+index ced9237..f94d316 100644
+--- a/src/evdev-mt-touchpad.c
++++ b/src/evdev-mt-touchpad.c
+@@ -28,9 +28,7 @@
+ 
+ #include "evdev-mt-touchpad.h"
+ 
+-#define DEFAULT_CONSTANT_ACCEL_NUMERATOR 100
+-#define DEFAULT_MIN_ACCEL_FACTOR 0.20
+-#define DEFAULT_MAX_ACCEL_FACTOR 0.40
++#define DEFAULT_ACCEL_NUMERATOR 1200.0
+ #define DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR 700.0
+ 
+ static inline int
+@@ -47,27 +45,6 @@ tp_hysteresis(int in, int center, int margin)
+ 	return center + diff;
+ }
+ 
+-static double
+-tp_accel_profile(struct motion_filter *filter,
+-		 void *data,
+-		 double velocity,
+-		 uint64_t time)
+-{
+-	struct tp_dispatch *tp =
+-		(struct tp_dispatch *) data;
+-
+-	double accel_factor;
+-
+-	accel_factor = velocity * tp->accel.constant_factor;
+-
+-	if (accel_factor > tp->accel.max_factor)
+-		accel_factor = tp->accel.max_factor;
+-	else if (accel_factor < tp->accel.min_factor)
+-		accel_factor = tp->accel.min_factor;
+-
+-	return accel_factor;
+-}
+-
+ static inline struct tp_motion *
+ tp_motion_history_offset(struct tp_touch *t, int offset)
+ {
+@@ -465,11 +442,11 @@ tp_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time)
+ 
+ 	tp_filter_motion(tp, &dx, &dy, time);
+ 
+-	/* Require at least three px scrolling to start */
+-	if (dy <= -3.0 || dy >= 3.0)
++	/* Require at least five px scrolling to start */
++	if (dy <= -5.0 || dy >= 5.0)
+ 		tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
+ 
+-	if (dx <= -3.0 || dx >= 3.0)
++	if (dx <= -5.0 || dx >= 5.0)
+ 		tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
+ 
+ 	if (dy != 0.0 &&
+@@ -666,9 +643,10 @@ tp_init_slots(struct tp_dispatch *tp,
+ 	return 0;
+ }
+ 
+-static void
+-calculate_scale_coefficients(struct tp_dispatch *tp)
++static int
++tp_init_accel(struct tp_dispatch *tp, double diagonal)
+ {
++	struct motion_filter *accel;
+ 	int res_x, res_y;
+ 
+ 	if (tp->has_mt) {
+@@ -683,35 +661,31 @@ calculate_scale_coefficients(struct tp_dispatch *tp)
+ 						    ABS_Y);
+ 	}
+ 
+-	if (res_x <= 0 || res_y <= 0) {
+-		tp->accel.x_scale_coeff = 1.0;
+-		tp->accel.y_scale_coeff = 1.0;
+-	} else if (res_x > res_y) {
+-		tp->accel.x_scale_coeff = res_y / (double) res_x;
+-		tp->accel.y_scale_coeff = 1.0f;
++	/*
++	 * Not all touchpads report the same amount of units/mm (resolution).
++	 * Normalize motion events to a resolution of 10 units/mm as base
++	 * (unaccelerated) speed. This also evens out any differences in x
++	 * and y resolution, so that a circle on the touchpad does not turn
++	 * into an elipse on the screen.
++	 */
++	if (res_x > 1 && res_y > 1) {
++		tp->accel.x_scale_coeff = 10.0 / res_x;
++		tp->accel.y_scale_coeff = 10.0 / res_y;
+ 	} else {
+-		tp->accel.y_scale_coeff = res_x / (double) res_y;
+-		tp->accel.x_scale_coeff = 1.0f;
++	/*
++	 * For touchpads where the driver does not provide resolution, fall
++	 * back to scaling motion events based on the diagonal size in units.
++	 */
++		tp->accel.x_scale_coeff = DEFAULT_ACCEL_NUMERATOR / diagonal;
++		tp->accel.y_scale_coeff = DEFAULT_ACCEL_NUMERATOR / diagonal;
+ 	}
+-}
+ 
+-static int
+-tp_init_accel(struct tp_dispatch *touchpad, double diagonal)
+-{
+-	struct motion_filter *accel;
+-
+-	calculate_scale_coefficients(touchpad);
+-
+-	touchpad->accel.constant_factor =
+-		DEFAULT_CONSTANT_ACCEL_NUMERATOR / diagonal;
+-	touchpad->accel.min_factor = DEFAULT_MIN_ACCEL_FACTOR;
+-	touchpad->accel.max_factor = DEFAULT_MAX_ACCEL_FACTOR;
+-
+-	accel = create_pointer_accelator_filter(tp_accel_profile);
++	accel = create_pointer_accelator_filter(
++			pointer_accel_profile_smooth_simple);
+ 	if (accel == NULL)
+ 		return -1;
+ 
+-	touchpad->filter = accel;
++	tp->filter = accel;
+ 
+ 	return 0;
+ }
+diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
+index 7afb3c4..051a7eb 100644
+--- a/src/evdev-mt-touchpad.h
++++ b/src/evdev-mt-touchpad.h
+@@ -152,10 +152,6 @@ struct tp_dispatch {
+ 	struct motion_filter *filter;
+ 
+ 	struct {
+-		double constant_factor;
+-		double min_factor;
+-		double max_factor;
+-
+ 		double x_scale_coeff;
+ 		double y_scale_coeff;
+ 	} accel;
+-- 
+1.9.3
+
diff --git a/libinput.spec b/libinput.spec
index d8d6bb3..10c65f3 100644
--- a/libinput.spec
+++ b/libinput.spec
@@ -1,12 +1,14 @@
 Name:           libinput
 Version:        0.4.0
-Release:        1%{?dist}
+Release:        2%{?dist}
 Summary:        Input device library
 
 License:        MIT
 URL:            http://www.freedesktop.org/wiki/Software/libinput/
 Source0:        http://www.freedesktop.org/software/libinput/libinput-%{version}.tar.xz
 
+Patch01:        0001-touchpad-Switch-to-smooth-simple-acceleration-code-f.patch
+
 BuildRequires:  libevdev-devel
 BuildRequires:  libudev-devel
 BuildRequires:  mtdev-devel
@@ -31,7 +33,7 @@ developing applications that use %{name}.
 
 %prep
 %setup -q
-
+%patch01 -p1
 
 %build
 %configure --disable-static
@@ -59,6 +61,9 @@ find $RPM_BUILD_ROOT -name '*.la' -delete
 
 
 %changelog
+* Wed Jul 02 2014 Peter Hutterer <peter.hutterer at redhat.com> 0.4.0-2
+- Add the new touchpad pointer acceleration code
+
 * Wed Jun 25 2014 Kalev Lember <kalevlember at gmail.com> - 0.4.0-1
 - Update to 0.4.0
 


More information about the scm-commits mailing list