[PATCH v2 libinput 5/3] touchpad: accumulate the initial scroll edge delta
Hans de Goede
hdegoede at redhat.com
Mon Mar 9 06:10:13 PDT 2015
Hi,
On 09-03-15 01:54, Peter Hutterer wrote:
> The previous setting of 10 wasn't 10 mm, it was used against the deltas
> normalized to a 1000DPI mouse, i.e. closer to 4mm. It was also also per-event,
> so a slow movement or a high-frequency touchpad can struggle to meet the
> threshold.
>
> Change the trigger to be ~5 mm from the initial touch down, accumulated until
> we either meet the threshold or the timeout expires. The first scroll event
> includes the delta since the touch down rather than the most recent delta.
> This removes the delay otherwise seen in scrolling and makes the scroll motion
> match the finger motion. This accumulated delta only applies when exceeding
> the motion threshold, when the timeout triggers the switch to scrolling the
> first delta posted is the current delta.
>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> Reviewed-by: Hans de Goede <hdegoede at redhat.com>
Looks good, my reviewed-by still stands.
Regards,
Hans
> ---
> Changes to v1:
> - use TP_MM_TO_DPI_NORMALIZED
> - reset dx/dy, not just *delta
> - expand commit message that we're using accumulated deltas on the first scroll
> - rename the slow_distance test to timeout, that's what we're triggering
> here
>
> src/evdev-mt-touchpad-edge-scroll.c | 37 ++++++++++++++++++++++++++++++++++---
> src/evdev-mt-touchpad.h | 2 ++
> test/litest.c | 6 ++++++
> test/litest.h | 1 +
> test/touchpad.c | 16 +++++++++++-----
> 5 files changed, 54 insertions(+), 8 deletions(-)
>
> diff --git a/src/evdev-mt-touchpad-edge-scroll.c b/src/evdev-mt-touchpad-edge-scroll.c
> index 28f29c2..3adde8c 100644
> --- a/src/evdev-mt-touchpad-edge-scroll.c
> +++ b/src/evdev-mt-touchpad-edge-scroll.c
> @@ -34,8 +34,7 @@
> avoid accidentally locking in scrolling mode when trying to use the entire
> touchpad to move the pointer. The user can wait for the timeout to trigger
> to do a small scroll. */
> -/* In mm for touchpads with valid resolution, see tp_init_accel() */
> -#define DEFAULT_SCROLL_THRESHOLD 10.0
> +#define DEFAULT_SCROLL_THRESHOLD TP_MM_TO_DPI_NORMALIZED(5)
>
> enum scroll_event {
> SCROLL_EVENT_TOUCH,
> @@ -78,6 +77,8 @@ tp_edge_scroll_set_state(struct tp_dispatch *tp,
> break;
> case EDGE_SCROLL_TOUCH_STATE_EDGE_NEW:
> t->scroll.edge = tp_touch_get_edge(tp, t);
> + t->scroll.initial_x = t->x;
> + t->scroll.initial_y = t->y;
> libinput_timer_set(&t->scroll.timer,
> t->millis + DEFAULT_SCROLL_LOCK_TIMEOUT);
> break;
> @@ -315,6 +316,7 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
> struct tp_touch *t;
> enum libinput_pointer_axis axis;
> double dx, dy, *delta;
> + double initial_dx, initial_dy, *initial_delta;
>
> if (tp->scroll.method != LIBINPUT_CONFIG_SCROLL_EDGE)
> return 0;
> @@ -338,10 +340,12 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
> case EDGE_RIGHT:
> axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL;
> delta = &dy;
> + initial_delta = &initial_dy;
> break;
> case EDGE_BOTTOM:
> axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
> delta = &dx;
> + initial_delta = &initial_dx;
> break;
> default: /* EDGE_RIGHT | EDGE_BOTTOM */
> continue; /* Don't know direction yet, skip */
> @@ -350,7 +354,34 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
> tp_get_delta(t, &dx, &dy);
> tp_filter_motion(tp, &dx, &dy, NULL, NULL, time);
>
> - if (fabs(*delta) < t->scroll.threshold)
> + switch (t->scroll.edge_state) {
> + case EDGE_SCROLL_TOUCH_STATE_NONE:
> + case EDGE_SCROLL_TOUCH_STATE_AREA:
> + log_bug_libinput(device->seat->libinput,
> + "unexpected scroll state %d\n",
> + t->scroll.edge_state);
> + break;
> + case EDGE_SCROLL_TOUCH_STATE_EDGE_NEW:
> + initial_dx = t->x - t->scroll.initial_x;
> + initial_dy = t->y - t->scroll.initial_y;
> + tp_normalize_delta(tp,
> + &initial_dx,
> + &initial_dy);
> + if (fabs(*initial_delta) < t->scroll.threshold) {
> + dx = 0.0;
> + dy = 0.0;
> + } else {
> + dx = initial_dx;
> + dy = initial_dy;
> + }
> + break;
> + case EDGE_SCROLL_TOUCH_STATE_EDGE:
> + if (fabs(*delta) < t->scroll.threshold)
> + *delta = 0.0;
> + break;
> + }
> +
> + if (*delta == 0.0)
> continue;
>
> pointer_notify_axis(device, time,
> diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
> index fc75f93..239bddd 100644
> --- a/src/evdev-mt-touchpad.h
> +++ b/src/evdev-mt-touchpad.h
> @@ -176,6 +176,8 @@ struct tp_touch {
> int direction;
> double threshold;
> struct libinput_timer timer;
> + int32_t initial_x; /* in device coordinates */
> + int32_t initial_y; /* in device coordinates */
> } scroll;
>
> struct {
> diff --git a/test/litest.c b/test/litest.c
> index 4d04b52..3646446 100644
> --- a/test/litest.c
> +++ b/test/litest.c
> @@ -1391,6 +1391,12 @@ litest_timeout_finger_switch(void)
> }
>
> void
> +litest_timeout_edgescroll(void)
> +{
> + msleep(300);
> +}
> +
> +void
> litest_push_event_frame(struct litest_device *dev)
> {
> assert(!dev->skip_ev_syn);
> diff --git a/test/litest.h b/test/litest.h
> index 8f16851..e85b511 100644
> --- a/test/litest.h
> +++ b/test/litest.h
> @@ -183,6 +183,7 @@ struct libevdev_uinput * litest_create_uinput_abs_device(const char *name,
> void litest_timeout_tap(void);
> void litest_timeout_softbuttons(void);
> void litest_timeout_buttonscroll(void);
> +void litest_timeout_edgescroll(void);
> void litest_timeout_finger_switch(void);
>
> void litest_push_event_frame(struct litest_device *dev);
> diff --git a/test/touchpad.c b/test/touchpad.c
> index 5c8f579..ff4edb0 100644
> --- a/test/touchpad.c
> +++ b/test/touchpad.c
> @@ -2057,7 +2057,7 @@ START_TEST(touchpad_edge_scroll)
> }
> END_TEST
>
> -START_TEST(touchpad_edge_scroll_slow_distance)
> +START_TEST(touchpad_edge_scroll_timeout)
> {
> struct litest_device *dev = litest_current_device();
> struct libinput *li = dev->libinput;
> @@ -2067,6 +2067,10 @@ START_TEST(touchpad_edge_scroll_slow_distance)
> litest_drain_events(li);
>
> litest_touch_down(dev, 0, 99, 20);
> + libinput_dispatch(li);
> + litest_timeout_edgescroll();
> + libinput_dispatch(li);
> +
> litest_touch_move_to(dev, 0, 99, 20, 99, 80, 60, 10);
> litest_touch_up(dev, 0);
> libinput_dispatch(li);
> @@ -2074,6 +2078,8 @@ START_TEST(touchpad_edge_scroll_slow_distance)
> event = libinput_get_event(li);
> ck_assert_notnull(event);
>
> + litest_wait_for_event_of_type(li, LIBINPUT_EVENT_POINTER_AXIS, -1);
> +
> while (libinput_next_event_type(li) != LIBINPUT_EVENT_NONE) {
> double axisval;
> ck_assert_int_eq(libinput_event_get_type(event),
> @@ -2105,10 +2111,10 @@ START_TEST(touchpad_edge_scroll_no_motion)
>
> litest_drain_events(li);
>
> - litest_touch_down(dev, 0, 99, 20);
> - litest_touch_move_to(dev, 0, 99, 20, 99, 60, 10, 0);
> + litest_touch_down(dev, 0, 99, 10);
> + litest_touch_move_to(dev, 0, 99, 10, 99, 70, 10, 0);
> /* moving outside -> no motion event */
> - litest_touch_move_to(dev, 0, 99, 60, 20, 80, 10, 0);
> + litest_touch_move_to(dev, 0, 99, 70, 20, 80, 10, 0);
> /* moving down outside edge once scrolling had started -> scroll */
> litest_touch_move_to(dev, 0, 20, 80, 40, 99, 10, 0);
> litest_touch_up(dev, 0);
> @@ -3427,7 +3433,7 @@ int main(int argc, char **argv) {
> litest_add("touchpad:scroll", touchpad_edge_scroll, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY);
> litest_add("touchpad:scroll", touchpad_edge_scroll_no_motion, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY);
> litest_add("touchpad:scroll", touchpad_edge_scroll_no_edge_after_motion, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY);
> - litest_add("touchpad:scroll", touchpad_edge_scroll_slow_distance, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY);
> + litest_add("touchpad:scroll", touchpad_edge_scroll_timeout, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY);
> litest_add("touchpad:scroll", touchpad_edge_scroll_source, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY);
>
> litest_add("touchpad:palm", touchpad_palm_detect_at_edge, LITEST_TOUCHPAD, LITEST_ANY);
>
More information about the wayland-devel
mailing list