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>
}
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:
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;
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)
{
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);
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,
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)
{
if (!filter)
return NULL;
- filter->base.interface = &accelerator_interface;
+ filter->base.interface = &accelerator_interface_touchpad;
filter->profile = touchpad_accel_profile_linear;
return &filter->base;