From 8e7f99c27ab39df0ef6a79443266b00ad43d824f Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 13 Jul 2016 11:47:30 +1000 Subject: [PATCH] touchpad: don't init a horizontal scroll area on touchpads <50mm high We simply don't have enough space on those touchpads to have an area carved out for horizontal scrolling. Given that horizontal scrolling is rarely needed anyway users of these touchpads will just have to cling to scroll bars or use two-finger scrolling. Exception are small clickpads because they already have an area blocked off for software buttons and those small clickpads generally come from a time when clickfinger wasn't much of a thing yet. https://bugs.freedesktop.org/show_bug.cgi?id=96910 Signed-off-by: Peter Hutterer Reviewed-by: Hans de Goede --- src/evdev-mt-touchpad-edge-scroll.c | 18 ++++++- test/touchpad.c | 78 ++++++++++++++++++++++++++++- 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/src/evdev-mt-touchpad-edge-scroll.c b/src/evdev-mt-touchpad-edge-scroll.c index 8222bba4..610744a1 100644 --- a/src/evdev-mt-touchpad-edge-scroll.c +++ b/src/evdev-mt-touchpad-edge-scroll.c @@ -286,13 +286,29 @@ tp_edge_scroll_init(struct tp_dispatch *tp, struct evdev_device *device) { struct tp_touch *t; int edge_width, edge_height; + double width, height; + bool want_horiz_scroll = true; + + /* Touchpads smaller than 50mm are not tall enough to have a + horizontal scroll area, it takes too much space away. But + clickpads have enough space here anyway because of the + software button area (and all these tiny clickpads were built + when software buttons were a thing, e.g. Lenovo *20 series) + */ + if (!tp->buttons.is_clickpad) { + evdev_device_get_size(device, &width, &height); + want_horiz_scroll = (height >= 50); + } /* 7mm edge size */ edge_width = device->abs.absinfo_x->resolution * 7; edge_height = device->abs.absinfo_y->resolution * 7; tp->scroll.right_edge = device->abs.absinfo_x->maximum - edge_width; - tp->scroll.bottom_edge = device->abs.absinfo_y->maximum - edge_height; + if (want_horiz_scroll) + tp->scroll.bottom_edge = device->abs.absinfo_y->maximum - edge_height; + else + tp->scroll.bottom_edge = INT_MAX; tp_for_each_touch(tp, t) { t->scroll.direction = -1; diff --git a/test/touchpad.c b/test/touchpad.c index 28cf1f18..57e47123 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -450,11 +450,51 @@ START_TEST(touchpad_edge_scroll_vert) } END_TEST +static int +touchpad_has_horiz_edge_scroll_size(struct litest_device *dev) +{ + double width, height; + int rc; + + rc = libinput_device_get_size(dev->libinput_device, &width, &height); + + return rc == 0 && height >= 50; +} + START_TEST(touchpad_edge_scroll_horiz) { struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; + if (!touchpad_has_horiz_edge_scroll_size(dev)) + return; + + litest_drain_events(li); + litest_enable_edge_scroll(dev); + + litest_touch_down(dev, 0, 20, 99); + litest_touch_move_to(dev, 0, 20, 99, 70, 99, 10, 0); + litest_touch_up(dev, 0); + + libinput_dispatch(li); + litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 4); + litest_assert_empty_queue(li); + + litest_touch_down(dev, 0, 70, 99); + litest_touch_move_to(dev, 0, 70, 99, 20, 99, 10, 0); + litest_touch_up(dev, 0); + + libinput_dispatch(li); + litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -4); + litest_assert_empty_queue(li); +} +END_TEST + +START_TEST(touchpad_edge_scroll_horiz_clickpad) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + litest_drain_events(li); litest_enable_edge_scroll(dev); @@ -476,6 +516,31 @@ START_TEST(touchpad_edge_scroll_horiz) } END_TEST +START_TEST(touchpad_edge_scroll_no_horiz) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + + if (touchpad_has_horiz_edge_scroll_size(dev)) + return; + + litest_drain_events(li); + litest_enable_edge_scroll(dev); + + litest_touch_down(dev, 0, 20, 99); + litest_touch_move_to(dev, 0, 20, 99, 70, 99, 10, 0); + litest_touch_up(dev, 0); + + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); + + litest_touch_down(dev, 0, 70, 99); + litest_touch_move_to(dev, 0, 70, 99, 20, 99, 10, 0); + litest_touch_up(dev, 0); + + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); +} +END_TEST + START_TEST(touchpad_scroll_defaults) { struct litest_device *dev = litest_current_device(); @@ -700,6 +765,9 @@ START_TEST(touchpad_edge_scroll_within_buttonareas) struct litest_device *dev = litest_current_device(); struct libinput *li = dev->libinput; + if (!touchpad_has_horiz_edge_scroll_size(dev)) + return; + litest_enable_buttonareas(dev); litest_enable_edge_scroll(dev); litest_drain_events(li); @@ -728,6 +796,9 @@ START_TEST(touchpad_edge_scroll_buttonareas_click_stops_scroll) struct libinput_event_pointer *ptrev; double val; + if (!touchpad_has_horiz_edge_scroll_size(dev)) + return; + litest_enable_buttonareas(dev); litest_enable_edge_scroll(dev); litest_drain_events(li); @@ -775,6 +846,9 @@ START_TEST(touchpad_edge_scroll_clickfinger_click_stops_scroll) struct libinput_event_pointer *ptrev; double val; + if (!touchpad_has_horiz_edge_scroll_size(dev)) + return; + litest_enable_clickfinger(dev); litest_enable_edge_scroll(dev); litest_drain_events(li); @@ -4081,7 +4155,9 @@ litest_setup_tests(void) litest_add("touchpad:scroll", touchpad_scroll_natural_edge, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("touchpad:scroll", touchpad_scroll_defaults, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:scroll", touchpad_edge_scroll_vert, LITEST_TOUCHPAD, LITEST_ANY); - litest_add("touchpad:scroll", touchpad_edge_scroll_horiz, LITEST_TOUCHPAD, LITEST_ANY); + litest_add("touchpad:scroll", touchpad_edge_scroll_horiz, LITEST_TOUCHPAD, LITEST_CLICKPAD); + litest_add("touchpad:scroll", touchpad_edge_scroll_horiz_clickpad, LITEST_CLICKPAD, LITEST_ANY); + litest_add("touchpad:scroll", touchpad_edge_scroll_no_horiz, LITEST_TOUCHPAD, LITEST_CLICKPAD); litest_add("touchpad:scroll", touchpad_edge_scroll_no_motion, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:scroll", touchpad_edge_scroll_no_edge_after_motion, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:scroll", touchpad_edge_scroll_timeout, LITEST_TOUCHPAD, LITEST_ANY);