summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/evdev-tablet.c52
-rw-r--r--test/test-tablet.c29
2 files changed, 67 insertions, 14 deletions
diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
index 4bc12632..c8d7ebb5 100644
--- a/src/evdev-tablet.c
+++ b/src/evdev-tablet.c
@@ -2150,6 +2150,30 @@ tablet_setup_touch_arbitration(struct evdev_device *device,
{
struct tablet_dispatch *tablet = tablet_dispatch(device->dispatch);
+ /* We enable touch arbitration with the first touch screen/external
+ * touchpad we see. This may be wrong in some cases, so we have some
+ * heuristics in case we find a "better" device.
+ */
+ if (tablet->touch_device != NULL) {
+ struct libinput_device_group *group1 = libinput_device_get_device_group(&device->base);
+ struct libinput_device_group *group2 = libinput_device_get_device_group(&new_device->base);
+
+ /* same phsical device? -> better, otherwise keep the one we have */
+ if (group1 != group2)
+ return;
+
+ /* We found a better device, let's swap it out */
+ struct libinput *li = tablet_libinput_context(tablet);
+ tablet_set_touch_device_enabled(tablet,
+ ARBITRATION_NOT_ACTIVE,
+ NULL,
+ libinput_now(li));
+ evdev_log_debug(device,
+ "touch-arbitration: removing pairing for %s<->%s\n",
+ device->devname,
+ tablet->touch_device->devname);
+ }
+
evdev_log_debug(device,
"touch-arbitration: activated for %s<->%s\n",
device->devname,
@@ -2162,16 +2186,20 @@ tablet_setup_rotation(struct evdev_device *device,
struct evdev_device *new_device)
{
struct tablet_dispatch *tablet = tablet_dispatch(device->dispatch);
-
- evdev_log_debug(device,
- "tablet-rotation: %s will rotate %s\n",
- device->devname,
- new_device->devname);
- tablet->rotation.touch_device = new_device;
-
- if (libinput_device_config_left_handed_get(&new_device->base)) {
- tablet->rotation.touch_device_left_handed_state = true;
- tablet_change_rotation(device, DO_NOTIFY);
+ struct libinput_device_group *group1 = libinput_device_get_device_group(&device->base);
+ struct libinput_device_group *group2 = libinput_device_get_device_group(&new_device->base);
+
+ if (tablet->rotation.touch_device == NULL && (group1 == group2)) {
+ evdev_log_debug(device,
+ "tablet-rotation: %s will rotate %s\n",
+ device->devname,
+ new_device->devname);
+ tablet->rotation.touch_device = new_device;
+
+ if (libinput_device_config_left_handed_get(&new_device->base)) {
+ tablet->rotation.touch_device_left_handed_state = true;
+ tablet_change_rotation(device, DO_NOTIFY);
+ }
}
}
@@ -2181,10 +2209,6 @@ tablet_device_added(struct evdev_device *device,
{
bool is_touchscreen, is_ext_touchpad;
- if (libinput_device_get_device_group(&device->base) !=
- libinput_device_get_device_group(&added_device->base))
- return;
-
is_touchscreen = evdev_device_has_capability(added_device,
LIBINPUT_DEVICE_CAP_TOUCH);
is_ext_touchpad = evdev_device_has_capability(added_device,
diff --git a/test/test-tablet.c b/test/test-tablet.c
index 5a92ea6e..9a6602e6 100644
--- a/test/test-tablet.c
+++ b/test/test-tablet.c
@@ -5338,6 +5338,34 @@ START_TEST(touch_arbitration_late_touch_lift)
}
END_TEST
+START_TEST(touch_arbitration_swap_device)
+{
+ struct litest_device *tablet = litest_current_device();
+ struct libinput *li = tablet->libinput;
+
+ enum litest_device_type paired = paired_device(tablet);
+ if (paired == LITEST_NO_DEVICE)
+ return;
+
+ /* First, add a normal touchscreen */
+ struct litest_device *touchscreen = litest_add_device(li, LITEST_GENERIC_MULTITOUCH_SCREEN);
+ libinput_device_config_gesture_set_hold_enabled(touchscreen->libinput_device,
+ LIBINPUT_CONFIG_HOLD_DISABLED);
+ litest_drain_events(li);
+ assert_touch_is_arbitrated(tablet, touchscreen);
+
+ /* Now add a better device to override the pairing */
+ struct litest_device *finger = litest_add_device(li, paired);
+ libinput_device_config_gesture_set_hold_enabled(finger->libinput_device,
+ LIBINPUT_CONFIG_HOLD_DISABLED);
+ litest_drain_events(li);
+ assert_touch_is_arbitrated(tablet, finger);
+
+ litest_delete_device(touchscreen);
+ litest_delete_device(finger);
+}
+END_TEST
+
#if HAVE_LIBWACOM
static void
verify_left_handed_tablet_motion(struct litest_device *tablet,
@@ -6209,6 +6237,7 @@ TEST_COLLECTION(tablet)
litest_add(touch_arbitration_late_touch_lift, LITEST_TABLET, LITEST_ANY);
litest_add(touch_arbitration_outside_rect, LITEST_TABLET | LITEST_DIRECT, LITEST_ANY);
litest_add(touch_arbitration_remove_after, LITEST_TABLET | LITEST_DIRECT, LITEST_ANY);
+ litest_add(touch_arbitration_swap_device, LITEST_TABLET, LITEST_ANY);
litest_add_ranged(tablet_rotation_left_handed, LITEST_TABLET, LITEST_ANY, &lh_transitions);
litest_add_ranged(tablet_rotation_left_handed_configuration, LITEST_TABLET, LITEST_ANY, &lh_transitions);