Commit a8e3f4d1 authored by Peter Hutterer's avatar Peter Hutterer

touchpad: ignore motion speed for hovering touches

tp_detect_thumb_while_moving() assumes that of the 2 fingers down, at least
one must be in TOUCH_UPDATE, otherwise we wouldn't have a speed to analyze for
thumb.

If a touch starts in HOVERING and exceeds the speed limit, we were previously
increasing the 'exceeded count'. This later leads to an assert() in
tp_detect_thumb_while_moving() when the second finger comes down because
although we have multiple fingers, none of them are in TOUCH_UPDATE.

This only happens when fingers 2 and 3 come down in the same event frame,
because then we have nfingers_down at 2 (the hovering one doesn't count) but
we don't yet have a finger in TOUCH_UPDATE.

Fix this twofold, first by now calculating the speed on anything but
TOUCH_UPDATE. And second by force-resetting the speed count on
TOUCH_BEGIN/TOUCH_END so we definitely cover all the hover transitions.

Fixes #150Signed-off-by: Peter Hutterer's avatarPeter Hutterer <peter.hutterer@who-t.net>
parent b5991772
Pipeline #5206 passed with stages
in 5 minutes and 29 seconds
......@@ -98,6 +98,9 @@ tp_calculate_motion_speed(struct tp_dispatch *tp, struct tp_touch *t)
if (!tp->has_mt || tp->semi_mt)
return;
if (t->state != TOUCH_UPDATE)
return;
/* This doesn't kick in until we have at least 4 events in the
* motion history. As a side-effect, this automatically handles the
* 2fg scroll where a finger is down and moving fast before the
......@@ -332,6 +335,7 @@ tp_begin_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
t->thumb.first_touch_time = time;
t->tap.is_thumb = false;
t->tap.is_palm = false;
t->speed.exceeded_count = 0;
assert(tp->nfingers_down >= 1);
tp->hysteresis.last_motion_time = time;
}
......@@ -409,6 +413,7 @@ tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
t->pinned.is_pinned = false;
t->time = time;
t->palm.time = 0;
t->speed.exceeded_count = 0;
tp->queued |= TOUCHPAD_EVENT_MOTION;
}
......
......@@ -6274,6 +6274,42 @@ START_TEST(touchpad_speed_ignore_finger_edgescroll)
}
END_TEST
START_TEST(touchpad_speed_ignore_hovering_finger)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct axis_replacement axes[] = {
{ ABS_MT_TOUCH_MAJOR, 1 },
{ ABS_MT_TOUCH_MINOR, 1 },
{ -1, 0 }
};
litest_drain_events(li);
/* first finger down but below touch size. we use slot 2 because
* it's easier this way for litest */
litest_touch_down_extended(dev, 2, 20, 20, axes);
litest_touch_move_to_extended(dev, 2, 20, 20, 60, 80, axes, 20);
litest_drain_events(li);
/* second, third finger down withn same frame */
litest_push_event_frame(dev);
litest_touch_down(dev, 0, 59, 70);
litest_touch_down(dev, 1, 65, 70);
litest_pop_event_frame(dev);
litest_touch_move_two_touches(dev, 59, 70, 65, 70, 0, 30, 10);
libinput_dispatch(li);
litest_touch_up(dev, 2);
libinput_dispatch(li);
litest_touch_up(dev, 1);
litest_touch_up(dev, 0);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
}
END_TEST
enum suspend {
SUSPEND_EXT_MOUSE = 1,
SUSPEND_SENDEVENTS,
......@@ -6778,6 +6814,7 @@ TEST_COLLECTION(touchpad)
litest_add("touchpad:speed", touchpad_speed_ignore_finger, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
litest_add("touchpad:speed", touchpad_speed_allow_nearby_finger, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
litest_add("touchpad:speed", touchpad_speed_ignore_finger_edgescroll, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
litest_add_for_device("touchpad:speed", touchpad_speed_ignore_hovering_finger, LITEST_BCM5974);
litest_add_ranged("touchpad:suspend", touchpad_suspend_abba, LITEST_TOUCHPAD, LITEST_ANY, &suspends);
litest_add_ranged("touchpad:suspend", touchpad_suspend_abab, LITEST_TOUCHPAD, LITEST_ANY, &suspends);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment