diff options
-rw-r--r-- | src/evdev-tablet.c | 52 | ||||
-rw-r--r-- | test/test-tablet.c | 29 |
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); |