double dx,
double dy)
{
- if (fabs(dy) >= device->scroll.threshold)
- evdev_start_scrolling(device,
+ double trigger_horiz, trigger_vert;
+
+ if (!evdev_is_scrolling(device,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
+ device->scroll.buildup_vertical += dy;
+ if (!evdev_is_scrolling(device,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
+ device->scroll.buildup_horizontal += dx;
+
+ trigger_vert = device->scroll.buildup_vertical;
+ trigger_horiz = device->scroll.buildup_horizontal;
+
+ /* If we're not scrolling yet, use a distance trigger: moving
+ past a certain distance starts scrolling */
+ if (!evdev_is_scrolling(device,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL) &&
+ !evdev_is_scrolling(device,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) {
+ if (fabs(trigger_vert) >= device->scroll.threshold)
+ evdev_start_scrolling(device,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
+ if (fabs(trigger_horiz) >= device->scroll.threshold)
+ evdev_start_scrolling(device,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
+ /* We're already scrolling in one direction. Require some
+ trigger speed to start scrolling in the other direction */
+ } else if (!evdev_is_scrolling(device,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) {
+ if (fabs(dy) >= device->scroll.threshold)
+ evdev_start_scrolling(device,
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
-
- if (fabs(dx) >= device->scroll.threshold)
- evdev_start_scrolling(device,
+ } else if (!evdev_is_scrolling(device,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) {
+ if (fabs(dx) >= device->scroll.threshold)
+ evdev_start_scrolling(device,
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
+ }
+ /* We use the trigger to enable, but the delta from this event for
+ * the actual scroll movement. Otherwise we get a jump once
+ * scrolling engages */
if (dy != 0.0 &&
evdev_is_scrolling(device,
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) {
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
0);
+ device->scroll.buildup_horizontal = 0;
+ device->scroll.buildup_vertical = 0;
device->scroll.direction = 0;
}
bool middle_button_scroll_active;
double threshold;
uint32_t direction;
+ double buildup_vertical;
+ double buildup_horizontal;
} scroll;
enum evdev_event_type pending_event;
* @ingroup device
*
* Axes on a device that are not x or y coordinates.
+ *
+ * The two scroll axes @ref LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL and
+ * @ref LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL are engaged separately,
+ * depending on the device. libinput provides some scroll direction locking
+ * but it is up to the caller to determine which axis is needed and
+ * appropriate in the current interaction
*/
enum libinput_pointer_axis {
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL = 0,
}
END_TEST
+START_TEST(touchpad_2fg_scroll_slow_distance)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput *li = dev->libinput;
+ struct libinput_event *event;
+ struct libinput_event_pointer *ptrev;
+
+ litest_drain_events(li);
+
+ litest_touch_down(dev, 0, 20, 30);
+ litest_touch_down(dev, 1, 40, 30);
+ litest_touch_move_to(dev, 0, 20, 30, 20, 50, 60, 10);
+ litest_touch_move_to(dev, 1, 40, 30, 40, 50, 60, 10);
+ litest_touch_up(dev, 1);
+ litest_touch_up(dev, 0);
+ libinput_dispatch(li);
+
+ event = libinput_get_event(li);
+ ck_assert_notnull(event);
+
+ /* last event is value 0, tested elsewhere */
+ while (libinput_next_event_type(li) != LIBINPUT_EVENT_NONE) {
+ ck_assert_int_eq(libinput_event_get_type(event),
+ LIBINPUT_EVENT_POINTER_AXIS);
+ ptrev = libinput_event_get_pointer_event(event);
+
+ ck_assert_int_eq(libinput_event_pointer_get_axis(ptrev),
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
+ ck_assert(libinput_event_pointer_get_axis_value(ptrev) > 0.0);
+
+ /* this is to verify we test the right thing, if the value
+ is greater than scroll.threshold we triggered the wrong
+ condition */
+ ck_assert(libinput_event_pointer_get_axis_value(ptrev) < 5.0);
+
+ libinput_event_destroy(event);
+ event = libinput_get_event(li);
+ }
+
+ litest_assert_empty_queue(li);
+ libinput_event_destroy(event);
+}
+END_TEST
+
START_TEST(touchpad_scroll_natural_defaults)
{
struct litest_device *dev = litest_current_device();
litest_add("touchpad:topsoftbuttons", clickpad_topsoftbuttons_move_out_ignore, LITEST_TOPBUTTONPAD, LITEST_ANY);
litest_add("touchpad:scroll", touchpad_2fg_scroll, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
+ litest_add("touchpad:scroll", touchpad_2fg_scroll_slow_distance, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:scroll", touchpad_scroll_natural_defaults, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:scroll", touchpad_scroll_natural_enable_config, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:scroll", touchpad_scroll_natural, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);