[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