mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-25 09:20:07 +01:00
touchpad: use unaccelerated motion data for scrolling
For short and quick scroll gestures, those that should only trigger a few lines of scroll the pointer acceleration is wildly unpredictable. Since we average the motion of both fingers it's hard enough to intuitively predict what the motion will be like. On top of that is the small threshold before we start scrolling, so some of the initial motion gets swallowed before we accelerate, making the next motion even more unpredictable. The end result is that multiple seemingly identical finger motions cause wildly different scroll motion. Drop pointer acceleration for two-finger and edge scrolling. This makes short scroll motions much more predictable and doesn't seem to have much effect on long scroll motions. Plus, in natural scroll mode it really feels like the content is stuck to your fingers now. Go wash your hands. https://bugzilla.redhat.com/show_bug.cgi?id=1249365 Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
d8c37a94c0
commit
c8da19b50a
5 changed files with 42 additions and 3 deletions
|
|
@ -390,7 +390,8 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
|
|||
}
|
||||
|
||||
normalized = tp_get_delta(t);
|
||||
normalized = tp_filter_motion(tp, &normalized, time);
|
||||
/* scroll is not accelerated */
|
||||
normalized = tp_filter_motion_unaccelerated(tp, &normalized, time);
|
||||
|
||||
switch (t->scroll.edge_state) {
|
||||
case EDGE_SCROLL_TOUCH_STATE_NONE:
|
||||
|
|
|
|||
|
|
@ -328,7 +328,8 @@ tp_gesture_twofinger_handle_state_scroll(struct tp_dispatch *tp, uint64_t time)
|
|||
delta = tp_get_average_touches_delta(tp);
|
||||
}
|
||||
|
||||
delta = tp_filter_motion(tp, &delta, time);
|
||||
/* scroll is not accelerated */
|
||||
delta = tp_filter_motion_unaccelerated(tp, &delta, time);
|
||||
|
||||
if (normalized_is_zero(delta))
|
||||
return GESTURE_2FG_STATE_SCROLL;
|
||||
|
|
|
|||
|
|
@ -71,6 +71,18 @@ tp_filter_motion(struct tp_dispatch *tp,
|
|||
unaccelerated, tp, time);
|
||||
}
|
||||
|
||||
struct normalized_coords
|
||||
tp_filter_motion_unaccelerated(struct tp_dispatch *tp,
|
||||
const struct normalized_coords *unaccelerated,
|
||||
uint64_t time)
|
||||
{
|
||||
if (normalized_is_zero(*unaccelerated))
|
||||
return *unaccelerated;
|
||||
|
||||
return filter_dispatch_constant(tp->device->pointer.filter,
|
||||
unaccelerated, tp, time);
|
||||
}
|
||||
|
||||
static inline void
|
||||
tp_motion_history_push(struct tp_touch *t)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -395,6 +395,10 @@ struct normalized_coords
|
|||
tp_filter_motion(struct tp_dispatch *tp,
|
||||
const struct normalized_coords *unaccelerated,
|
||||
uint64_t time);
|
||||
struct normalized_coords
|
||||
tp_filter_motion_unaccelerated(struct tp_dispatch *tp,
|
||||
const struct normalized_coords *unaccelerated,
|
||||
uint64_t time);
|
||||
|
||||
int
|
||||
tp_touch_active(struct tp_dispatch *tp, struct tp_touch *t);
|
||||
|
|
|
|||
23
src/filter.c
23
src/filter.c
|
|
@ -420,6 +420,19 @@ accelerator_filter_x230(struct motion_filter *filter,
|
|||
return accelerated;
|
||||
}
|
||||
|
||||
static struct normalized_coords
|
||||
touchpad_constant_filter(struct motion_filter *filter,
|
||||
const struct normalized_coords *unaccelerated,
|
||||
void *data, uint64_t time)
|
||||
{
|
||||
struct normalized_coords normalized;
|
||||
|
||||
normalized.x = TP_MAGIC_SLOWDOWN * unaccelerated->x;
|
||||
normalized.y = TP_MAGIC_SLOWDOWN * unaccelerated->y;
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
static void
|
||||
accelerator_restart(struct motion_filter *filter,
|
||||
void *data,
|
||||
|
|
@ -757,6 +770,14 @@ create_pointer_accelerator_filter_linear_low_dpi(int dpi)
|
|||
return &filter->base;
|
||||
}
|
||||
|
||||
struct motion_filter_interface accelerator_interface_touchpad = {
|
||||
.filter = accelerator_filter,
|
||||
.filter_constant = touchpad_constant_filter,
|
||||
.restart = accelerator_restart,
|
||||
.destroy = accelerator_destroy,
|
||||
.set_speed = accelerator_set_speed,
|
||||
};
|
||||
|
||||
struct motion_filter *
|
||||
create_pointer_accelerator_filter_touchpad(int dpi)
|
||||
{
|
||||
|
|
@ -766,7 +787,7 @@ create_pointer_accelerator_filter_touchpad(int dpi)
|
|||
if (!filter)
|
||||
return NULL;
|
||||
|
||||
filter->base.interface = &accelerator_interface;
|
||||
filter->base.interface = &accelerator_interface_touchpad;
|
||||
filter->profile = touchpad_accel_profile_linear;
|
||||
|
||||
return &filter->base;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue