|
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 |
|