Blame 0009-filter-add-a-custom-low-dpi-acceleration.patch

Peter Hutterer 7eb3526
From 348401a5de950314faadfdd69d160cdeda1362fa Mon Sep 17 00:00:00 2001
Peter Hutterer 7eb3526
From: Peter Hutterer <peter.hutterer@who-t.net>
Peter Hutterer 7eb3526
Date: Tue, 23 Jun 2015 12:45:16 +1000
Peter Hutterer 7eb3526
Subject: [PATCH libinput 9/9] filter: add a custom low-dpi acceleration
Peter Hutterer 7eb3526
Peter Hutterer 7eb3526
Motion normalization does not work well for devices below the default 1000dpi
Peter Hutterer 7eb3526
rate. A 400dpi mouse's minimum movement generates a 2.5 normalized motion,
Peter Hutterer 7eb3526
causing it to skip pixels at low speeds even when unaccelerated.
Peter Hutterer 7eb3526
Peter Hutterer 7eb3526
Likewise, we don't want 1000dpi mice to be normalized to a 400dpi mouse, it
Peter Hutterer 7eb3526
feels sluggish even at higher acceleration speeds.
Peter Hutterer 7eb3526
Instead, add a custom acceleration method for lower-dpi mice. At low-speeds,
Peter Hutterer 7eb3526
one device unit results in a one-pixel movement. Depending on the DPI factor,
Peter Hutterer 7eb3526
the acceleration kicks in earlier and goes to higher acceleration so faster
Peter Hutterer 7eb3526
movements with a low-dpi mouse feel approximately the same as the same
Peter Hutterer 7eb3526
movement on a higher-dpi mouse.
Peter Hutterer 7eb3526
Peter Hutterer 7eb3526
https://bugzilla.redhat.com/show_bug.cgi?id=1231304
Peter Hutterer 7eb3526
Peter Hutterer 7eb3526
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Peter Hutterer 7eb3526
---
Peter Hutterer 7eb3526
 src/evdev.c  | 17 ++++++++++++++---
Peter Hutterer 7eb3526
 src/filter.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++------
Peter Hutterer 7eb3526
 src/filter.h |  5 +++++
Peter Hutterer 7eb3526
 3 files changed, 69 insertions(+), 9 deletions(-)
Peter Hutterer 7eb3526
Peter Hutterer 7eb3526
diff --git a/src/evdev.c b/src/evdev.c
Peter Hutterer 7eb3526
index b98b47a..1edf93f 100644
Peter Hutterer 7eb3526
--- a/src/evdev.c
Peter Hutterer 7eb3526
+++ b/src/evdev.c
Peter Hutterer 7eb3526
@@ -1823,6 +1823,19 @@ evdev_configure_mt_device(struct evdev_device *device)
Peter Hutterer 7eb3526
 	return 0;
Peter Hutterer 7eb3526
 }
Peter Hutterer 7eb3526
 
Peter Hutterer 7eb3526
+static inline int
Peter Hutterer 7eb3526
+evdev_init_accel(struct evdev_device *device)
Peter Hutterer 7eb3526
+{
Peter Hutterer 7eb3526
+	accel_profile_func_t profile;
Peter Hutterer 7eb3526
+
Peter Hutterer 7eb3526
+	if (device->dpi < DEFAULT_MOUSE_DPI)
Peter Hutterer 7eb3526
+		profile = pointer_accel_profile_linear_low_dpi;
Peter Hutterer 7eb3526
+	else
Peter Hutterer 7eb3526
+		profile = pointer_accel_profile_linear;
Peter Hutterer 7eb3526
+
Peter Hutterer 7eb3526
+	return evdev_device_init_pointer_acceleration(device, profile);
Peter Hutterer 7eb3526
+}
Peter Hutterer 7eb3526
+
Peter Hutterer 7eb3526
 static int
Peter Hutterer 7eb3526
 evdev_configure_device(struct evdev_device *device)
Peter Hutterer 7eb3526
 {
Peter Hutterer 7eb3526
@@ -1914,9 +1927,7 @@ evdev_configure_device(struct evdev_device *device)
Peter Hutterer 7eb3526
 	    udev_tags & EVDEV_UDEV_TAG_POINTINGSTICK) {
Peter Hutterer 7eb3526
 		if (libevdev_has_event_code(evdev, EV_REL, REL_X) &&
Peter Hutterer 7eb3526
 		    libevdev_has_event_code(evdev, EV_REL, REL_Y) &&
Peter Hutterer 7eb3526
-		    evdev_device_init_pointer_acceleration(
Peter Hutterer 7eb3526
-					device,
Peter Hutterer 7eb3526
-					pointer_accel_profile_linear) == -1)
Peter Hutterer 7eb3526
+		    evdev_init_accel(device) == -1)
Peter Hutterer 7eb3526
 			return -1;
Peter Hutterer 7eb3526
 
Peter Hutterer 7eb3526
 		device->seat_caps |= EVDEV_DEVICE_POINTER;
Peter Hutterer 7eb3526
diff --git a/src/filter.c b/src/filter.c
Peter Hutterer 7eb3526
index 04dd2b9..35449f5 100644
Peter Hutterer 7eb3526
--- a/src/filter.c
Peter Hutterer 7eb3526
+++ b/src/filter.c
Peter Hutterer 7eb3526
@@ -264,8 +264,16 @@ accelerator_filter(struct motion_filter *filter,
Peter Hutterer 7eb3526
 	double velocity; /* units/ms */
Peter Hutterer 7eb3526
 	double accel_value; /* unitless factor */
Peter Hutterer 7eb3526
 	struct normalized_coords accelerated;
Peter Hutterer 7eb3526
+	struct normalized_coords unnormalized;
Peter Hutterer 7eb3526
+	double dpi_factor = accel->dpi_factor;
Peter Hutterer 7eb3526
 
Peter Hutterer 7eb3526
-	feed_trackers(accel, unaccelerated, time);
Peter Hutterer 7eb3526
+	/* For low-dpi mice, use device units, everything else uses
Peter Hutterer 7eb3526
+	   1000dpi normalized */
Peter Hutterer 7eb3526
+	dpi_factor = min(1.0, dpi_factor);
Peter Hutterer 7eb3526
+	unnormalized.x = unaccelerated->x * dpi_factor;
Peter Hutterer 7eb3526
+	unnormalized.y = unaccelerated->y * dpi_factor;
Peter Hutterer 7eb3526
+
Peter Hutterer 7eb3526
+	feed_trackers(accel, &unnormalized, time);
Peter Hutterer 7eb3526
 	velocity = calculate_velocity(accel, time);
Peter Hutterer 7eb3526
 	accel_value = calculate_acceleration(accel,
Peter Hutterer 7eb3526
 					     data,
Peter Hutterer 7eb3526
@@ -273,10 +281,10 @@ accelerator_filter(struct motion_filter *filter,
Peter Hutterer 7eb3526
 					     accel->last_velocity,
Peter Hutterer 7eb3526
 					     time);
Peter Hutterer 7eb3526
 
Peter Hutterer 7eb3526
-	accelerated.x = accel_value * unaccelerated->x;
Peter Hutterer 7eb3526
-	accelerated.y = accel_value * unaccelerated->y;
Peter Hutterer 7eb3526
+	accelerated.x = accel_value * unnormalized.x;
Peter Hutterer 7eb3526
+	accelerated.y = accel_value * unnormalized.y;
Peter Hutterer 7eb3526
 
Peter Hutterer 7eb3526
-	accel->last = *unaccelerated;
Peter Hutterer 7eb3526
+	accel->last = unnormalized;
Peter Hutterer 7eb3526
 
Peter Hutterer 7eb3526
 	accel->last_velocity = velocity;
Peter Hutterer 7eb3526
 
Peter Hutterer 7eb3526
@@ -372,15 +380,51 @@ create_pointer_accelerator_filter(accel_profile_func_t profile,
Peter Hutterer 7eb3526
 	filter->accel = DEFAULT_ACCELERATION;
Peter Hutterer 7eb3526
 	filter->incline = DEFAULT_INCLINE;
Peter Hutterer 7eb3526
 
Peter Hutterer 7eb3526
-	filter->dpi = dpi;
Peter Hutterer 7eb3526
+	filter->dpi_factor = dpi/(double)DEFAULT_MOUSE_DPI;
Peter Hutterer 7eb3526
 
Peter Hutterer 7eb3526
 	return &filter->base;
Peter Hutterer 7eb3526
 }
Peter Hutterer 7eb3526
 
Peter Hutterer 7eb3526
+/**
Peter Hutterer 7eb3526
+ * Custom acceleration function for mice < 1000dpi.
Peter Hutterer 7eb3526
+ * At slow motion, a single device unit causes a one-pixel movement.
Peter Hutterer 7eb3526
+ * The threshold/max accel depends on the DPI, the smaller the DPI the
Peter Hutterer 7eb3526
+ * earlier we accelerate and the higher the maximum acceleration is. Result:
Peter Hutterer 7eb3526
+ * at low speeds we get pixel-precision, at high speeds we get approx. the
Peter Hutterer 7eb3526
+ * same movement as a high-dpi mouse.
Peter Hutterer 7eb3526
+ *
Peter Hutterer 7eb3526
+ * Note: data fed to this function is in device units, not normalized.
Peter Hutterer 7eb3526
+ */
Peter Hutterer 7eb3526
+double
Peter Hutterer 7eb3526
+pointer_accel_profile_linear_low_dpi(struct motion_filter *filter,
Peter Hutterer 7eb3526
+				     void *data,
Peter Hutterer 7eb3526
+				     double speed_in, /* in device units */
Peter Hutterer 7eb3526
+				     uint64_t time)
Peter Hutterer 7eb3526
+{
Peter Hutterer 7eb3526
+	struct pointer_accelerator *accel_filter =
Peter Hutterer 7eb3526
+		(struct pointer_accelerator *)filter;
Peter Hutterer 7eb3526
+
Peter Hutterer 7eb3526
+	double s1, s2;
Peter Hutterer 7eb3526
+	double max_accel = accel_filter->accel; /* unitless factor */
Peter Hutterer 7eb3526
+	const double threshold = accel_filter->threshold; /* units/ms */
Peter Hutterer 7eb3526
+	const double incline = accel_filter->incline;
Peter Hutterer 7eb3526
+	double factor;
Peter Hutterer 7eb3526
+	double dpi_factor = accel_filter->dpi_factor;
Peter Hutterer 7eb3526
+
Peter Hutterer 7eb3526
+	max_accel /= dpi_factor;
Peter Hutterer 7eb3526
+
Peter Hutterer 7eb3526
+	s1 = min(1, 0.3 + speed_in * 10);
Peter Hutterer 7eb3526
+	s2 = 1 + (speed_in - threshold * dpi_factor) * incline;
Peter Hutterer 7eb3526
+
Peter Hutterer 7eb3526
+	factor = min(max_accel, s2 > 1 ? s2 : s1);
Peter Hutterer 7eb3526
+
Peter Hutterer 7eb3526
+	return factor;
Peter Hutterer 7eb3526
+}
Peter Hutterer 7eb3526
+
Peter Hutterer 7eb3526
 double
Peter Hutterer 7eb3526
 pointer_accel_profile_linear(struct motion_filter *filter,
Peter Hutterer 7eb3526
 			     void *data,
Peter Hutterer 7eb3526
-			     double speed_in,
Peter Hutterer 7eb3526
+			     double speed_in, /* 1000-dpi normalized */
Peter Hutterer 7eb3526
 			     uint64_t time)
Peter Hutterer 7eb3526
 {
Peter Hutterer 7eb3526
 	struct pointer_accelerator *accel_filter =
Peter Hutterer 7eb3526
diff --git a/src/filter.h b/src/filter.h
Peter Hutterer 7eb3526
index 64a8b50..617fab1 100644
Peter Hutterer 7eb3526
--- a/src/filter.h
Peter Hutterer 7eb3526
+++ b/src/filter.h
Peter Hutterer 7eb3526
@@ -66,6 +66,11 @@ create_pointer_accelerator_filter(accel_profile_func_t filter,
Peter Hutterer 7eb3526
  */
Peter Hutterer 7eb3526
 
Peter Hutterer 7eb3526
 double
Peter Hutterer 7eb3526
+pointer_accel_profile_linear_low_dpi(struct motion_filter *filter,
Peter Hutterer 7eb3526
+				     void *data,
Peter Hutterer 7eb3526
+				     double speed_in,
Peter Hutterer 7eb3526
+				     uint64_t time);
Peter Hutterer 7eb3526
+double
Peter Hutterer 7eb3526
 pointer_accel_profile_linear(struct motion_filter *filter,
Peter Hutterer 7eb3526
 			     void *data,
Peter Hutterer 7eb3526
 			     double speed_in,
Peter Hutterer 7eb3526
-- 
Peter Hutterer 7eb3526
2.4.3
Peter Hutterer 7eb3526