tablet: extend touch arbitration rect to cover full tablet height

The arbitration rectangle previously only covered a region from 100mm
above the pen tip to 150mm below it (250mm total). This let a few
unintentional touches through such as when some of the fingers are
extended while using the pen. Likewise, a large hand could fall below
the bottom edge of the rectangle.

Change the rect to span the full height and width of the tablet while
keeping the same horizontal logic (200mm wide, starting 20mm from the
pen tip toward the hand side). Simplify a few things too, there is no
need for clipping the rect.

Related: #1276
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1463>
This commit is contained in:
Peter Hutterer 2026-04-14 08:35:31 +10:00 committed by Marge Bot
parent 5f29257569
commit 2bea0f3e4e
2 changed files with 32 additions and 57 deletions

View file

@ -1866,38 +1866,24 @@ tablet_calculate_arbitration_rect(struct tablet_dispatch *tablet)
{
struct evdev_device *device = tablet->device;
struct phys_rect r = { 0 };
struct phys_coords mm;
const double maxdim = 600; /* 600mm covers all the way to the right/bottom */
mm = evdev_device_units_to_mm(device, &tablet->axes.point);
struct phys_coords mm = evdev_device_units_to_mm(device, &tablet->axes.point);
/* The rect we disable is 20mm left of the tip, 100mm north of the
* tip, and 200x250mm large.
* If the stylus is tilted left (tip further right than the eraser
* end) assume left-handed mode.
*
* Obviously if we'd run out of the boundaries, we clip the rect
* accordingly.
/* The rect we disable is 20mm left of the tip, covering that whole side of the
* tablet. If the stylus is tilted left (tip further right than the eraser end)
* assume left-handed mode.
*/
if (tablet->axes.tilt.x > 0) {
r.x = mm.x - 20;
r.w = 200;
r.w = maxdim;
} else {
r.x = mm.x + 20;
r.w = 200;
r.x -= r.w;
}
if (r.x < 0) {
r.w += r.x;
r.x = 0;
r.w = mm.x + 20;
}
r.y = mm.y - 100;
r.h = 250;
if (r.y < 0) {
r.h += r.y;
r.y = 0;
}
r.y = 0;
r.h = maxdim;
return r;
}

View file

@ -6293,6 +6293,13 @@ START_TEST(touch_arbitration_outside_rect)
double x, y;
bool is_touchpad;
bool tilt_left = litest_test_param_get_bool(test_env->params, "tilt-left");
if (tilt_left) {
litest_axis_set_value(axes, ABS_TILT_X, 40);
} else {
litest_axis_set_value(axes, ABS_TILT_X, 80);
}
other = paired_device(dev);
if (other == LITEST_NO_DEVICE)
return LITEST_NOT_APPLICABLE;
@ -6304,8 +6311,8 @@ START_TEST(touch_arbitration_outside_rect)
if (is_touchpad)
return LITEST_NOT_APPLICABLE;
x = 20;
y = 70;
x = 50;
y = 50;
/* disable prox-out timer quirk */
litest_tablet_proximity_in(dev, x, y - 1, axes);
@ -6321,37 +6328,17 @@ START_TEST(touch_arbitration_outside_rect)
litest_tablet_motion(dev, x, y, axes);
litest_drain_events(li);
/* left of rect */
litest_touch_sequence(finger, 0, x - 10, y + 2, x - 10, y + 20, 3);
litest_dispatch(li);
litest_assert_touch_sequence(li);
/* above rect */
litest_touch_sequence(finger, 0, x + 2, y - 65, x + 20, y - 40, 3);
litest_dispatch(li);
litest_assert_touch_sequence(li);
/* right of rect */
litest_touch_sequence(finger, 0, x + 80, y + 2, x + 20, y + 10, 3);
litest_dispatch(li);
litest_assert_touch_sequence(li);
#if 0
/* This *should* work but the Cintiq test devices is <200mm
high, so we can't test for anything below the tip */
x = 20;
y = 10;
litest_tablet_proximity_out(dev);
litest_timeout_tablet_proxout(li);
litest_tablet_motion(dev, x, y, axes);
litest_tablet_proximity_in(dev, x, y - 1, axes);
litest_drain_events(li);
/* below rect */
litest_touch_sequence(finger, 0, x + 2, y + 80, x + 20, y + 20, 30);
litest_dispatch(li);
litest_assert_touch_sequence(li);
#endif
if (tilt_left) {
/* slightly right of tip */
litest_touch_sequence(finger, 0, x + 10, y + 2, x - 10, y + 20, 3);
litest_dispatch(li);
litest_assert_touch_sequence(li);
} else {
/* slightly left of tip */
litest_touch_sequence(finger, 0, x - 10, y + 2, x - 10, y + 20, 3);
litest_dispatch(li);
litest_assert_touch_sequence(li);
}
litest_device_destroy(finger);
}
@ -8232,7 +8219,9 @@ TEST_COLLECTION(tablet)
litest_add(touch_arbitration_remove_tablet, LITEST_TOUCH, LITEST_ANY);
litest_add(touch_arbitration_keep_ignoring, LITEST_TABLET, LITEST_ANY);
litest_add(touch_arbitration_late_touch_lift, LITEST_TABLET, LITEST_ANY);
litest_add(touch_arbitration_outside_rect, LITEST_TABLET | LITEST_DIRECT, LITEST_ANY);
litest_with_parameters(params, "tilt-left", 'b') {
litest_add_parametrized(touch_arbitration_outside_rect, LITEST_TABLET | LITEST_DIRECT, LITEST_ANY, params);
}
litest_add(touch_arbitration_remove_after, LITEST_TABLET | LITEST_DIRECT, LITEST_ANY);
litest_add(touch_arbitration_swap_device, LITEST_TABLET, LITEST_ANY);