gestures: don't try to pinch for nfingers > slots

We don't know the position of the third finger on 2-slot touchpads, differing
between swipe and pinch is reliable. Simply disable 3-finger pinch and always
use swipe; 3fg pinch is uncommon anyway and it's better to have one of the
gestures working reliably than both unreliably.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
Peter Hutterer 2017-07-29 13:59:40 +01:00
parent 6bb05c594a
commit 6d435cda06
2 changed files with 6 additions and 212 deletions

View file

@ -334,6 +334,10 @@ tp_gesture_handle_state_unknown(struct tp_dispatch *tp, uint64_t time)
if (tp->gesture.finger_count == 2) {
tp_gesture_set_scroll_buildup(tp);
return GESTURE_STATE_SCROLL;
/* more fingers than slots, don't bother with pinch, always
* assume swipe */
} else if (tp->gesture.finger_count > tp->num_slots) {
return GESTURE_STATE_SWIPE;
}
/* for 3+ finger gestures, check if one finger is > 20mm
@ -356,7 +360,8 @@ tp_gesture_handle_state_unknown(struct tp_dispatch *tp, uint64_t time)
/* If both touches are moving in the same direction assume
* scroll or swipe */
if (tp_gesture_same_directions(dir1, dir2)) {
if (tp->gesture.finger_count > tp->num_slots ||
tp_gesture_same_directions(dir1, dir2)) {
if (tp->gesture.finger_count == 2) {
tp_gesture_set_scroll_buildup(tp);
return GESTURE_STATE_SCROLL;

View file

@ -754,110 +754,6 @@ START_TEST(gestures_pinch_3fg)
}
END_TEST
START_TEST(gestures_pinch_3fg_btntool)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct libinput_event *event;
struct libinput_event_gesture *gevent;
double dx, dy;
int cardinal = _i; /* ranged test */
double dir_x, dir_y;
int i;
double scale, oldscale;
double angle;
int cardinals[8][2] = {
{ 0, 30 },
{ 30, 30 },
{ 30, 0 },
{ 30, -30 },
{ 0, -30 },
{ -30, -30 },
{ -30, 0 },
{ -30, 30 },
};
if (libevdev_get_num_slots(dev->evdev) > 2 ||
!libinput_device_has_capability(dev->libinput_device,
LIBINPUT_DEVICE_CAP_GESTURE))
return;
dir_x = cardinals[cardinal][0];
dir_y = cardinals[cardinal][1];
litest_drain_events(li);
litest_touch_down(dev, 0, 50 + dir_x, 50 + dir_y);
litest_touch_down(dev, 1, 50 - dir_x, 50 - dir_y);
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
libinput_dispatch(li);
for (i = 0; i < 8; i++) {
litest_push_event_frame(dev);
if (dir_x > 0.0)
dir_x -= 2;
else if (dir_x < 0.0)
dir_x += 2;
if (dir_y > 0.0)
dir_y -= 2;
else if (dir_y < 0.0)
dir_y += 2;
litest_touch_move(dev,
0,
50 + dir_x,
50 + dir_y);
litest_touch_move(dev,
1,
50 - dir_x,
50 - dir_y);
litest_pop_event_frame(dev);
libinput_dispatch(li);
}
event = libinput_get_event(li);
gevent = litest_is_gesture_event(event,
LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
3);
dx = libinput_event_gesture_get_dx(gevent);
dy = libinput_event_gesture_get_dy(gevent);
scale = libinput_event_gesture_get_scale(gevent);
ck_assert(dx == 0.0);
ck_assert(dy == 0.0);
ck_assert(scale == 1.0);
libinput_event_destroy(event);
while ((event = libinput_get_event(li)) != NULL) {
gevent = litest_is_gesture_event(event,
LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
3);
oldscale = scale;
scale = libinput_event_gesture_get_scale(gevent);
ck_assert(scale < oldscale);
angle = libinput_event_gesture_get_angle_delta(gevent);
ck_assert_double_le(fabs(angle), 1.0);
libinput_event_destroy(event);
libinput_dispatch(li);
}
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
libinput_dispatch(li);
event = libinput_get_event(li);
gevent = litest_is_gesture_event(event,
LIBINPUT_EVENT_GESTURE_PINCH_END,
3);
ck_assert(!libinput_event_gesture_get_cancelled(gevent));
libinput_event_destroy(event);
}
END_TEST
START_TEST(gestures_pinch_4fg)
{
struct litest_device *dev = litest_current_device();
@ -969,111 +865,6 @@ START_TEST(gestures_pinch_4fg)
}
END_TEST
START_TEST(gestures_pinch_4fg_btntool)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct libinput_event *event;
struct libinput_event_gesture *gevent;
double dx, dy;
int cardinal = _i; /* ranged test */
double dir_x, dir_y;
int i;
double scale, oldscale;
double angle;
int cardinals[8][2] = {
{ 0, 30 },
{ 30, 30 },
{ 30, 0 },
{ 30, -30 },
{ 0, -30 },
{ -30, -30 },
{ -30, 0 },
{ -30, 30 },
};
if (libevdev_get_num_slots(dev->evdev) > 2 ||
!libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_QUADTAP) ||
!libinput_device_has_capability(dev->libinput_device,
LIBINPUT_DEVICE_CAP_GESTURE))
return;
dir_x = cardinals[cardinal][0];
dir_y = cardinals[cardinal][1];
litest_drain_events(li);
litest_touch_down(dev, 0, 50 + dir_x, 50 + dir_y);
litest_touch_down(dev, 1, 50 - dir_x, 50 - dir_y);
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
litest_event(dev, EV_KEY, BTN_TOOL_QUADTAP, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
libinput_dispatch(li);
for (i = 0; i < 8; i++) {
litest_push_event_frame(dev);
if (dir_x > 0.0)
dir_x -= 3;
else if (dir_x < 0.0)
dir_x += 3;
if (dir_y > 0.0)
dir_y -= 3;
else if (dir_y < 0.0)
dir_y += 3;
litest_touch_move(dev,
0,
50 + dir_x,
50 + dir_y);
litest_touch_move(dev,
1,
50 - dir_x,
50 - dir_y);
litest_pop_event_frame(dev);
libinput_dispatch(li);
}
event = libinput_get_event(li);
gevent = litest_is_gesture_event(event,
LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
4);
dx = libinput_event_gesture_get_dx(gevent);
dy = libinput_event_gesture_get_dy(gevent);
scale = libinput_event_gesture_get_scale(gevent);
ck_assert(dx == 0.0);
ck_assert(dy == 0.0);
ck_assert(scale == 1.0);
libinput_event_destroy(event);
while ((event = libinput_get_event(li)) != NULL) {
gevent = litest_is_gesture_event(event,
LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
4);
oldscale = scale;
scale = libinput_event_gesture_get_scale(gevent);
ck_assert(scale < oldscale);
angle = libinput_event_gesture_get_angle_delta(gevent);
ck_assert_double_le(fabs(angle), 1.5);
libinput_event_destroy(event);
libinput_dispatch(li);
}
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
libinput_dispatch(li);
event = libinput_get_event(li);
gevent = litest_is_gesture_event(event,
LIBINPUT_EVENT_GESTURE_PINCH_END,
4);
ck_assert(!libinput_event_gesture_get_cancelled(gevent));
libinput_event_destroy(event);
}
END_TEST
START_TEST(gestures_spread)
{
struct litest_device *dev = litest_current_device();
@ -1282,9 +1073,7 @@ litest_setup_tests_gestures(void)
litest_add_ranged("gestures:swipe", gestures_swipe_4fg_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
litest_add_ranged("gestures:pinch", gestures_pinch, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
litest_add_ranged("gestures:pinch", gestures_pinch_3fg, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
litest_add_ranged("gestures:pinch", gestures_pinch_3fg_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
litest_add_ranged("gestures:pinch", gestures_pinch_4fg, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
litest_add_ranged("gestures:pinch", gestures_pinch_4fg_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
litest_add_ranged("gestures:pinch", gestures_spread, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals);
litest_add_ranged("gestures:pinch", gestures_pinch_vertical_positon, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &fingers);