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);