diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2015-06-16 13:52:02 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2015-06-16 13:52:02 +1000 |
commit | 2b99363a1ff948917a1a81c18d6079fb4a8cd4c2 (patch) | |
tree | 79bba625edcd0e82e30fa302475124d8bacee5ed | |
parent | 99aa1f5dc3593826e512460a5c914a87a3a7c16a (diff) | |
parent | 8025b374d564f4a30b089e5cf6fd65e0c6af8da2 (diff) |
Merge branch 'master' into tablet-support
-rw-r--r-- | doc/scrolling.dox | 20 | ||||
-rw-r--r-- | src/evdev-mt-touchpad-buttons.c | 19 | ||||
-rw-r--r-- | src/evdev-mt-touchpad.c | 42 | ||||
-rw-r--r-- | src/evdev-mt-touchpad.h | 5 | ||||
-rw-r--r-- | src/evdev.c | 2 | ||||
-rw-r--r-- | src/evdev.h | 2 | ||||
-rw-r--r-- | src/filter-private.h | 3 | ||||
-rw-r--r-- | src/filter.c | 33 | ||||
-rw-r--r-- | src/filter.h | 5 | ||||
-rw-r--r-- | src/libinput-util.h | 6 | ||||
-rw-r--r-- | test/Makefile.am | 10 | ||||
-rw-r--r-- | test/litest.c | 101 | ||||
-rw-r--r-- | test/touchpad.c | 48 | ||||
-rw-r--r-- | udev/90-libinput-model-quirks.hwdb | 37 | ||||
-rw-r--r-- | udev/90-libinput-model-quirks.rules | 6 |
15 files changed, 282 insertions, 57 deletions
diff --git a/doc/scrolling.dox b/doc/scrolling.dox index 94aa8158..1ecd0333 100644 --- a/doc/scrolling.dox +++ b/doc/scrolling.dox @@ -2,12 +2,24 @@ @page scrolling Scrolling libinput supports three different types of scrolling methods: @ref -twofinger_scrolling, @ref edge_scrolling and @ref button_scrolling. Some devices -support multiple methods, though only one can be enabled at a time. See +twofinger_scrolling, @ref edge_scrolling and @ref button_scrolling. Some +devices support multiple methods, though only one can be enabled at a time. +As a general overview: +- touchpad devices with physical buttons below the touchpad support edge and + two-finger scrolling +- touchpad devices without physical buttons (@ref clickpad_softbuttons + "clickpads") support two-finger scrolling only +- pointing sticks provide on-button scrolling by default +- mice and other pointing devices support on-button scrolling but it is not + enabled by default + +A device may differ from the above based on its capabilities. See libinput_device_config_scroll_set_method() for documentation on how to switch methods and libinput_device_config_scroll_get_methods() for documentation on how to query a device for available scroll methods. +@section horizontal_scrolling Horizontal scrolling + Scroll movements provide vertical and horizontal directions, each scroll event contains both directions where applicable, see libinput_event_pointer_get_axis_value(). libinput does not provide separate @@ -55,6 +67,10 @@ a designated button is held down. For example, Lenovo devices provide a <a href="http://en.wikipedia.org/wiki/Pointing_stick">pointing stick</a> that emulates scroll events when the trackstick's middle mouse button is held down. +@note On-button scrolling is enabled by default for pointing sticks. This +prevents middle-button dragging; all motion events while the middle button is +down are converted to scroll events. + @image html button-scrolling.svg "Button scrolling" The button may be changed with diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c index 5786ea8b..eb0ddcb0 100644 --- a/src/evdev-mt-touchpad-buttons.c +++ b/src/evdev-mt-touchpad-buttons.c @@ -31,7 +31,6 @@ #include "evdev-mt-touchpad.h" -#define DEFAULT_BUTTON_MOTION_THRESHOLD 0.02 /* 2% of size */ #define DEFAULT_BUTTON_ENTER_TIMEOUT 100 /* ms */ #define DEFAULT_BUTTON_LEAVE_TIMEOUT 300 /* ms */ @@ -709,11 +708,19 @@ tp_init_buttons(struct tp_dispatch *tp, absinfo_x = device->abs.absinfo_x; absinfo_y = device->abs.absinfo_y; - width = abs(absinfo_x->maximum - absinfo_x->minimum); - height = abs(absinfo_y->maximum - absinfo_y->minimum); - diagonal = sqrt(width*width + height*height); - - tp->buttons.motion_dist = diagonal * DEFAULT_BUTTON_MOTION_THRESHOLD; + /* pinned-finger motion threshold, see tp_unpin_finger. + The MAGIC for resolution-less touchpads ends up as 2% of the diagonal */ + if (device->abs.fake_resolution) { + const int BUTTON_MOTION_MAGIC = 0.007; + width = abs(absinfo_x->maximum - absinfo_x->minimum); + height = abs(absinfo_y->maximum - absinfo_y->minimum); + diagonal = sqrt(width*width + height*height); + tp->buttons.motion_dist.x_scale_coeff = diagonal * BUTTON_MOTION_MAGIC; + tp->buttons.motion_dist.y_scale_coeff = diagonal * BUTTON_MOTION_MAGIC; + } else { + tp->buttons.motion_dist.x_scale_coeff = 1.0/absinfo_x->resolution; + tp->buttons.motion_dist.y_scale_coeff = 1.0/absinfo_y->resolution; + } tp->buttons.config_method.get_methods = tp_button_config_click_get_methods; tp->buttons.config_method.set_method = tp_button_config_click_set_method; diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index e7abe945..4858e86b 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -431,17 +431,15 @@ tp_unpin_finger(struct tp_dispatch *tp, struct tp_touch *t) return; xdist = abs(t->point.x - t->pinned.center.x); + xdist *= tp->buttons.motion_dist.x_scale_coeff; ydist = abs(t->point.y - t->pinned.center.y); + ydist *= tp->buttons.motion_dist.y_scale_coeff; - if (xdist * xdist + ydist * ydist >= - tp->buttons.motion_dist * tp->buttons.motion_dist) { + /* 3mm movement -> unpin */ + if (vector_length(xdist, ydist) >= 3.0) { t->pinned.is_pinned = false; return; } - - /* The finger may slowly drift, adjust the center */ - t->pinned.center.x = t->point.x + t->pinned.center.x / 2; - t->pinned.center.y = t->point.y + t->pinned.center.y / 2; } static void @@ -666,6 +664,7 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time) struct tp_touch *t; struct tp_touch *first = tp_get_touch(tp, 0); unsigned int i; + bool restart_filter = false; tp_process_fake_touches(tp, time); tp_unhover_touches(tp, time); @@ -692,8 +691,14 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time) tp_motion_history_push(t); tp_unpin_finger(tp, t); + + if (t->state == TOUCH_BEGIN) + restart_filter = true; } + if (restart_filter) + filter_restart(tp->device->pointer.filter, tp, time); + tp_button_handle_state(tp, time); tp_edge_scroll_handle_state(tp, time); @@ -1150,7 +1155,7 @@ evdev_tag_touchpad(struct evdev_device *device, */ bustype = libevdev_get_id_bustype(device->evdev); if (bustype == BUS_USB) { - if (libevdev_get_id_vendor(device->evdev) == VENDOR_ID_APPLE) + if (device->model == EVDEV_MODEL_APPLE_TOUCHPAD) device->tags |= EVDEV_TAG_INTERNAL_TOUCHPAD; } else if (bustype != BUS_BLUETOOTH) device->tags |= EVDEV_TAG_INTERNAL_TOUCHPAD; @@ -1389,7 +1394,6 @@ tp_init_palmdetect(struct tp_dispatch *tp, struct evdev_device *device) { int width, height; - unsigned int vendor_id; tp->palm.right_edge = INT_MAX; tp->palm.left_edge = INT_MIN; @@ -1400,13 +1404,11 @@ tp_init_palmdetect(struct tp_dispatch *tp, height = abs(device->abs.absinfo_y->maximum - device->abs.absinfo_y->minimum); - vendor_id = evdev_device_get_id_vendor(device); - /* Wacom doesn't have internal touchpads, * Apple touchpads are always big enough to warrant palm detection */ - if (vendor_id == VENDOR_ID_WACOM) { + if (device->model == EVDEV_MODEL_WACOM_TOUCHPAD) { return 0; - } else if (vendor_id != VENDOR_ID_APPLE) { + } else if (device->model != EVDEV_MODEL_APPLE_TOUCHPAD) { /* We don't know how big the touchpad is */ if (device->abs.absinfo_x->resolution == 1) return 0; @@ -1489,10 +1491,18 @@ tp_init(struct tp_dispatch *tp, EV_ABS, ABS_MT_DISTANCE); - tp->hysteresis_margin.x = - diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR; - tp->hysteresis_margin.y = - diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR; + if (device->abs.fake_resolution) { + tp->hysteresis_margin.x = + diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR; + tp->hysteresis_margin.y = + diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR; + } else { + int res_x = tp->device->abs.absinfo_x->resolution, + res_y = tp->device->abs.absinfo_y->resolution; + + tp->hysteresis_margin.x = res_x/2; + tp->hysteresis_margin.y = res_y/2; + } if (tp_init_accel(tp, diagonal) != 0) return -1; diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h index fef5cb32..bd2d1633 100644 --- a/src/evdev-mt-touchpad.h +++ b/src/evdev-mt-touchpad.h @@ -223,7 +223,10 @@ struct tp_dispatch { bool click_pending; uint32_t state; uint32_t old_state; - uint32_t motion_dist; /* for pinned touches */ + struct { + double x_scale_coeff; + double y_scale_coeff; + } motion_dist; /* for pinned touches */ unsigned int active; /* currently active button, for release event */ bool active_is_topbutton; /* is active a top button? */ diff --git a/src/evdev.c b/src/evdev.c index 3e66df36..074ee3b1 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -1514,6 +1514,8 @@ evdev_read_model(struct evdev_device *device) { "LIBINPUT_MODEL_SYSTEM76_GALAGO", EVDEV_MODEL_SYSTEM76_GALAGO }, { "LIBINPUT_MODEL_SYSTEM76_KUDU", EVDEV_MODEL_SYSTEM76_KUDU }, { "LIBINPUT_MODEL_CLEVO_W740SU", EVDEV_MODEL_CLEVO_W740SU }, + { "LIBINPUT_MODEL_APPLE_TOUCHPAD", EVDEV_MODEL_APPLE_TOUCHPAD }, + { "LIBINPUT_MODEL_WACOM_TOUCHPAD", EVDEV_MODEL_WACOM_TOUCHPAD }, { NULL, EVDEV_MODEL_DEFAULT }, }; const struct model_map *m = model_map; diff --git a/src/evdev.h b/src/evdev.h index 17ae0d95..1600b091 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -104,6 +104,8 @@ enum evdev_device_model { EVDEV_MODEL_SYSTEM76_GALAGO, EVDEV_MODEL_SYSTEM76_KUDU, EVDEV_MODEL_CLEVO_W740SU, + EVDEV_MODEL_APPLE_TOUCHPAD, + EVDEV_MODEL_WACOM_TOUCHPAD, }; struct mt_slot { diff --git a/src/filter-private.h b/src/filter-private.h index 0e796f1a..8a206d69 100644 --- a/src/filter-private.h +++ b/src/filter-private.h @@ -32,6 +32,9 @@ struct motion_filter_interface { struct motion_filter *filter, const struct normalized_coords *unaccelerated, void *data, uint64_t time); + void (*restart)(struct motion_filter *filter, + void *data, + uint64_t time); void (*destroy)(struct motion_filter *filter); bool (*set_speed)(struct motion_filter *filter, double speed); diff --git a/src/filter.c b/src/filter.c index c54d866c..ee4ce9e6 100644 --- a/src/filter.c +++ b/src/filter.c @@ -44,6 +44,13 @@ filter_dispatch(struct motion_filter *filter, } void +filter_restart(struct motion_filter *filter, + void *data, uint64_t time) +{ + filter->interface->restart(filter, data, time); +} + +void filter_destroy(struct motion_filter *filter) { if (!filter) @@ -274,6 +281,29 @@ accelerator_filter(struct motion_filter *filter, } static void +accelerator_restart(struct motion_filter *filter, + void *data, + uint64_t time) +{ + struct pointer_accelerator *accel = + (struct pointer_accelerator *) filter; + unsigned int offset; + struct pointer_tracker *tracker; + + for (offset = 1; offset < NUM_POINTER_TRACKERS; offset++) { + tracker = tracker_by_offset(accel, offset); + tracker->time = 0; + tracker->dir = 0; + tracker->delta.x = 0; + tracker->delta.y = 0; + } + + tracker = tracker_by_offset(accel, 0); + tracker->time = time; + tracker->dir = UNDEFINED_DIRECTION; +} + +static void accelerator_destroy(struct motion_filter *filter) { struct pointer_accelerator *accel = @@ -309,6 +339,7 @@ accelerator_set_speed(struct motion_filter *filter, struct motion_filter_interface accelerator_interface = { accelerator_filter, + accelerator_restart, accelerator_destroy, accelerator_set_speed, }; @@ -354,7 +385,7 @@ pointer_accel_profile_linear(struct motion_filter *filter, const double threshold = accel_filter->threshold; /* units/ms */ const double incline = accel_filter->incline; - s1 = min(1, speed_in * 5); + s1 = min(1, 0.3 + speed_in * 4); s2 = 1 + (speed_in - threshold) * incline; return min(max_accel, s2 > 1 ? s2 : s1); diff --git a/src/filter.h b/src/filter.h index 16896a4c..03f510d0 100644 --- a/src/filter.h +++ b/src/filter.h @@ -37,6 +37,11 @@ struct normalized_coords filter_dispatch(struct motion_filter *filter, const struct normalized_coords *unaccelerated, void *data, uint64_t time); + +void +filter_restart(struct motion_filter *filter, + void *data, uint64_t time); + void filter_destroy(struct motion_filter *filter); diff --git a/src/libinput-util.h b/src/libinput-util.h index 5db3e3fa..9c00f792 100644 --- a/src/libinput-util.h +++ b/src/libinput-util.h @@ -308,4 +308,10 @@ int parse_mouse_dpi_property(const char *prop); int parse_mouse_wheel_click_angle_property(const char *prop); double parse_trackpoint_accel_property(const char *prop); +static inline double +vector_length(double x, double y) +{ + return sqrt(x * x + y * y); +} + #endif /* LIBINPUT_UTIL_H */ diff --git a/test/Makefile.am b/test/Makefile.am index 3f28a0a3..fb8d5de0 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -42,7 +42,9 @@ liblitest_la_SOURCES = \ litest-vmware-virtual-usb-mouse.c \ litest.c liblitest_la_LIBADD = $(top_builddir)/src/libinput-util.la -liblitest_la_CFLAGS = $(AM_CFLAGS) +liblitest_la_CFLAGS = $(AM_CFLAGS) \ + -DLIBINPUT_UDEV_RULES_FILE="\"$(abs_top_srcdir)/udev/90-libinput-model-quirks.rules\"" \ + -DLIBINPUT_UDEV_HWDB_FILE="\"$(abs_top_srcdir)/udev/90-libinput-model-quirks.hwdb\"" if HAVE_LIBUNWIND liblitest_la_LIBADD += $(LIBUNWIND_LIBS) -ldl liblitest_la_CFLAGS += $(LIBUNWIND_CFLAGS) @@ -119,9 +121,13 @@ test_device_LDADD = $(TEST_LIBS) test_device_LDFLAGS = -no-install test_litest_selftest_SOURCES = litest-selftest.c litest.c litest-int.h litest.h -test_litest_selftest_CFLAGS = -DLITEST_DISABLE_BACKTRACE_LOGGING -DLITEST_NO_MAIN +test_litest_selftest_CFLAGS = -DLITEST_DISABLE_BACKTRACE_LOGGING -DLITEST_NO_MAIN $(liblitest_la_CFLAGS) test_litest_selftest_LDADD = $(TEST_LIBS) test_litest_selftest_LDFLAGS = -no-install +if HAVE_LIBUNWIND +test_litest_selftest_LDADD += $(LIBUNWIND_LIBS) -ldl +test_litest_selftest_CFLAGS += $(LIBUNWIND_CFLAGS) +endif # build-test only test_build_pedantic_c99_SOURCES = build-pedantic.c diff --git a/test/litest.c b/test/litest.c index 8c82cc76..db32b9c2 100644 --- a/test/litest.c +++ b/test/litest.c @@ -40,6 +40,7 @@ #include <unistd.h> #include "linux/input.h" #include <sys/ptrace.h> +#include <sys/sendfile.h> #include <sys/timerfd.h> #include <sys/wait.h> @@ -49,6 +50,9 @@ #define UDEV_RULES_D "/run/udev/rules.d" #define UDEV_RULE_PREFIX "99-litest-" +#define UDEV_HWDB_D "/etc/udev/hwdb.d" +#define UDEV_COMMON_RULE_FILE UDEV_RULES_D "/91-litest-model-quirks.rules" +#define UDEV_COMMON_HWDB_FILE UDEV_HWDB_D "/91-litest-model-quirks-REMOVEME.hwdb" static int in_debugger = -1; static int verbose = 0; @@ -56,13 +60,15 @@ const char *filter_test = NULL; const char *filter_device = NULL; const char *filter_group = NULL; +static inline void litest_remove_model_quirks(void); + /* defined for the litest selftest */ #ifndef LITEST_DISABLE_BACKTRACE_LOGGING #define litest_log(...) fprintf(stderr, __VA_ARGS__) #define litest_vlog(format_, args_) vfprintf(stderr, format_, args_) #else -#define litest_log(...) /* __VA_ARGS__ */ -#define litest_vlog(...) /* __VA_ARGS__ */ +#define litest_log(...) { /* __VA_ARGS__ */ } +#define litest_vlog(...) { /* __VA_ARGS__ */ } #endif #ifdef HAVE_LIBUNWIND @@ -382,28 +388,40 @@ struct litest_test_device* devices[] = { static struct list all_tests; -static void -litest_reload_udev_rules(void) +static inline void +litest_system(const char *command) { - int ret = system("udevadm control --reload-rules"); + int ret; + + ret = system(command); + if (ret == -1) { - litest_abort_msg("Failed to execute: udevadm"); + litest_abort_msg("Failed to execute: %s", command); } else if (WIFEXITED(ret)) { if (WEXITSTATUS(ret)) - litest_abort_msg("udevadm failed with %d", + litest_abort_msg("'%s' failed with %d", + command, WEXITSTATUS(ret)); } else if (WIFSIGNALED(ret)) { - litest_abort_msg("udevadm terminated with signal %d", + litest_abort_msg("'%s' terminated with signal %d", + command, WTERMSIG(ret)); } } +static void +litest_reload_udev_rules(void) +{ + litest_system("udevadm control --reload-rules"); + litest_system("udevadm hwdb --update"); +} + static int litest_udev_rule_filter(const struct dirent *entry) { - return strncmp(entry->d_name, - UDEV_RULE_PREFIX, - strlen(UDEV_RULE_PREFIX)) == 0; + return strneq(entry->d_name, + UDEV_RULE_PREFIX, + strlen(UDEV_RULE_PREFIX)); } static void @@ -438,6 +456,7 @@ litest_drop_udev_rules(void) } free(entries); + litest_remove_model_quirks(); litest_reload_udev_rules(); } @@ -881,21 +900,70 @@ merge_events(const int *orig, const int *override) return events; } +static inline void +litest_copy_file(const char *dest, const char *src, const char *header) +{ + int in, out; + + out = open(dest, O_CREAT|O_WRONLY, 0644); + litest_assert_int_gt(out, -1); + + if (header) + write(out, header, strlen(header)); + + in = open(src, O_RDONLY); + litest_assert_int_gt(in, -1); + /* lazy, just check for error and empty file copy */ + litest_assert_int_gt(sendfile(out, in, NULL, 4096), 0); + close(out); + close(in); +} + +static inline void +litest_install_model_quirks(void) +{ + litest_copy_file(UDEV_COMMON_RULE_FILE, LIBINPUT_UDEV_RULES_FILE, NULL); + litest_copy_file(UDEV_COMMON_HWDB_FILE, + LIBINPUT_UDEV_HWDB_FILE, + "#################################################################\n" + "# WARNING: REMOVE THIS FILE\n" + "# This is the run-time hwdb file for the libinput test suite and\n" + "# should be removed on exit. If the test-suite is not currently \n" + "# running, remove this file and update your hwdb: \n" + "# sudo udevadm hwdb --update\n" + "#################################################################\n\n"); +} + +static inline void +litest_remove_model_quirks(void) +{ + unlink(UDEV_COMMON_RULE_FILE); + unlink(UDEV_COMMON_HWDB_FILE); +} + static char * litest_init_udev_rules(struct litest_test_device *dev) { int rc; FILE *f; - char *path; - - if (!dev->udev_rule) - return NULL; + char *path = NULL; rc = mkdir(UDEV_RULES_D, 0755); if (rc == -1 && errno != EEXIST) ck_abort_msg("Failed to create udev rules directory (%s)\n", strerror(errno)); + rc = mkdir(UDEV_HWDB_D, 0755); + if (rc == -1 && errno != EEXIST) + ck_abort_msg("Failed to create udev hwdb directory (%s)\n", + strerror(errno)); + + litest_install_model_quirks(); + + /* device-specific udev rules */ + if (!dev->udev_rule) + goto out; + rc = xasprintf(&path, "%s/%s%s.rules", UDEV_RULES_D, @@ -911,6 +979,7 @@ litest_init_udev_rules(struct litest_test_device *dev) litest_assert_int_ge(fputs(dev->udev_rule, f), 0); fclose(f); +out: litest_reload_udev_rules(); return path; @@ -950,6 +1019,7 @@ litest_create(enum litest_device_type which, if ((*dev)->create) { (*dev)->create(d); if (abs_override || events_override) { + litest_remove_model_quirks(); if (udev_file) unlink(udev_file); litest_abort_msg("Custom create cannot be overridden"); @@ -1128,6 +1198,7 @@ litest_delete_device(struct litest_device *d) return; if (d->udev_rule_file) { + litest_remove_model_quirks(); unlink(d->udev_rule_file); free(d->udev_rule_file); d->udev_rule_file = NULL; diff --git a/test/touchpad.c b/test/touchpad.c index 692698ce..1e5e97bd 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -2153,6 +2153,53 @@ START_TEST(clickpad_click_n_drag) } END_TEST +START_TEST(clickpad_finger_pin) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libevdev *evdev = dev->evdev; + const struct input_absinfo *abs; + + abs = libevdev_get_abs_info(evdev, ABS_MT_POSITION_X); + ck_assert_notnull(abs); + if (abs->resolution == 0) + return; + + litest_drain_events(li); + + /* make sure the movement generates pointer events when + not pinned */ + litest_touch_down(dev, 0, 50, 50); + litest_touch_move_to(dev, 0, 50, 50, 52, 52, 10, 1); + litest_touch_move_to(dev, 0, 52, 52, 48, 48, 10, 1); + litest_touch_move_to(dev, 0, 48, 48, 50, 50, 10, 1); + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); + + litest_button_click(dev, BTN_LEFT, true); + litest_drain_events(li); + + litest_touch_move_to(dev, 0, 50, 50, 52, 52, 10, 1); + litest_touch_move_to(dev, 0, 52, 52, 48, 48, 10, 1); + litest_touch_move_to(dev, 0, 48, 48, 50, 50, 10, 1); + + litest_assert_empty_queue(li); + + litest_button_click(dev, BTN_LEFT, false); + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_BUTTON); + + /* still pinned after release */ + litest_touch_move_to(dev, 0, 50, 50, 52, 52, 10, 1); + litest_touch_move_to(dev, 0, 52, 52, 48, 48, 10, 1); + litest_touch_move_to(dev, 0, 48, 48, 50, 50, 10, 1); + + litest_assert_empty_queue(li); + + /* move to unpin */ + litest_touch_move_to(dev, 0, 50, 50, 70, 70, 10, 1); + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); +} +END_TEST + START_TEST(clickpad_softbutton_left) { struct litest_device *dev = litest_current_device(); @@ -5144,6 +5191,7 @@ litest_setup_tests(void) litest_add("touchpad:click", touchpad_btn_left, LITEST_TOUCHPAD|LITEST_BUTTON, LITEST_CLICKPAD); litest_add("touchpad:click", clickpad_btn_left, LITEST_CLICKPAD, LITEST_ANY); litest_add("touchpad:click", clickpad_click_n_drag, LITEST_CLICKPAD, LITEST_SINGLE_TOUCH); + litest_add("touchpad:click", clickpad_finger_pin, LITEST_CLICKPAD, LITEST_ANY); litest_add("touchpad:softbutton", clickpad_softbutton_left, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD); litest_add("touchpad:softbutton", clickpad_softbutton_right, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD); diff --git a/udev/90-libinput-model-quirks.hwdb b/udev/90-libinput-model-quirks.hwdb index 048e5cc6..7442f828 100644 --- a/udev/90-libinput-model-quirks.hwdb +++ b/udev/90-libinput-model-quirks.hwdb @@ -16,6 +16,13 @@ # Sort by brand, model ########################################## +# Apple +########################################## +libinput:touchpad:input:b0003v05ACp* +libinput:touchpad:input:b0005v05ACp* + LIBINPUT_MODEL_APPLE_TOUCHPAD=1 + +########################################## # Google ########################################## @@ -23,18 +30,18 @@ # extrapolated from the chromiumos touchad-tests repo # https://chromium.googlesource.com/chromiumos/platform/touchpad-tests libinput:name:Cypress APA Trackpad (cyapa):dmi:*pnFalco:pvr* -libinput:name:SynPS/2 Synaptics TouchPad:dmi:*pn*Mario*: -libinput:name:Cypress APA Trackpad (cyapa):dmi:*pn*Butterfly*: -libinput:name:Cypress APA Trackpad (cyapa):dmi:*pn*Peppy*: -libinput:name:SynPS/2 Synaptics TouchPad:dmi:*pn*ZGB*: -libinput:name:Cypress APA Trackpad (cyapa):dmi:*pn*Parrot*: -libinput:name:Cypress APA Trackpad (cyapa):dmi:*bvn*coreboot*:pn*Leon*: -libinput:name:Cypress APA Trackpad (cyapa):dmi:*bvn*coreboot*:pn*Falco*: -libinput:name:Cypress APA Trackpad (cyapa):dmi:*bvn*coreboot*:pn*Wolf*: -libinput:name:Cypress APA Trackpad (cyapa):dmi:*svn*GOOGLE*:pn*Link*: -libinput:name:SynPS/2 Synaptics TouchPad:dmi:*pn*Alex*: -libinput:name:Cypress APA Trackpad (cyapa):dmi:*svn*SAMSUNG*:pn*Lumpy*: -libinput:name:Atmel maXTouch Touchpad:dmi:*svn*GOOGLE*:pn*Samus*: +libinput:name:SynPS/2 Synaptics TouchPad:dmi:*pn*Mario* +libinput:name:Cypress APA Trackpad (cyapa):dmi:*pn*Butterfly* +libinput:name:Cypress APA Trackpad (cyapa):dmi:*pn*Peppy* +libinput:name:SynPS/2 Synaptics TouchPad:dmi:*pn*ZGB* +libinput:name:Cypress APA Trackpad (cyapa):dmi:*pn*Parrot* +libinput:name:Cypress APA Trackpad (cyapa):dmi:*bvn*coreboot*:pn*Leon* +libinput:name:Cypress APA Trackpad (cyapa):dmi:*bvn*coreboot*:pn*Falco* +libinput:name:Cypress APA Trackpad (cyapa):dmi:*bvn*coreboot*:pn*Wolf* +libinput:name:Cypress APA Trackpad (cyapa):dmi:*svn*GOOGLE*:pn*Link* +libinput:name:SynPS/2 Synaptics TouchPad:dmi:*pn*Alex* +libinput:name:Cypress APA Trackpad (cyapa):dmi:*svn*SAMSUNG*:pn*Lumpy* +libinput:name:Atmel maXTouch Touchpad:dmi:*svn*GOOGLE*:pn*Samus* LIBINPUT_MODEL_CHROMEBOOK=1 ########################################## @@ -64,3 +71,9 @@ libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnSystem76*pvrgalu1* # Kudu Professional libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnSystem76*pvrkudp1* LIBINPUT_MODEL_SYSTEM76_KUDU=1 + +########################################## +# Wacom +########################################## +libinput:touchpad:input:b0003v056Ap* + LIBINPUT_MODEL_WACOM_TOUCHPAD=1 diff --git a/udev/90-libinput-model-quirks.rules b/udev/90-libinput-model-quirks.rules index 4b988748..79b9b36f 100644 --- a/udev/90-libinput-model-quirks.rules +++ b/udev/90-libinput-model-quirks.rules @@ -13,8 +13,9 @@ KERNEL!="event*", GOTO="libinput_model_quirks_end" # hwdb matches: # -# libinput:<modalias> -IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=libinput:", \ +# libinput:touchpad:<modalias> +ENV{ID_INPUT_TOUCHPAD}=="1", \ + IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=libinput:touchpad:", \ GOTO="libinput_model_quirks_end" # libinput:name:<name>:dmi:<dmi string> @@ -22,4 +23,5 @@ KERNELS=="input*", \ IMPORT{builtin}="hwdb 'libinput:name:$attr{name}:$attr{[dmi/id]modalias}'", \ GOTO="libinput_model_quirks_end" + LABEL="libinput_model_quirks_end" |