Steepen deceleration curve to get better 1:1 movement on slow speeds
(#1231304) - Provide custom accel method for <1000dpi mice (#1227039)
This commit is contained in:
parent
a50ef2a58c
commit
7eb3526873
40
0001-filter-reduce-deceleration-to-minimal-speeds-only.patch
Normal file
40
0001-filter-reduce-deceleration-to-minimal-speeds-only.patch
Normal file
@ -0,0 +1,40 @@
|
||||
From 6984628d6acf4695c24261c094def44ff37337be Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Fri, 12 Jun 2015 15:31:56 +1000
|
||||
Subject: [PATCH libinput 1/9] filter: reduce deceleration to minimal speeds
|
||||
only
|
||||
|
||||
Deceleration at low speeds is intended to enhance precision when moving the
|
||||
pointer slowly. However, the adaptive deceleration we used was badly
|
||||
calibrated, at slow-but-normal speeds the pointer became too slow to manouver.
|
||||
|
||||
We don't want to drop deceleration completely, the subpixel precision it
|
||||
provides is useful. And it also helps those that can't move a 1000dpi mouse by
|
||||
exactly one unit.
|
||||
|
||||
Make the adaptive deceleration steeper so it only kicks in at extremely slow
|
||||
motions and defaults to 1 at anything resembling normal movement (i.e. pointer
|
||||
moves like the physical device does).
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
src/filter.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/filter.c b/src/filter.c
|
||||
index a4142e9..69f78b1 100644
|
||||
--- a/src/filter.c
|
||||
+++ b/src/filter.c
|
||||
@@ -386,7 +386,7 @@ pointer_accel_profile_linear(struct motion_filter *filter,
|
||||
const double threshold = accel_filter->threshold; /* units/ms */
|
||||
const double incline = accel_filter->incline;
|
||||
|
||||
- s1 = min(1, 0.3 + speed_in * 4);
|
||||
+ s1 = min(1, 0.3 + speed_in * 10);
|
||||
s2 = 1 + (speed_in - threshold) * incline;
|
||||
|
||||
return min(max_accel, s2 > 1 ? s2 : s1);
|
||||
--
|
||||
2.4.3
|
||||
|
37
0002-evdev-read-dpi-before-evdev_configure_device.patch
Normal file
37
0002-evdev-read-dpi-before-evdev_configure_device.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From d1639c88ce2a710ab9b771766f473a72b66100db Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Fri, 19 Jun 2015 16:01:34 +1000
|
||||
Subject: [PATCH libinput 2/9] evdev: read dpi before evdev_configure_device
|
||||
|
||||
So we can use to set up accel during evdev_configure_device.
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
---
|
||||
src/evdev.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/evdev.c b/src/evdev.c
|
||||
index 7e1e5c8..2644b76 100644
|
||||
--- a/src/evdev.c
|
||||
+++ b/src/evdev.c
|
||||
@@ -2083,6 +2083,8 @@ evdev_device_create(struct libinput_seat *seat,
|
||||
device->scroll.wheel_click_angle =
|
||||
evdev_read_wheel_click_prop(device);
|
||||
device->model = evdev_read_model(device);
|
||||
+ device->dpi = evdev_read_dpi_prop(device);
|
||||
+
|
||||
/* at most 5 SYN_DROPPED log-messages per 30s */
|
||||
ratelimit_init(&device->syn_drop_limit, 30ULL * 1000, 5);
|
||||
|
||||
@@ -2093,8 +2095,6 @@ evdev_device_create(struct libinput_seat *seat,
|
||||
if (evdev_configure_device(device) == -1)
|
||||
goto err;
|
||||
|
||||
- device->dpi = evdev_read_dpi_prop(device);
|
||||
-
|
||||
if (device->seat_caps == 0) {
|
||||
unhandled_device = 1;
|
||||
goto err;
|
||||
--
|
||||
2.4.3
|
||||
|
30
0003-evdev-log-device-s-DPI-setting-if-any.patch
Normal file
30
0003-evdev-log-device-s-DPI-setting-if-any.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From 6dbfd81e26a9adff5b07398ff7e588683e3e6bf6 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Tue, 23 Jun 2015 12:41:57 +1000
|
||||
Subject: [PATCH libinput 3/9] evdev: log device's DPI setting if any
|
||||
|
||||
Makes debugging things easier.
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
---
|
||||
src/evdev.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/src/evdev.c b/src/evdev.c
|
||||
index 2644b76..67843db 100644
|
||||
--- a/src/evdev.c
|
||||
+++ b/src/evdev.c
|
||||
@@ -1496,6 +1496,10 @@ evdev_read_dpi_prop(struct evdev_device *device)
|
||||
DEFAULT_MOUSE_DPI);
|
||||
dpi = DEFAULT_MOUSE_DPI;
|
||||
}
|
||||
+ log_info(libinput,
|
||||
+ "Device '%s' set to %d DPI\n",
|
||||
+ device->devname,
|
||||
+ dpi);
|
||||
}
|
||||
|
||||
return dpi;
|
||||
--
|
||||
2.4.3
|
||||
|
@ -0,0 +1,59 @@
|
||||
From f9503763adbaef8fc7220e2da782917cea8803ee Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Fri, 26 Jun 2015 09:27:20 +1000
|
||||
Subject: [PATCH libinput 4/9] evdev: move posting a trackpoint scroll event
|
||||
into a helper
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
---
|
||||
src/evdev.c | 27 +++++++++++++++++++--------
|
||||
1 file changed, 19 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/evdev.c b/src/evdev.c
|
||||
index 67843db..b2595d4 100644
|
||||
--- a/src/evdev.c
|
||||
+++ b/src/evdev.c
|
||||
@@ -253,6 +253,23 @@ normalize_delta(struct evdev_device *device,
|
||||
normalized->y = delta->y * DEFAULT_MOUSE_DPI / (double)device->dpi;
|
||||
}
|
||||
|
||||
+static inline bool
|
||||
+evdev_post_trackpoint_scroll(struct evdev_device *device,
|
||||
+ struct normalized_coords unaccel,
|
||||
+ uint64_t time)
|
||||
+{
|
||||
+ if (device->scroll.method != LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN ||
|
||||
+ !hw_is_key_down(device, device->scroll.button))
|
||||
+ return false;
|
||||
+
|
||||
+ if (device->scroll.button_scroll_active)
|
||||
+ evdev_post_scroll(device, time,
|
||||
+ LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS,
|
||||
+ &unaccel);
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
|
||||
{
|
||||
@@ -275,14 +292,8 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
|
||||
device->rel.y = 0;
|
||||
|
||||
/* Use unaccelerated deltas for pointing stick scroll */
|
||||
- if (device->scroll.method == LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN &&
|
||||
- hw_is_key_down(device, device->scroll.button)) {
|
||||
- if (device->scroll.button_scroll_active)
|
||||
- evdev_post_scroll(device, time,
|
||||
- LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS,
|
||||
- &unaccel);
|
||||
- break;
|
||||
- }
|
||||
+ if (evdev_post_trackpoint_scroll(device, unaccel, time))
|
||||
+ break;
|
||||
|
||||
/* Apply pointer acceleration. */
|
||||
accel = filter_dispatch(device->pointer.filter,
|
||||
--
|
||||
2.4.3
|
||||
|
@ -0,0 +1,40 @@
|
||||
From 03a02107c597fd1b3e738002431c35bb2057b7ce Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Fri, 26 Jun 2015 10:00:24 +1000
|
||||
Subject: [PATCH libinput 5/9] tools: don't drop the accelerated deltas in
|
||||
ptraccel-debug
|
||||
|
||||
Leftover from the initial (out-of-tree) implementation where we updated motion
|
||||
in place. That hasn't been true since libinput switched to type-safe
|
||||
coordinates.
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
---
|
||||
tools/ptraccel-debug.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tools/ptraccel-debug.c b/tools/ptraccel-debug.c
|
||||
index 8b800ee..335781b 100644
|
||||
--- a/tools/ptraccel-debug.c
|
||||
+++ b/tools/ptraccel-debug.c
|
||||
@@ -95,7 +95,7 @@ print_ptraccel_movement(struct motion_filter *filter,
|
||||
motion.y = 0;
|
||||
time += 12; /* pretend 80Hz data */
|
||||
|
||||
- filter_dispatch(filter, &motion, NULL, time);
|
||||
+ motion = filter_dispatch(filter, &motion, NULL, time);
|
||||
|
||||
printf("%d %.3f %.3f\n", i, motion.x, dx);
|
||||
|
||||
@@ -129,7 +129,7 @@ print_ptraccel_sequence(struct motion_filter *filter,
|
||||
motion.y = 0;
|
||||
time += 12; /* pretend 80Hz data */
|
||||
|
||||
- filter_dispatch(filter, &motion, NULL, time);
|
||||
+ motion = filter_dispatch(filter, &motion, NULL, time);
|
||||
|
||||
printf("%d %.3f %.3f\n", i, motion.x, *dx);
|
||||
}
|
||||
--
|
||||
2.4.3
|
||||
|
35
0006-filter-use-a-tmp-variable-for-the-accel-factor.patch
Normal file
35
0006-filter-use-a-tmp-variable-for-the-accel-factor.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From 07ffabc58c1f967e1efe0b593135e835aa5deed4 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Tue, 23 Jun 2015 12:45:55 +1000
|
||||
Subject: [PATCH libinput 6/9] filter: use a tmp variable for the accel factor
|
||||
|
||||
No real effect, just makes the diff for debugging printfs smaller.
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
---
|
||||
src/filter.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/filter.c b/src/filter.c
|
||||
index 69f78b1..1e05782 100644
|
||||
--- a/src/filter.c
|
||||
+++ b/src/filter.c
|
||||
@@ -385,11 +385,14 @@ pointer_accel_profile_linear(struct motion_filter *filter,
|
||||
const double max_accel = accel_filter->accel; /* unitless factor */
|
||||
const double threshold = accel_filter->threshold; /* units/ms */
|
||||
const double incline = accel_filter->incline;
|
||||
+ double factor;
|
||||
|
||||
s1 = min(1, 0.3 + speed_in * 10);
|
||||
s2 = 1 + (speed_in - threshold) * incline;
|
||||
|
||||
- return min(max_accel, s2 > 1 ? s2 : s1);
|
||||
+ factor = min(max_accel, s2 > 1 ? s2 : s1);
|
||||
+
|
||||
+ return factor;
|
||||
}
|
||||
|
||||
double
|
||||
--
|
||||
2.4.3
|
||||
|
289
0007-Drop-motion-normalization-of-unaccelerated-deltas.patch
Normal file
289
0007-Drop-motion-normalization-of-unaccelerated-deltas.patch
Normal file
@ -0,0 +1,289 @@
|
||||
From 753e5eb654a5da96b5cb42e5d612380adac7229f Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Fri, 26 Jun 2015 09:07:24 +1000
|
||||
Subject: [PATCH libinput 7/9] Drop motion normalization of unaccelerated
|
||||
deltas
|
||||
|
||||
This simply doesn't work for low-dpi mice. Normalizing a 400dpi mouse to a
|
||||
1000dpi mouse forces a minimum movement of 2.5 units and the resulting pixel
|
||||
jumps. It is impossible for the caller to detect whether the jump was caused
|
||||
by a single motion or multiple motion events.
|
||||
|
||||
This is technically an API break, but not really.
|
||||
|
||||
The accelerated data was already relatively meaningless, even if normalized as
|
||||
the data did not correspond predictably to any input motion (unless you know
|
||||
the implementation acceleration function in the caller). So we can drop the
|
||||
mention from there without expecting any ill effects in the caller.
|
||||
|
||||
The unaccelerated data was useless for low-dpi mice and could only be used to
|
||||
measure the physical distance of the mouse movement - something not used in
|
||||
any caller we're aware of (if needed, we can add that functionality as a
|
||||
separate call). Dropping motion normalization for unaccelerated deltas also
|
||||
restores true dpi capabilities to users of that API, mostly games that want to
|
||||
make use of high-dpi mice.
|
||||
|
||||
This is a simplified patch, the normalization is still in place for most of
|
||||
libinput, it merely carries the original coordinates in the event itself.
|
||||
|
||||
In the case of touchpads, the coordinates are unnormalized into the x-axis
|
||||
coordinate space as per the documentation.
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
---
|
||||
doc/normalization-of-relative-motion.dox | 31 +++++++++++++++++++++++++++----
|
||||
src/evdev-mt-touchpad-gestures.c | 8 ++++++--
|
||||
src/evdev-mt-touchpad.h | 15 +++++++++++++++
|
||||
src/evdev.c | 5 ++++-
|
||||
src/libinput-private.h | 2 +-
|
||||
src/libinput.c | 10 +++++-----
|
||||
src/libinput.h | 26 ++++++++++++++------------
|
||||
7 files changed, 72 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/doc/normalization-of-relative-motion.dox b/doc/normalization-of-relative-motion.dox
|
||||
index aaa1735..dd5d39b 100644
|
||||
--- a/doc/normalization-of-relative-motion.dox
|
||||
+++ b/doc/normalization-of-relative-motion.dox
|
||||
@@ -12,10 +12,33 @@ physical movement or 10 millimeters, depending on the sensor. This
|
||||
affects pointer acceleration in libinput and interpretation of relative
|
||||
coordinates in callers.
|
||||
|
||||
-libinput normalizes all relative input to a physical resolution of
|
||||
-1000dpi, the same delta from two different devices thus represents the
|
||||
-same physical movement of those two devices (within sensor error
|
||||
-margins).
|
||||
+libinput does partial normalization of relative input. For devices with a
|
||||
+resolution of 1000dpi and higher, motion events are normalized to a default
|
||||
+of 1000dpi before pointer acceleration is applied. As a result, devices with
|
||||
+1000dpi and above feel the same.
|
||||
+
|
||||
+Devices below 1000dpi are not normalized (normalization of a 1-device unit
|
||||
+movement on a 400dpi mouse would cause a 2.5 pixel movement). Instead,
|
||||
+libinput applies a dpi-dependent acceleration function. At low speeds, a
|
||||
+1-device unit movement usually translates into a 1-pixel movements. As the
|
||||
+movement speed increases, acceleration is applied - at high speeds a low-dpi
|
||||
+device will roughly feel the same as a higher-dpi mouse.
|
||||
+
|
||||
+This normalization only applies to accelerated coordinates, unaccelerated
|
||||
+coordiantes are left in device-units. It is up to the caller to interpret
|
||||
+those coordinates correctly.
|
||||
+
|
||||
+@section Normalization of touchpad coordinates
|
||||
+
|
||||
+Touchpads may have a different resolution for the horizontal and vertical
|
||||
+axis. Interpreting coordinates from the touchpad without taking resolutino
|
||||
+into account results in uneven motion.
|
||||
+
|
||||
+libinput scales unaccelerated touchpad motion do the resolution of the
|
||||
+touchpad's x axis, i.e. the unaccelerated value for the y axis is:
|
||||
+ y = (x / resolution_x) * resolution_y
|
||||
+
|
||||
+@section Setting custom DPI settings
|
||||
|
||||
Devices usually do not advertise their resolution and libinput relies on
|
||||
the udev property <b>MOUSE_DPI</b> for this information. This property is usually
|
||||
diff --git a/src/evdev-mt-touchpad-gestures.c b/src/evdev-mt-touchpad-gestures.c
|
||||
index 328a744..e85a9d7 100644
|
||||
--- a/src/evdev-mt-touchpad-gestures.c
|
||||
+++ b/src/evdev-mt-touchpad-gestures.c
|
||||
@@ -91,6 +91,7 @@ static void
|
||||
tp_gesture_post_pointer_motion(struct tp_dispatch *tp, uint64_t time)
|
||||
{
|
||||
struct normalized_coords delta, unaccel;
|
||||
+ struct device_float_coords raw;
|
||||
|
||||
/* When a clickpad is clicked, combine motion of all active touches */
|
||||
if (tp->buttons.is_clickpad && tp->buttons.state)
|
||||
@@ -101,8 +102,11 @@ tp_gesture_post_pointer_motion(struct tp_dispatch *tp, uint64_t time)
|
||||
delta = tp_filter_motion(tp, &unaccel, time);
|
||||
|
||||
if (!normalized_is_zero(delta) || !normalized_is_zero(unaccel)) {
|
||||
- pointer_notify_motion(&tp->device->base, time,
|
||||
- &delta, &unaccel);
|
||||
+ raw = tp_unnormalize_for_xaxis(tp, unaccel);
|
||||
+ pointer_notify_motion(&tp->device->base,
|
||||
+ time,
|
||||
+ &delta,
|
||||
+ &raw);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
|
||||
index 9357969..08c1732 100644
|
||||
--- a/src/evdev-mt-touchpad.h
|
||||
+++ b/src/evdev-mt-touchpad.h
|
||||
@@ -316,6 +316,21 @@ tp_normalize_delta(struct tp_dispatch *tp, struct device_float_coords delta)
|
||||
return normalized;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * Takes a dpi-normalized set of coordinates, returns a set of coordinates
|
||||
+ * in the x-axis' coordinate space.
|
||||
+ */
|
||||
+static inline struct device_float_coords
|
||||
+tp_unnormalize_for_xaxis(struct tp_dispatch *tp, struct normalized_coords delta)
|
||||
+{
|
||||
+ struct device_float_coords raw;
|
||||
+
|
||||
+ raw.x = delta.x / tp->accel.x_scale_coeff;
|
||||
+ raw.y = delta.y / tp->accel.x_scale_coeff; /* <--- not a typo */
|
||||
+
|
||||
+ return raw;
|
||||
+}
|
||||
+
|
||||
struct normalized_coords
|
||||
tp_get_delta(struct tp_touch *t);
|
||||
|
||||
diff --git a/src/evdev.c b/src/evdev.c
|
||||
index b2595d4..a5f1d47 100644
|
||||
--- a/src/evdev.c
|
||||
+++ b/src/evdev.c
|
||||
@@ -280,6 +280,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
|
||||
struct libinput_seat *seat = base->seat;
|
||||
struct normalized_coords accel, unaccel;
|
||||
struct device_coords point;
|
||||
+ struct device_float_coords raw;
|
||||
|
||||
slot = device->mt.slot;
|
||||
|
||||
@@ -288,6 +289,8 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
|
||||
return;
|
||||
case EVDEV_RELATIVE_MOTION:
|
||||
normalize_delta(device, &device->rel, &unaccel);
|
||||
+ raw.x = device->rel.x;
|
||||
+ raw.y = device->rel.y;
|
||||
device->rel.x = 0;
|
||||
device->rel.y = 0;
|
||||
|
||||
@@ -304,7 +307,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
|
||||
if (normalized_is_zero(accel) && normalized_is_zero(unaccel))
|
||||
break;
|
||||
|
||||
- pointer_notify_motion(base, time, &accel, &unaccel);
|
||||
+ pointer_notify_motion(base, time, &accel, &raw);
|
||||
break;
|
||||
case EVDEV_ABSOLUTE_MT_DOWN:
|
||||
if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
|
||||
diff --git a/src/libinput-private.h b/src/libinput-private.h
|
||||
index a7c8838..2f94597 100644
|
||||
--- a/src/libinput-private.h
|
||||
+++ b/src/libinput-private.h
|
||||
@@ -319,7 +319,7 @@ void
|
||||
pointer_notify_motion(struct libinput_device *device,
|
||||
uint64_t time,
|
||||
const struct normalized_coords *delta,
|
||||
- const struct normalized_coords *unaccel);
|
||||
+ const struct device_float_coords *raw);
|
||||
|
||||
void
|
||||
pointer_notify_motion_absolute(struct libinput_device *device,
|
||||
diff --git a/src/libinput.c b/src/libinput.c
|
||||
index 7a097c0..a6bd079 100644
|
||||
--- a/src/libinput.c
|
||||
+++ b/src/libinput.c
|
||||
@@ -96,7 +96,7 @@ struct libinput_event_pointer {
|
||||
struct libinput_event base;
|
||||
uint32_t time;
|
||||
struct normalized_coords delta;
|
||||
- struct normalized_coords delta_unaccel;
|
||||
+ struct device_float_coords delta_raw;
|
||||
struct device_coords absolute;
|
||||
struct discrete_coords discrete;
|
||||
uint32_t button;
|
||||
@@ -339,7 +339,7 @@ libinput_event_pointer_get_dx_unaccelerated(
|
||||
0,
|
||||
LIBINPUT_EVENT_POINTER_MOTION);
|
||||
|
||||
- return event->delta_unaccel.x;
|
||||
+ return event->delta_raw.x;
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT double
|
||||
@@ -351,7 +351,7 @@ libinput_event_pointer_get_dy_unaccelerated(
|
||||
0,
|
||||
LIBINPUT_EVENT_POINTER_MOTION);
|
||||
|
||||
- return event->delta_unaccel.y;
|
||||
+ return event->delta_raw.y;
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT double
|
||||
@@ -1130,7 +1130,7 @@ void
|
||||
pointer_notify_motion(struct libinput_device *device,
|
||||
uint64_t time,
|
||||
const struct normalized_coords *delta,
|
||||
- const struct normalized_coords *unaccel)
|
||||
+ const struct device_float_coords *raw)
|
||||
{
|
||||
struct libinput_event_pointer *motion_event;
|
||||
|
||||
@@ -1144,7 +1144,7 @@ pointer_notify_motion(struct libinput_device *device,
|
||||
*motion_event = (struct libinput_event_pointer) {
|
||||
.time = time,
|
||||
.delta = *delta,
|
||||
- .delta_unaccel = *unaccel,
|
||||
+ .delta_raw = *raw,
|
||||
};
|
||||
|
||||
post_device_event(device, time,
|
||||
diff --git a/src/libinput.h b/src/libinput.h
|
||||
index 0d3200f..e76fa9a 100644
|
||||
--- a/src/libinput.h
|
||||
+++ b/src/libinput.h
|
||||
@@ -460,8 +460,8 @@ libinput_event_pointer_get_time(struct libinput_event_pointer *event);
|
||||
* If a device employs pointer acceleration, the delta returned by this
|
||||
* function is the accelerated delta.
|
||||
*
|
||||
- * Relative motion deltas are normalized to represent those of a device with
|
||||
- * 1000dpi resolution. See @ref motion_normalization for more details.
|
||||
+ * Relative motion deltas are to be interpreted as pixel movement of a
|
||||
+ * standardized mouse. See @ref motion_normalization for more details.
|
||||
*
|
||||
* @note It is an application bug to call this function for events other than
|
||||
* @ref LIBINPUT_EVENT_POINTER_MOTION.
|
||||
@@ -481,8 +481,8 @@ libinput_event_pointer_get_dx(struct libinput_event_pointer *event);
|
||||
* If a device employs pointer acceleration, the delta returned by this
|
||||
* function is the accelerated delta.
|
||||
*
|
||||
- * Relative motion deltas are normalized to represent those of a device with
|
||||
- * 1000dpi resolution. See @ref motion_normalization for more details.
|
||||
+ * Relative motion deltas are to be interpreted as pixel movement of a
|
||||
+ * standardized mouse. See @ref motion_normalization for more details.
|
||||
*
|
||||
* @note It is an application bug to call this function for events other than
|
||||
* @ref LIBINPUT_EVENT_POINTER_MOTION.
|
||||
@@ -499,10 +499,11 @@ libinput_event_pointer_get_dy(struct libinput_event_pointer *event);
|
||||
* current event. For pointer events that are not of type @ref
|
||||
* LIBINPUT_EVENT_POINTER_MOTION, this function returns 0.
|
||||
*
|
||||
- * Relative unaccelerated motion deltas are normalized to represent those of a
|
||||
- * device with 1000dpi resolution. See @ref motion_normalization for more
|
||||
- * details. Note that unaccelerated events are not equivalent to 'raw' events
|
||||
- * as read from the device.
|
||||
+ * Relative unaccelerated motion deltas are raw device coordinates.
|
||||
+ * Note that these coordinates are subject to the device's native
|
||||
+ * resolution. Touchpad coordinates represent raw device coordinates in the
|
||||
+ * X resolution of the touchpad. See @ref motion_normalization for more
|
||||
+ * details.
|
||||
*
|
||||
* @note It is an application bug to call this function for events other than
|
||||
* @ref LIBINPUT_EVENT_POINTER_MOTION.
|
||||
@@ -520,10 +521,11 @@ libinput_event_pointer_get_dx_unaccelerated(
|
||||
* current event. For pointer events that are not of type @ref
|
||||
* LIBINPUT_EVENT_POINTER_MOTION, this function returns 0.
|
||||
*
|
||||
- * Relative unaccelerated motion deltas are normalized to represent those of a
|
||||
- * device with 1000dpi resolution. See @ref motion_normalization for more
|
||||
- * details. Note that unaccelerated events are not equivalent to 'raw' events
|
||||
- * as read from the device.
|
||||
+ * Relative unaccelerated motion deltas are raw device coordinates.
|
||||
+ * Note that these coordinates are subject to the device's native
|
||||
+ * resolution. Touchpad coordinates represent raw device coordinates in the
|
||||
+ * X resolution of the touchpad. See @ref motion_normalization for more
|
||||
+ * details.
|
||||
*
|
||||
* @note It is an application bug to call this function for events other than
|
||||
* @ref LIBINPUT_EVENT_POINTER_MOTION.
|
||||
--
|
||||
2.4.3
|
||||
|
122
0008-filter-pass-the-DPI-to-the-acceleration-filter.patch
Normal file
122
0008-filter-pass-the-DPI-to-the-acceleration-filter.patch
Normal file
@ -0,0 +1,122 @@
|
||||
From 415bc6d956e9c4836f20e661e3ee77d2adfb1cd5 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Fri, 19 Jun 2015 16:03:42 +1000
|
||||
Subject: [PATCH libinput 8/9] filter: pass the DPI to the acceleration filter
|
||||
|
||||
Currently unused, but store the ratio of DPI:default DPI for later use.
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
---
|
||||
src/evdev.c | 3 ++-
|
||||
src/evdev.h | 3 ---
|
||||
src/filter.c | 7 ++++++-
|
||||
src/filter.h | 3 ++-
|
||||
src/libinput-util.h | 3 +++
|
||||
tools/ptraccel-debug.c | 3 ++-
|
||||
6 files changed, 15 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/evdev.c b/src/evdev.c
|
||||
index a5f1d47..b98b47a 100644
|
||||
--- a/src/evdev.c
|
||||
+++ b/src/evdev.c
|
||||
@@ -1409,7 +1409,8 @@ int
|
||||
evdev_device_init_pointer_acceleration(struct evdev_device *device,
|
||||
accel_profile_func_t profile)
|
||||
{
|
||||
- device->pointer.filter = create_pointer_accelerator_filter(profile);
|
||||
+ device->pointer.filter = create_pointer_accelerator_filter(profile,
|
||||
+ device->dpi);
|
||||
if (!device->pointer.filter)
|
||||
return -1;
|
||||
|
||||
diff --git a/src/evdev.h b/src/evdev.h
|
||||
index 566b0a4..b58e021 100644
|
||||
--- a/src/evdev.h
|
||||
+++ b/src/evdev.h
|
||||
@@ -36,9 +36,6 @@
|
||||
#include "timer.h"
|
||||
#include "filter.h"
|
||||
|
||||
-/* The HW DPI rate we normalize to before calculating pointer acceleration */
|
||||
-#define DEFAULT_MOUSE_DPI 1000
|
||||
-
|
||||
/*
|
||||
* The constant (linear) acceleration factor we use to normalize trackpoint
|
||||
* deltas before calculating pointer acceleration.
|
||||
diff --git a/src/filter.c b/src/filter.c
|
||||
index 1e05782..04dd2b9 100644
|
||||
--- a/src/filter.c
|
||||
+++ b/src/filter.c
|
||||
@@ -111,6 +111,8 @@ struct pointer_accelerator {
|
||||
double threshold; /* units/ms */
|
||||
double accel; /* unitless factor */
|
||||
double incline; /* incline of the function */
|
||||
+
|
||||
+ double dpi_factor;
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -346,7 +348,8 @@ struct motion_filter_interface accelerator_interface = {
|
||||
};
|
||||
|
||||
struct motion_filter *
|
||||
-create_pointer_accelerator_filter(accel_profile_func_t profile)
|
||||
+create_pointer_accelerator_filter(accel_profile_func_t profile,
|
||||
+ int dpi)
|
||||
{
|
||||
struct pointer_accelerator *filter;
|
||||
|
||||
@@ -369,6 +372,8 @@ create_pointer_accelerator_filter(accel_profile_func_t profile)
|
||||
filter->accel = DEFAULT_ACCELERATION;
|
||||
filter->incline = DEFAULT_INCLINE;
|
||||
|
||||
+ filter->dpi = dpi;
|
||||
+
|
||||
return &filter->base;
|
||||
}
|
||||
|
||||
diff --git a/src/filter.h b/src/filter.h
|
||||
index de94997..64a8b50 100644
|
||||
--- a/src/filter.h
|
||||
+++ b/src/filter.h
|
||||
@@ -58,7 +58,8 @@ typedef double (*accel_profile_func_t)(struct motion_filter *filter,
|
||||
uint64_t time);
|
||||
|
||||
struct motion_filter *
|
||||
-create_pointer_accelerator_filter(accel_profile_func_t filter);
|
||||
+create_pointer_accelerator_filter(accel_profile_func_t filter,
|
||||
+ int dpi);
|
||||
|
||||
/*
|
||||
* Pointer acceleration profiles.
|
||||
diff --git a/src/libinput-util.h b/src/libinput-util.h
|
||||
index 4f73ad4..bb4834e 100644
|
||||
--- a/src/libinput-util.h
|
||||
+++ b/src/libinput-util.h
|
||||
@@ -37,6 +37,9 @@
|
||||
#define VENDOR_ID_APPLE 0x5ac
|
||||
#define VENDOR_ID_WACOM 0x56a
|
||||
|
||||
+/* The HW DPI rate we normalize to before calculating pointer acceleration */
|
||||
+#define DEFAULT_MOUSE_DPI 1000
|
||||
+
|
||||
void
|
||||
set_logging_enabled(int enabled);
|
||||
|
||||
diff --git a/tools/ptraccel-debug.c b/tools/ptraccel-debug.c
|
||||
index 335781b..9fdb4cd 100644
|
||||
--- a/tools/ptraccel-debug.c
|
||||
+++ b/tools/ptraccel-debug.c
|
||||
@@ -199,7 +199,8 @@ main(int argc, char **argv)
|
||||
OPT_SPEED,
|
||||
};
|
||||
|
||||
- filter = create_pointer_accelerator_filter(pointer_accel_profile_linear);
|
||||
+ filter = create_pointer_accelerator_filter(pointer_accel_profile_linear,
|
||||
+ 1000);
|
||||
assert(filter != NULL);
|
||||
|
||||
while (1) {
|
||||
--
|
||||
2.4.3
|
||||
|
170
0009-filter-add-a-custom-low-dpi-acceleration.patch
Normal file
170
0009-filter-add-a-custom-low-dpi-acceleration.patch
Normal file
@ -0,0 +1,170 @@
|
||||
From 348401a5de950314faadfdd69d160cdeda1362fa Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Tue, 23 Jun 2015 12:45:16 +1000
|
||||
Subject: [PATCH libinput 9/9] filter: add a custom low-dpi acceleration
|
||||
|
||||
Motion normalization does not work well for devices below the default 1000dpi
|
||||
rate. A 400dpi mouse's minimum movement generates a 2.5 normalized motion,
|
||||
causing it to skip pixels at low speeds even when unaccelerated.
|
||||
|
||||
Likewise, we don't want 1000dpi mice to be normalized to a 400dpi mouse, it
|
||||
feels sluggish even at higher acceleration speeds.
|
||||
Instead, add a custom acceleration method for lower-dpi mice. At low-speeds,
|
||||
one device unit results in a one-pixel movement. Depending on the DPI factor,
|
||||
the acceleration kicks in earlier and goes to higher acceleration so faster
|
||||
movements with a low-dpi mouse feel approximately the same as the same
|
||||
movement on a higher-dpi mouse.
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1231304
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
---
|
||||
src/evdev.c | 17 ++++++++++++++---
|
||||
src/filter.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++------
|
||||
src/filter.h | 5 +++++
|
||||
3 files changed, 69 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/evdev.c b/src/evdev.c
|
||||
index b98b47a..1edf93f 100644
|
||||
--- a/src/evdev.c
|
||||
+++ b/src/evdev.c
|
||||
@@ -1823,6 +1823,19 @@ evdev_configure_mt_device(struct evdev_device *device)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static inline int
|
||||
+evdev_init_accel(struct evdev_device *device)
|
||||
+{
|
||||
+ accel_profile_func_t profile;
|
||||
+
|
||||
+ if (device->dpi < DEFAULT_MOUSE_DPI)
|
||||
+ profile = pointer_accel_profile_linear_low_dpi;
|
||||
+ else
|
||||
+ profile = pointer_accel_profile_linear;
|
||||
+
|
||||
+ return evdev_device_init_pointer_acceleration(device, profile);
|
||||
+}
|
||||
+
|
||||
static int
|
||||
evdev_configure_device(struct evdev_device *device)
|
||||
{
|
||||
@@ -1914,9 +1927,7 @@ evdev_configure_device(struct evdev_device *device)
|
||||
udev_tags & EVDEV_UDEV_TAG_POINTINGSTICK) {
|
||||
if (libevdev_has_event_code(evdev, EV_REL, REL_X) &&
|
||||
libevdev_has_event_code(evdev, EV_REL, REL_Y) &&
|
||||
- evdev_device_init_pointer_acceleration(
|
||||
- device,
|
||||
- pointer_accel_profile_linear) == -1)
|
||||
+ evdev_init_accel(device) == -1)
|
||||
return -1;
|
||||
|
||||
device->seat_caps |= EVDEV_DEVICE_POINTER;
|
||||
diff --git a/src/filter.c b/src/filter.c
|
||||
index 04dd2b9..35449f5 100644
|
||||
--- a/src/filter.c
|
||||
+++ b/src/filter.c
|
||||
@@ -264,8 +264,16 @@ accelerator_filter(struct motion_filter *filter,
|
||||
double velocity; /* units/ms */
|
||||
double accel_value; /* unitless factor */
|
||||
struct normalized_coords accelerated;
|
||||
+ struct normalized_coords unnormalized;
|
||||
+ double dpi_factor = accel->dpi_factor;
|
||||
|
||||
- feed_trackers(accel, unaccelerated, time);
|
||||
+ /* For low-dpi mice, use device units, everything else uses
|
||||
+ 1000dpi normalized */
|
||||
+ dpi_factor = min(1.0, dpi_factor);
|
||||
+ unnormalized.x = unaccelerated->x * dpi_factor;
|
||||
+ unnormalized.y = unaccelerated->y * dpi_factor;
|
||||
+
|
||||
+ feed_trackers(accel, &unnormalized, time);
|
||||
velocity = calculate_velocity(accel, time);
|
||||
accel_value = calculate_acceleration(accel,
|
||||
data,
|
||||
@@ -273,10 +281,10 @@ accelerator_filter(struct motion_filter *filter,
|
||||
accel->last_velocity,
|
||||
time);
|
||||
|
||||
- accelerated.x = accel_value * unaccelerated->x;
|
||||
- accelerated.y = accel_value * unaccelerated->y;
|
||||
+ accelerated.x = accel_value * unnormalized.x;
|
||||
+ accelerated.y = accel_value * unnormalized.y;
|
||||
|
||||
- accel->last = *unaccelerated;
|
||||
+ accel->last = unnormalized;
|
||||
|
||||
accel->last_velocity = velocity;
|
||||
|
||||
@@ -372,15 +380,51 @@ create_pointer_accelerator_filter(accel_profile_func_t profile,
|
||||
filter->accel = DEFAULT_ACCELERATION;
|
||||
filter->incline = DEFAULT_INCLINE;
|
||||
|
||||
- filter->dpi = dpi;
|
||||
+ filter->dpi_factor = dpi/(double)DEFAULT_MOUSE_DPI;
|
||||
|
||||
return &filter->base;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * Custom acceleration function for mice < 1000dpi.
|
||||
+ * At slow motion, a single device unit causes a one-pixel movement.
|
||||
+ * The threshold/max accel depends on the DPI, the smaller the DPI the
|
||||
+ * earlier we accelerate and the higher the maximum acceleration is. Result:
|
||||
+ * at low speeds we get pixel-precision, at high speeds we get approx. the
|
||||
+ * same movement as a high-dpi mouse.
|
||||
+ *
|
||||
+ * Note: data fed to this function is in device units, not normalized.
|
||||
+ */
|
||||
+double
|
||||
+pointer_accel_profile_linear_low_dpi(struct motion_filter *filter,
|
||||
+ void *data,
|
||||
+ double speed_in, /* in device units */
|
||||
+ uint64_t time)
|
||||
+{
|
||||
+ struct pointer_accelerator *accel_filter =
|
||||
+ (struct pointer_accelerator *)filter;
|
||||
+
|
||||
+ double s1, s2;
|
||||
+ double max_accel = accel_filter->accel; /* unitless factor */
|
||||
+ const double threshold = accel_filter->threshold; /* units/ms */
|
||||
+ const double incline = accel_filter->incline;
|
||||
+ double factor;
|
||||
+ double dpi_factor = accel_filter->dpi_factor;
|
||||
+
|
||||
+ max_accel /= dpi_factor;
|
||||
+
|
||||
+ s1 = min(1, 0.3 + speed_in * 10);
|
||||
+ s2 = 1 + (speed_in - threshold * dpi_factor) * incline;
|
||||
+
|
||||
+ factor = min(max_accel, s2 > 1 ? s2 : s1);
|
||||
+
|
||||
+ return factor;
|
||||
+}
|
||||
+
|
||||
double
|
||||
pointer_accel_profile_linear(struct motion_filter *filter,
|
||||
void *data,
|
||||
- double speed_in,
|
||||
+ double speed_in, /* 1000-dpi normalized */
|
||||
uint64_t time)
|
||||
{
|
||||
struct pointer_accelerator *accel_filter =
|
||||
diff --git a/src/filter.h b/src/filter.h
|
||||
index 64a8b50..617fab1 100644
|
||||
--- a/src/filter.h
|
||||
+++ b/src/filter.h
|
||||
@@ -66,6 +66,11 @@ create_pointer_accelerator_filter(accel_profile_func_t filter,
|
||||
*/
|
||||
|
||||
double
|
||||
+pointer_accel_profile_linear_low_dpi(struct motion_filter *filter,
|
||||
+ void *data,
|
||||
+ double speed_in,
|
||||
+ uint64_t time);
|
||||
+double
|
||||
pointer_accel_profile_linear(struct motion_filter *filter,
|
||||
void *data,
|
||||
double speed_in,
|
||||
--
|
||||
2.4.3
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
Name: libinput
|
||||
Version: 0.18.0
|
||||
Release: 3%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist}
|
||||
Release: 4%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist}
|
||||
Summary: Input device library
|
||||
|
||||
License: MIT
|
||||
@ -22,6 +22,18 @@ Patch01: 0001-touchpad-only-send-most-recent-edge-delta-when-trigg.patch
|
||||
Patch02: 0001-touchpad-reduce-edge-scroll-motion-threshold-to-3mm.patch
|
||||
Patch03: 0001-touchpad-fix-stuck-finger-after-a-click.patch
|
||||
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1227039
|
||||
Patch04: 0001-filter-reduce-deceleration-to-minimal-speeds-only.patch
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1231304
|
||||
Patch05: 0002-evdev-read-dpi-before-evdev_configure_device.patch
|
||||
Patch06: 0003-evdev-log-device-s-DPI-setting-if-any.patch
|
||||
Patch07: 0004-evdev-move-posting-a-trackpoint-scroll-event-into-a-.patch
|
||||
Patch08: 0005-tools-don-t-drop-the-accelerated-deltas-in-ptraccel-.patch
|
||||
Patch09: 0006-filter-use-a-tmp-variable-for-the-accel-factor.patch
|
||||
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
|
||||
|
||||
BuildRequires: git
|
||||
BuildRequires: autoconf automake libtool pkgconfig
|
||||
BuildRequires: libevdev-devel
|
||||
@ -98,6 +110,11 @@ find $RPM_BUILD_ROOT -name '*.la' -delete
|
||||
|
||||
|
||||
%changelog
|
||||
* Mon Jun 29 2015 Peter Hutterer <peter.hutterer@redhat.com> 0.18.0-4
|
||||
- Steepen deceleration curve to get better 1:1 movement on slow speeds
|
||||
(#1231304)
|
||||
- Provide custom accel method for <1000dpi mice (#1227039)
|
||||
|
||||
* Thu Jun 25 2015 Peter Hutterer <peter.hutterer@redhat.com> 0.18.0-3
|
||||
- Fix stuck finger after a clickpad click on resolutionless touchpads
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user