mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-29 09:00:08 +01:00
touchpad: accumulate the initial scroll edge delta
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@who-t.net> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
82be678e79
commit
1cebdc7a2b
5 changed files with 54 additions and 8 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -1390,6 +1390,12 @@ litest_timeout_finger_switch(void)
|
|||
msleep(120);
|
||||
}
|
||||
|
||||
void
|
||||
litest_timeout_edgescroll(void)
|
||||
{
|
||||
msleep(300);
|
||||
}
|
||||
|
||||
void
|
||||
litest_push_event_frame(struct litest_device *dev)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue