diff --git a/configure.ac b/configure.ac index 4a997c90..7b06209c 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ([2.64]) m4_define([libinput_major_version], [1]) m4_define([libinput_minor_version], [1]) -m4_define([libinput_micro_version], [1]) +m4_define([libinput_micro_version], [2]) m4_define([libinput_version], [libinput_major_version.libinput_minor_version.libinput_micro_version]) @@ -31,7 +31,7 @@ AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz]) # b) If interfaces have been changed or added, but binary compatibility has # been preserved, change to C+1:0:A+1 # c) If the interface is the same as the previous version, change to C:R+1:A -LIBINPUT_LT_VERSION=16:1:6 +LIBINPUT_LT_VERSION=16:2:6 AC_SUBST(LIBINPUT_LT_VERSION) AM_SILENT_RULES([yes]) diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index c90baeff..8e2a5c5b 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -832,7 +832,8 @@ tp_position_fake_touches(struct tp_dispatch *tp) struct tp_touch *topmost = NULL; unsigned int start, i; - if (tp_fake_finger_count(tp) <= tp->num_slots) + if (tp_fake_finger_count(tp) <= tp->num_slots || + tp->nfingers_down == 0) return; /* We have at least one fake touch down. Find the top-most real diff --git a/src/evdev.c b/src/evdev.c index 993c5d8a..83b1c20e 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -439,8 +439,22 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time) static enum evdev_key_type get_key_type(uint16_t code) { - if (code == BTN_TOUCH) + switch (code) { + case BTN_TOOL_PEN: + case BTN_TOOL_RUBBER: + case BTN_TOOL_BRUSH: + case BTN_TOOL_PENCIL: + case BTN_TOOL_AIRBRUSH: + case BTN_TOOL_MOUSE: + case BTN_TOOL_LENS: + case BTN_TOOL_QUINTTAP: + case BTN_TOOL_DOUBLETAP: + case BTN_TOOL_TRIPLETAP: + case BTN_TOOL_QUADTAP: + case BTN_TOOL_FINGER: + case BTN_TOUCH: return EVDEV_KEY_TYPE_NONE; + } if (code >= KEY_ESC && code <= KEY_MICMUTE) return EVDEV_KEY_TYPE_KEY; @@ -2557,9 +2571,16 @@ evdev_post_scroll(struct evdev_device *device, if (!normalized_is_zero(event)) { const struct discrete_coords zero_discrete = { 0.0, 0.0 }; + uint32_t axes = device->scroll.direction; + + if (event.y == 0.0) + axes &= ~AS_MASK(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); + if (event.x == 0.0) + axes &= ~AS_MASK(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); + evdev_notify_axis(device, time, - device->scroll.direction, + axes, source, &event, &zero_discrete); diff --git a/test/litest.c b/test/litest.c index 01d97d9f..73aa977f 100644 --- a/test/litest.c +++ b/test/litest.c @@ -600,6 +600,7 @@ litest_add_tcase(const char *suite_name, { struct litest_test_device **dev = devices; struct suite *suite; + bool added = false; assert(required >= LITEST_DISABLE_DEVICE); assert(excluded >= LITEST_DISABLE_DEVICE); @@ -617,6 +618,7 @@ litest_add_tcase(const char *suite_name, if (required == LITEST_DISABLE_DEVICE && excluded == LITEST_DISABLE_DEVICE) { litest_add_tcase_no_device(suite, func, range); + added = true; } else if (required != LITEST_ANY || excluded != LITEST_ANY) { for (; *dev; dev++) { if (filter_device && @@ -631,6 +633,7 @@ litest_add_tcase(const char *suite_name, func, *dev, range); + added = true; } } else { for (; *dev; dev++) { @@ -643,8 +646,14 @@ litest_add_tcase(const char *suite_name, func, *dev, range); + added = true; } } + + if (!added) { + fprintf(stderr, "Test '%s' does not match any devices. Aborting.\n", funcname); + abort(); + } } void @@ -1318,9 +1327,9 @@ litest_auto_assign_value(struct litest_device *d, } static void -send_btntool(struct litest_device *d) +send_btntool(struct litest_device *d, bool hover) { - litest_event(d, EV_KEY, BTN_TOUCH, d->ntouches_down != 0); + litest_event(d, EV_KEY, BTN_TOUCH, d->ntouches_down != 0 && !hover); litest_event(d, EV_KEY, BTN_TOOL_FINGER, d->ntouches_down == 1); litest_event(d, EV_KEY, BTN_TOOL_DOUBLETAP, d->ntouches_down == 2); litest_event(d, EV_KEY, BTN_TOOL_TRIPLETAP, d->ntouches_down == 3); @@ -1341,7 +1350,7 @@ litest_slot_start(struct litest_device *d, assert(d->ntouches_down >= 0); d->ntouches_down++; - send_btntool(d); + send_btntool(d, !touching); if (d->interface->touch_down) { d->interface->touch_down(d, slot, x, y); @@ -1396,7 +1405,7 @@ litest_touch_up(struct litest_device *d, unsigned int slot) litest_assert_int_gt(d->ntouches_down, 0); d->ntouches_down--; - send_btntool(d); + send_btntool(d, false); if (d->interface->touch_up) { d->interface->touch_up(d, slot); @@ -1577,8 +1586,8 @@ litest_touch_move_two_touches(struct litest_device *d, if (sleep_ms) { libinput_dispatch(d->libinput); msleep(sleep_ms); - libinput_dispatch(d->libinput); } + libinput_dispatch(d->libinput); } litest_touch_move(d, 0, x0 + dx, y0 + dy); litest_touch_move(d, 1, x1 + dx, y1 + dy); @@ -1634,7 +1643,7 @@ litest_hover_end(struct litest_device *d, unsigned int slot) litest_assert_int_gt(d->ntouches_down, 0); d->ntouches_down--; - send_btntool(d); + send_btntool(d, true); if (d->interface->touch_up) { d->interface->touch_up(d, slot); diff --git a/test/touchpad.c b/test/touchpad.c index 8bff5a9f..7bc99e98 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -144,6 +144,54 @@ START_TEST(touchpad_2fg_scroll) } END_TEST +START_TEST(touchpad_2fg_scroll_diagonal) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + struct libinput_event_pointer *ptrev; + int i; + + if (!litest_has_2fg_scroll(dev)) + return; + + litest_enable_2fg_scroll(dev); + litest_drain_events(li); + + litest_touch_down(dev, 0, 45, 30); + litest_touch_down(dev, 1, 55, 30); + + litest_touch_move_two_touches(dev, 45, 30, 55, 30, 10, 10, 10, 0); + libinput_dispatch(li); + litest_wait_for_event_of_type(li, + LIBINPUT_EVENT_POINTER_AXIS, + -1); + litest_drain_events(li); + + /* get rid of any touch history still adding x deltas sideways */ + for (i = 0; i < 5; i++) + litest_touch_move(dev, 0, 55, 41 + i); + litest_drain_events(li); + + for (i = 6; i < 10; i++) { + litest_touch_move(dev, 0, 55, 41 + i); + libinput_dispatch(li); + + event = libinput_get_event(li); + ptrev = litest_is_axis_event(event, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, + LIBINPUT_POINTER_AXIS_SOURCE_FINGER); + ck_assert(!libinput_event_pointer_has_axis(ptrev, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)); + libinput_event_destroy(event); + } + + litest_touch_up(dev, 1); + litest_touch_up(dev, 0); + libinput_dispatch(li); +} +END_TEST + START_TEST(touchpad_2fg_scroll_slow_distance) { struct litest_device *dev = litest_current_device(); @@ -1703,6 +1751,31 @@ START_TEST(touchpad_semi_mt_hover_2fg_1fg_down) } END_TEST +START_TEST(touchpad_semi_mt_hover_2fg_up) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + + litest_touch_down(dev, 0, 70, 50); + litest_touch_down(dev, 1, 50, 50); + + litest_push_event_frame(dev); + litest_touch_move(dev, 0, 72, 50); + litest_touch_move(dev, 1, 52, 50); + litest_event(dev, EV_KEY, BTN_TOUCH, 0); + litest_pop_event_frame(dev); + + litest_event(dev, EV_ABS, ABS_MT_SLOT, 0); + litest_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); + litest_event(dev, EV_ABS, ABS_MT_SLOT, 1); + litest_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); + litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + + litest_drain_events(li); +} +END_TEST + START_TEST(touchpad_hover_noevent) { struct litest_device *dev = litest_current_device(); @@ -3475,6 +3548,7 @@ litest_setup_tests(void) litest_add("touchpad:motion", touchpad_2fg_no_motion, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("touchpad:scroll", touchpad_2fg_scroll, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); + litest_add("touchpad:scroll", touchpad_2fg_scroll_diagonal, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT); litest_add("touchpad:scroll", touchpad_2fg_scroll_slow_distance, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("touchpad:scroll", touchpad_2fg_scroll_return_to_motion, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("touchpad:scroll", touchpad_2fg_scroll_source, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); @@ -3514,13 +3588,14 @@ litest_setup_tests(void) litest_add("touchpad:left-handed", touchpad_left_handed_clickpad_delayed, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD); /* Semi-MT hover tests aren't generic, they only work on this device and - * ignore the semi-mt capability (it doesn't matter for the tests */ + * ignore the semi-mt capability (it doesn't matter for the tests) */ litest_add_for_device("touchpad:semi-mt-hover", touchpad_semi_mt_hover_noevent, LITEST_SYNAPTICS_HOVER_SEMI_MT); litest_add_for_device("touchpad:semi-mt-hover", touchpad_semi_mt_hover_down, LITEST_SYNAPTICS_HOVER_SEMI_MT); litest_add_for_device("touchpad:semi-mt-hover", touchpad_semi_mt_hover_down_up, LITEST_SYNAPTICS_HOVER_SEMI_MT); litest_add_for_device("touchpad:semi-mt-hover", touchpad_semi_mt_hover_down_hover_down, LITEST_SYNAPTICS_HOVER_SEMI_MT); litest_add_for_device("touchpad:semi-mt-hover", touchpad_semi_mt_hover_2fg_noevent, LITEST_SYNAPTICS_HOVER_SEMI_MT); litest_add_for_device("touchpad:semi-mt-hover", touchpad_semi_mt_hover_2fg_1fg_down, LITEST_SYNAPTICS_HOVER_SEMI_MT); + litest_add_for_device("touchpad:semi-mt-hover", touchpad_semi_mt_hover_2fg_up, LITEST_SYNAPTICS_HOVER_SEMI_MT); litest_add("touchpad:hover", touchpad_hover_noevent, LITEST_TOUCHPAD|LITEST_HOVER, LITEST_ANY); litest_add("touchpad:hover", touchpad_hover_down, LITEST_TOUCHPAD|LITEST_HOVER, LITEST_ANY); diff --git a/tools/event-debug.c b/tools/event-debug.c index fd4033a3..1fd29c6d 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -313,17 +313,23 @@ print_pointer_axis_event(struct libinput_event *ev) { struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev); double v = 0, h = 0; + const char *have_vert = "", + *have_horiz = ""; if (libinput_event_pointer_has_axis(p, - LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) { v = libinput_event_pointer_get_axis_value(p, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); + have_vert = "*"; + } if (libinput_event_pointer_has_axis(p, - LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) { h = libinput_event_pointer_get_axis_value(p, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); + have_horiz = "*"; + } print_event_time(libinput_event_pointer_get_time(p)); - printf("vert %.2f horiz %.2f\n", v, h); + printf("vert %.2f%s horiz %.2f%s\n", v, have_vert, h, have_horiz); } static const char*