We differ between a fast 3fg swipe and a 3fg drag based on whether we
move 5mm within 80ms of contact. Alas, the code started the timeout once
we had enough motion, not on initial contact.
Three fingers down, then resting for >80ms, then moving 5mm within the
subsequent 80ms would thus trigger a fast swipe because the timer wasn't
set until sufficient movement happened. Fix this by setting the timer
based on the initial touch point's time. This requires potentially
setting a negative timer to avoid duplicating parts of the state
machine.
Closes#1266
Fixes: fe1d44637f ("touchpad: add support for fast swipe when 3fg drag is enabled")
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1466>
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>
luaL_loadfile() by default allows for both text files and precompiled
lua files. Precompiled files are not verified on load allowing for a
sandbox escape.
CVE-2026-35093
Fixes: #1271
Found-by: Koen Tange <koen@monokles.eu>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1459>
Previously we had one vtable for the libinputplugin and EvdevDevice
objects. This allowed plugins to call __gc(), a decidedly internal
method.
This fixes a use-after-free: A plugin that called EvdevDevice::__gc()
frees the plugin's copy of device->name but leaves the pointer in-place,
a subsequent call will thus cause a UAF read.
Fix this by separating what is the object's metatable from the public
methods that are accessible to a plugin.
CVE-2026-35094
Fixes: #1272
Found-by: Koen Tange <koen@monokles.eu>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1459>
If drag-lock is disabled but we're in a tap-and-drag state and the
finger is released near the edge (within 5mm), enable automatic drag
lock for 400ms. This allows a user to quickly reset the finger and
continue with the drag.
The 400ms is a randomly guessed timeout - if you're using tap-and-drag
without draglock, finger dexterity should be high enough that resetting
the single finger can be done quickly but it's also short enough to not
make the occasional delayed button be painful in day-to-day use.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1447>
The second 'Expect button event' block in
tablet_eraser_button_different_buttons is missing the button state
assertion that the first block has. This event should be a
BUTTON_STATE_RELEASED (the eraser left proximity), but without the
check the test passes even if the state is wrong.
Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1444>
Instead of adding a new ENABLED_HOLD enum value, modify the existing
ENABLED lock mode so that hold+scroll+release doesn't engage the lock.
Add a 500ms grace period: if the button was held and used to scroll for
longer than 500ms, releasing the button does not engage the lock
(temporary scroll). If released within 500ms (e.g. shaky hands
triggering accidental motion), the lock still engages as before.
This fixes the unintuitive behavior where the lock engages even after
actively scrolling, without requiring new API surface.
Closes: https://gitlab.freedesktop.org/libinput/libinput/-/issues/1259
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1435>
Now we have in udev the ID_INTEGRATION propery that tells us if a device
is internal or external, use it while still allow hwdb and quirks to
override it.
In the future is possible that we could remove quirks for keyboards
integration and hwdb for touchpads and joysticks integration.
Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1429>
The previous restriction was BTN_STYLUS* or any button the pen
advertises. This is too restrictive - it works well enough for any pen
with less than 3 buttons (BTN_STYLUS3 is always available on those) but
otherwise it cannot work. A 3-button pen may not advertise any other
buttons, leaving us with the eraser button being a duplicate button. And
events cannot be distinquished between eraser button or real button.
Open up the configuration to effectively any BTN_ event code.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1436>
This recovers the testing that a USB keyboard plus touchpad combo both
set as external, only its own keyboard should affect to DWT that was
removed when Acer Hawaii combo was set as internal.
This is uncommon as usb touchpads nowadays are set as internal, but,
perhaps someone that adds a quirk for a really external combo also adds
in udev's hwdb the external integration for the touchpad, or perhaps we
should set the integration to external when AttrTPKComboLayout=below is
used for the touchpad.
The issue is if the touchpad is leave as internal every keyboard affect
DWT, not only the one that belongs to its combo.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1415>
This adds a movement threshold (5mm) and a timeout (80ms) to the 3fg
drag gesture. On 3fg down with 3fg drag enabled we immediately send a
GESTURE_SWIPE event. After the timeout expires we check the movement of
the fingers - if it is below the threshold cancel the swipe and hold a
button down (i.e. a 3fg drag). Otherwise, continue with this being a
swipe.
This allows for swipe gestures to be used while 3fg drag is enabled.
Above applies the same way for 4fg with 4fg drag enabled.
Thresholds selected using the "yeah, that seems about alright" method,
intentionally quite low because we assume that users that enable 3fg
drag prefer 3fg dragging over swipe.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1410>
Instead of disabling the touchpad as soon as a mouse is seen by
libinput, disable it as soon as a mouse sends an actual event. This
works around the current issues with many devices (touchpads and
keyboards alike) announcing a HID Mouse Application Collection which
gets its own event node in the kernel. That event node usually just sits
there and does nothing but its mere presence disabled the touchpad.
Let's change this and instead only disable once we see an event.
Closes: #1104
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1414>
If a lua pcall takes longer than one second, kill the plugin.
How often to call the timeout handler is a trade-off but we err on the
side of "possibly too high" since the overwhelmingly vast majority of
plugins will never trigger it anyway.
Gemini suggests that Lua 5.4 can do ~500k ops per second for string
concat (the slowest listed), Claude suggests 1 to 10 million ops per
second. The test in this patch on my 4y old cheap desktop runs the
timeout hook roughly every 37ms. Any normal plugin will be well and
truly done with its work by then.
Closes: #1245
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1416>
If the tool has a name let's provide that to the caller. We have it
easily accessible so let's export it to make everyone's life easier. The
name is provided by libwacom, there is no need for us
to even copy that value since we don't need it ourselves.
Note that at this point effectively only (some) Wacom devices have
meaningful names. Virtually all non-wacom devices will use a generic
tool and even the built-in Wacoms will largely just say "AES Pen".
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1399>
The WHEEL_STATE_NONE check was effectively always false:
- if we didn't receive any event yet, wheel_maybe_disable() wasn't
called in any code path
- if we did receive a scroll event, the wheel state was either
WHEEL_STATE_SCROLLING or WHEEL_STATE_ACCUMULATING_SCROLL
Fix this two-pronged: remove the check for WHEEL_STATE_NONE but also
immediately call disable when we disable the feature. We don't carry
enough state in this plugin to really worry about the device being in
a fully neutral state (and realistically the vast majority of use-cases
will likely disable wheel debouncing on new device anyway).
Closes#1241
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1408>
Actually all usb touchpads are internal by default, reflect this in the
acer touchpad definition.
This causes that not only the acer keyboard in its group activates DWT
but all the intenal keyboards.
Remove asserting that other keyboards doesn't affect DWT as that is the
intended behaviour.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1400>
Ifdef out any special behavior we want so we no longer leak this via
strings in the resulting binary. Ideally we want the compile to fail for
anything missed rather than surprising behavior when we try to access
files in the build directory.
Closes: #1230
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1396>
This tests for a known bug in the implementation rather than the ideal case
how it should work.
The config is applied to the tool and on prox out to the current tablet
but then the tool goes in prox on a new tablet and the configuration
doesn't get applied there. In the test we work around this by injecting
an extra proximity event to get the range applied.
This needs some rework in the evdev-tablet code but it's questionable
whether it makes a difference given the small number of users with
multiple tablets and pressure ranges set.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1397>
Previously test devices had to set LITEST_AUTO_ASSIGN to be able
to override an axis-specific value. But this prevented us from
easily overriding other axis values (e.g. tablet tool ids) that usually
have the same value.
LITEST_AUTO_ASSIGN should indicate a value that must always be
auto-assigned, that makes a lot more sense.
This does mean we need to handle ABS_MT_TRACKING_ID -1 to avoid that
getting overwritten by auto_assign_tablet_value() but oh well.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1398>
This only worked because any all our test devices declare a fixed 0
value for x/y in the proximity out event frame. Since 0 !=
LITEST_AUTO_ASSIGN we never got to the litest_scale() for x/y which
would abort because of the -1 value.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1398>
A few devices have a keyboard/keypad which can be slid under the device,
leaving the device with only touch-based interaction. The corresponding kernel
event is reported as SW_KEYPAD_SLIDE [0]. Implement support in libinput.
Since the position of the switch varies across devices, it cannot always be
certain whether the keypad is usable when the switch is in the set position.
Therefore, do not automatically disable the keyboard.
[0] e68d80b13b/include/linux/linux/input-event-codes.h (L885)Closes: #1069
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1242>
Touchpads that don't give us useful palm detection data are getting more
common (see e.g. our ABS_MT_TOOL_TYPE quirks). On those touchpads we can
only rely on dwt and palm edge detection which means those two must be
more spot on than ever before.
DWT in particular is more prone to user-specific requirements, the
current timeouts have been insufficient for a number of users. So let's
make them more configurable.
Currently limited to >100ms and <5 seconds to avoid DWT being used in
the xkcd workflow style.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1372>
If the device is unplugged, our tool's last_device is NULL. If a caller
then tries to the toggle the eraser button setting libinput would crash.
Fix this by simply skipping the configuration until the tool goes back
into proximity over some other device (if any).
Closes#1223
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1370>
The existence of the log global was in part due to early (pre-merge)
versions of the Lua plugins supporting multiple libinput plugin objects
per file. This is no longer the case and integrating the log functions
into the (single) libinput object makes the code more obvious (we're
calling libinput:log_debug() now, so it's obviously a libinput log
function) and we no longer mix dot with colon notations.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1350>