Compare commits

...

307 commits

Author SHA1 Message Date
Peter Hutterer
e53c2141b3 util: add a free_clear() helper to reset after free
Same as e.g. g_clear_pointer(). Switch a number of obvious call sites
over to use this, the rest will come over time.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1472>
2026-04-24 00:24:24 +00:00
Peter Hutterer
c2c8414605 tools: update the tool option parsing test for newer options
Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1473>
2026-04-23 23:21:07 +00:00
Peter Hutterer
86a775b3ca tools/debug-tablet: guard against open() failures
This is a debugging tool so we don't expect NDEBUG but let's handle
errors correctly anyway.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1467>
2026-04-22 04:53:14 +00:00
Peter Hutterer
0fa334600d tools: always open with O_CLOEXEC
Doesn't have any effect but it's easy enough and good practice to do.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1467>
2026-04-22 04:53:14 +00:00
Peter Hutterer
a5a9d2d8df tools: guard against zero-length os-release files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1467>
2026-04-22 04:53:14 +00:00
Peter Hutterer
8afdc52eaf tools: Use xclose() over close()
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1467>
2026-04-22 04:53:14 +00:00
Peter Hutterer
e53a78f7d7 tools/record: fix missing NULL check on tmpfile() return value
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1467>
2026-04-22 04:53:14 +00:00
Peter Hutterer
a51398cb8d tools: use save_atod instead of atof()
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1467>
2026-04-22 04:53:13 +00:00
Peter Hutterer
74b4ca132f tools/debug-tablet-pad: add bounds checks for array accesses
A few not-really-an-issue fixes found by Claude:

1. ctx->buttons_down[number]: the 'number' value comes from
   libinput_event_tablet_pad_get_button_number() and is written into
   a fixed-size array of 32 elements without bounds checking. A crafted
   or malicious device reporting button numbers >= 32 causes a stack
   buffer overflow.

2. ctx->ring[number], ctx->strip[number], ctx->dial[number]: these are
   fixed-size arrays of 2 elements each. Ring/strip/dial numbers from
   libinput events are used as indices without bounds checking. Values
   >= 2 cause out-of-bounds writes.

3. assert()-based error handling for open() and libevdev_new_from_fd():
   assert() is compiled to a no-op in release builds (NDEBUG). This
   means that in release builds, a failed open() returns fd=-1, and
   libevdev_new_from_fd() is called with an invalid fd. The result is
   undefined behavior.

4. Variable-length array (VLA) 'empty[termwidth]' in print_bar():
   termwidth comes from an ioctl(TIOCGWINSZ) call and could be very
   large, causing a stack overflow. Replace with a fixed-size buffer.

None of these really matter for a niche debugging tool.

Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1467>
2026-04-22 04:53:13 +00:00
Peter Hutterer
f899da7552 tools/ptraccel-debug: replace atoi() with safe_atoi()
It's a niche development/debugging tool, argument parsing issues aren't
really something we need to care about but hey, this change is easy.

Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1467>
2026-04-22 04:53:13 +00:00
Peter Hutterer
20b52ffafc udev: use xclose() instead of close()
xclose does the fd == -1 dance which makes analyzers happier.

Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1467>
2026-04-22 04:53:13 +00:00
Peter Hutterer
c276c9579e plugin: use safe_strdup() instead of strdup()
safe_strdup() handles NULL correctly instead of just blowing up. This
shouldn't matter because without a name our plugins won't get here but
let's do this anwyay.

Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1467>
2026-04-22 04:53:13 +00:00
Peter Hutterer
d97983ee5e util: use lstat() instead of stat() in rmdir_r to prevent symlink attacks
stat() follows symbolic links which is definitely something we don't
want. If an attacker can place a symlink inside a directory being
recursively deleted (e.g. a temporary directory), stat() will report the
type of the symlink's target rather than the symlink itself. If the
target is a directory, rmdir_r() will follow the symlink and recursively
delete the target directory's contents outside the intended directory
tree.

This has no real effect, this is only used in the test suite.

Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1467>
2026-04-22 04:53:13 +00:00
Peter Hutterer
b87532dfb5 touchpad: replace sprintf strv_join in the touch state debugging
This is purely to make Claude happy, the function is ifdef'd out and to
actually hit the limit we'd need more than ~25 slots active.

Anyway, the strv helpers make for much nicer code anyway.

Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1467>
2026-04-22 04:53:13 +00:00
Peter Hutterer
75d4acfe94 util: allow for 'e' in safe_atod strings
1.5e2 is a valid string, so let's parse those.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1467>
2026-04-22 04:53:13 +00:00
Peter Hutterer
cc72db48fb doc/user: add an illustration of the touch arbitration rectangle
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1462>
2026-04-21 11:12:59 +10:00
Peter Hutterer
0e4492155f doc: add HOLD_END to libinput_event_gesture_get_cancelled() doc
The implementation accepts LIBINPUT_EVENT_GESTURE_HOLD_END in
require_event_type() but the API documentation only listed SWIPE_END
and PINCH_END. This was likely missed when hold gesture support was
added.

Co-authored-by: Claude <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1469>
2026-04-20 01:10:05 +00:00
Peter Hutterer
2da19a8802 doc: remove ID_INPUT from lua plugin udev properties list
The code in libinput-plugin-lua.c filters udev properties with
strstartswith(key, "ID_INPUT_") which requires a trailing underscore.
The bare 'ID_INPUT' property does not match this filter and is never
included in the properties table provided to plugins.

Co-authored-by: Claude <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1469>
2026-04-20 01:10:05 +00:00
Peter Hutterer
37e1dfd2d1 doc: update multi-device recording docs, --multiple is deprecated
The --multiple flag is deprecated and a no-op in the current code
(libinput-record.c). Multiple devices can simply be specified as
arguments on the commandline. Update the documentation to reflect
the current usage.

Co-authored-by: Claude <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1469>
2026-04-20 01:10:05 +00:00
Peter Hutterer
f87bae4ed2 doc: fix libinput replay output format in tools.rst
The example output showed 'Name: /dev/input/eventN' but the actual code
(libinput-replay.py) prints '/dev/input/eventN: Name'. Update the
example to match the actual output format.

Co-authored-by: Claude <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1469>
2026-04-20 01:10:05 +00:00
Peter Hutterer
20a53db063 doc: fix ClickPad scroll method description in scrolling.rst
ClickPads support both two-finger scrolling and edge scrolling, not
two-finger scrolling only. The code in evdev-mt-touchpad.c always
includes LIBINPUT_CONFIG_SCROLL_EDGE in the supported methods and adds
LIBINPUT_CONFIG_SCROLL_2FG if the touchpad supports 2+ touches.

Co-authored-by: Claude <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1469>
2026-04-20 01:10:05 +00:00
Peter Hutterer
f854eb0515 doc: fix typos and misspellings across documentation
Co-authored-by: Claude <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1469>
2026-04-20 01:10:05 +00:00
Peter Hutterer
60028ea595 doc: fix simplified hold gesture table in gestures.rst
The simplified table showed 'Finger 1 down' producing '<no event>' but
all the detailed examples later in the same document show that a single
finger down triggers a hold begin event with finger count 1, followed by
a cancel and new begin when the second finger arrives. Update the
simplified table to be consistent with the detailed examples and the
actual implementation.

Co-authored-by: Claude <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1469>
2026-04-20 01:10:05 +00:00
Peter Hutterer
2400a5c128 doc: fix reference to non-existent 'hold update' event in gestures.rst
There is no LIBINPUT_EVENT_GESTURE_HOLD_UPDATE event in the API.
When a finger is detected as thumb/palm during a hold and other fingers
remain, the implementation cancels the current hold and starts a new one
with an updated finger count. Update the documentation to describe the
actual behavior.

Co-authored-by: Claude <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1469>
2026-04-20 01:10:05 +00:00
Peter Hutterer
fdd43a4fcd touchpad: time the 3fg fast swipe timeout from the initial contact
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>
2026-04-17 02:32:50 +00:00
Peter Hutterer
2bea0f3e4e 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>
2026-04-16 05:10:53 +00:00
Peter Hutterer
5f29257569 util: use zalloc in stringbuf
zalloc() aborts on allocation failure and it's what we use everywhere
else.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1465>
2026-04-16 04:55:23 +00:00
Peter Hutterer
2ea3fb1d13 tablet-pad: use strdup_printf in sysfs path construction
This simplifies the code and means we don't have to deal with snprintf
return values to ensure we're not truncating.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1465>
2026-04-16 04:55:23 +00:00
Peter Hutterer
9d8a8b4530 util: use snprintf for PID formatting in backtrace helper
Use snprintf to make analyziers happier and bump the buffer size to 16.
That's way larger than we'll need given the kernel's PID_MAX_LIMIT
(4194304) but it doesn't cost us anything.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1465>
2026-04-16 04:55:23 +00:00
Peter Hutterer
e32202eeae util: check for NULL on realloc in _infmask_ensure_size
And abort if that ever happens because it really shouldn't.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1465>
2026-04-16 04:55:23 +00:00
Peter Hutterer
aa04f67b1c plugin: guard against unsigned underflow in plugin_has_mask
nevents should never be zero but let's prevent against an underflow, if
only to make the analyzers happy.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1465>
2026-04-16 04:55:23 +00:00
Peter Hutterer
8c06ceecb2 quirks: add missing modification warning to a quirks file
And add a test to make sure we don't forget this in the future.

Fixes: 488c0c9645 ("quirks: add quirk for the Wareus B15")
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1464>
2026-04-14 09:48:15 +10:00
Peter Hutterer
356c498fd4 lua: force text mode for loading plugins
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>
2026-04-01 23:53:12 +00:00
Peter Hutterer
45dfd0f030 lua: separate the API from the metatables
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>
2026-04-01 23:53:12 +00:00
David Santamaría Rogado
7face63bd5 quirks: add positivo vaio fe15 right button
Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1458>
2026-03-30 00:07:52 +02:00
Artem Proskurnev
488c0c9645 quirks: add quirk for the Wareus B15
Fix:
https://gitlab.freedesktop.org/libinput/libinput/-/work_items/1267

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1457>
2026-03-28 12:39:42 +03:00
Richie Roy Jayme
baddf1e2b6 quirks: add support for Goodix touchpad GXTP5400:00 27C6:0F96
This commit adds a specific vendor HWID for Goodix Haptic Touchpad to
improve detection and handling.

Signed-off-by: Richie Roy Jayme <rjayme.jp@gmail.com>
Signed-off-by: Richie Roy Jayme <rjayme2@lenovo.com>
Reviewed-by: Vishnu Sankar <vishnuocv@gmail.com>
Reviewed-by: Vishnu Sankar <vsankar@lenovo.com>
Tested-by: Ameer Ivan Julkarnain <ajulkarnain1@lenovo.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1455>
2026-03-25 18:33:21 +09:00
Peter Hutterer
9baccdf44c touchpad: support automatic drag-lock when releasing at the edge
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>
2026-03-24 05:50:24 +00:00
Peter Hutterer
1486c7ae17 test: change where our finger ends up before releasing
No effect on the test right now but on some small test touchpads
this is close enough to the edge to mess with future tests.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1447>
2026-03-24 05:50:24 +00:00
Peter Hutterer
f97d0e6db1 doc/user: document sticky vs timeout based drag lock a bit better
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1447>
2026-03-24 05:50:23 +00:00
Peter Hutterer
1c4040ffa3 tools/debug-tablet: switch an snprintf to strvs
Less having to think about snprintf's buffer correctness

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1453>
2026-03-24 05:24:35 +00:00
Peter Hutterer
166201d9fc util: fix remaininig usec computation on 32 bits
Follow-up from commit dcbfbc4cf1 ("util: fix usec computation on 32 bits")
which didn't fix all instances, make this consistent.

Fixes: dcbfbc4cf1 ("util: fix usec computation on 32 bits")
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1453>
2026-03-24 05:24:35 +00:00
Peter Hutterer
7d15503b45 evdev: fix rel axis disabling on accelerometers
Copy/paste caused only the abs axes being disabled (REL_X == ABS_X,
etc. so the EV_REL bits had no effect).

Found-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1453>
2026-03-24 05:24:35 +00:00
Peter Hutterer
2dc491de1f Fix various typos
Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1452>
2026-03-24 05:09:07 +00:00
Marcin Jahn
bb7aa004f8 quirks: add clevetura clvx s touchpad quirk
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1454>
2026-03-22 20:59:13 +01:00
Freeman Zhang
a1c5f35a69 Add Goodix haptic touchpad 27C6:0F90 support
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1451>
2026-03-22 10:53:44 +00:00
Freeman Zhang
57c71c567f Add Elan haptic touchpad 04F3:3355 support
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1450>
2026-03-22 12:37:19 +08:00
Peter Hutterer
ef9624a16b evdev: store the SYN_REPORT value in the frame
If the SYN_REPORT has a value of nonzero we need to keep that value in
the frame - our upper layers rely on this to detect repeat frames.

Closes #1261

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1449>
2026-03-19 00:09:30 +00:00
GKraats
dcbfbc4cf1 util: fix usec computation on 32 bits
Enforce the needed 64-bit computing on 32 bits.

Signed-off-by: GKraats <vd.kraats@hccnet.nl>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1446>
2026-03-18 00:25:48 +00:00
Peter Hutterer
ad857a51a4 tools/record: fix delta times not being relative
Missing last_time assignment caused the delta time between events to be
the total time.

Fixes: a202ed6115 ("Use a newtype usec_t for timestamps for better type-safety")
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1448>
2026-03-17 05:05:14 +00:00
Peter Hutterer
a521d054d4 tools: fix leak of evdev_prev in libinput-record
Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1444>
2026-03-17 00:46:46 +00:00
Peter Hutterer
f86d5ab2ab test: add missing button state assertion for eraser button release
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>
2026-03-17 00:46:46 +00:00
Peter Hutterer
32fd9ec95f tools: Remove dead eraser_button_button initialization to BTN_STYLUS
Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1444>
2026-03-17 00:46:46 +00:00
Peter Hutterer
45150cc6ec tools: fix missing fd assignment in libinput-debug-tablet
The fd opened for the evdev device is never stored in ctx->fds[1].fd
so we never poll for it. Real impact was limited since we do poll for
the libinput fd and we process libevdev events whenever any of the fds
triggers.

Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1444>
2026-03-17 00:46:46 +00:00
Peter Hutterer
c8c1c07a2a tools: fix swapped fread arguments causing DMI modalias to always be "unknown"
fread(buf, sizeof(buf), 1, dmi) reads one block of 2048 bytes,
returning the number of complete blocks (0 or 1). Since DMI modalias
files are always shorter than 2048 bytes, fread returns 0 even when
data was successfully read into buf. The 'if (n > 0)' check then
always fails and the DMI string stays as "unknown".

Swap the size and nmemb arguments so fread returns the number of
bytes read instead.

Fixes: 0ecd08c134 ("tools: use __attribute__(cleanup)")

Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1444>
2026-03-17 00:46:46 +00:00
Peter Hutterer
b1f478b897 tools: fix pencil tablet tool type in libinput-record
Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1444>
2026-03-17 00:46:45 +00:00
Peter Hutterer
333d7131ab tools: fix swapped strstartswith arguments in find_device()
Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1444>
2026-03-17 00:46:45 +00:00
Peter Hutterer
cd9d6c66fd tablet: fix eraser button get_default_mode/get_default_button return values
Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1444>
2026-03-17 00:46:45 +00:00
Peter Hutterer
a0dc0997f5 meson.build: explicitly convert a boolean to string
Fixes:
  DEPRECATION: Variable substitution with boolean value 'MESON_ENABLED_DEBUG_GUI' is deprecated.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1445>
2026-03-13 12:15:21 +10:00
Peter Hutterer
c6813dc7d8 tools: add --compress-motion-events to the man page and zsh completion
Fixes: dc249b0ffe ("tools/debug-events: add ability to compress motion events")
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1443>
2026-03-11 14:22:40 +10:00
Ilya Kamenko
8dd25ece10 Fold hold-to-scroll into existing scroll button lock mode
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>
2026-03-10 23:12:25 +00:00
Mingcong Bai
43547b461b quirks: add Goodix pressure pad quirk for 27C6:01E7
This touchpad is found on the newly released Lenovo ThinkBook G8+ IPH.

Signed-off-by: Mingcong Bai <jeffbai@aosc.io>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1442>
2026-03-10 11:37:34 +08:00
David Santamaría Rogado
2ddc734114 test: set ID_INTEGRATION into test devices
Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1429>
2026-03-10 02:27:36 +00:00
David Santamaría Rogado
819e943ab0 evdev: use udev's ID_INTEGRATION
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>
2026-03-10 02:27:36 +00:00
David Santamaría Rogado
1c82aa1659 quirks: add some more goodix haptic touchpads
Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1440>
2026-03-09 09:48:05 +01:00
David Santamaría Rogado
526130fe8d quirks: hp omnibook ultra flip 14 touch pressure
Add pressure attributes to make libinput measure touchpad-pressure
behave right.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1430>
2026-03-09 01:34:07 +00:00
David Santamaría Rogado
b95840d36e quirks: hp omnibook ultra flip 14 improve rule set
Some initial units had 14t-fh000 instead 14-fh0xxx in their product name
but they are exactly the same model.

We could match both in product version SBKPF or in board product name
8CDE. Match board as seems the way hp-wmi kernel module uses to match.

While at it rewrite the entire huge comment to a little less huge
comment but with more really interesting info.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1430>
2026-03-09 01:34:07 +00:00
Peter Hutterer
7726350420 tablet: allow for the eraser button to be any button
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>
2026-03-09 01:14:21 +00:00
Peter Hutterer
cdcb827365 Fix the evdev_usage_is_button check for the BTN_STYLUS group
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1436>
2026-03-09 01:14:21 +00:00
Peter Hutterer
0a3ecbea24 tablet: fix missing linebreak after an error message
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1436>
2026-03-09 01:14:21 +00:00
BBaoVanC
db62bf7ab1 quirks/apple: Add AttrSizeHint to Magic Trackpad USB-C
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1437>
2026-03-04 04:53:28 +00:00
David Santamaría Rogado
9eae99d4fe quirks: microsoft surface keyboard event BTN_0
Apply AttrEventCode=-BTN_0 to all surface keyboards.

Fixes: #1251.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1431>
2026-02-22 08:40:11 +00:00
David Santamaría Rogado
a86b8a0008 doc: list-quirks should be quirks list
while at it replace also a code comment in the same line.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1432>
2026-02-20 19:56:46 +01:00
Sicelo A. Mhlongo
3428edf1ea doc/user: document keypad slide switch support
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1428>
2026-02-17 12:03:56 +02:00
Peter Hutterer
659967488e libinput 1.31.0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2026-02-13 09:25:46 +10:00
Lorenzo Ianotto
b9fc550f28 Set ModelTabletModeNoSuspend only for Thinkpad S1 Yoga and X1 Yoga 1st gen
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1425>
2026-02-09 02:42:33 +00:00
Richie Roy Jayme
df8f5a3627 quirks: add quirk support for Goodix touchpad
This commit adds a specific vendor HWID for Goodix Haptic Touchpad to
improve detection and handling.

Signed-off-by: Richie Roy Jayme <rjayme.jp@gmail.com>
Signed-off-by: Richie Roy Jayme <rjayme2@lenovo.com>
Reviewed-by: Vishnu Sankar <vishnuocv@gmail.com>
Reviewed-by: Vishnu Sankar <vsankar@lenovo.com>
Reported-by: Ameer Ivan Julkarnain <ajulkarnain1@lenovo.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1426>
2026-02-07 08:27:58 +00:00
Peter Hutterer
e0ba559117 libinput 1.30.901
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1424>
2026-02-04 12:41:58 +10:00
Peter Hutterer
e78f4f689d util: add guards for the etrace/trace defines
This file is really useful on its own for other projects if
auto-included via export CFLAGS="$CFLAGS -include /path/to/file.h"
However, that causes compiler warnings, let's add indef checks for this
as a quick workaround.

Since these three come as a set and are only used for debugging, we can
ifndef them all in one go rather than individually.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1423>
2026-02-04 11:18:54 +10:00
Peter Hutterer
ad89a83ae6 tablet: ignore the tablet tool name if it's a generic tool
libwacom has generic pens that are used for devices that don't have tool
ids. Let's ignore the names for those pens since they're just made up
names anyway.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1422>
2026-02-03 23:27:14 +00:00
Peter Hutterer
6d514ee6fa touchpad: add get_default_timeout for dwt and dwtp
I doubt this is really needed but our convention for all config options
is set/get/get_default so let's stick with that.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1421>
2026-02-03 13:01:59 +10:00
David Santamaría Rogado
6f79797308 test: recover external usb keyboard touchpad combo
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>
2026-02-02 09:52:08 +00:00
Michał Chojnowski
b58d5a165b tablet: fix handling of AttrPressureRange quirk
tablet_get_quirked_pressure_thresholds() is wrong:
the pressure thresholds for tip press and tip release are swapped around.
This seems to be a regression introduced in commit 4bc27543e9.

This prevents AttrPressureRange from working as intended for tablets,
and causes weird things to happen if it's set.
(For example, when pressure is in the range between
the intended release threshold and the intended press threshold,
the "pressed" status flip-flops between 0 and 1 every frame).

Fix that.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1420>
2026-02-02 08:41:24 +01:00
Peter Hutterer
fe1d44637f touchpad: add support for fast swipe when 3fg drag is enabled
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>
2026-02-02 06:44:48 +00:00
Peter Hutterer
5b7b8f1bb2 gestures: remove two empty helper functions
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1410>
2026-02-02 06:44:48 +00:00
Peter Hutterer
33b1d87c08 touchpad: don't disable on external mice until we see an event
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>
2026-01-28 00:43:37 +00:00
Peter Hutterer
89351c715a test: parametrize the external mouse test
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1414>
2026-01-28 00:43:37 +00:00
Peter Hutterer
e161abdc19 evdev: rename evdev_paired_keyboard to evdev_paired_device
We'll be using this struct for other devices than keyboards.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1414>
2026-01-28 00:43:36 +00:00
David Santamaría Rogado
47482bcd8b quirks: add more specific matches to actual quirks
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1418>
2026-01-27 00:43:51 +00:00
David Santamaría Rogado
307d2509a9 quirks: merge ibm with lenovo
ScrollPoint mouses as well IBM USB Travel Keyboard with Ultra Nav Mouse
are owned by Lenovo.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1419>
2026-01-27 00:19:16 +00:00
Peter Hutterer
86f19a0978 lua: install a timeout hook before any pcalls to prevent infinite loops
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>
2026-01-27 00:02:15 +00:00
Helga K
cc1499fbb3 quirks: Add quirk for Gigabyte Aorus 15BKF keyboard
This keyboard sits on the USB bus, so it's considered an external
keyboard by default. This commit changes that to internal
so that DWT detection on the laptop touchpad works.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1411>
2026-01-22 15:59:42 +04:00
Jens Peters
8854066e93 plugin: add an example for controlling a mouse with a tablet
This plugin controls a mouse/pointer from a tablet device. This
effectively hides stylus interactions and sends pointer events
instead. In other words: mouse emulation for tablets, implemented
by (remote) controlling a mouse device. This allows using a
tablet stylus as a mouse replacement without tablet limitations
from compositors or clients. Note that axis usually needed for
drawing (like pressure, tilt or distance) are no longer emitted
when this plugin is active and a mouse is connected. When no
mouse is connected, this plugin doesn't change tablet events,
thus the stylus works like a normal stylus.

Follow up from https://gitlab.freedesktop.org/libinput/libinput/-/issues/1195

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1412>
2026-01-21 08:44:13 +00:00
Peter Hutterer
074a6f57b8 test: fix some comments for accuracy
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1413>
2026-01-20 14:59:02 +10:00
Peter Hutterer
9f096b0403 test: move two helper functions into the only caller
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1413>
2026-01-20 14:59:02 +10:00
Peter Hutterer
328b9a8a32 test: fix the gesture hold cancel test
This didn't actually check for the cancellation of the gesture, so let's
add that.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1413>
2026-01-20 14:59:02 +10:00
Peter Hutterer
7ff2326efb test: change the gesture state color to normal yellow
The current color is unreadable on my screens and since no-one else
really looks at this much, let's change it for my benefit.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1413>
2026-01-20 14:59:02 +10:00
Peter Hutterer
6bca272629 test: parametrize a gesture test
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1413>
2026-01-20 14:59:02 +10:00
Peter Hutterer
00e568f43a test: correct a copy/pasted comment
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1413>
2026-01-20 13:14:24 +10:00
Peter Hutterer
13405e4b8c test: add missing BTN_TOOL_QUINTTAP to the acer hawaii test device
This recording comes from
https://bugs.freedesktop.org/show_bug.cgi?id=99140 and it's set there so
this si presumably a copy/paste issue.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1413>
2026-01-20 11:49:58 +10:00
Peter Hutterer
bee28a7e53 test: remove a leftover etrace()
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1413>
2026-01-20 11:49:58 +10:00
Peter Hutterer
dee2d38476 Add libinput_tablet_tool_get_name() for the tool's specific name
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>
2026-01-14 16:44:01 +10:00
Peter Hutterer
7d19cb5f40 CI: rebuild to pick up newer libwacom on Fedora 43
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1399>
2026-01-14 09:27:28 +10:00
Peter Hutterer
21ac8568d5 CI: temporarily drop FreeBSD
14.2 is 404 so we cannot rebuild any images and,
14.3 has a bug that blocks it from building images:
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=292375

So let's disable BSD until the bug is fixed.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1409>
2026-01-13 22:42:07 +00:00
Peter Hutterer
6b4d1905b6 plugin: always disable wheel debouncing on request
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>
2026-01-13 21:52:52 +00:00
Peter Hutterer
005a3e5622 test: remove a leftover etrace()
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1408>
2026-01-13 21:52:52 +00:00
David Santamaría Rogado
2772863af0 quirks: separate logitech quirks
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1407>
2026-01-13 01:50:51 +00:00
David Santamaría Rogado
47312e99d8 quirks: wipe HP Elite x2 G3 keyboard and touchpad
Actually not needed using internal approach.

Keyboard is ps2 wired in pogo pins and touchpad is usb, both internal by
default so dwt is in effect.

If tablet side buttons are also within ps2, they are not going to be
disabled as chassis is detachable.

Tablet mode switch untouched as is unclear if actual kernels play nice
with it.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1406>
2026-01-13 01:53:28 +01:00
David Santamaría Rogado
24ac440ecc quirks: add edit warning where missing
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1405>
2026-01-13 01:00:19 +01:00
David Santamaría Rogado
0110512b3e quirks: huawei better use pn instead pvr
Huawei MateBook X 2020 used M1010 product version but is used within
different Matebook X over the years.

Use EUL-WX9 product name instead.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1403>
2026-01-12 03:49:00 +01:00
David Santamaría Rogado
605abf2f37 quirks: normalize dmi matches
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1403>
2026-01-12 03:49:00 +01:00
David Santamaría Rogado
9a036bec30 test: set usb touchpad as internal
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>
2026-01-10 23:33:41 +01:00
Peter Hutterer
731d4452c3 meson: revamp the debug build detection for the builddir lookup
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>
2026-01-10 10:39:21 +00:00
David Santamaría Rogado
48e367e841 quirks: missing matches
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1402>
2026-01-10 10:23:19 +00:00
David Santamaría Rogado
1e9b81f75d quirks: refactor pixart touchpads
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1401>
2026-01-09 18:46:40 +01:00
David Santamaría Rogado
02b495e790 quirks: internal integration for lenovo detachable
These are quirks needed for Lenovo detachable devices by setting the
keyboard as internal to enable DWT and act as if it's a laptop.

Here we try to cover all the ideapad ones.

Also remove a quirk in Chicony that sets the touchpad below to enable
DWT, prefer to set the keyboard as internal as touchpad position is
intended for external ones like the input device we also move to the
bottom in Lenovo to have all pure input device quirks in one place.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1389>
2026-01-09 02:44:11 +00:00
Peter Hutterer
822a6d9365 tools: make the touchpad-pressure thresholds interactive
Easier to play around with than having to re-start with different
commandline arguments all the time.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1394>
2026-01-09 02:21:13 +00:00
Peter Hutterer
49624ace16 tools: use box-drawing characters for the table in touchpad-pressure
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1394>
2026-01-09 02:21:13 +00:00
Peter Hutterer
82cbbdab78 test: add (a broken) test for a second range config
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>
2026-01-09 02:01:14 +00:00
Peter Hutterer
47c7bd934a test: fix the multiple-tablet-pressure-range test
The previous test was incomplete, add support for setting pressure
ranges and generally expand and tighten up the test case so it tests
more specficially for the expected events.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1397>
2026-01-09 02:01:14 +00:00
Peter Hutterer
ef1ee837e4 test: allow overriding any axis value
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>
2026-01-09 01:47:13 +00:00
Peter Hutterer
c8e0312195 test: don't assign -1/-1 to x/y on proximity out
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>
2026-01-09 01:47:13 +00:00
Peter Hutterer
c9e175a507 test: correct overriding ABS_MISC in litest event frames
This still requires LITEST_AUTO_ASSIGN for that value in the test
devices (which no device currently sets) but meanwhile: not scaling
ABS_MISC into a magic range is the correct thing to do.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1398>
2026-01-09 01:47:12 +00:00
David Santamaría Rogado
d5110e1e68 quirks: acer add detachable keyboards
Cover Acer detachable keyboards used in Switch tablet devices to set
them internal and allow DWT.

Move one of them from chicony using the below method.

While at it change the match for internal keyboard in Acer Spin 5 to
rely of bus and type and add ':' before svn dmi match.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1392>
2026-01-06 22:41:37 +00:00
David Santamaría Rogado
130f95fd43 quirks: rework minisforum keyboard and add one
Use ids for Minisforum V3 and remove dmi match.

Also add Minisforum V3 SE one.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1395>
2026-01-06 13:58:57 +01:00
David Santamaría Rogado
b60416083e quirks: rework tablet mode using chassis type
Don't disable inputs for detachable and tablet devices, they are
physically unplugged from their input devices but tend to have buttons
as internal keyboard in the tablet part that must work always. We know
what kind of device is using the Chassis Type DMI value.

Also remove specific device quirks now covered by the chassis type.

Finally refactor some Lenovo devices using this quirk and redefine Dell
2-in-1 with this quirk using chassis type.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1390>
2026-01-05 04:44:41 +00:00
Peter Hutterer
58228f12f0 tools: fix the man page for the libinput-test command
The way we run this, the feature is appended to the libinput-test
command so this resulted in trying to execute libinput
libinput-test-libinput-test-suite.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1384>
2026-01-05 01:53:41 +00:00
Peter Hutterer
b48ce4c5be test: fix --help output for --filter-deviceless
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1384>
2026-01-05 01:53:41 +00:00
Peter Hutterer
6c2b9dcbde meson.build: add a summary for the test options
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1384>
2026-01-05 01:53:41 +00:00
Peter Hutterer
1d4ce84746 test: only use the quirks srcdir if we have a builddir
Same approach as we already do for other constants though note the
builddir_lookup() hack only works for release builds.

Closes #1230

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1384>
2026-01-05 01:53:41 +00:00
David Santamaría Rogado
08a8e0cc38 quirks: add missing match in synaptic touchpad
Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1391>
2026-01-02 06:07:28 +01:00
David Santamaría Rogado
83966ee306 quirks: remove now not needed entries
The recently added ITE usb keyboard and pressure touchpad entries makes
them unnecessary.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1383>
2025-12-23 21:06:27 +01:00
David Santamaría Rogado
56eec4afca quirks: add another lenovo haptic touchpad quirk
Used at least in another more Lenovo model that the one in the comment
where is actually.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1383>
2025-12-23 20:03:05 +01:00
David Santamaría Rogado
a525b30326 quirks: add Lenovo touchpad quirk in a generic way
Matching in vendor and product covers many models as possible.

01E8 product is always haptic.

01E0 can be or not haptic, leave it outside this and mantain it per
system model. When the kernel detects haptic touchpads the ones that
cannot be differenciated won't need to have quirk neither.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1383>
2025-12-23 18:27:53 +01:00
David Santamaría Rogado
8901ddf354 quirks: define generic quirks for ITE
Actual quirk in ITE vendor changed for a more generic one.
This is a step prior to cleanup other quirks.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1383>
2025-12-23 15:22:30 +01:00
David Santamaría Rogado
3cac03c8b2 quirks: Remove Vaio quirks file
The only rule is already defined for the touchpad in it's vendor file.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1386>
2025-12-22 23:35:05 +00:00
David Santamaría Rogado
3a54526d03 quirks: Move Synaptics touchpad to Hanticks
Synaptics 0911:5288 Touchpad really is a Hantick one, move it.

Also change it to rely on bus and ids because name can vary.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1381>
2025-12-22 22:20:18 +00:00
David Santamaría Rogado
23cd0408cc quirks: HP 14-fh0xxx just match internal touchpad
Apply ModelTabletModeNoSuspend just for internal touchpad no matter what
model is.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1388>
2025-12-22 00:01:34 +01:00
Peter Hutterer
0412fb3d44 pad: fix missing newline for mode group error messages
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1380>
2025-12-17 14:37:59 +10:00
David Santamaría Rogado
a376fe366c quirks: HP 14-fh0xxx rely on bus, ids and type
Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1378>
2025-12-16 21:52:31 +01:00
David Santamaría Rogado
9a07784451 quirks: Sort HP entries alphabetically
Also remove generic HP Haptics Touchpad CFD2 moved to Synaptics.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1378>
2025-12-16 21:51:53 +01:00
David Santamaría Rogado
3cf723451f quirks: Add generic Synaptics quirk found in HP ones
This quirk is a generic one for all the HP laptops with haptic touchpad
so makes more sense here because we are applying it dmi independent
being more difficult to track this change if the touchpad became used in
other vendors.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1378>
2025-12-16 16:35:22 +01:00
Peter Hutterer
2d3e47290c quirks: add a quirk for the RazerBlade182025 keyboard
Generated by tools/razer-quirks-lister.py

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1379>
2025-12-16 16:54:18 +10:00
Peter Hutterer
5bd7f93c16 doc/user: add a graph of how different contexts work
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1376>
2025-12-12 04:29:13 +00:00
Peter Hutterer
a202ed6115 Use a newtype usec_t for timestamps for better type-safety
This avoids mixing up milliseconds and usec, both by failing if
we're providing just a number somewhere we expect usecs and also
by making the API blindingly obvious that we're in usecs now.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1373>
2025-12-12 04:15:15 +00:00
Peter Hutterer
c0c809aaa1 util: fix documentation issues for newtypes
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1373>
2025-12-12 04:15:15 +00:00
Peter Hutterer
e8dfc3bfd6 util: make the newtype comparision functions return bool
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1373>
2025-12-12 04:15:15 +00:00
Sicelo A. Mhlongo
b3f7b4b1ea evdev: add support for SW_KEYPAD_SLIDE
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>
2025-12-11 13:28:41 +02:00
Peter Hutterer
0285001272 touchpad: make the dwt/dwtp timeout inclusive min/max
This makes it easier in callers that don't really differ between
inclusive and exclusive and makes the visualization in UIs a bit
nicer to look at too.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1377>
2025-12-10 03:07:36 +00:00
Peter Hutterer
bde6d07d57 quirks: replace ModelPressurepad with setting INPUT_PROP_PRESSUREPAD
This is the more generic approach and doesn't require us to have any
specific implementation in libinput itself.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1374>
2025-12-09 06:07:01 +00:00
Peter Hutterer
1b4dbb9087 doc/user: minor update to the forcepad/pressurepad documentation
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1374>
2025-12-09 06:07:01 +00:00
Peter Hutterer
d5d38b2ed1 doc/user: fix two typos in ref anchors
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1374>
2025-12-09 06:07:01 +00:00
Peter Hutterer
38b5c2e0cc touchpad: add configurable timeouts to disable-while-trackpointing
Same motivation as in commit
"touchpad: add configurable timeouts to disable-while-typing"

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1372>
2025-12-02 09:24:15 +10:00
Peter Hutterer
20851b5020 touchpad: add configurable timeouts to disable-while-typing
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>
2025-12-02 09:24:15 +10:00
Peter Hutterer
2003ab3aef test: rename a dwt test for better clarity
This is the "short-timeout after a single key press" dwt test so let's
rename it that way

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1372>
2025-12-02 09:20:08 +10:00
Peter Hutterer
4bb6a31894 doc: fix a few miss-hyphenated disable-while-typing comments
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1372>
2025-12-02 09:20:08 +10:00
Peter Hutterer
db6a04665c touchpad: use INPUT_PROP_PRESSUREPAD as signal it's a pressurepad
Because, well, it says so on the box now. No more quirks, hopefully!

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1359>
2025-12-01 21:39:11 +00:00
Peter Hutterer
7621edab05 include: sync headers with kernel 6.18
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1359>
2025-12-01 21:39:11 +00:00
Peter Hutterer
39aea2a8d6 test: silence a valgrind warning
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1370>
2025-11-27 09:32:13 +10:00
Peter Hutterer
7e8298e9ec tablet: when destroying a tablet, unlink the tablet tools
If a caller holds a ref to a tablet tool when the device is
destroyed, the tool didn't get removed from the tablet->tool_list.

Later on tool unref the list_remove() would try to reset the pointers
but the list head was long since freed, causing an invalid write.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1370>
2025-11-27 09:26:54 +10:00
Peter Hutterer
49d9528bdf tablet: after three valid prox out events, unload the forced prox plugin
Once we receive three valid proximity out events for the pen, unload the
plugin that generates forced proximity in events for tablets that
don't send BTN_TOOL_PEN.

Closes #1222

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1370>
2025-11-26 10:55:03 +10:00
Peter Hutterer
1e8901d009 tablet: only apply eraser button settings if we have a device
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>
2025-11-26 10:54:47 +10:00
Peter Hutterer
a6ad084280 tablet: return the wanted eraser button mode/button from the config
This matches our behavior for other settings - always return the
user-configured setting from the configuration API, not the current
setting (which may be delayed until the device is in a netural state).

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1370>
2025-11-26 10:32:18 +10:00
Peter Hutterer
11b97edcdc libinput 1.30.0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2025-11-25 13:40:43 +10:00
Peter Hutterer
c2f9ffe17e doc/user: drop references to the touchpad-edge-detector
We've had libinput measure touchpad-size for 5 years now, let's refer
only to that.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1368>
2025-11-24 14:29:56 +10:00
Peter Hutterer
21e3a76bf5 libinput 1.29.902 2025-11-18 12:29:32 +10:00
Peter Hutterer
9461d1a9a1 Revert "lua: drop compatibility to 5.1 to allow for luajit"
While luajit seems to be the most popular (and fastest) lua
implementation for higher-level implementations, at the system level
it is relatively unused. Lua 5.4 on the other hand is used by other
system-level components like wireplumber and RPM. In the latter case
this means that lua is already available on every rpm-based distro
without further dependencies.

The performance of 5.4 seems to be acceptable and while luajit may be
faster the extra dependency requires more maintenance. Let's only expose
ourselves to that if absolutely needed.

This is not a strict revert because the code has changed a bit since
with several bugfixes deployed on top.

This reverts commit 2723cadaeb.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1366>
2025-11-18 01:46:53 +00:00
Peter Hutterer
a595f0bd48 lua: export _VERSION so plugins can check the lua version
Since we only support one version this is not very informative but let's
include this now in case we ever need it in the future.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1365>
2025-11-17 16:48:35 +10:00
David Senoner
32ed3060f9 meson.build: use absolute path for callouts in udev rules
Udev rules can be put in many different directories to be found by udev
(see link #1). The callouts can be put only in one specific directory
if you want them to be found by using a relative path (only in
UDEV_LIBEXECDIR, see link #2). By passing the absolute path to the rule
you can make sure the callout will always be found.

Link 1: https://man7.org/linux/man-pages/man7/udev.7.html
Link 2: https://github.com/systemd/systemd/blob/main/src/udev/udev-spawn.c#L289

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1364>
2025-11-12 07:49:18 +01:00
Yinon Burgansky
a12dc6eba3 filter: differentiate scroll wheel from button scrolling to fix wheel speed
Commit 94b7836456 ("filter: support accelerating high-resolution
scroll wheel events") introduced a regression where high-res scroll
wheel events were incorrectly normalized by DPI. Mice with non-default
DPI (e.g., Logitech G502 at 2400 DPI) had their scroll wheel speed
reduced by the DPI ratio (1000/2400), resulting in 2-3x slower
scrolling.

The "noop" filter functions were actually performing DPI normalization
or applying a constant acceleration factor, which is appropriate for
button scrolling but incorrect for scroll wheels that have their own
units.

Add a filter_scroll_type enum (CONTINOUS, WHEEL, FINGER to match the
public events) passed through the filter_scroll interface. Update all
filter implementations to skip acceleration and normalization for wheel
events while maintaining existing behavior for button scrolling and
touchpad scrolling.

The custom acceleration profile continues to accelerate high-res wheel
events as designed.

Fixes: 94b7836456 ("filter: support accelerating high-resolution scroll wheel events")

Closes: #1212

Signed-off-by: Yinon Burgansky <yinonburgansky@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1363>
2025-11-11 14:43:41 +10:00
Marien Zwart
f6caae2289 quirks: add quirk for MX Master 4
The scrollwheels are similar to the MX Master 3, and need the same
quirks: the horizontal wheel events are inverted (it scrolls "naturally"
by default while the horizontal scrollwheel direction is "traditional"),
and middle-clicking without scrolling is very difficult with high-res
scroll events (from the hid_logitech_hidpp kernel module) enabled.

This adds the device ID seen through Bluetooth, which seems to be the
only one we can add a quirk for:

- When connected using the Bolt receiver, there is no separate device ID
  for the mouse (just the same 046d:c548 ID for the receiver already
  documented as supporting multiple mice).

- When connected through USB, the mouse charges but does not provide HID
  events through USB (it can be used while charging but only by using a
  separate Bluetooth or Bolt connection for HID).

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1362>
2025-11-09 00:09:47 +00:00
Jan Hendrik Farr
20a3131947 quirks: add quirk for Google Chromebook Rull
Signed-off-by: Jan Hendrik Farr <kernel@jfarr.cc>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1360>
2025-11-08 23:53:49 +00:00
Marien Zwart
822e571272 doc: fix gitlab remote url
SSH to gitlab.freedesktop.org times out.
ssh.gitlab.freedesktop.org (copied from the Gitlab UI) works..

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1361>
2025-11-08 15:02:59 +11:00
Peter Hutterer
9c78f989fb CI: bump to Fedora 43 and Ubuntu 25.10
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1355>
2025-11-07 15:13:08 +00:00
Peter Hutterer
9b37ffd340 meson.build: fix indentation for the python files
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1357>
2025-11-06 23:46:42 +00:00
Peter Hutterer
b9a04e4d57 meson.build: export the plugin dir via pkgconfig
This is for the system-wide plugindir only - the only path where we'd
expect other packages to put plugins.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1357>
2025-11-06 23:46:42 +00:00
Peter Hutterer
4fd5fe9d30 Fix clang-tidy false positives
Array out of bounds complaints but it's a false positive where
clang-tidy makes up some event flow that cannot happen.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1358>
2025-11-06 23:31:27 +00:00
Peter Hutterer
941aa9f997 plugins: add an example for using a wheel to trigger button scrolling
See https://gitlab.freedesktop.org/libinput/libinput/-/issues/1206

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1356>
2025-11-06 23:18:43 +00:00
Peter Hutterer
b870abd2f3 libinput 1.29.901
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2025-11-04 11:58:29 +10:00
Peter Hutterer
ad6f580b6d lua: add select to the list of allowed functions
This function is safe (and was already documented) so let's make sure
it's available.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1354>
2025-11-04 00:27:15 +00:00
Peter Hutterer
4ffd8ab544 lua: fix the event type/code loops - EV_MAX/ABS_MAX is inclusive
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1354>
2025-11-04 00:27:15 +00:00
Peter Hutterer
eac44529d8 lua: return an empty table as device info after device removal
As the documentation already promises.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1354>
2025-11-04 00:27:14 +00:00
Peter Hutterer
4fe3225050 lua: remove the unpack global function
Looks like 5.1 and later has unpack as table.unpack().

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1354>
2025-11-04 00:27:14 +00:00
Peter Hutterer
45878c3aac lua: fix superfluous comma
Not sure how this compiled but whoah, definitely not supposed to be
there.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1354>
2025-11-04 00:27:14 +00:00
Peter Hutterer
f0d8002255 plugins: fix some minor issues with the example plugins
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1354>
2025-11-04 00:27:13 +00:00
Peter Hutterer
037c07d76f doc/user: fix a few issues with the Lua API documentation
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1354>
2025-11-04 00:27:13 +00:00
Peter Hutterer
1dcf630584 plugins: add an example plugin on how to reconfigure the Copilot key
As Microsoft has decreed, that key sends LEFTMETA + LEFTSHIFT + F23
(usually across multiple frames) and the then the same in reverse when
released.

xkeyboard-config 2.44 maps this sequence by default to XF86Assistant but
for the use-cases where this does not work reshuffling the whole event
sequence is the best approach and that can easily be done with a plugin.

Note that this is the minimum effort plugin - it works for one
keyboard at at time (duplicate the plugin if two keyboards are needed,
or remove the vid/pid check) and it does *not* intercept the meta/shift
key presses and delay them, it simply releases them on F23 and then
replays the new sequence. Good enough for an example plugin.

Example sequence produces shift + a on press and releases a + shift on
release. Holding the key will thus produce AAAAAAAAA which is an
excellent summary of how this key was designed.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1352>
2025-11-03 03:57:00 +00:00
Peter Hutterer
eb01a4e73f plugins: add meson option to autoload plugins
Add an option to enable autoloading plugins from the default paths.
This makes testing and adoption for new users easier as they can (if
necessary) rebuild libinput with that option enabled instead of having
to wait for the compositor stack to update.

Autoloading will only use the default paths (/etc and /usr/lib) and will
only happen if the client does not modify those paths since that implies
the client wants to load plugins themselves. A client that adds a plugin
path but doesn't load the plugins is considered buggy anyway.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1347>
2025-10-31 05:25:29 +00:00
Peter Hutterer
f27fbdfa53 meson.build: change set10 to set
Follow-up to cfec80582e ("meson.build: change from config.set10() and #if to config.set() and #ifdef")
which was parallel to 9e37bc0cfa and the latter didn't get updated.

Fixes: 9e37bc0cfa ("plugins: add support for lua plugins to change evdev event streams")
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1347>
2025-10-31 05:25:29 +00:00
Jan Hendrik Farr
07659db3d9 quirks: add quirk for Google Chromebook Roric
Signed-off-by: Jan Hendrik Farr <kernel@jfarr.cc>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1353>
2025-10-30 13:40:59 +01:00
Peter Hutterer
f18bf988f7 lua: drop the log global in favor of libinput:log_*
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>
2025-10-30 13:12:50 +10:00
Peter Hutterer
6b9dbc2a25 lua: remove the inject_frame API
Injecting frame was the first implementation of adding event frames but
it has since effectively been replaced by append/prepend_frame which are
more predictable and easier to support.

In the Lua API injecting frames was only possible within the timer and
the only real use-case for this is to inject events that are then also
seen by other plugins. But that can be achieved by simply ordering the
plugin before the other plugins and using the append/prepend approach.

Until we have a real use-case for injecting events let's remove the API
so we don't lock ourselves into an API that may not do what it needs to
but needs to be supported for a long time.

Closes: #1210
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1351>
2025-10-30 02:08:13 +00:00
Peter Hutterer
2784973b4d doc/user: update the lua plugin documentation
Some clarifications, some fixes, some reshuffling, overall somewhat
better.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1349>
2025-10-30 01:46:33 +00:00
Peter Hutterer
22dda5b154 doc: some updates to the plugin system docs
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1349>
2025-10-30 01:46:33 +00:00
Peter Hutterer
07a9161ef2 tools: add support for NO_COLOR/FORCE_COLOR
Environment variables to control whether the output should not have
color or must have color, regardless of the tty-ness of the output
stream.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1348>
2025-10-27 12:35:44 +10:00
Peter Hutterer
141f571aae tools: don't set the tool pressure range if we're using the default
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1340>
2025-10-24 01:55:25 +00:00
Peter Hutterer
48a3391f33 tablet: don't consider a 0.0-1.0 pressure range as configured range
A caller is likely to unconditionally call
libinput_tablet_tool_config_pressure_range_set() with whatever
values it has in its config storage. Those values will be 0 and 1 by
default, we should not take this as a sign that the tool has a pressure
range.

Setting a pressure range resets the automatic offset handling which we
definitely don't want to do for the default range.

Fixes: #1177
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1340>
2025-10-24 01:55:25 +00:00
Peter Hutterer
bda0c7478e tablet: when configuring a user-defined pressure range, zero the offset
When a user configures a pressure range, the tool would get locked into
the current offset even if that offset was still pending. For example, a
sequence of

- tool in-prox with pressure 50%
- libinput_tablet_tool_config_pressure_range_set(tool, 0.0, 0.9)
- tool out-of-prox, tool-in-prox
- libinput applies the tool config, tool now has a configured range,
  has_offset = true
- tool out-of-prox, tool-in-prox
- update_pressure_range() sees has_offset = true, scales the last offset
  (50%) to the actual offset.

Fix this by resetting the detected offset to zero when we shortcut the
heuristics. A user-defined pressure range should include the tool's
pressure offset anyway, the user knows this much better than our
heuristics.

Closes: 1177
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1340>
2025-10-24 01:55:25 +00:00
Peter Hutterer
66f2d121ee tablet: log the pressure offset's percentage once we detected it
Saying the offset is e.g. 15% is more informative to the user than a
vauge "we detected something".

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1340>
2025-10-24 01:55:25 +00:00
Peter Hutterer
60c5fdbc2f doc: fix wrong reference to the plugin system
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1345>
2025-10-24 01:34:52 +00:00
Yinon Burgansky
cc7dfccd22 filter: avoid division-by-zero when delta_time is zero in custom filter
delta_time can be zero when:
- the fallback acceleration function is used for multiple movement types
  (for example, pointer motion and wheel scrolling simultaneously)
- two different methods produce the same movement at the same time
  (for example, button-scrolling and wheel-scrolling)

Reusing the last delta_time is a graceful fallback even if there are
duplicate events or event-ordering bugs.

Signed-off-by: Yinon Burgansky <yinonburgansky@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1336>
2025-10-24 01:18:40 +00:00
Yinon Burgansky
94b7836456 filter: support accelerating high-resolution scroll wheel events
Dispatch high-resolution scroll wheel events through filter_dispatch_scroll
so they can be accelerated using the custom acceleration profile.

Low-resolution scroll wheel events are not accelerated to avoid zero
delta-time in the filter.

Signed-off-by: Yinon Burgansky <yinonburgansky@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1316>
2025-10-24 01:05:54 +00:00
Zephyr Lykos
2d4482e03d meson.build: remove useless meson version checks
meson version requirement is bumped to 0.64.0 since
9e37bc0cfa ("plugins: add support for lua plugins to change evdev event streams")

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1344>
2025-10-24 00:21:12 +00:00
Zephyr Lykos
607852e66d meson.build: mark executables with install_tag
install_tag is available since meson 0.60.0:
https://mesonbuild.com/Reference-manual_functions.html#executable_install_tag

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1344>
2025-10-24 00:21:12 +00:00
wangyafei
a60976c1d4 quirks: add quirks for Dell laptop with Sensel Touchpad.
This touchpad is a pressure pad and needs the pressure
handling disable.

Signed-off-by: Charles Wang <charles.goodix@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1342>
2025-10-24 00:01:00 +00:00
José Expósito
aac0d3c2f8 quirks: Avoid accidental scroll for Logitech MX Master 2S
Similar to the MX Master 3, this mouse can send scroll events when the
wheel is pressed.

Add the "ModelScrollOnMiddleClick" quirk to avoid it.

Closes: https://gitlab.freedesktop.org/libinput/libinput/-/issues/1181
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1343>
2025-10-23 21:51:36 +00:00
José Expósito
327db95a7c doc/user: Document ModelScrollOnMiddleClick quirk
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1343>
2025-10-23 21:51:35 +00:00
José Expósito
4a705ba8d7 quirks: Rename QUIRK_MODEL_LOGITECH_MX_MASTER_3
The Logitech MX Master 2S also triggers accidental scroll events when
the mouse wheel is pressed [1].

Rename the "ModelLogitechMXMaster3" quirk to "ModelScrollOnMiddleClick"
to make it more generic.

[1] https://gitlab.freedesktop.org/libinput/libinput/-/issues/1181

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1343>
2025-10-23 21:51:35 +00:00
Peter Hutterer
d6e1f93812 plugins: update plugins for the current API
A few changes to the Lua API didn't get reflected in the example
plugins, let's update them.

Also included here is naming of all arguments, instead of _ use the
argument name even where unused. These are examples so being expressive
is more important than making any lua static checkers happy.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1339>
2025-10-23 13:28:16 +00:00
Peter Hutterer
dd3f931481 plugins: rename the flags to libinput_plugin_system_flags
"libinput_plugins_flags" is bound to be annoying to approximately
everyone who'll ever have to use them so let's rename this while we
still can. Renamed to libinput_plugin_system_flags to leave the
namespace open for a possible future libinput_plugin_flags that works
on individual plugins.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1337>
2025-10-23 13:13:01 +00:00
Peter Hutterer
d1720d351d meson.build: bump to 1.29.900
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1338>
2025-10-23 00:06:09 +00:00
Marge Yang
fcb5dfe515 quirks: add Dell laptop touchpad quirks
This touchpad is a pressure pad.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1335>
2025-10-21 17:25:13 +08:00
Peter Hutterer
43c7644f01 quirks: add a quirk for the RazerBlade142025 keyboard
Generated by tools/razer-quirks-lister.py

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1334>
2025-10-21 04:56:12 +00:00
Peter Hutterer
3307341ebf CI: drop the ci-fairy check-mr job
The only thing this checked was the checkbox for allowing maintainers to
edit the MR. Changed permissions checks now fail this job but luckily
the setting it checked has been the default for years anyway so we can
drop it.

https://gitlab.freedesktop.org/freedesktop/ci-templates/-/issues/81

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1332>
2025-10-20 12:35:51 +10:00
Peter Hutterer
4b1bae3f8c tools/replay: rmdir, not unlink for directories
And if the directory happens to be nonempty, well, maybe anyother
libinput reply is running so let's ignore that.

Fixes: cdfe34f62a ("replay: use the runtime quirks for our replay quirks")
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1330>
2025-10-20 02:01:23 +00:00
Peter Hutterer
f9977dba9c tools/replay: set the multiprocessing start method to fork
Python 3.14 has changed from fork to forkserver[1] which causes
libinput replay to fail with the following error when starting the
subprocesses:
   ValueError: ctypes objects containing pointers cannot be pickled

This is caused by the libevdev device being passed to the sub process.
A more proper fix may be to only initialize the device in the subprocess
and then signal the process to start replaying. But meanwhile, switching
back to fork will do.

[1] https://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methods

Closes #1204

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1330>
2025-10-20 02:01:23 +00:00
Marge Yang
3725bb0b93 quirks: add Dell laptop touchpad quirks
This touchpad is a pressure pad.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1329>
2025-10-16 06:13:34 +00:00
Cyrus Lien
d19f95ec21 quirks: add quirks for Dell Pro Rugged tablets for volume keys.
Close #1205

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1331>
2025-10-16 13:42:37 +08:00
Peter Hutterer
533d5f6ee1 lua: ignore unsupported event codes in modified frames
If a plugin adds events to an event frame that are not supported by the
target device we may eventually dereference a null pointer (for ABS_*
events) or, possibly, use an OOB index access (for buttons or keys).
Let's filter out any events that the device doesn't support immediately.

Fixes #1202

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1324>
2025-10-14 06:08:37 +00:00
Peter Hutterer
3250686e70 lua: add missing lua_pop for the evdev frame
Where a plugin returns a table to be processed we never popped that
table from the stack. Eventually this would lead to the plugin failing
as the stack size is exceeded.

Fixes #1195

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1323>
2025-10-14 05:53:06 +00:00
Sertonix
aa7d58005e Fix format strings on 32-bit with 64-bit time_t
This fixes a segfault when running the test suite on ppc musl

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1318>
2025-10-14 05:40:19 +00:00
José Expósito
5df3eb8527 quirks: add Dell 14 Premium touchpad quirks
This touchpad is a pressure pad.

Closes: https://gitlab.freedesktop.org/libinput/libinput/-/issues/1185
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1320>
2025-10-13 06:53:31 +00:00
José Expósito
185e1bd824 quirks: add Dell 16 Premium touchpad quirks
This touchpad is a pressure pad.

Closes: https://gitlab.freedesktop.org/libinput/libinput/-/issues/1198
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1320>
2025-10-13 06:53:31 +00:00
Daniel Brackenbury
195c39b21a quirks: revert Nulea USB quirk due to ID conflict
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1325>
2025-10-13 06:35:42 +00:00
Peter Hutterer
6dcb47185e triage-policies: add a bugbot hook for re-closing a bug
Having the bugbot comment on re-closing the same bug is friendlier than
just closing it, even if we explained it before already.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1321>
2025-10-13 06:21:26 +00:00
Daniel Brackenbury
e07e138809 quirks: add vendor quirks for Nulea M501 thumb trackball
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1322>
2025-10-09 18:39:49 -04:00
José Expósito
a4ea1e2d97 libinput: Add libinput_event_gesture forward declaration
Closes: https://gitlab.freedesktop.org/libinput/libinput/-/issues/1189
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1319>
2025-10-07 00:31:38 +00:00
Dan Forest
772c1f5ebb quirks: add quirk for Asus ROG Flow Z13 2025 (GZ302EA) keyboard
Keyboard must be detected as internal in order for "disable touchpad while typing" to work as expected.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1317>
2025-10-03 15:04:37 +00:00
Mingcong Bai
95281de7e4 quirks: lower AttrTrackpointMultiplier for Lenovo ThinkPad E16 Gen 3
Lower TrackPoint multiplier for Lenovo ThinkPad E16 Gen 3 to match closer
to Windows defaults. The default multiplier was way too quick.

Signed-off-by: Mingcong Bai <jeffbai@aosc.io>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1315>
2025-09-06 17:17:34 +08:00
José Expósito
32a9863507 quirks: Add quirks for the GPD MicroPC 2 touchpad
This laptop's touchpad has physical left, middle and right button, but
advertises itself as a clickpad.

Drop the incorrectly set INPUT_PROP_BUTTONPAD property.

Closes: https://gitlab.freedesktop.org/libinput/libinput/-/issues/1182

Signed-off-by: José Expósito <jose.exposito89@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1314>
2025-09-04 09:57:26 +02:00
José Expósito
a0a6ff2777 plugin/wheel: Use libinput_device_is_virtual()
Use this function instead of evdev_device_is_virtual().

Signed-off-by: José Expósito <jose.exposito89@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1313>
2025-09-02 10:59:31 +02:00
Peter Hutterer
60bcbb6c88 quirks: change VM devices to AttrIsVirtual
These devices had the debouncing disabled via a model quirk but
really they are virtual devices and should have all hw-specific
processing disabled - on the assumption that this will be handled
in the host. See also e.g. commit 5d23794d53 ("tablet: disable
smoothing for uinput devices").

Closes #1175

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1308>
2025-09-02 07:44:11 +00:00
David Santamaría Rogado
4f6c741570 quirks: HP OmniBook Ultra Flip Laptop 14-fh0xxx
HP OmniBook Ultra Flip Laptop 14-fh0xxx manages itself keyboard and
touchpad deactivation when HP's custom Intel ISH firmware is installed
in the system. Without the custom firmware tablet-mode switch isn't
exposed so there is no way we don't need this.
More detailed information in the file comment.

Signed-off-by: David Santamaría Rogado <howl.nsp@gmail.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1311>
2025-09-02 07:23:22 +00:00
José Expósito
69ed729e80 quirks: don't disable the keyboard on the Dell Latitude 7285
Closes: https://gitlab.freedesktop.org/libinput/libinput/-/issues/1180
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1312>
2025-09-02 09:05:30 +02:00
Peter Hutterer
f3f8e8ef6c plugin: ensure prox out for a forced proximity tool if the tool changes
A device may send axis events while the tool is out of proximity,
causing our plugin to force a proximity in for the pen. If the tool then
sends a proximity event for a different tool we ended up with two tools
in proximity.

The sequence in #1171 shows this:

  - evdev:
    - [  1, 499608,   3,  27,       0] # EV_ABS / ABS_TILT_Y                0 (+30)
    - [  1, 499608,   0,   0,       0] # ------------ SYN_REPORT (0) ---------- +0ms
  - evdev:
    - [  2, 199637,   1, 321,       1] # EV_KEY / BTN_TOOL_RUBBER           1
    - [  2, 199637,   4,   4,      30] # EV_MSC / MSC_SCAN                 30 (obfuscated)
    - [  2, 199637,   1, 330,       1] # EV_KEY / BTN_TOUCH                 1
    - [  2, 199637,   3,   0,     910] # EV_ABS / ABS_X                   910 (+246)
    - [  2, 199637,   3,   1,    8736] # EV_ABS / ABS_Y                  8736 (-105)
    - [  2, 199637,   3,  27,     -25] # EV_ABS / ABS_TILT_Y              -25 (-25)
    - [  2, 199637,   0,   0,       0] # ------------ SYN_REPORT (0) ---------- +700ms

Fix this by remembering that we forced the tool out of proximity so if
we see tool events for another tool we force the pen out of proximity
again.

This will have some interplay with the other tablet plugins but
hopefully none that affect real-world devices, e.g. forcing a proximity
out means the proximity out timer plugin gets disabled. Since devices
behave in unexpected manners anyway let's see if it affects a real-world
device.

Closes #1171

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1306>
2025-08-31 00:18:59 +00:00
Peter Hutterer
ce1112c263 plugin: remove the proximity timer callback after prox out events
One of the code paths was addressed in b2cd9c69a0 but this path was
missing.

Fixes: b2cd9c69a0 ("plugin: remove the event frame callbacks when disabling a plugin")
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1306>
2025-08-31 00:18:59 +00:00
Peter Hutterer
428a3299a8 plugin: don't initialize the debounce plugin on a virtual device
Effectively the same motivation as commit 5d23794d53 ("tablet: disable
smoothing for uinput devices") - virtual devices should not need
debouncing and if they do let's do the debouncing on the other end that
creates those devices.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1307>
2025-08-28 01:56:12 +00:00
Peter Hutterer
bdb51593fe quirks: add quirk for the RazerBlade162025 keyboard
Generated by tools/razer-quirks-lister.py

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1305>
2025-08-26 20:51:55 +00:00
Alexander Bruy
d9c9e0ff25 add quirk for TongFang GX4 (X4SP4NAL) touchpad
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1302>
2025-08-20 08:07:36 +00:00
Peter Hutterer
4d317eae17 plugin: reset the filtered frame after sending it with buttons
Our filtered frame (frame without any button events) that gets passed
down to here may include relative motion or other events. Once we use
that frame to prepend the button event we need to reset it so we don't
cause duplicate motion and/or events with zero delta timestamps.

With the the previous code we got two identical frames:

  42: event25: plugin button-debounce        - 0.360 EV_MSC           MSC_SCAN               30
  ... event25: plugin button-debounce        - 0.360 EV_KEY           BTN_RIGHT               1
  ... event25: plugin button-debounce        - 0.360 EV_REL           REL_X                  -7
  ... event25: plugin button-debounce        - 0.360 EV_REL           REL_Y                  -7
  ... event25: plugin button-debounce        - 0.360 ----------------- EV_SYN ----------------- +8ms
  ... Plugin:button-debounce - debounce state: DEBOUNCE_STATE_IS_UP → DEBOUNCE_EVENT_OTHERBUTTON → DEBOUNCE_STATE_IS_UP
  ... Plugin:button-debounce - debounce state: DEBOUNCE_STATE_IS_UP → DEBOUNCE_EVENT_PRESS → DEBOUNCE_STATE_IS_DOWN_WAITING
  ... event25: plugin evdev                  - 0.360 EV_MSC           MSC_SCAN               30
  ... event25: plugin evdev                  - 0.360 EV_REL           REL_X                  -7
  ... event25: plugin evdev                  - 0.360 EV_REL           REL_Y                  -7
  ... event25: plugin evdev                  - 0.360 EV_KEY           BTN_RIGHT               1
  ... event25: plugin evdev                  - 0.360 ----------------- EV_SYN ----------------- +0ms
  ... Queuing  event25  POINTER_MOTION               +0.000s	-7.00/ -7.00 ( -7.00/ -7.00)
  ... event25 - middlebutton state: MIDDLEBUTTON_IDLE → MIDDLEBUTTON_EVENT_R_DOWN → MIDDLEBUTTON_RIGHT_DOWN, rc 1
  ... event25: plugin evdev                  - 0.360 EV_MSC           MSC_SCAN               30
  ... event25: plugin evdev                  - 0.360 EV_REL           REL_X                  -7
  ... event25: plugin evdev                  - 0.360 EV_REL           REL_Y                  -7
  ... event25: plugin evdev                  - 0.360 EV_KEY           BTN_RIGHT               1
  ... event25: plugin evdev                  - 0.360 ----------------- EV_SYN ----------------- +0ms
  ... Queuing  event25  POINTER_MOTION               +0.000s	 -nan/  -nan ( -7.00/ -7.00)
 event25  POINTER_MOTION               +0.360s	-7.00/ -7.00 ( -7.00/ -7.00)
 event25  POINTER_MOTION            2  +0.360s	 -nan/  -nan ( -7.00/ -7.00)

The 0ms delta caused a -nan in the custom pointer accel but even without
that bug the pointer would've jumped more than it should.

Closes #1172

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1301>
2025-08-20 07:49:01 +00:00
Peter Hutterer
2f2bd357bc plugin: don't register the mouse-wheel plugin for passthrough devices
If a device is immediately set to PASSTHROUGH let's skip registering
this plugin for this device. We're not doing anything with the events
anyway.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1300>
2025-08-19 15:22:49 +10:00
Peter Hutterer
b2cd9c69a0 plugin: remove the event frame callbacks when disabling a plugin
In all cases we remove the device's handling from the plugin so let's
remove the event frame callback for this device.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1300>
2025-08-19 15:22:49 +10:00
Peter Hutterer
3ff1a2e24d plugin: when disabling wheel-debouncing set to the correct enum value
This isn't a boolean. Let's change the first enum value to something
truthy so any use as boolean is more likely to trigger test failures.

Fixes: 18992b2ec0 ("plugin: allow disabling the wheel debouncing feature")
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1300>
2025-08-19 15:22:49 +10:00
Peter Hutterer
e45cd2bc13 util: print nonchanged axis with a space instead of a *
When printing tablet events always print a '*' or ' ' suffix to ensure
the alignment of the next field matches. We're using a tab to align
after each field so if the string length doesn't match, our events may
print at different tab stops.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1299>
2025-08-18 23:11:03 +00:00
Peter Hutterer
537552480d plugin: expand the plugin name prefix to 22 chars
That's the longest name we have for our internal plugins so let's make
sure those align nicely for easier debugging.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1299>
2025-08-18 23:11:03 +00:00
Peter Hutterer
5abe051a9c doc/user: fixes and a TOC for the Configuration Options page
A typo fix, more links and a local TOC since we now have quite a few
options.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1296>
2025-08-12 15:20:12 +00:00
Peter Hutterer
9b58177a7e doc/user: add eraser buttons to the "Configuration Options" page
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1296>
2025-08-12 15:20:12 +00:00
Peter Hutterer
cdfe34f62a replay: use the runtime quirks for our replay quirks
Closes #1166

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1297>
2025-08-12 07:58:07 +00:00
Peter Hutterer
ce87da63ba quirks: add XDG_RUNTIME_DIR/libinput to the quirks directories
This allows tools like libinput-replay and the test suite to install
temporary quirks without having to mess with actual system-installed
files or directories.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1297>
2025-08-12 07:58:07 +00:00
Peter Hutterer
4e002383cf clang-tidy: fix WarningAsErrors option to actually work
Not a boolean, despite what one would immediately assume.

Closes #1168

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1298>
2025-08-11 15:27:35 +10:00
Peter Hutterer
17617a75c4 pad: add some extra asserts to shut up clang-tidy
For some reason clang-tidy believes that in the second iteration group
is set to NULL and causes a NULL-pointer dereference.

../src/evdev-tablet-pad.c:305:2: error: Access to field 'next' results in a dereference of a null pointer [clang-analyzer-core.NullDereference,-warnings-as-errors]
  305 |         list_for_each(group, &pad->modes.mode_group_list, link) {
      |         ^
../src/util-list.h:265:13: note: expanded from macro 'list_for_each'
  265 |              pos = list_first_entry_by_type(&pos->member, __typeof__(*pos), member))
      |                    ^
../src/util-list.h:202:2: note: expanded from macro 'list_first_entry_by_type'
  202 |         container_of((head)->next, container_type, member)
      |         ^

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1298>
2025-08-11 15:27:31 +10:00
Peter Hutterer
48a26f91c3 CI: change the wayland-web job to use rules
"only: ..." is deprecated and we should be using rules

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1294>
2025-08-08 09:18:22 +00:00
Peter Hutterer
c0519c3b5e Correct the @since tags for the new plugin functions
Fixes: d557a649fd ("Add a public plugin system to libinput")
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1295>
2025-08-08 05:06:04 +00:00
Nat Karmios
960df4d8b8 quirks: Ignore BTN_0 for Microsoft Surface Keyboard
Signed-off-by: Nat Karmios <nat@karmios.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1293>
2025-08-08 00:39:06 +01:00
Peter Hutterer
347ff90871 lua: implement support for disabling of features
Because our lua hooks don't expose the device-added callback we need to
cache any calls to disable a feature and then apply it quietly when the
device is actually added. Any other call can go straight through.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1249>
2025-08-07 10:23:30 +10:00
Peter Hutterer
5b2a723a02 touchpad: allow disabling palm detection altogether
Also a long-requested configuration option but it's difficult to expose
- depending on the touchpad we utilize different palm detection methods
and in theory may add to those at any time as we see fit.

Disabling it completely via a configuration option is only going to get
us more bug reports because *some* palm detection is likely desired on
most setups. So let's allow disabling it in a plugin and thus leave any
further palm detection code up to the plugin.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1249>
2025-08-07 10:23:30 +10:00
Peter Hutterer
afd3be9a99 touchpad: allow disabling the touchpad hysteresis
Over the years we had a few devices that required some special
hysteresis handling - all of it very customized to the device and not
upstreamable (or even implementable by upstream without the device).

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1249>
2025-08-07 10:23:30 +10:00
Peter Hutterer
2bb9c66cd7 touchpad: allow disabling the touchpad jumping cursor detection
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1249>
2025-08-07 10:23:30 +10:00
Peter Hutterer
18992b2ec0 plugin: allow disabling the wheel debouncing feature
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1249>
2025-08-07 10:23:30 +10:00
Peter Hutterer
cf52552eef plugin: allow disabling the button debouncing feature
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1249>
2025-08-07 10:21:59 +10:00
Peter Hutterer
7ac051ab41 plugin: add hooks to disable internal features
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1249>
2025-08-07 10:21:36 +10:00
Peter Hutterer
4f0b82800a plugins: remove two unused cleanup functions
Let's make clang tidy happy so at least one of us is.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1292>
2025-08-06 07:34:55 +00:00
Peter Hutterer
aa9d5bf630 util: silence two clang-tidy false positives
Both about the same complaint, somehow it is of the impression that
masks->mask can be an uninitialized value. The only place where we
allocate those is in _infmask_ensure_size() and they're set to zero
there.

libinput/src/util-bits.h:166:22: warning: The left operand of '&' is a garbage value [clang-analyzer-core.UndefinedBinaryOperatorResult]
  166 |         return !!(mask.mask & bit(bit));
      |                             ^
libinput/src/util-bits.h:444:2: note: Calling 'infmask_set_bit'
  444 |         infmask_set_bit(&m, mask);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~
libinput/src/util-bits.h:394:15: note: Calling 'infmask_bit_is_set'
  394 |         bool isset = infmask_bit_is_set(mask, bit);
      |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
libinput/src/util-bits.h:382:13: note: Field 'mask' is non-null
  382 |         if (!mask->mask || bit / bitmask_size() >= mask->nmasks)
      |                    ^
libinput/src/util-bits.h:382:6: note: Left side of '||' is false
  382 |         if (!mask->mask || bit / bitmask_size() >= mask->nmasks)
      |             ^
libinput/src/util-bits.h:382:2: note: Taking false branch
  382 |         if (!mask->mask || bit / bitmask_size() >= mask->nmasks)
      |         ^
libinput/src/util-bits.h:385:9: note: Uninitialized value stored to 'mask.mask'
  385 |         return bitmask_bit_is_set(mask->mask[bit / bitmask_size()], // NOLINT(core.UndefinedBinaryOperatorResult)
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  386 |                                   bit % bitmask_size());
      |                                   ~~~~~~~~~~~~~~~~~~~~~
libinput/src/util-bits.h:385:9: note: Calling 'bitmask_bit_is_set'
  385 |         return bitmask_bit_is_set(mask->mask[bit / bitmask_size()], // NOLINT(core.UndefinedBinaryOperatorResult)
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  386 |                                   bit % bitmask_size());
      |                                   ~~~~~~~~~~~~~~~~~~~~~
libinput/src/util-bits.h:166:22: note: The left operand of '&' is a garbage value
  166 |         return !!(mask.mask & bit(bit));
      |                   ~~~~~~~~~ ^

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1292>
2025-08-06 07:34:55 +00:00
Peter Hutterer
b831068fbb util: annotate that our mask cannot be NULL
Poor clang-tidy thinks that there's a code-path here that lets us
return with a NULL mask.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1292>
2025-08-06 07:34:55 +00:00
Peter Hutterer
a0d286741c touchpad: fix a clang-tidy warning
../src/evdev-mt-touchpad-buttons.c:1233:16: warning: Value stored to 'button' during its initialization is never read [clang-analyzer-deadcode.DeadStores]
 1233 |         evdev_usage_t button = evdev_usage_from_uint32_t(0);
      |                       ^~~~~~   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1292>
2025-08-06 07:34:54 +00:00
Peter Hutterer
5495511485 tools: move a clang-tidy silence back to where it needs to be
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1292>
2025-08-06 07:34:54 +00:00
Peter Hutterer
4ef50ee946 test: fix two clang-tidy dead store complaints
udev_device isn't used but we assign it for being auto-freed.

And color is overwritten immediately but it's better to have a known
good value for it anyway.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1292>
2025-08-06 07:34:54 +00:00
Peter Hutterer
a102269364 util: mark the various bitmask functions as nonnull
Might as well get a bit of compiler help here.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1292>
2025-08-06 07:34:54 +00:00
Peter Hutterer
2562c24f95 pad: don't assert when unable to find the mode group, just discard
Instead of a hard assert if we fail to find the mode group for the given
ring/dial/strip let's just log an error and discard the event.

I'm not sure this assert can be triggered in the current code base but
if it can an error message is going to be more useful to the user than
an assert.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1291>
2025-08-04 12:53:10 +10:00
Adam Sampson
47d4c563f4 evdev: remove duplicate sizeof
This looks like a copy-and-paste error. In practice it was harmless on
64-bit systems because evdev_event happens to be 64 bits long, but on
32-bit systems it would allocate too little memory.

Found by GCC 15 with _FORTIFY_SOURCE=3 on ia32.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1288>
2025-08-01 22:34:07 +00:00
Adam Sampson
931dad76a9 test: correct value type in atou64_test
This needs to be an unsigned 64-bit value, given the constants that are
stored in this field below; unsigned long is 32 bits on some platforms
(e.g. ia32).

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1288>
2025-08-01 22:34:07 +00:00
Matt Turner
7f3aa8058a test: Accept mkdir_p("/proc/foo") might return EACCES
... as it does under Gentoo's sandbox.

Fixes: 6770131e ("util: fix a memleak in mkdir_p")
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1289>
2025-08-01 11:11:31 -04:00
Peter Hutterer
c1d8d92b57 Drop evdev_frame_new_on_stack()
Was unused anwyay but also cannot work, returning an address to a frame
allocated on the stack is not a great idea...

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1192>
2025-08-01 16:49:00 +10:00
Peter Hutterer
2723cadaeb lua: drop compatibility to 5.1 to allow for luajit
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1192>
2025-08-01 16:49:00 +10:00
Peter Hutterer
9e37bc0cfa plugins: add support for lua plugins to change evdev event streams
This patch adds support for Lua scripts to modify evdev devices and
event frames before libinput sees those events.

Plugins in Lua are sandboxed and restricted in what they can do: no IO,
no network, not much of anything else.

A plugin is notified about a new device before libinput handles it and
it can thus modify that device (changes are passed through to our libevdev
context). A plugin can then also connect an evdev frame handler which
gives it access to the evdev frames before libinput processes them. The
example plugin included shows how to swap left/right mouse buttons:

    libinput:register({1})

    function frame(device, frame)
        for _, v in ipairs(frame.events) do
            if v.usage == evdev.BTN_RIGHT then
                v.usage = evdev.BTN_LEFT
            elseif v.usage == evdev.BTN_LEFT then
                v.usage = evdev.BTN_RIGHT
            end
        end
        return frame
    end

    function device_new(plugin, device)
        local usages = device:usages()
        if usages[evdev.BTN_LEFT] and usages[evdev.BTN_RIGHT] then
            device:connect("evdev-frame", frame)
        end
    end

    libinput:connect("new-evdev-device", device_new)

A few other example plugins are included in this patch

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1192>
2025-08-01 16:04:09 +10:00
Peter Hutterer
0c65b1069b test: allow creating a context with a custom plugindir
For runtime creation of plugins for testing

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1192>
2025-08-01 15:38:39 +10:00
Peter Hutterer
d557a649fd Add a public plugin system to libinput
This patch adds a new API for enabling public "plugins" in libinput, in
addition to the exisitng internal ones. The API is currently limited to
specifying which paths should be loaded and whether to load them.
Public plugins are static, they are loaded before the context is initialized
and do not update after that.

If plugins are to be loaded, libinput will then run through those paths,
look up files and pass them to (future) plugins to load the actual
files.

Our debugging tools have an --enable-plugins and
--disable-plugins option that load from the default data paths
(/etc/libinput/plugins and /usr/lib{64}/libinput/plugins) and from
the $builddir/plugins directory.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1192>
2025-08-01 15:38:39 +10:00
Peter Hutterer
d1dbbb7328 plugin: register plugins for the plugin-specific usages
The debounce, wheel/wheel-low-res, double-tool and eraser-button plugins can limit
themselves to a specific usage.

The mtdev plugin needs to pass each each event to mtdev and the proximity
timer plugin needs to get each event's timestamp so they cannot be
restricted.

The forced-tool could be restricted but effectively any event on the
devices it works on will have one of those usages set so there's no
point.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1271>
2025-08-01 14:29:44 +10:00
Peter Hutterer
3a86b6ea58 plugin: add evdev usage masks for plugins
This adds the ability for a plugin to announce the evdev usages it may
possibly care about. Only event frames that contain one or more of those
usages will be passed to the plugin. Ideally this is an optimization
over calling every plugin for every frame but that largely also depends
on what exactly the plugin does with each frame.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1271>
2025-08-01 14:29:44 +10:00
Peter Hutterer
f04b276ac1 util: add a helper struct for an evdev mask
Allows to keep track of a set of evdev masks, or at least the subset we
care about.

The EV_KEY range is split into two masks to save some memory. The future
use of this is for the plugins to use those masks and some of those will
set BTN_TOOL_PEN and friends. This would immediately create an 81 byte
mask of zeroes just to keep that one bit.

Splitting it into a key/btn mask with the latter starting at BTN_MISC
means we duplicate the infmask struct (2x16 bytes) but instead only use
8 bytes for the mask itself to keep the BTN_TOOL_PEN bits.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1271>
2025-08-01 14:29:44 +10:00
Peter Hutterer
d45f4493f1 util: add an infmask_t type for an infinitely-sized bitmask
Using the bitmask-size underneath but this mask can grow to any number
of bits requested. Notably, the sized of the mask is the nearest 4-byte
multiple for the highest bit ever set in the mask.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1271>
2025-08-01 14:29:44 +10:00
Peter Hutterer
4c4d5f33ee util: add bitmask_size() to return the size of a bitmask
This way we can theoretically change the bitmask to use a longer type in
the future.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1271>
2025-08-01 14:29:44 +10:00
Peter Hutterer
8336721dc0 test: fix the keycode obfuscation test
An earlier version of 73103a5c38 only obfuscated the plugin key codes,
not the "Queuing ..." message libinput itself uses. The test didn't get
updated when the queuing message was updated to obfuscate.

Fixes: 73103a5c38 ("plugin: always obfuscate keycodes")
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1284>
2025-08-01 04:02:57 +00:00
Peter Hutterer
6dfd72dc03 test: add litest_assert_strv_no_substring
To verify a strv does *not* include a given substring

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1284>
2025-08-01 04:02:57 +00:00
Peter Hutterer
ce85ee7d35 test: switch another test to use logcapture
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1284>
2025-08-01 04:02:57 +00:00
Peter Hutterer
d9a4667a14 test: track bug messages separately in log captures
Notably, this also tracks kernel bugs now as opposed to just other bugs.
It is up to tests checking for the expected message.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1284>
2025-08-01 04:02:57 +00:00
Peter Hutterer
465fce9128 test: don't run the check for lowres events if we don't have hires events
This test explicitly checks for devices only sending REL_WHEEL but *not*
REL_WHEEL_HI_RES. But that check only needs to run if the device has
the HI_RES axis.

The test device with REL_WHEEL_HI_RES disabled via quirk needs to be
special-cased since we cannot detect this in the test suite otherwise.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1284>
2025-08-01 04:02:57 +00:00
Peter Hutterer
68dbb98f04 clang-format: add litest_with_logcapture to foreach macros
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1284>
2025-08-01 04:02:56 +00:00
Peter Hutterer
a22883f7e2 CI: don't run the wayland-web job for marge
marge doesn't have sufficient permissions to trigger the pipeline, so
all we get is every trigger job failing. Let's disable this until it can
be figured out properly.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1287>
2025-08-01 03:46:22 +00:00
Peter Hutterer
7d59252643 quirks: minor cleanup to use attribute(cleanup)
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1285>
2025-08-01 02:19:15 +00:00
Peter Hutterer
59f0d8f647 tools/replay: improve the verbose output a bit
Make sure our SYN_REPORT line is indented correctly for multi-device
replay and match the output a bit closer to the one from libinput
record.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1286>
2025-08-01 11:24:06 +10:00
Peter Hutterer
936cee2242 libinput 1.29.0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2025-07-31 15:26:54 +10:00
Peter Hutterer
3ca34aa88a evdev: move the SYN_REPORT 1 filtering to the touchpad backend
In commit 9a9466b6a9 ("evdev: discard any frame with EV_SYN SYN_REPORT 1")
all frames with a SYN_REPORT 1 were discarded on the assumption of those
being key repeat frames. Unfortunately the kernel uses the same sequence
to simply mark *any* injected/emulated event, regardless of the cause. Key repeat
events are merely the most numerous ones but as shown in commit
7140f13d82 ("evdev: track KEY_SYSRQ frames and pass them even as repeat frames")
Alt+PrintScreen is also an emulated event.

Issue #1165 details another case: keyboards with n-key rollover can
exceed the kernel-internal event buffer, typically 8 events for devices
without EV_REL/EV_ABS. Those events will be broken up by the kernel into
multiple frames - once nevents == buffer_size the current state is
flushed as SYN_REPORT 1 frame. Then, if any more events are pending
those are flushed as SYN_REPORT 0 frame. In the case of exactly 8
events, the second frame is never present, so we cannot easily detect if
another one is coming.

Issue #1145 only affects us in the touchpad code, the rest of the
backends seem to (so far) be fine. So let's move the discarding of
SYN_REPORT 1 to the touchpad backend and leave the rest of the code
as-is.

This effectively
Reverts: 7140f13d82 ("evdev: track KEY_SYSRQ frames and pass them even as repeat frames")
Reverts: 9a9466b6a9 ("evdev: discard any frame with EV_SYN SYN_REPORT 1")

Closes #1165

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1282>
2025-07-31 00:50:30 +00:00
Peter Hutterer
96d1954dce tools: add missing AttrIsVirtual handling for listing quirks
If a device has AttrIsVirtual set in the quirks we'd abort() when trying
to list those quirks.

Fixes: efb4b6a3be ("evdev: detect virtual devices")
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1281>
2025-07-30 05:43:03 +00:00
Peter Hutterer
b8651d798c tools: add a debug-tablet-pad tool
A simple tool to check the evdev and libinput events from a tablet pad.
This is near-identical to the existing debug-tablet tool but adjusted
for tablet pad events.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1280>
2025-07-28 23:40:33 +00:00
Peter Hutterer
74705ee94c util: add a clamp macro
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1280>
2025-07-28 23:40:33 +00:00
Peter Hutterer
e8d24f818b util: add two macros for clearing a line
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1280>
2025-07-28 23:40:33 +00:00
Peter Hutterer
4a67ddc111 utils: allow strv_join on a null string
NULL in means NULL out, as the docs says, no need for an assert here.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1280>
2025-07-28 23:40:32 +00:00
Peter Hutterer
cfec80582e meson.build: change from config.set10() and #if to config.set() and #ifdef
config.set10 is much more convenient and nicer to read but can provide
false positive if the value is 0 and #ifdef is used instead of #if. So
let's switch everything to use #ifdef instead, that way we cannot get
false positives if the value is unset.

Closes #1162

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1277>
2025-07-28 12:04:09 +10:00
Peter Hutterer
36b2afae82 plugin: ignore high-resolution wheel events from disabled wheels
Make sure we drop any potential high-resolution wheel events from a
device that isn't supposed to have them.

Where the device's axes were disabled due to a quirk, re-enabling the
axes means the device's events won't be filtered anymore. Our wheel
emulation plugin thus emulates high-resolution wheel events in addition
to the hardware events.

Fix this by simply filtering out any high-resolution wheel events on any
device that uses this plugin.

Closes #1160

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1279>
2025-07-24 09:13:12 +10:00
Peter Hutterer
6aefc2f166 libinput 1.28.903
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2025-07-21 13:34:46 +10:00
Peter Hutterer
4326413238 libinput: obfuscate the keycodes in the "Queuing ..." debug log
These messages are behind the 'internal-event-debugging' meson options
but let's be extra safe. It's rarely if ever required to see the actual
keycode anyway.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1276>
2025-07-21 13:02:43 +10:00
Peter Hutterer
73103a5c38 plugin: always obfuscate keycodes
Same approach as chosen in libinput-record, this leaves the F1-F10 out
but otherwise prints every other "normal" key (including modifiers) as
KEY_A.

In the future we may need some more specific approach but for now this
will do. For the use-cases where we do need some specific approach,
libinput record and libinput debug-events will still show the full
keycode on request anyway.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1276>
2025-07-21 13:02:43 +10:00
Peter Hutterer
abd5989ee8 plugin: prevent potential keycode leakage to the logs
Mixup of #if vs #ifdef caused this condition to always be treated as
true, resulting in leakage of key codes to the logs if the libinput log
level was set to debug.

Fixes: 7137eb9702 ("plugin: add ability to queue more events in the evdev_frame callback")

Closes #1163

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1276>
2025-07-21 13:02:20 +10:00
Peter Hutterer
7a22eb8d08 plugin/evdev: drop the duplicate event frame printing
The plugin system prints all events before they're passed to the plugin
anyway and the special evdev plugin does not do anything but pass it on.
We can thus assume that the events passed to libinput are the same as
the ones passed to this plugin.

Let's do that and adjust the print format to be closer to what
evdev_log_debug() would print.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1276>
2025-07-21 11:53:57 +10:00
Peter Hutterer
80b45ff28e test: a skipped test does not count as failure
There's a blurry line between NOT_APPLICABLE and SKIP but the latter
has a stronger "should run but can't right now". But where it happens
the skip shouldn't count as a failure.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1276>
2025-07-21 11:53:57 +10:00
Peter Hutterer
35838e9b2c test: fix litest_assert_str_not_in
Looks like an inadvertent paste or possibly a search regex gone wrong.
And the strstr condition was wrong too.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1276>
2025-07-21 10:12:29 +10:00
341 changed files with 13773 additions and 3296 deletions

View file

@ -74,6 +74,7 @@ ForEachMacros:
- tp_for_each_touch - tp_for_each_touch
- range_for_each - range_for_each
- litest_log_group - litest_log_group
- litest_with_logcapture
- litest_with_parameters - litest_with_parameters
- litest_with_event_frame - litest_with_event_frame
- udev_list_entry_foreach - udev_list_entry_foreach

View file

@ -4,4 +4,4 @@
Checks: > Checks: >
-clang-analyzer-unix.Malloc, -clang-analyzer-unix.Malloc,
-clang-analyzer-optin.core.EnumCastOutOfRange -clang-analyzer-optin.core.EnumCastOutOfRange
WarningsAsErrors: true WarningsAsErrors: '*'

View file

@ -49,8 +49,6 @@ include:
- '/templates/debian.yml' - '/templates/debian.yml'
# Fedora container builder template # Fedora container builder template
- '/templates/fedora.yml' - '/templates/fedora.yml'
# Freebsd container builder template
- '/templates/freebsd.yml'
# Ubuntu container builder template # Ubuntu container builder template
- '/templates/ubuntu.yml' - '/templates/ubuntu.yml'
@ -98,24 +96,22 @@ variables:
# See the documentation here: # # See the documentation here: #
# https://wayland.freedesktop.org/libinput/doc/latest/building.html # # https://wayland.freedesktop.org/libinput/doc/latest/building.html #
############################################################################### ###############################################################################
FEDORA_PACKAGES: 'git-core gcc gcc-c++ pkgconf-pkg-config meson check-devel libudev-devel libevdev-devel doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx_rtd_theme python3-pytest-xdist libwacom-devel cairo-devel gtk4-devel glib2-devel mtdev-devel diffutils wayland-protocols-devel black clang clang-tools-extra jq rpmdevtools valgrind systemd-udev qemu-img qemu-system-x86-core qemu-system-aarch64-core jq python3-click python3-rich virtme-ng' FEDORA_PACKAGES: 'git-core gcc gcc-c++ pkgconf-pkg-config meson check-devel libudev-devel libevdev-devel doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx_rtd_theme python3-pytest-xdist libwacom-devel cairo-devel gtk4-devel glib2-devel mtdev-devel diffutils wayland-protocols-devel black clang clang-tools-extra jq rpmdevtools valgrind systemd-udev qemu-img qemu-system-x86-core qemu-system-aarch64-core jq python3-click python3-rich virtme-ng lua-devel'
DEBIAN_PACKAGES: 'git gcc g++ pkg-config meson check libudev-dev libevdev-dev doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx-rtd-theme python3-pytest-xdist libwacom-dev libcairo2-dev libgtk-3-dev libglib2.0-dev libmtdev-dev curl' DEBIAN_PACKAGES: 'git gcc g++ pkg-config meson check libudev-dev libevdev-dev doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx-rtd-theme python3-pytest-xdist libwacom-dev libcairo2-dev libgtk-3-dev libglib2.0-dev libmtdev-dev curl lua5.4-dev'
UBUNTU_PACKAGES: 'git gcc g++ pkg-config meson check libudev-dev libevdev-dev doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx-rtd-theme python3-pytest-xdist libwacom-dev libcairo2-dev libgtk-3-dev libglib2.0-dev libmtdev-dev' UBUNTU_PACKAGES: 'git gcc g++ pkg-config meson check libudev-dev libevdev-dev doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx-rtd-theme python3-pytest-xdist libwacom-dev libcairo2-dev libgtk-3-dev libglib2.0-dev libmtdev-dev lua5.4-dev'
ARCH_PACKAGES: 'git gcc pkgconfig meson check libsystemd libevdev python-pytest-xdist libwacom gtk4 mtdev diffutils' ARCH_PACKAGES: 'git gcc pkgconfig meson check libsystemd libevdev python-pytest-xdist libwacom gtk4 mtdev diffutils lua'
ALPINE_PACKAGES: 'git gcc build-base pkgconfig meson check-dev eudev-dev libevdev-dev libwacom-dev cairo-dev gtk4.0-dev mtdev-dev bash' ALPINE_PACKAGES: 'git gcc build-base pkgconfig meson check-dev eudev-dev libevdev-dev libwacom-dev cairo-dev gtk4.0-dev mtdev-dev bash lua5.4-dev'
FREEBSD_PACKAGES: 'git pkgconf meson libepoll-shim libudev-devd libevdev libwacom gtk3 libmtdev bash wayland'
############################ end of package lists ############################# ############################ end of package lists #############################
# these tags should be updated each time the list of packages is updated # these tags should be updated each time the list of packages is updated
# changing these will force rebuilding the associated image # changing these will force rebuilding the associated image
# Note: these tags have no meaning and are not tied to a particular # Note: these tags have no meaning and are not tied to a particular
# libinput version # libinput version
FEDORA_TAG: '2025-05-19.0' FEDORA_TAG: '2026-01-09.0'
DEBIAN_TAG: '2025-05-19.0' DEBIAN_TAG: '2026-01-09.0'
UBUNTU_TAG: '2025-05-19.0' UBUNTU_TAG: '2026-01-09.0'
ARCH_TAG: '2025-05-19.0' ARCH_TAG: '2026-01-09.0'
ALPINE_TAG: '2025-05-19.0' ALPINE_TAG: '2026-01-09.0'
FREEBSD_TAG: '2025-05-19.0'
FDO_UPSTREAM_REPO: libinput/libinput FDO_UPSTREAM_REPO: libinput/libinput
@ -267,18 +263,6 @@ pre-commit-hooks:
# # # #
################################################################# #################################################################
fedora:41@container-prep:
extends:
- .fdo.container-build@fedora
- .policy
- .fdo-runner-tags
stage: prep
variables:
GIT_STRATEGY: none
FDO_DISTRIBUTION_VERSION: '41'
FDO_DISTRIBUTION_PACKAGES: $FEDORA_PACKAGES
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
fedora:42@container-prep: fedora:42@container-prep:
extends: extends:
- .fdo.container-build@fedora - .fdo.container-build@fedora
@ -291,6 +275,18 @@ fedora:42@container-prep:
FDO_DISTRIBUTION_PACKAGES: $FEDORA_PACKAGES FDO_DISTRIBUTION_PACKAGES: $FEDORA_PACKAGES
FDO_DISTRIBUTION_TAG: $FEDORA_TAG FDO_DISTRIBUTION_TAG: $FEDORA_TAG
fedora:43@container-prep:
extends:
- .fdo.container-build@fedora
- .policy
- .fdo-runner-tags
stage: prep
variables:
GIT_STRATEGY: none
FDO_DISTRIBUTION_VERSION: '43'
FDO_DISTRIBUTION_PACKAGES: $FEDORA_PACKAGES
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
debian:stable@container-prep: debian:stable@container-prep:
extends: extends:
- .fdo.container-build@debian - .fdo.container-build@debian
@ -303,7 +299,7 @@ debian:stable@container-prep:
FDO_DISTRIBUTION_PACKAGES: $DEBIAN_PACKAGES FDO_DISTRIBUTION_PACKAGES: $DEBIAN_PACKAGES
FDO_DISTRIBUTION_TAG: $DEBIAN_TAG FDO_DISTRIBUTION_TAG: $DEBIAN_TAG
ubuntu:25.04@container-prep: ubuntu:25.10@container-prep:
extends: extends:
- .fdo.container-build@ubuntu - .fdo.container-build@ubuntu
- .policy - .policy
@ -311,7 +307,7 @@ ubuntu:25.04@container-prep:
stage: prep stage: prep
variables: variables:
GIT_STRATEGY: none GIT_STRATEGY: none
FDO_DISTRIBUTION_VERSION: '25.04' FDO_DISTRIBUTION_VERSION: '25.10'
FDO_DISTRIBUTION_PACKAGES: $UBUNTU_PACKAGES FDO_DISTRIBUTION_PACKAGES: $UBUNTU_PACKAGES
FDO_DISTRIBUTION_TAG: $UBUNTU_TAG FDO_DISTRIBUTION_TAG: $UBUNTU_TAG
@ -339,20 +335,6 @@ alpine:latest@container-prep:
FDO_DISTRIBUTION_PACKAGES: $ALPINE_PACKAGES FDO_DISTRIBUTION_PACKAGES: $ALPINE_PACKAGES
FDO_DISTRIBUTION_TAG: $ALPINE_TAG FDO_DISTRIBUTION_TAG: $ALPINE_TAG
freebsd:14.2@container-prep:
extends:
- .fdo.qemu-build@freebsd
- .policy
- .fdo-runner-tags
tags:
- $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM
stage: prep
variables:
GIT_STRATEGY: none
FDO_DISTRIBUTION_VERSION: '14.2'
FDO_DISTRIBUTION_PACKAGES: $FREEBSD_PACKAGES
FDO_DISTRIBUTION_TAG: $FREEBSD_TAG
################################################################# #################################################################
@ -386,16 +368,6 @@ freebsd:14.2@container-prep:
only: only:
- schedules - schedules
fedora:41@container-clean:
extends:
- .policy
- .container-clean
variables:
GIT_STRATEGY: none
CURRENT_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/fedora/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG
FDO_DISTRIBUTION_VERSION: '41'
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
fedora:42@container-clean: fedora:42@container-clean:
extends: extends:
- .policy - .policy
@ -406,6 +378,16 @@ fedora:42@container-clean:
FDO_DISTRIBUTION_VERSION: '42' FDO_DISTRIBUTION_VERSION: '42'
FDO_DISTRIBUTION_TAG: $FEDORA_TAG FDO_DISTRIBUTION_TAG: $FEDORA_TAG
fedora:43@container-clean:
extends:
- .policy
- .container-clean
variables:
GIT_STRATEGY: none
CURRENT_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/fedora/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG
FDO_DISTRIBUTION_VERSION: '43'
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
debian:stable@container-clean: debian:stable@container-clean:
extends: extends:
- .policy - .policy
@ -416,14 +398,14 @@ debian:stable@container-clean:
FDO_DISTRIBUTION_VERSION: 'stable' FDO_DISTRIBUTION_VERSION: 'stable'
FDO_DISTRIBUTION_TAG: $DEBIAN_TAG FDO_DISTRIBUTION_TAG: $DEBIAN_TAG
ubuntu:25.04@container-clean: ubuntu:25.10@container-clean:
extends: extends:
- .policy - .policy
- .container-clean - .container-clean
variables: variables:
GIT_STRATEGY: none GIT_STRATEGY: none
CURRENT_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/ubuntu/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG CURRENT_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/ubuntu/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG
FDO_DISTRIBUTION_VERSION: '25.04' FDO_DISTRIBUTION_VERSION: '25.10'
FDO_DISTRIBUTION_TAG: $UBUNTU_TAG FDO_DISTRIBUTION_TAG: $UBUNTU_TAG
arch:rolling@container-clean: arch:rolling@container-clean:
@ -446,16 +428,6 @@ alpine:latest@container-clean:
FDO_DISTRIBUTION_VERSION: 'latest' FDO_DISTRIBUTION_VERSION: 'latest'
FDO_DISTRIBUTION_TAG: $ALPINE_TAG FDO_DISTRIBUTION_TAG: $ALPINE_TAG
freebsd:14.2@container-clean:
extends:
- .policy
- .container-clean
variables:
GIT_STRATEGY: none
CURRENT_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/freebsd/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG
FDO_DISTRIBUTION_VERSION: '14.2'
FDO_DISTRIBUTION_TAG: $FREEBSD_TAG
################################################################# #################################################################
# # # #
@ -577,20 +549,20 @@ freebsd:14.2@container-clean:
- export MESON_TEST_ARGS="$MESON_TEST_ARGS $SUITES" - export MESON_TEST_ARGS="$MESON_TEST_ARGS $SUITES"
.fedora:42@test-suite-vm: .fedora:43@test-suite-vm:
extends: extends:
- .fdo.distribution-image@fedora - .fdo.distribution-image@fedora
- .test-suite-vm - .test-suite-vm
variables: variables:
FDO_DISTRIBUTION_VERSION: 42 FDO_DISTRIBUTION_VERSION: 43
FDO_DISTRIBUTION_TAG: $FEDORA_TAG FDO_DISTRIBUTION_TAG: $FEDORA_TAG
needs: needs:
- "fedora:42@container-prep" - "fedora:43@container-prep"
vm-touchpad: vm-touchpad:
extends: extends:
- .fedora:42@test-suite-vm - .fedora:43@test-suite-vm
variables: variables:
SUITE_NAMES: 'touchpad' SUITE_NAMES: 'touchpad'
@ -603,7 +575,7 @@ vm-touchpad-no-libwacom:
vm-touchpad_palm: vm-touchpad_palm:
extends: extends:
- .fedora:42@test-suite-vm - .fedora:43@test-suite-vm
variables: variables:
SUITE_NAMES: 'touchpad_palm' SUITE_NAMES: 'touchpad_palm'
@ -616,7 +588,7 @@ vm-touchpad_palm-no-libwacom:
vm-touchpad_dwt: vm-touchpad_dwt:
extends: extends:
- .fedora:42@test-suite-vm - .fedora:43@test-suite-vm
variables: variables:
SUITE_NAMES: 'touchpad_dwt' SUITE_NAMES: 'touchpad_dwt'
@ -629,7 +601,7 @@ vm-touchpad_dwt-no-libwacom:
vm-tap: vm-tap:
extends: extends:
- .fedora:42@test-suite-vm - .fedora:43@test-suite-vm
variables: variables:
SUITE_NAMES: 'touchpad_tap' SUITE_NAMES: 'touchpad_tap'
@ -642,7 +614,7 @@ vm-tap-no-libwacom:
vm-tap-drag: vm-tap-drag:
extends: extends:
- .fedora:42@test-suite-vm - .fedora:43@test-suite-vm
variables: variables:
SUITE_NAMES: 'touchpad_tap_drag' SUITE_NAMES: 'touchpad_tap_drag'
@ -655,7 +627,7 @@ vm-tap-drag-no-libwacom:
vm-tap-palm: vm-tap-palm:
extends: extends:
- .fedora:42@test-suite-vm - .fedora:43@test-suite-vm
variables: variables:
SUITE_NAMES: 'touchpad_tap_palm' SUITE_NAMES: 'touchpad_tap_palm'
@ -668,7 +640,7 @@ vm-tap-palm-no-libwacom:
vm-touchpad-buttons: vm-touchpad-buttons:
extends: extends:
- .fedora:42@test-suite-vm - .fedora:43@test-suite-vm
variables: variables:
SUITE_NAMES: 'touchpad_buttons' SUITE_NAMES: 'touchpad_buttons'
@ -681,7 +653,7 @@ vm-touchpad-buttons-no-libwacom:
vm-tablet: vm-tablet:
extends: extends:
- .fedora:42@test-suite-vm - .fedora:43@test-suite-vm
variables: variables:
SUITE_NAMES: 'tablet' SUITE_NAMES: 'tablet'
@ -694,7 +666,7 @@ vm-tablet-no-libwacom:
vm-tablet_left_handed: vm-tablet_left_handed:
extends: extends:
- .fedora:42@test-suite-vm - .fedora:43@test-suite-vm
variables: variables:
SUITE_NAMES: 'tablet_left_handed' SUITE_NAMES: 'tablet_left_handed'
@ -707,7 +679,7 @@ vm-tablet_left_handed-no-libwacom:
vm-tablet_proximity_tip: vm-tablet_proximity_tip:
extends: extends:
- .fedora:42@test-suite-vm - .fedora:43@test-suite-vm
variables: variables:
SUITE_NAMES: 'tablet_proximity tablet_tip' SUITE_NAMES: 'tablet_proximity tablet_tip'
@ -720,7 +692,7 @@ vm-tablet_proximity_tip-no-libwacom:
vm-tablet_eraser: vm-tablet_eraser:
extends: extends:
- .fedora:42@test-suite-vm - .fedora:43@test-suite-vm
variables: variables:
SUITE_NAMES: 'tablet_eraser' SUITE_NAMES: 'tablet_eraser'
@ -733,7 +705,7 @@ vm-tablet_eraser-no-libwacom:
vm-gestures: vm-gestures:
extends: extends:
- .fedora:42@test-suite-vm - .fedora:43@test-suite-vm
variables: variables:
SUITE_NAMES: 'gestures' SUITE_NAMES: 'gestures'
@ -746,7 +718,7 @@ vm-gestures-no-libwacom:
vm-backends: vm-backends:
extends: extends:
- .fedora:42@test-suite-vm - .fedora:43@test-suite-vm
variables: variables:
SUITE_NAMES: 'path udev' SUITE_NAMES: 'path udev'
@ -759,7 +731,7 @@ vm-backends-no-libwacom:
vm-misc: vm-misc:
extends: extends:
- .fedora:42@test-suite-vm - .fedora:43@test-suite-vm
variables: variables:
SUITE_NAMES: 'log misc quirks device' SUITE_NAMES: 'log misc quirks device'
@ -772,7 +744,7 @@ vm-misc-no-libwacom:
vm-other devices: vm-other devices:
extends: extends:
- .fedora:42@test-suite-vm - .fedora:43@test-suite-vm
variables: variables:
SUITE_NAMES: 'keyboard pad switch trackball trackpoint totem touch' SUITE_NAMES: 'keyboard pad switch trackball trackpoint totem touch'
@ -785,7 +757,7 @@ vm-other devices-no-libwacom:
vm-pointer: vm-pointer:
extends: extends:
- .fedora:42@test-suite-vm - .fedora:43@test-suite-vm
variables: variables:
SUITE_NAMES: 'pointer' SUITE_NAMES: 'pointer'
@ -796,6 +768,19 @@ vm-pointer-no-libwacom:
variables: variables:
MESON_ARGS: '-Dlibwacom=false' MESON_ARGS: '-Dlibwacom=false'
vm-lua:
extends:
- .fedora:43@test-suite-vm
variables:
SUITE_NAMES: 'lua'
vm-lua-no-libwacom:
extends:
- vm-lua
stage: test-suite-no-libwacom
variables:
MESON_ARGS: '-Dlibwacom=false'
vm-valgrind-touchpad: vm-valgrind-touchpad:
stage: valgrind stage: valgrind
@ -1005,18 +990,32 @@ vm-valgrind-pointer:
rules: rules:
- if: $GITLAB_USER_LOGIN != "marge-bot" - if: $GITLAB_USER_LOGIN != "marge-bot"
vm-valgrind-lua:
stage: valgrind
extends:
- vm-lua
- .policy-retry-on-failure
variables:
MESON_TEST_ARGS: '--setup=valgrind'
LITEST_JOBS: 0
retry:
max: 2
rules:
- if: $GITLAB_USER_LOGIN != "marge-bot"
.fedora-build@template: .fedora-build@template:
extends: extends:
- .fdo.distribution-image@fedora - .fdo.distribution-image@fedora
- .build@template - .build@template
variables: variables:
FDO_DISTRIBUTION_VERSION: '42' FDO_DISTRIBUTION_VERSION: '43'
FDO_DISTRIBUTION_TAG: $FEDORA_TAG FDO_DISTRIBUTION_TAG: $FEDORA_TAG
needs: needs:
- "fedora:42@container-prep" - "fedora:43@container-prep"
default-build-release@fedora:42: default-build-release@fedora:43:
stage: distro stage: distro
extends: extends:
- .fedora-build@template - .fedora-build@template
@ -1024,7 +1023,7 @@ default-build-release@fedora:42:
MESON_ARGS: "-Dbuildtype=release" MESON_ARGS: "-Dbuildtype=release"
CFLAGS: "-Werror" CFLAGS: "-Werror"
clang-tidy@fedora:42: clang-tidy@fedora:43:
extends: extends:
- .fedora-build@template - .fedora-build@template
variables: variables:
@ -1039,13 +1038,13 @@ clang-tidy@fedora:42:
# run them on one image, they shouldn't fail on one distro # run them on one image, they shouldn't fail on one distro
# when they succeed on another. # when they succeed on another.
build-no-libwacom@fedora:42: build-no-libwacom@fedora:43:
extends: extends:
- .fedora-build@template - .fedora-build@template
variables: variables:
MESON_ARGS: "-Dlibwacom=false" MESON_ARGS: "-Dlibwacom=false"
build-no-libwacom-nodeps@fedora:42: build-no-libwacom-nodeps@fedora:43:
extends: extends:
- .fedora-build@template - .fedora-build@template
variables: variables:
@ -1053,13 +1052,13 @@ build-no-libwacom-nodeps@fedora:42:
before_script: before_script:
- dnf remove -y libwacom libwacom-devel - dnf remove -y libwacom libwacom-devel
build-no-mtdev@fedora:42: build-no-mtdev@fedora:43:
extends: extends:
- .fedora-build@template - .fedora-build@template
variables: variables:
MESON_ARGS: "-Dmtdev=false" MESON_ARGS: "-Dmtdev=false"
build-no-mtdev-nodeps@fedora:42: build-no-mtdev-nodeps@fedora:43:
extends: extends:
- .fedora-build@template - .fedora-build@template
variables: variables:
@ -1067,13 +1066,27 @@ build-no-mtdev-nodeps@fedora:42:
before_script: before_script:
- dnf remove -y mtdev mtdev-devel - dnf remove -y mtdev mtdev-devel
build-docs@fedora:42: build-no-lua@fedora:43:
extends:
- .fedora-build@template
variables:
MESON_ARGS: "-Dlua-plugins=disabled"
build-no-lua-nodeps@fedora:43:
extends:
- .fedora-build@template
variables:
MESON_ARGS: "-Dlua-plugins=disabled"
before_script:
- dnf remove -y lua lua-devel
build-docs@fedora:43:
extends: extends:
- .fedora-build@template - .fedora-build@template
variables: variables:
MESON_ARGS: "-Ddocumentation=true" MESON_ARGS: "-Ddocumentation=true"
build-no-docs-nodeps@fedora:42: build-no-docs-nodeps@fedora:43:
extends: extends:
- .fedora-build@template - .fedora-build@template
variables: variables:
@ -1081,13 +1094,13 @@ build-no-docs-nodeps@fedora:42:
before_script: before_script:
- dnf remove -y doxygen graphviz - dnf remove -y doxygen graphviz
build-no-debuggui@fedora:42: build-no-debuggui@fedora:43:
extends: extends:
- .fedora-build@template - .fedora-build@template
variables: variables:
MESON_ARGS: "-Ddebug-gui=false" MESON_ARGS: "-Ddebug-gui=false"
build-no-debuggui-nodeps@fedora:42: build-no-debuggui-nodeps@fedora:43:
extends: extends:
- .fedora-build@template - .fedora-build@template
variables: variables:
@ -1095,13 +1108,13 @@ build-no-debuggui-nodeps@fedora:42:
before_script: before_script:
- dnf remove -y gtk3-devel gtk4-devel - dnf remove -y gtk3-devel gtk4-devel
build-no-tests@fedora:42: build-no-tests@fedora:43:
extends: extends:
- .fedora-build@template - .fedora-build@template
variables: variables:
MESON_ARGS: "-Dtests=false" MESON_ARGS: "-Dtests=false"
build-no-tests-nodeps@fedora:42: build-no-tests-nodeps@fedora:43:
extends: extends:
- .fedora-build@template - .fedora-build@template
variables: variables:
@ -1109,7 +1122,7 @@ build-no-tests-nodeps@fedora:42:
before_script: before_script:
- dnf remove -y check-devel - dnf remove -y check-devel
valgrind@fedora:42: valgrind@fedora:43:
extends: extends:
- .fedora-build@template - .fedora-build@template
variables: variables:
@ -1117,7 +1130,7 @@ valgrind@fedora:42:
# Python checks, only run on Fedora # Python checks, only run on Fedora
usr-bin-env-python@fedora:42: usr-bin-env-python@fedora:43:
extends: extends:
- .fedora-build@template - .fedora-build@template
script: script:
@ -1163,6 +1176,7 @@ check-test-suites:
libinput-test-suite-totem libinput-test-suite-totem
libinput-test-suite-touch libinput-test-suite-touch
libinput-test-suite-pointer libinput-test-suite-pointer
libinput-test-suite-lua
EOF EOF
- sort -o ci-testsuites ci-testsuites - sort -o ci-testsuites ci-testsuites
- diff -u8 -w ci-testsuites meson-testsuites || (echo "Some test suites are not run in the CI" && false) - diff -u8 -w ci-testsuites meson-testsuites || (echo "Some test suites are not run in the CI" && false)
@ -1227,18 +1241,6 @@ coverity:
# # # #
################################################################# #################################################################
fedora:41@default-build:
stage: distro
extends:
- .build@template
- .fdo.distribution-image@fedora
variables:
FDO_DISTRIBUTION_VERSION: '41'
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
needs:
- "fedora:41@container-prep"
fedora:42@default-build: fedora:42@default-build:
stage: distro stage: distro
extends: extends:
@ -1251,6 +1253,18 @@ fedora:42@default-build:
- "fedora:42@container-prep" - "fedora:42@container-prep"
fedora:43@default-build:
stage: distro
extends:
- .build@template
- .fdo.distribution-image@fedora
variables:
FDO_DISTRIBUTION_VERSION: '43'
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
needs:
- "fedora:43@container-prep"
debian:stable@default-build: debian:stable@default-build:
stage: distro stage: distro
extends: extends:
@ -1263,16 +1277,16 @@ debian:stable@default-build:
- "debian:stable@container-prep" - "debian:stable@container-prep"
ubuntu:25.04@default-build: ubuntu:25.10@default-build:
stage: distro stage: distro
extends: extends:
- .build@template - .build@template
- .fdo.distribution-image@ubuntu - .fdo.distribution-image@ubuntu
variables: variables:
FDO_DISTRIBUTION_VERSION: '25.04' FDO_DISTRIBUTION_VERSION: '25.10'
FDO_DISTRIBUTION_TAG: $UBUNTU_TAG FDO_DISTRIBUTION_TAG: $UBUNTU_TAG
needs: needs:
- "ubuntu:25.04@container-prep" - "ubuntu:25.10@container-prep"
arch:rolling@default-build: arch:rolling@default-build:
@ -1302,19 +1316,6 @@ alpine:latest@default-build:
- "alpine:latest@container-prep" - "alpine:latest@container-prep"
freebsd:14.2@default-build:
stage: distro
extends:
- .build-in-qemu@template
- .fdo.distribution-image@freebsd
variables:
FDO_DISTRIBUTION_VERSION: '14.2'
FDO_DISTRIBUTION_TAG: $FREEBSD_TAG
MESON_ARGS: '-Dtests=false -Ddocumentation=false' # doxygen drags down too many deps
MESON_TEST_ARGS: '' # test suite doesn't work on BSD yet
needs:
- "freebsd:14.2@container-prep"
################################################################# #################################################################
# # # #
@ -1322,27 +1323,6 @@ freebsd:14.2@default-build:
# # # #
################################################################# #################################################################
#
# Verify that the merge request has the allow-collaboration checkbox ticked
#
check-merge-request:
extends:
- .fdo.ci-fairy
- .policy
- .fdo-runner-tags
stage: deploy
script:
- ci-fairy check-merge-request --require-allow-collaboration --junit-xml=results.xml
artifacts:
when: on_failure
reports:
junit: results.xml
allow_failure: true
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
build rpm: build rpm:
extends: extends:
- .fdo.distribution-image@fedora - .fdo.distribution-image@fedora
@ -1350,10 +1330,10 @@ build rpm:
- .fdo-runner-tags - .fdo-runner-tags
stage: deploy stage: deploy
variables: variables:
FDO_DISTRIBUTION_VERSION: '42' FDO_DISTRIBUTION_VERSION: '43'
FDO_DISTRIBUTION_TAG: $FEDORA_TAG FDO_DISTRIBUTION_TAG: $FEDORA_TAG
needs: needs:
- "fedora:42@container-prep" - "fedora:43@container-prep"
script: script:
- meson "$MESON_BUILDDIR" - meson "$MESON_BUILDDIR"
- VERSION=$(meson introspect "$MESON_BUILDDIR" --projectinfo | jq -r .version) - VERSION=$(meson introspect "$MESON_BUILDDIR" --projectinfo | jq -r .version)
@ -1371,14 +1351,12 @@ build rpm:
wayland-web: wayland-web:
stage: deploy stage: deploy
trigger: wayland/wayland.freedesktop.org trigger: wayland/wayland.freedesktop.org
except:
refs:
- schedules
variables: variables:
MESON_ARGS: '-Ddocumentation=true -Ddebug-gui=false -Dlibwacom=false -Dtests=false' MESON_ARGS: '-Ddocumentation=true -Ddebug-gui=false -Dlibwacom=false -Dtests=false'
MESON_BUILDDIR: 'builddir' MESON_BUILDDIR: 'builddir'
only: rules:
refs: - if: '$CI_PIPELINE_SOURCE == "schedule"'
- main when: never
variables: - if: '$CI_COMMIT_BRANCH == "main" && $GITLAB_USER_LOGIN != "marge-bot" && $CI_PROJECT_PATH == $FDO_UPSTREAM_REPO'
- $CI_PROJECT_PATH == "libinput/libinput" when: on_success
- when: never

View file

@ -492,6 +492,7 @@ vm-valgrind-{{suite.name}}:
- if: $GITLAB_USER_LOGIN != "marge-bot" - if: $GITLAB_USER_LOGIN != "marge-bot"
{% endfor %} {% endfor %}
{% endfor %}{# for if distro.use_for_qemu_tests #} {% endfor %}{# for if distro.use_for_qemu_tests #}
{% for distro in distributions if distro.use_for_custom_build_tests %} {% for distro in distributions if distro.use_for_custom_build_tests %}
@ -557,6 +558,20 @@ build-no-mtdev-nodeps@{{distro.name}}:{{version}}:
before_script: before_script:
- dnf remove -y mtdev mtdev-devel - dnf remove -y mtdev mtdev-devel
build-no-lua@{{distro.name}}:{{version}}:
extends:
- .{{distro.name}}-build@template
variables:
MESON_ARGS: "-Dlua-plugins=disabled"
build-no-lua-nodeps@{{distro.name}}:{{version}}:
extends:
- .{{distro.name}}-build@template
variables:
MESON_ARGS: "-Dlua-plugins=disabled"
before_script:
- dnf remove -y lua lua-devel
build-docs@{{distro.name}}:{{version}}: build-docs@{{distro.name}}:{{version}}:
extends: extends:
- .{{distro.name}}-build@template - .{{distro.name}}-build@template
@ -746,27 +761,6 @@ coverity:
# # # #
################################################################# #################################################################
#
# Verify that the merge request has the allow-collaboration checkbox ticked
#
check-merge-request:
extends:
- .fdo.ci-fairy
- .policy
- .fdo-runner-tags
stage: deploy
script:
- ci-fairy check-merge-request --require-allow-collaboration --junit-xml=results.xml
artifacts:
when: on_failure
reports:
junit: results.xml
allow_failure: true
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
{% for distro in distributions if distro.name == "fedora" %} {% for distro in distributions if distro.name == "fedora" %}
{% set version = "{}".format(distro.versions|last()) %} {% set version = "{}".format(distro.versions|last()) %}
build rpm: build rpm:
@ -798,14 +792,12 @@ build rpm:
wayland-web: wayland-web:
stage: deploy stage: deploy
trigger: wayland/wayland.freedesktop.org trigger: wayland/wayland.freedesktop.org
except:
refs:
- schedules
variables: variables:
MESON_ARGS: '-Ddocumentation=true -Ddebug-gui=false -Dlibwacom=false -Dtests=false' MESON_ARGS: '-Ddocumentation=true -Ddebug-gui=false -Dlibwacom=false -Dtests=false'
MESON_BUILDDIR: 'builddir' MESON_BUILDDIR: 'builddir'
only: rules:
refs: - if: '$CI_PIPELINE_SOURCE == "schedule"'
- main when: never
variables: - if: '$CI_COMMIT_BRANCH == "main" && $GITLAB_USER_LOGIN != "marge-bot" && $CI_PROJECT_PATH == $FDO_UPSTREAM_REPO'
- $CI_PROJECT_PATH == "libinput/libinput" when: on_success
- when: never

View file

@ -3,14 +3,14 @@
# #
# We're happy to rebuild all containers when one changes. # We're happy to rebuild all containers when one changes.
.default_tag: &default_tag '2025-05-19.0' .default_tag: &default_tag '2026-01-09.0'
distributions: distributions:
- name: fedora - name: fedora
tag: *default_tag tag: *default_tag
versions: versions:
- '41'
- '42' - '42'
- '43'
use_for_custom_build_tests: true use_for_custom_build_tests: true
use_for_qemu_tests: true use_for_qemu_tests: true
packages: packages:
@ -50,6 +50,7 @@ distributions:
- python3-click - python3-click
- python3-rich - python3-rich
- virtme-ng - virtme-ng
- lua-devel
- name: debian - name: debian
tag: *default_tag tag: *default_tag
versions: versions:
@ -75,10 +76,11 @@ distributions:
- libglib2.0-dev - libglib2.0-dev
- libmtdev-dev - libmtdev-dev
- curl # for the coverity job - curl # for the coverity job
- lua5.4-dev
- name: ubuntu - name: ubuntu
tag: *default_tag tag: *default_tag
versions: versions:
- '25.04' - '25.10'
packages: packages:
- git - git
- gcc - gcc
@ -99,6 +101,7 @@ distributions:
- libgtk-3-dev - libgtk-3-dev
- libglib2.0-dev - libglib2.0-dev
- libmtdev-dev - libmtdev-dev
- lua5.4-dev
- name: arch - name: arch
tag: *default_tag tag: *default_tag
versions: versions:
@ -116,6 +119,7 @@ distributions:
- gtk4 - gtk4
- mtdev - mtdev
- diffutils - diffutils
- lua
build: build:
extra_variables: extra_variables:
- "MESON_ARGS: '-Ddocumentation=false'" # python-recommonmark is no longer in the repos - "MESON_ARGS: '-Ddocumentation=false'" # python-recommonmark is no longer in the repos
@ -136,6 +140,7 @@ distributions:
- gtk4.0-dev - gtk4.0-dev
- mtdev-dev - mtdev-dev
- bash - bash
- lua5.4-dev
build: build:
extra_variables: extra_variables:
- "MESON_ARGS: '-Ddocumentation=false' # alpine does not have python-recommonmark" - "MESON_ARGS: '-Ddocumentation=false' # alpine does not have python-recommonmark"
@ -143,29 +148,6 @@ distributions:
# for any tcase_add_exit_test/tcase_add_test_raise_signal # for any tcase_add_exit_test/tcase_add_test_raise_signal
# but someone more invested in musl will have to figure that out. # but someone more invested in musl will have to figure that out.
- "MESON_TEST_ARGS: '' # litest-selftest fails on musl" - "MESON_TEST_ARGS: '' # litest-selftest fails on musl"
- name: freebsd
tag: *default_tag
qemu_based: true
versions:
- '14.2'
packages:
- git
- pkgconf
- meson
- libepoll-shim
- libudev-devd
- libevdev
- libwacom
- gtk3
- libmtdev
- bash
- wayland
build:
extra_variables:
- "MESON_ARGS: '-Dtests=false -Ddocumentation=false' # doxygen drags down too many deps"
# We don't run the tests on FreeBSD, someone would have to fix the
# test suite to work on BSD first.
- "MESON_TEST_ARGS: '' # test suite doesn't work on BSD yet"
test_suites: test_suites:
- name: touchpad - name: touchpad
@ -227,6 +209,9 @@ test_suites:
- name: pointer - name: pointer
suites: suites:
- pointer - pointer
- name: lua
suites:
- lua
vng: vng:
kernel: https://gitlab.freedesktop.org/api/v4/projects/libevdev%2Fhid-tools/packages/generic/kernel-x86_64/v6.14/bzImage kernel: https://gitlab.freedesktop.org/api/v4/projects/libevdev%2Fhid-tools/packages/generic/kernel-x86_64/v6.14/bzImage

View file

@ -100,6 +100,7 @@ intended to be run by users.
%files utils %files utils
%{_libexecdir}/libinput/libinput-debug-gui %{_libexecdir}/libinput/libinput-debug-gui
%{_libexecdir}/libinput/libinput-debug-tablet %{_libexecdir}/libinput/libinput-debug-tablet
%{_libexecdir}/libinput/libinput-debug-tablet-pad
%{_libexecdir}/libinput/libinput-list-kernel-devices %{_libexecdir}/libinput/libinput-list-kernel-devices
%{_libexecdir}/libinput/libinput-measure %{_libexecdir}/libinput/libinput-measure
%{_libexecdir}/libinput/libinput-measure-fuzz %{_libexecdir}/libinput/libinput-measure-fuzz
@ -117,6 +118,7 @@ intended to be run by users.
%{_libexecdir}/libinput/libinput-analyze-touch-down-state %{_libexecdir}/libinput/libinput-analyze-touch-down-state
%{_mandir}/man1/libinput-debug-gui.1* %{_mandir}/man1/libinput-debug-gui.1*
%{_mandir}/man1/libinput-debug-tablet.1* %{_mandir}/man1/libinput-debug-tablet.1*
%{_mandir}/man1/libinput-debug-tablet-pad.1*
%{_mandir}/man1/libinput-list-kernel-devices.1* %{_mandir}/man1/libinput-list-kernel-devices.1*
%{_mandir}/man1/libinput-measure.1* %{_mandir}/man1/libinput-measure.1*
%{_mandir}/man1/libinput-measure-fuzz.1* %{_mandir}/man1/libinput-measure-fuzz.1*

View file

@ -183,6 +183,16 @@ resource_rules:
For a detailed explanation on the how and why of this process please see For a detailed explanation on the how and why of this process please see
the [Closed Issues wiki page](https://gitlab.freedesktop.org/libinput/libinput/-/wikis/Closed-Issues). the [Closed Issues wiki page](https://gitlab.freedesktop.org/libinput/libinput/-/wikis/Closed-Issues).
status: "close" status: "close"
- name: "Re-close bug for reopening"
conditions:
labels:
- "bugbot::re-close"
actions:
remove_labels:
- "bugbot::re-close"
comment: |
I'm temporarily closing this bug again. This is not a final close, see my comments above for the open/close process.
status: "close"
- *udev_hid_bpf - *udev_hid_bpf
- *libinput_record - *libinput_record
- *hid_recorder - *hid_recorder

View file

@ -45,6 +45,7 @@ __all_seats()
'--verbose[Use verbose output]' \ '--verbose[Use verbose output]' \
'--show-keycodes[Make all keycodes visible]' \ '--show-keycodes[Make all keycodes visible]' \
'--grab[Exclusively grab all opened devices]' \ '--grab[Exclusively grab all opened devices]' \
'--compress-motion-events[Compress repeated motion events on a TTY]' \
'--device=[Use the given device with the path backend]:device:_files -W /dev/input/ -P /dev/input/' \ '--device=[Use the given device with the path backend]:device:_files -W /dev/input/ -P /dev/input/' \
'--udev=[Listen for notifications on the given seat]:seat:__all_seats' \ '--udev=[Listen for notifications on the given seat]:seat:__all_seats' \
'--apply-to=[Apply configuration options where the device name matches the pattern]:pattern' \ '--apply-to=[Apply configuration options where the device name matches the pattern]:pattern' \
@ -93,6 +94,9 @@ __all_seats()
+ '(natural-scrolling)' \ + '(natural-scrolling)' \
'--enable-natural-scrolling[Enable natural scrolling]' \ '--enable-natural-scrolling[Enable natural scrolling]' \
'--disable-natural-scrolling[Disable natural scrolling]' \ '--disable-natural-scrolling[Disable natural scrolling]' \
+ '(plugins)' \
'--enable-plugins[Enable plugins]' \
'--disable-plugins[Disable plugins]' \
+ '(tap-to-click)' \ + '(tap-to-click)' \
'--enable-tap[Enable tap-to-click]' \ '--enable-tap[Enable tap-to-click]' \
'--disable-tap[Disable tap-to-click]' '--disable-tap[Disable tap-to-click]'

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 181 KiB

After

Width:  |  Height:  |  Size: 489 KiB

View file

@ -110,7 +110,7 @@ The most common matrices are:
.. math:: .. math::
\begin{pmatrix} \begin{pmatrix}
-1 & 0 & 1 \\ -1 & 0 & 1 \\
1 & 0 & 0 \\ 0 & 1 & 0 \\
0 & 0 & 1 0 & 0 & 1
\end{pmatrix} \end{pmatrix}

View file

@ -40,11 +40,6 @@ To fix the touchpad you need to:
Detailed explanations are below. Detailed explanations are below.
.. note:: ``libinput measure touchpad-size`` was introduced in libinput
1.16. For earlier versions, use `libevdev <http://freedesktop.org/wiki/Software/libevdev/>`_'s
``touchpad-edge-detector`` tool.
The ``libinput measure touchpad-size`` tool is an interactive tool. It must The ``libinput measure touchpad-size`` tool is an interactive tool. It must
be called with the physical dimensions of the touchpad in mm. In the example be called with the physical dimensions of the touchpad in mm. In the example
below, we use 100mm wide and 55mm high. The tool will find the touchpad device below, we use 100mm wide and 55mm high. The tool will find the touchpad device
@ -92,7 +87,7 @@ suggested hwdb entry. ::
If there are discrepancies between the coordinate range the kernels If there are discrepancies between the coordinate range the kernels
advertises and what what the touchpad sends, the hwdb entry should be added to the advertises and what the touchpad sends, the hwdb entry should be added to the
``60-evdev.hwdb`` file provided by the `systemd project <https://github.com/systemd/systemd>`_. ``60-evdev.hwdb`` file provided by the `systemd project <https://github.com/systemd/systemd>`_.
An example commit can be found An example commit can be found
`here <https://github.com/systemd/systemd/commit/26f667eac1c5e89b689aa0a1daef6a80f473e045>`_. `here <https://github.com/systemd/systemd/commit/26f667eac1c5e89b689aa0a1daef6a80f473e045>`_.

View file

@ -198,7 +198,7 @@ events is performed within the dispatch method.
evdev [label="evdev_device_dispatch()"] evdev [label="evdev_device_dispatch()"]
plugins [label="plugin pipline"] plugins [label="plugin pipeline"]
fallback [label="fallback_interface_process()"]; fallback [label="fallback_interface_process()"];
touchpad [label="tp_interface_process()"] touchpad [label="tp_interface_process()"]

View file

@ -13,7 +13,7 @@ Instructions on how to build libinput and its tools and how to build against
libinput. libinput.
The build instruction on this page detail how to overwrite your The build instruction on this page detail how to overwrite your
system-provided libinput with one from the git repository, see system-provided libinput with one from the git repository,
see :ref:`reverting_install` to revert to the previous state. see :ref:`reverting_install` to revert to the previous state.
.. _distribution_repos: .. _distribution_repos:
@ -27,7 +27,7 @@ the latest libinput without building it manually.
.. note:: The list below is provided for convenience. The libinput community .. note:: The list below is provided for convenience. The libinput community
cannot provide any guarantees that the packages in those repositories are cannot provide any guarantees that the packages in those repositories are
correct, up-to-date and/or unmodified from the git branch. Due dilligence correct, up-to-date and/or unmodified from the git branch. Due diligence
is recommended. is recommended.
The following repositories provide an up-to-date package for libinput: The following repositories provide an up-to-date package for libinput:

View file

@ -30,7 +30,7 @@ The "bounce" method guarantees that all press events are delivered
immediately and most release events are delivered immediately. The immediately and most release events are delivered immediately. The
"spurious" method requires that release events are delayed, libinput thus "spurious" method requires that release events are delayed, libinput thus
does not enable this method unless a faulty event sequence is detected. A does not enable this method unless a faulty event sequence is detected. A
message is printed to the log when spurious deboucing was detected. message is printed to the log when spurious debouncing was detected.
libinput's debouncing is supposed to correct hardware damage or libinput's debouncing is supposed to correct hardware damage or
substandard hardware. Debouncing also exists as an accessibility feature substandard hardware. Debouncing also exists as an accessibility feature

View file

@ -60,7 +60,7 @@ is unfortunately not visibly obvious.
available. available.
If fingers are down in the main area in addition to fingers in the If fingers are down in the main area in addition to fingers in the
left or right button area, those fingers are are ignored. left or right button area, those fingers are ignored.
A release event always releases the buttons logically down, regardless of A release event always releases the buttons logically down, regardless of
the current finger position the current finger position
@ -77,7 +77,7 @@ The movement of a finger can alter the button area behavior:
- once a finger has moved out of the button area, it cannot move back in and - once a finger has moved out of the button area, it cannot move back in and
trigger a right or middle button event trigger a right or middle button event
- a finger moving within the software button area does not move the pointer - a finger moving within the software button area does not move the pointer
- once a finger moves out out of the button area it will control the - once a finger moves out of the button area it will control the
pointer (this only applies if there is no other finger down on the pointer (this only applies if there is no other finger down on the
touchpad) touchpad)

View file

@ -29,7 +29,7 @@ MyVendor OEM::
[MyVendor MyModel Touchpad] [MyVendor MyModel Touchpad]
MatchName=Foo Bar Touchpad MatchName=Foo Bar Touchpad
MatchUdevtype=touchpad MatchUdevtype=touchpad
MatchDMIModAlias=dmi:*svnMyVendor:pnMyModel:* MatchDMIModAlias=dmi:*:svnMyVendor:pnMyModel:*
AttrEventCode=-BTN_RIGHT AttrEventCode=-BTN_RIGHT
The name of the device can be obtained using :ref:`libinput record <libinput-record>`, The name of the device can be obtained using :ref:`libinput record <libinput-record>`,

View file

@ -6,15 +6,21 @@ Configuration options
Below is a list of configurable options exposed to the users. Below is a list of configurable options exposed to the users.
.. contents::
:depth: 1
:local:
.. hint:: Not all configuration options are available on all devices. Use .. hint:: Not all configuration options are available on all devices. Use
:ref:`libinput list-devices <libinput-list-devices>` to show the :ref:`libinput list-devices <libinput-list-devices>` to show the
configuration options for local devices. configuration options for local devices.
libinput's configuration interface is available to the caller only, not libinput's configuration interface is available to the caller only, not
directly to the user. Thus is is the responsibility of the caller to expose directly to the user. Thus it is the responsibility of the caller to expose
the various options and how these options are exposed. For example, the the various options and how these options are exposed. For example, the
xf86-input-libinput driver exposes the options through X Input device `xf86-input-libinput driver <https://gitlab.freedesktop.org/xorg/driver/xf86-input-libinput/>`_
properties and xorg.conf.d options. See the `libinput(4) exposes the options through X Input device properties and `xorg.conf.d
<https://linux.die.net/man/5/xorg.conf.d>`_ options. See the `libinput(4)
<https://www.mankier.com/4/libinput>`_ man page for more details. <https://www.mankier.com/4/libinput>`_ man page for more details.
@ -41,7 +47,7 @@ for those devices it is expected to be implemented by the toolkit.
Three-finger drag Three-finger drag
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
Three-finger drag allows emulates the mouse button down while three fingers Three-finger drag emulates the mouse button down while three fingers
are down on a touchpad without the need to press a physical button or use are down on a touchpad without the need to press a physical button or use
:ref:`tapndrag`. See :ref:`drag_3fg` for details on how this feature works. :ref:`tapndrag`. See :ref:`drag_3fg` for details on how this feature works.
@ -159,7 +165,7 @@ most touchpads.
Disable while trackpointing Disable while trackpointing
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
DWTP is a form of palm detecion for devices that have a trackpoint (like DWTP is a form of palm detection for devices that have a trackpoint (like
Thinkpads). While the user is using the trackpoint, the touchpad is disabled, Thinkpads). While the user is using the trackpoint, the touchpad is disabled,
being enabled again after a timeout. See :ref:`disable-while-trackpointing` for being enabled again after a timeout. See :ref:`disable-while-trackpointing` for
more info. more info.
@ -199,12 +205,24 @@ Tablet tool pressure range
The pressure range on a :ref:`Tablet tool <tablet-tools>` can be reduced The pressure range on a :ref:`Tablet tool <tablet-tools>` can be reduced
from the full available hardware range to a subset of that range. The effect from the full available hardware range to a subset of that range. The effect
of this is that the tablet will not register pressure below the given of this is that the tablet will not register pressure until the given
the given threshold is met, and will reach the maximum logical pressure threshold is met, and will reach the maximum logical pressure
before the maximum hardware-supported pressure is reached. before the maximum hardware-supported pressure is reached.
See :ref:`tablet-pressure-range` for more info. See :ref:`tablet-pressure-range` for more info.
.. _config-tablet-eraser-buttons:
------------------------------------------------------------------------------
Tablet tool eraser buttons
------------------------------------------------------------------------------
On many contemporary :ref:`Tablet tools <tablet-tools>` one button is hardcoded
in firmware to emulate an eraser. This button can be remapped to provide
a normal stylus button instead.
See :ref:`tablet-eraser-button` for more info.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
Area configuration Area configuration
------------------------------------------------------------------------------ ------------------------------------------------------------------------------

View file

@ -144,10 +144,9 @@ This test suite can take test names etc. as arguments, have a look at
:ref:`test-suite` for more info. There are a bunch of other tests that are :ref:`test-suite` for more info. There are a bunch of other tests that are
run by the CI on merge requests, you can run those locally with :: run by the CI on merge requests, you can run those locally with ::
$> sudo ninja -C builddir check $> sudo meson test -C builddir
So it always pays to run that before submitting. This will also run the code So it always pays to run that before submitting.
through valgrind and pick up any memory leaks.
.. _contributing_submitting_code: .. _contributing_submitting_code:
@ -181,7 +180,7 @@ sufficient to make some of the more confusing steps obvious.
with your username). git will call this repository ``gitlab``. :: with your username). git will call this repository ``gitlab``. ::
cd /path/to/libinput.git cd /path/to/libinput.git
git remote add gitlab git@gitlab.freedesktop.org:USERNAME/libinput.git git remote add gitlab git@ssh.gitlab.freedesktop.org:USERNAME/libinput.git
git fetch gitlab git fetch gitlab
- Create a new branch and commit your changes to that branch. :: - Create a new branch and commit your changes to that branch. ::

View file

@ -64,7 +64,7 @@ MOUSE_DPI
MOUSE_WHEEL_CLICK_ANGLE MOUSE_WHEEL_CLICK_ANGLE
The angle in degrees for each click on a mouse wheel. See The angle in degrees for each click on a mouse wheel. See
**libinput_pointer_get_axis_source()** for details. **libinput_event_pointer_get_axis_source()** for details.
Below is an example udev rule to assign "seat1" to a device from vendor Below is an example udev rule to assign "seat1" to a device from vendor
@ -94,7 +94,7 @@ type label does not guarantee that the device is initialized by libinput.
If a device fails to meet the requirements for a device type (e.g. a keyboard If a device fails to meet the requirements for a device type (e.g. a keyboard
labelled as touchpad) the device will not be available through libinput. labelled as touchpad) the device will not be available through libinput.
Only one device type should be set per device at a type, though libinput can Only one device type should be set per device at a time, though libinput can
handle some combinations for historical reasons. handle some combinations for historical reasons.
Below is an example udev rule to remove an **ID_INPUT_TOUCHPAD** setting Below is an example udev rule to remove an **ID_INPUT_TOUCHPAD** setting

View file

@ -23,7 +23,7 @@ the serial bus (PS/2) as internal keyboards: ::
[Serial Keyboards] [Serial Keyboards]
MatchUdevType=keyboard MatchUdevType=keyboard
MatchBus=serial MatchBus=ps2
AttrKeyboardIntegration=internal AttrKeyboardIntegration=internal
@ -46,7 +46,7 @@ Installing temporary local device quirks
The model quirks are part of the source distribution and should never be The model quirks are part of the source distribution and should never be
modified. For temporary local workarounds, libinput reads the modified. For temporary local workarounds, libinput reads the
``/etc/libinput/local-overrides.quirks`` file. Users may add a sections to ``/etc/libinput/local-overrides.quirks`` file. Users may add sections to
this file to add a device quirk for a local device but beware that **any this file to add a device quirk for a local device but beware that **any
modification must be upstreamed** or it may cease to work at any time. modification must be upstreamed** or it may cease to work at any time.
@ -130,7 +130,7 @@ Quirks starting with **Model*** triggers implementation-defined behaviour
for this device not needed for any other device. Only the more for this device not needed for any other device. Only the more
general-purpose **Model*** flags are listed here. general-purpose **Model*** flags are listed here.
ModelALPSTouchpad, ModelAppleTouchpad, ModelWacomTouchpad, ModelChromebook ModelALPSSerialTouchpad, ModelAppleTouchpad, ModelWacomTouchpad, ModelChromebook
Reserved for touchpads made by the respective vendors Reserved for touchpads made by the respective vendors
ModelTouchpadVisibleMarker ModelTouchpadVisibleMarker
Indicates the touchpad has a drawn-on visible marker between the software Indicates the touchpad has a drawn-on visible marker between the software
@ -148,6 +148,9 @@ ModelBouncingKeys
ModelSynapticsSerialTouchpad ModelSynapticsSerialTouchpad
Reserved for touchpads made by Synaptics on the serial bus Reserved for touchpads made by Synaptics on the serial bus
ModelPressurePad ModelPressurePad
.. warning:: This quirk is no longer in use. Use
``AttrInputProp=+INPUT_PROP_PRESSUREPAD`` instead.
Unlike in traditional touchpads, whose pressure value equals contact size, Unlike in traditional touchpads, whose pressure value equals contact size,
on pressure pads pressure is a real physical axis. on pressure pads pressure is a real physical axis.
Indicates that the device is a pressure pad. Indicates that the device is a pressure pad.
@ -155,9 +158,13 @@ ModelTouchpadPhantomClicks
Some laptops are prone to registering touchpad clicks when the case is Some laptops are prone to registering touchpad clicks when the case is
bent. Indicates that clicks should be ignored if no fingers are on the bent. Indicates that clicks should be ignored if no fingers are on the
touchpad. touchpad.
AttrSizeHint=NxM, AttrResolutionHint=N ModelScrollOnMiddleClick
Some mice can generate unwanted high-resolution scroll events when the wheel
is pressed. Increases the scroll threshold required to start scrolling to
avoid accidentally scrolling when middle clicking.
AttrSizeHint=NxM, AttrResolutionHint=NxM
Hints at the width x height of the device in mm, or the resolution Hints at the width x height of the device in mm, or the resolution
of the x/y axis in units/mm. These may only be used where they apply to of the x and y axes in units/mm. These may only be used where they apply to
a large proportion of matching devices. They should not be used for any a large proportion of matching devices. They should not be used for any
specific device, override ``EVDEV_ABS_*`` instead, see specific device, override ``EVDEV_ABS_*`` instead, see
:ref:`absolute_coordinate_ranges_fix`. :ref:`absolute_coordinate_ranges_fix`.
@ -195,6 +202,9 @@ AttrInputProp=+INPUT_PROP_BUTTONPAD;-INPUT_PROP_POINTER;
Enables or disables the evdev input property on the device. The prefix Enables or disables the evdev input property on the device. The prefix
for each entry is either '+' (enable) or '-' (disable). Entries may be for each entry is either '+' (enable) or '-' (disable). Entries may be
a named input property or the hexadecimal value of that property. a named input property or the hexadecimal value of that property.
The most common use of this is ``AttrInputProp=+INPUT_PROP_PRESSUREPAD``
which marks a touchpad as a :ref:`forcepad or pressurepad <touchpads_buttons_forcepads>`.
AttrPointingStickIntegration=internal|external AttrPointingStickIntegration=internal|external
Indicates the integration of the pointing stick. This is a string enum. Indicates the integration of the pointing stick. This is a string enum.
Only needed for external pointing sticks. These are rare. Only needed for external pointing sticks. These are rare.

View file

@ -0,0 +1,36 @@
digraph stack
{
compound=true;
splines=line;
rankdir="LR";
node [
shape="box";
]
subgraph cluster_2 {
label="Kernel";
event0 [label="/dev/input/event0"];
event1 [label="/dev/input/event1"];
}
subgraph cluster_0 {
label="Compositor process";
libinput [label="libinput context 1"];
}
subgraph cluster_1 {
label="libinput debug-events";
libinput2 [label="libinput context 2"];
}
stdout;
client [label="Wayland client"];
event0:e -> libinput:w;
event1:e -> libinput:w;
event0:e -> libinput2:w;
event1:e -> libinput2:w;
libinput -> client [ltail=cluster_0 label="Wayland protocol"];
libinput2 -> stdout [ltail=cluster_1];
}

View file

@ -0,0 +1,31 @@
digraph stack
{
compound=true;
rankdir="LR";
node [
shape="box";
]
subgraph cluster_2 {
label="Kernel";
event0 [label="/dev/input/event0"]
}
subgraph cluster_1 {
label="libinput";
subgraph cluster_0 {
label="Plugin pipeline";
p1 [label="00-foo.lua"];
p2 [label="10-bar.lua"];
}
libinput [label="libinput core"];
}
compositor [label="Compositor"];
event0 -> p1;
p1 -> p2;
p2 -> libinput;
libinput -> compositor [ltail=cluster_1 label="libinput API"];
}

View file

@ -348,10 +348,14 @@ compositor. This indicates a misunderstanding of how libinput works:
libinput is a library that converts kernel events into libinput events, much libinput is a library that converts kernel events into libinput events, much
like ``sed`` reads data in, modifies it, and provides it to stdout. like ``sed`` reads data in, modifies it, and provides it to stdout.
If ``sed`` is used by a shell-script, that script has full control over how .. graphviz:: libinput-contexts.gv
``sed`` processes data. In this analogy, ``sed`` is libinput and the
shell script is the compositor. It is not possible to write a program A libinput context is private to the process and cannot be modified from the
to modify the behavior of the ``sed`` instance used inside that shell script outside. To use the ``sed`` analogy again: if ``sed`` is used by a
shell-script, that script has full control over how ``sed`` processes data. In
this analogy, ``sed`` is libinput and the shell script is the compositor. It is
not possible to write a program to modify the behavior of the ``sed`` instance
used inside that shell script.
Writing a program that uses libinput is akin to writing a new script that Writing a program that uses libinput is akin to writing a new script that
invoke ``sed``. It will not have any effect on the original ``sed`` instance. invoke ``sed``. It will not have any effect on the original ``sed`` instance.
@ -360,6 +364,14 @@ The only way to modify libinput's behavior is to use the configuration options
exposed by the respective compositor. Those affect the libinput context inside exposed by the respective compositor. Those affect the libinput context inside
the compositor and thus have an effect on the input device behavior. the compositor and thus have an effect on the input device behavior.
.. _faq_debug_events_not_showing_configuration:
------------------------------------------------------------------------------
Why doesn't libinput debug-events show my configuration
------------------------------------------------------------------------------
See :ref:`faq_separate_contexts`.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
Can I configure scroll speed? Can I configure scroll speed?
------------------------------------------------------------------------------ ------------------------------------------------------------------------------

View file

@ -99,7 +99,7 @@ Hold gestures have three potential logical states:
- **begin**: one or more fingers are placed on the device at the same time - **begin**: one or more fingers are placed on the device at the same time
- **end**: all fingers are removed and the device enters a neutral logical state - **end**: all fingers are removed and the device enters a neutral logical state
- **end(cancelled)**: all fingers are part of a known interaction and the - **end(cancelled)**: all fingers are part of a known interaction and the
currenthold gesture is no longer active. This may also occurs when current hold gesture is no longer active. This may also occur when
switching between hold gestures with different finger counts. switching between hold gestures with different finger counts.
.. note:: By definition, a hold gesture does not move and thus no coordinate .. note:: By definition, a hold gesture does not move and thus no coordinate
@ -108,14 +108,15 @@ Hold gestures have three potential logical states:
For example, a user that puts one finger, then a second finger down and For example, a user that puts one finger, then a second finger down and
releases them later may trigger the following event sequence: releases them later may trigger the following event sequence:
============= ============ ============ ============= ============== ============
Action Event Finger count Action Event Finger count
============= ============ ============ ============= ============== ============
Finger 1 down <no event> Finger 1 down **begin** 1
Finger 2 down **begin** 2 Finger 2 down **cancel** 1
\ **begin** 2
Finger 2 up **end** 2 Finger 2 up **end** 2
Finger 1 up <no event> Finger 1 up <no event>
============= ============ ============ ============= ============== ============
A hold gesture may by be **cancelled**. This occurs A hold gesture may by be **cancelled**. This occurs
when the hold gesture changes into some other interaction and should no when the hold gesture changes into some other interaction and should no
@ -254,7 +255,8 @@ towards an interaction, see :ref:`thumb_detection` and
In the context of hold gestures, thumbs and palms are treated by libinput as In the context of hold gestures, thumbs and palms are treated by libinput as
if the finger was removed from the device. Where other non-thumb/non-palm if the finger was removed from the device. Where other non-thumb/non-palm
fingers remain on the device, an **hold update** event is sent. Otherwise, fingers remain on the device, the current hold gesture is cancelled and a
new **hold begin** event with the updated finger count is sent. Otherwise,
the hold gesture terminates with a **hold cancel** event. the hold gesture terminates with a **hold cancel** event.
Notably, libinput's thumb and palm detection is not a simple boolean per Notably, libinput's thumb and palm detection is not a simple boolean per
@ -359,7 +361,7 @@ Touchpoints are assigned in sequential order and only the first two touch
points are trackable. For libinput this produces an ambiguity where it is points are trackable. For libinput this produces an ambiguity where it is
impossible to detect whether a gesture is a pinch gesture or a swipe gesture impossible to detect whether a gesture is a pinch gesture or a swipe gesture
whenever a user puts the index and middle finger down first. Since the third whenever a user puts the index and middle finger down first. Since the third
finger does not have positional information, it's location cannot be finger does not have positional information, its location cannot be
determined. determined.
.. figure:: gesture-2fg-ambiguity.svg .. figure:: gesture-2fg-ambiguity.svg

View file

@ -21,7 +21,7 @@ input devices (see :ref:`udev_device_type`) but that should not be used by
libinput. It is recommended that devices that should not be handled as input libinput. It is recommended that devices that should not be handled as input
devices at all unset the **ID_INPUT** and related properties instead. The devices at all unset the **ID_INPUT** and related properties instead. The
**LIBINPUT_IGNORE_DEVICE** property signals that only libinput should **LIBINPUT_IGNORE_DEVICE** property signals that only libinput should
ignore this property but other parts of the stack (if any) should continue ignore this device but other parts of the stack (if any) should continue
treating this device normally. treating this device normally.
Below is an example udev rule to assign **LIBINPUT_IGNORE_DEVICE** to the Below is an example udev rule to assign **LIBINPUT_IGNORE_DEVICE** to the

View file

@ -12,6 +12,7 @@
troubleshooting troubleshooting
contributing contributing
development development
lua-plugins
API documentation <@HTTP_DOC_LINK@/api/> API documentation <@HTTP_DOC_LINK@/api/>

661
doc/user/lua-plugins.rst Normal file
View file

@ -0,0 +1,661 @@
.. _lua_plugins:
==============================================================================
Lua Plugins
==============================================================================
libinput provides a plugin system that allows users to modify the behavior
of devices. For example, a plugin may add or remove axes and/or buttons on a
device and/or modify the event stream seen by this device before it is passed
to libinput.
Plugins are implemented in `Lua <https://www.lua.org/>`_ (version 5.4)
and are typically loaded from the following paths:
- ``/etc/libinput/plugins/*.lua``, and
- ``/usr/lib{64}/libinput/plugins/*.lua``
Plugins are loaded in alphabetical order and where
multiple plugins share the same file name, the one in the highest precedence
directory is used. Plugins in ``/etc`` take precedence over
plugins in ``/usr``.
.. note:: Plugins lookup paths and their order are decided by the compositor.
Some compositors may support more/fewer/other lookup paths than the
above defaults.
Plugins are run sequentially in ascending sort-order (i.e. ``00-foo.lua`` runs
before ``10-bar.lua``) and each plugin sees the state left by any previous
plugins. For example if ``00-foo.lua`` changes all left button events to right
button events, ``10-bar.lua`` only ever sees right button events.
See the `Lua Reference manual <https://www.lua.org/manual/5.4/manual.html>`_ for
details on the Lua language.
.. note:: Plugins are **not** loaded by default, it is up to the compositor
whether to allow plugins. An explicit call to
``libinput_plugin_system_load_plugins()`` is required.
------------------------------------------------------------------------------
Limitations
------------------------------------------------------------------------------
Each script runs in its own sandbox and cannot communicate or share state with
other scripts.
Tables that hold API methods are not writable, i.e. it is not possible
to overwrite the default functionality of those APIs.
The Lua API available to plugins is limited to the following calls::
assert error ipairs next pairs tonumber
pcall select print tostring type xpcall
table string math _VERSION
It is not possible to e.g. use the ``io`` module from a script.
To use methods on instantiated objects, the ``object:method`` method call
syntax must be used. For example:
.. code-block:: lua
libinput:register()
libinput.register() -- this will fail
------------------------------------------------------------------------------
When to use plugins
------------------------------------------------------------------------------
libinput plugins are a relatively niche use-case that typically need to
address either once-off issues (e.g. those caused by worn-out hardware) or
user preferences that libinput does not and will not cater for.
Plugins should not be used for issues that can be fixed generically, for
example via :ref:`device-quirks`.
As a rule of thumb: a plugin should be a once-off that only works for one
user's hardware. If a plugin can be shared with many users then the plugin
implements functionality that should be integrated into libinput proper.
------------------------------------------------------------------------------
Testing plugins
------------------------------------------------------------------------------
Our :ref:`tools` support plugins if passed the ``--enable-plugins`` commandline
option. For implementing and testing plugins the easiest commands to test are
- ``libinput debug-events --enable-plugins`` (see :ref:`libinput-debug-events` docs)
- ``libinput debug-gui --enable-plugins`` (see :ref:`libinput-debug-gui` docs)
Where libinput is built and run from git, the tools will also look for plugins
in the meson build directory. See the ``plugins/meson.build`` file for details.
.. _plugins_api_lua:
--------------------------------------------------------------------------------
Lua Plugin API
--------------------------------------------------------------------------------
Lua plugins sit effectively below libinput and the API is not a
representation of the libinput API. Plugins modify the evdev event stream
received from the kernel.
.. graphviz:: plugin-stack.gv
The API revolves around two types: ``libinput`` and ``EvdevDevice``. The
``libinput`` type is used to register a plugin from a script, the
``EvdevDevice`` represents one device that is present in the system (but may
not have yet been added by libinput).
Typically a script does the following steps:
- register with libinput via ``libinput:register({versions})``
- connect to the ``"new-evdev-device"`` event
- receive an ``EvdevDevice`` object in the ``"new-evdev-device"`` callback
- check and/or modify the evdev event codes on the device
- connect to the device's ``"evdev-frame"`` event
- receive an :ref:`evdev frame <plugins_api_evdev_frame>` in the device's
``"evdev-frame"`` callback
- check and/or modify the events in that frame
Where multiple plugins are active, the evdev frame passed to the callback is
the combined frame as processed by all previous plugins in ascending sort order.
For example, if one plugin discards all button events subsequent plugins will
never see those button events in the frame.
.. _plugins_api_version_stability:
..............................................................................
Plugin version stability
..............................................................................
Plugin API version stability is provided on a best effort basis. We aim to provide
stable plugin versions for as long as feasible but may need to retire some older
versions over time. For this reason a plugin can select multiple versions it
implements, libinput will pick one supported version and adjust the plugin
behavior to match that version. See the ``libinput:register()`` call for details.
--------------------------------------------------------------------------------
Lua Plugin API Reference
--------------------------------------------------------------------------------
libinput provides the following globals and types:
.. _plugins_api_evdev_usage:
................................................................................
Evdev Usages
................................................................................
Evdev usages are a libinput-specific wrapper around the ``linux/input-event-codes.h``
evdev types and codes. They are used by libinput internally and are a 32-bit
combination of ``type << 16 | code``. Each usage carries the type and code and
is thus simpler to pass around and less prone to type confusion.
The :ref:`evdev global <plugins_api_evdev_global>` attempts to provide all
available usages but for the niche cases where it does not provide a named constant
the value can be crafted manually:
.. code-block:: lua
evdev_type = 0x2 -- EV_REL
evdev_code = 0x1 -- REL_Y
evdev_usage = (evdev_type << 16) | evdev_code
assert(usage == evdev.REL_Y)
.. _plugins_api_evdev_global:
................................................................................
The ``evdev`` global
................................................................................
The ``evdev`` global represents all known :ref:`plugins_api_evdev_usage`,
effectively in the form:
.. code-block:: lua
evdev = {
ABS_X = (3 << 16) | 0,
ABS_Y = (3 << 16) | 1,
...
REL_X = (2 << 16) | 0,
REL_Y = (2 << 16) | 1,
...
}
This global is provided for convenience to improve readability in the code.
Note that the name uses the event code name only (e.g. ``evdev.ABS_Y``) but the
value is an :ref:`Evdev Usage <plugins_api_evdev_usage>` (type and code).
See the ``linux/input-event-codes.h`` header file provided by your kernel
for a list of all evdev types and codes.
The evdev global also provides the bus type constants, e.g. ``evdev.BUS_USB``.
See the ``linux/input.h`` header file provided by your kernel
for a list of bus types.
.. _plugins_api_evdev_frame:
................................................................................
Evdev frames
................................................................................
Evdev frames represent a single frame of evdev events for a device. A frame
is a group of events that occurred at the same time. The frame usually only
contains state that has changed compared to the previous frame.
In our API a frame is exposed as a nested table with the following structure:
.. code-block:: lua
frame1 = {
{ usage = evdev.ABS_X, value = 123 },
{ usage = evdev.ABS_Y, value = 456 },
{ usage = evdev.BTN_LEFT, value = 1 },
}
frame2 = {
{ usage = evdev.ABS_Y, value = 457 },
}
frame3 = {
{ usage = evdev.ABS_X, value = 124 },
{ usage = evdev.BTN_LEFT, value = 0 },
}
.. note:: This API does not use ``SYN_REPORT`` events, it is implied at the
end of the table. Where a plugin writes a ``SYN_REPORT`` into the
list of events, that ``SYN_REPORT`` terminates the event frame
(similar to writing a ``\0`` into the middle of a C string).
A frame containing only a ``SYN_REPORT`` is functionally equivalent
to an empty frame.
Events or frames do not have a timestamp. Where a timestamp is required, that
timestamp is passed as additional argument to the function or return value.
See :ref:`plugins_api_evdev_global` for a list of known usages.
.. warning:: Evdev frames have an implementation-defined size limit of how many
events can be added to a single frame. This limit should never be
hit by valid plugins.
.. _plugins_api_libinputglobal:
................................................................................
The ``libinput`` global object
................................................................................
The core of our plugin API is the ``libinput`` global object. A script must
immediately ``register()`` to be active, otherwise it is unloaded immediately.
All libinput-specific APIs can be accessed through the ``libinput`` object.
.. function:: libinput:register({1, 2, ...})
Register this plugin with the given table of supported version numbers and
returns the version number selected by libinput for this plugin. See
:ref:`plugins_api_version_stability` for details.
.. code-block:: lua
-- this plugin can support versions 1, 4 and 5
version = libinput:register({1, 4, 5})
if version == 1 then
...
This function must be the first function called.
If the plugin calls any other functions before ``register()``, those functions
return the default zero value for the return type (``nil``, ``0``, an empty
table, etc.).
If the plugin does not call ``register()`` it will be removed immediately.
Once registered, any connected callbacks will be invoked whenever libinput
detects new devices, removes devices, etc.
This function must only be called once.
.. function:: libinput:unregister()
Unregister this plugin. This removes the plugin from libinput and releases
any resources associated with this plugin. This call must be the last call
in your plugin, it is effectively equivalent to Lua's
`os.exit() <https://www.lua.org/manual/5.4/manual.html#pdf-os.exit>`_.
.. function:: libinput:log_debug(message)
Log a message at the libinput debug log priority. See
``libinput:log_error()`` for details.
.. function:: libinput:log_info(message)
Log a message at the libinput info log priority. See
``libinput:log_error()`` for details.
.. function:: libinput:log_error(message)
Log a message at the libinput error log priority. Whether a message is
displayed in the log depends on libinput's log priority, set by the caller.
A compositor may disable stdout and stderr. Log messages should be preferred
over Lua's ``print()`` function to ensure the messages end up in the same
location as other libinput log messages and are not discarded.
.. function:: libinput:now()
Returns the current time in microseconds in ``CLOCK_MONOTONIC``. This is
the timestamp libinput uses internally. This timestamp cannot be mapped
to any particular time of day, see the
`clock_gettime() man page <https://man7.org/linux/man-pages/man3/clock_gettime.3.html>`_
for details.
.. function:: libinput:version()
Returns the agreed-on version of the plugin, see ``libinput:register()``.
If called before ``libinput:register()`` this function returns ``0``.
.. function:: libinput:connect(name, function)
Set the callback to the given event name. Only one callback
may be set for an event name at any time, subsequent callbacks
will replace any earlier callbacks for the same name.
Version 1 of the plugin API supports the following events and callback arguments:
- ``"new-evdev-device"``: A new :ref:`EvdevDevice <plugins_api_evdevdevice>`
has been seen by libinput but not yet added.
.. code-block:: lua
libinput:connect("new-evdev-device", function (device) ... end)
- ``"timer-expired"``: The timer for this plugin has expired. This event is
only sent if the plugin has set a timer with ``timer_set()``.
.. code-block:: lua
libinput:connect("timer-expired", function (now) ... end)
The ``now`` argument is the current time in microseconds in
``CLOCK_MONOTONIC`` (see ``libinput:now()``).
.. function:: libinput:timer_cancel()
Cancel the timer for this plugin. This is a no-op if the timer
has not been set or has already expired.
.. function:: libinput:timer_set_absolute(time)
Set a timer for this plugin, with the given time in microseconds.
The timeout specifies an absolute time in microseconds (see
``libinput:now()``) The timer will expire once and then call the
``"timer-expired"`` event handler (if any).
See ``libinput:timer_set_relative()`` for a relative timer.
The following two lines of code are equivalent:
.. code-block:: lua
libinput:timer_set_relative(1000000) -- 1 second from now
libinput:timer_set_absolute(libinput:now() + 1000000) -- 1 second from now
Calling this function will cancel any existing (relative or absolute) timer.
.. function:: libinput:timer_set_relative(timeout)
Set a timer for this plugin, with the given timeout in microseconds from
the current time. The timer will expire once and then call the
``"timer-expired"`` event handler (if any).
See ``libinput:timer_set_absolute()`` for an absolute timer.
The following two lines of code are equivalent:
.. code-block:: lua
libinput:timer_set_relative(1000000) -- 1 second from now
libinput:timer_set_absolute(libinput:now() + 1000000) -- 1 second from now
Calling this function will cancel any existing (relative or absolute) timer.
.. _plugins_api_evdevdevice:
................................................................................
The ``EvdevDevice`` type
................................................................................
The ``EvdevDevice`` type represents a device available in the system
but not (yet) added by libinput. This device may be used to modify
a device's capabilities before the device is processed by libinput.
A plugin should always ``connect()`` to the ``"device-removed"`` callback
to be notified when a device is removed. If the plugin keeps a reference
to this device but the device is discarded by libinput, the device's query
methods will return zero values (e.g. ``nil``, ``0``, an empty table) and
methods will be noops.
.. function:: EvdevDevice:info()
A table containing static information about the device, e.g.
.. code-block:: lua
{
bustype = evdev.BUS_USB,
vid = 0x1234,
pid = 0x5678,
}
A plugin must ignore keys it does not know about.
Version 1 of the plugin API supports the following keys and values:
- ``bustype``: The numeric bustype of the device. See the
``BUS_*`` defines in ``linux/input.h`` for the list of possible values.
- ``vid``: The 16-bit vendor ID of the device
- ``pid``: The 16-bit product ID of the device
If the device has since been discarded by libinput, this function returns an
empty table.
.. function:: EvdevDevice:name()
The device name as set by the kernel
.. function:: EvdevDevice:usages()
Returns a table of all usages that are currently enabled for this
device. Any type that exists on the device has a table assigned and in this
table any code that exists on the device is a boolean true.
For example:
.. code-block:: lua
{
evdev.REL_X = true,
evdev.REL_Y = true,
evdev.BTN_LEFT = true,
}
All other usages are ``nil``, so that the following code is possible:
.. code-block:: lua
local usages = device:usages()
if usages[evdev.REL_X] then
-- do something
end
If the device has since been discarded by libinput, this function returns an
empty table.
.. function:: EvdevDevice:absinfos()
Returns a table of all ``EV_ABS`` codes that are currently enabled for this device.
The event code is the key, each value is a table containing the following keys:
``minimum``, ``maximum``, ``fuzz``, ``flat``, ``resolution``.
.. code-block:: lua
{
evdev.ABS_X = {
minimum = 0,
maximum = 1234,
fuzz = 0,
flat = 0,
resolution = 45,
},
}
If the device has since been discarded by libinput, this function returns an
empty table.
.. function:: EvdevDevice:udev_properties()
Returns a table containing a filtered list of udev properties available on this device
in the form ``{ property_name = property_value, ... }``.
udev properties used as a boolean (e.g. ``ID_INPUT``) are only present if their
value is a logical true.
Version 1 of the plugin API supports the following udev properties:
- All of ``ID_INPUT_*`` that denote the device type as assigned
by udev. This information is usually used by libinput to determine a
device type. Note that for historical reasons these properties have
varying rules - some properties may be mutually exclusive, others are
independent, others may only be set if another property is set. Refer to
the udev documentation (if any) for details. ``ID_INPUT_WIDTH_MM`` and
``ID_INPUT_HEIGHT_MM`` are excluded from this set.
If the device has since been discarded by libinput, this function returns an
empty table.
.. function:: EvdevDevice:enable_evdev_usage(usage)
Enable the given :ref:`evdev usage <plugins_api_evdev_usage>` for this device.
Use :ref:`plugins_api_evdev_global` for better readability,
e.g. ``device:enable_evdev_usage(evdev.REL_X)``.
This function must not be used for ``ABS_*`` events, use ``set_absinfo()``
instead.
Once a usage is enabled, events for that usage may be added to a device's
frame.
If the device has since been discarded by libinput, this function does nothing.
.. function:: EvdevDevice:disable_evdev_usage(usage)
Disable the given :ref:`evdev usage <plugins_api_evdev_usage>` for this device.
Use :ref:`plugins_api_evdev_global` for better readability,
e.g. ``device:disable_evdev_usage(evdev.REL_X)``.
Once a usage is disabled, events for that usage are discarded from any
device frame.
If the device has since been discarded by libinput, this function does nothing.
.. function:: EvdevDevice:set_absinfo(usage, absinfo)
Set the absolute axis information for the given :ref:`evdev usage <plugins_api_evdev_usage>`
and enable it if it does not yet exist on the device. The ``absinfo`` argument is a table
containing zero or more of the following keys: ``minimum``, ``maximum``, ``fuzz``,
``flat``, ``resolution``. Any missing key defaults the corresponding
value from the device if the device already has this event usage or zero otherwise.
For example, the following code changes the resolution but leaves everything
else as-is:
.. code-block:: lua
local absinfo = {
resolution = 40,
}
device:set_absinfo(evdev.ABS_X, absinfo)
device:set_absinfo(evdev.ABS_Y, absinfo)
Use :ref:`plugins_api_evdev_global` for better readability as shown in the
example above.
If the device has since been discarded by libinput, this function does nothing.
.. note:: Overriding the absinfo values often indicates buggy firmware. This should
typically be fixed with an entry in the
`60-evdev.hwdb <https://github.com/systemd/systemd/blob/main/hwdb.d/60-evdev.hwdb>`_
or :ref:`device-quirks` instead of a plugin so all users of that
device can benefit from the fix.
.. function:: EvdevDevice:connect(name, function)
Set the callback to the given event name. Only one callback
may be set for an event name at any time, subsequent callbacks
will overwrite any earlier callbacks for the same name.
If the device has since been discarded by libinput, this function does nothing.
Version 1 of the plugin API supports the following events and callback arguments:
- ``"evdev-frame"``: A new :ref:`evdev frame <plugins_api_evdev_frame>` has
started for this device. If the callback returns a value other than
``nil``, that value is the frame with any modified events.
An empty frame (``{}``) causes libinput to drop the current event frame.
.. code-block:: lua
device:connect("evdev-frame", function (device, frame, timestamp)
-- change any event into a movement left by 1 pixel
move_left = {
{ usage = evdev.REL_X, value = -1, },
}
return move_left
end
The timestamp of an event frame is in microseconds in ``CLOCK_MONOTONIC``, see
``libinput:now()`` for details.
For performance reasons plugins that do not modify the event frame should
return ``nil`` (or nothing) instead of the event frame that was passed
as argument.
- ``"device-removed"``: This device was removed by libinput. This may happen
without the device ever becoming a libinput device as seen by libinput's
public API (e.g. if the device does not meet the requirements to be
added). Once this callback is invoked, the plugin should remove any
references to this device and stop using it.
.. code-block:: lua
device:connect("device-removed", function (device) ... end)
Functions to query the device's capabilities (e.g. ``usages()``) will
return an empty table.
.. function:: EvdevDevice:disconnect(name)
Disconnect the existing callback (if any) for the given event name. See
``EvdevDevice:connect()`` for a list of supported names.
.. function:: EvdevDevice:prepend_frame(frame)
Prepend an :ref:`evdev frame <plugins_api_evdev_frame>` for this device
**before** the current frame (if any). The **next** plugin will see the
prepended frame first followed by the current frame.
This function can only be called from within a device's ``"evdev-frame"``
handler or from within the plugin's timer callback function.
For example, to change a single event into a drag, prepend a button
down and append a button up before each event:
.. code:: lua
function frame_handler(device, frame, timestamp)
device:prepend_frame({
{ usage = evdev.BTN_LEFT, value = 1}
})
device:append_frame({
{ usage = evdev.BTN_LEFT, value = 0}
})
return nil -- return the current frame unmodified
-- The next plugin sees the event sequence:
-- button down, frame, button up
end
If called from within the plugin's timer there is no current frame and this
function is identical to ``append_frame()``.
.. function:: EvdevDevice:append_frame(frame)
Appends an :ref:`evdev frame <plugins_api_evdev_frame>` for this device
**after** the current frame (if any). This function can only be called from
within a device's ``"evdev-frame"`` handler or from within the plugin's timer
callback function.
If called from within the plugin's timer there is no current frame and this
function is identical to ``prepend_frame()``.
See ``prepend_frame()`` for more details.
.. function:: EvdevDevice:disable_feature(feature_name)
Disable the given libinput-internal feature for this device. This should be used
by plugins that replace that feature with a custom implementation for this device.
libinput may have multiple internal implementations for any given feature, disabling
it via this API disables any and all of those implementations, causing the feature to
no longer work at all. It is up to the plugin implementation to re-implement that
feature to match the user's expectation.
Version 1 of the plugin API supports the following features:
- ``"button-debouncing"``: see :ref:`button_debouncing`
- ``"touchpad-hysteresis"``: see :ref:`touchpad_jitter`
- ``"touchpad-jump-detection"``: see :ref:`touchpad_jumping_cursor`
- ``"touchpad-palm-detection"``: see :ref:`palm_detection`
- ``"wheel-debouncing"``: some high-resolution mouse wheel movements inside libinput
are delayed and/or modified

View file

@ -95,11 +95,13 @@ src_rst = files(
# dot drawings # dot drawings
'dot/seats-sketch.gv', 'dot/seats-sketch.gv',
'dot/seats-sketch-libinput.gv', 'dot/seats-sketch-libinput.gv',
'dot/libinput-contexts.gv',
'dot/libinput-stack-wayland.gv', 'dot/libinput-stack-wayland.gv',
'dot/libinput-stack-xorg.gv', 'dot/libinput-stack-xorg.gv',
'dot/libinput-stack-gnome.gv', 'dot/libinput-stack-gnome.gv',
'dot/evemu.gv', 'dot/evemu.gv',
'dot/libinput-record.gv', 'dot/libinput-record.gv',
'dot/plugin-stack.gv',
# svgs # svgs
'svg/button-debouncing-wave-diagram.svg', 'svg/button-debouncing-wave-diagram.svg',
'svg/button-scrolling.svg', 'svg/button-scrolling.svg',
@ -129,6 +131,7 @@ src_rst = files(
'svg/tablet-intuos-modes.svg', 'svg/tablet-intuos-modes.svg',
'svg/tablet-left-handed.svg', 'svg/tablet-left-handed.svg',
'svg/tablet-out-of-bounds.svg', 'svg/tablet-out-of-bounds.svg',
'svg/tablet-touch-arbitration.svg',
'svg/tablet.svg', 'svg/tablet.svg',
'svg/tap-n-drag.svg', 'svg/tap-n-drag.svg',
'svg/thumb-detection.svg', 'svg/thumb-detection.svg',
@ -155,6 +158,7 @@ src_rst = files(
'middle-button-emulation.rst', 'middle-button-emulation.rst',
'normalization-of-relative-motion.rst', 'normalization-of-relative-motion.rst',
'palm-detection.rst', 'palm-detection.rst',
'lua-plugins.rst',
'pointer-acceleration.rst', 'pointer-acceleration.rst',
'reporting-bugs.rst', 'reporting-bugs.rst',
'scrolling.rst', 'scrolling.rst',

View file

@ -14,7 +14,7 @@ touch the bottom edges of the touchpad during normal interaction.
Interference from a palm depends on the size of the touchpad and the position Interference from a palm depends on the size of the touchpad and the position
of the user's hand. Data from touchpads showed that almost all palm events of the user's hand. Data from touchpads showed that almost all palm events
during tying on a Lenovo T440 happened in the left-most and right-most 5% of during typing on a Lenovo T440 happened in the left-most and right-most 5% of
the touchpad. The T440 series has one of the largest touchpads, other the touchpad. The T440 series has one of the largest touchpads, other
touchpads are less affected by palm touches. touchpads are less affected by palm touches.
@ -52,7 +52,7 @@ Palm detection based on pressure
The simplest form of palm detection labels a touch as palm when the pressure The simplest form of palm detection labels a touch as palm when the pressure
value goes above a certain threshold. This threshold is usually high enough value goes above a certain threshold. This threshold is usually high enough
that it cannot be triggered by a finger movement. One a touch is labelled as that it cannot be triggered by a finger movement. Once a touch is labelled as
palm based on pressure, it will remain so even if the pressure drops below palm based on pressure, it will remain so even if the pressure drops below
the threshold again. This ensures that a palm remains a palm even when the the threshold again. This ensures that a palm remains a palm even when the
pressure changes as the user is typing. pressure changes as the user is typing.
@ -187,7 +187,7 @@ Stylus-touch arbitration
A special case of palm detection is touch arbitration on devices that A special case of palm detection is touch arbitration on devices that
support styli. When interacting with a stylus on the screen, parts of the support styli. When interacting with a stylus on the screen, parts of the
hand may touch the surface and trigger touches. As the user is currently hand may touch the surface and trigger touches. As the user is currently
interacting with the stylus, these touches would interfer with the correct interacting with the stylus, these touches would interfere with the correct
working of the stylus. working of the stylus.
libinput employs a method similar to :ref:`disable-while-typing` to detect libinput employs a method similar to :ref:`disable-while-typing` to detect

View file

@ -39,7 +39,7 @@ Velocity calculation
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
The device's speed of movement is measured across multiple input events The device's speed of movement is measured across multiple input events
through so-called "trackers". Each event prepends a the tracker item, each through so-called "trackers". Each event prepends a tracker item, each
subsequent tracker contains the delta of that item to the current position, subsequent tracker contains the delta of that item to the current position,
the timestamp of the event that created it and the cardinal direction of the the timestamp of the event that created it and the cardinal direction of the
movement at the time. If a device moves into the same direction, the movement at the time. If a device moves into the same direction, the

View file

@ -113,8 +113,8 @@ When you file a bug, please attach the following information:
- the output from udevadm info, see :ref:`udev_info`. - the output from udevadm info, see :ref:`udev_info`.
- the vendor model number of your laptop (e.g. "Lenovo Thinkpad T440s") - the vendor model number of your laptop (e.g. "Lenovo Thinkpad T440s")
- and the content of ``/sys/class/dmi/id/modalias``. - and the content of ``/sys/class/dmi/id/modalias``.
- run the ``touchpad-edge-detector`` tool (provided by libevdev) and verify - run ``libinput measure touchpad-size`` tool (see :ref:`absolute_coordinate_ranges_fix`)
that the ranges and sizes it prints match the touchpad (up to 5mm and verify that the ranges and sizes it prints match the touchpad (up to 5mm
difference is ok) difference is ok)
If you are reporting a bug related to button event generation: If you are reporting a bug related to button event generation:
@ -185,7 +185,7 @@ When you file a bug, please attach the following information:
- a virtual description of your input device, see :ref:`libinput-record`. - a virtual description of your input device, see :ref:`libinput-record`.
This is the most important piece of information, do not forget it! This is the most important piece of information, do not forget it!
- the vendor model number of the device (e.g. "Sony Plastation3 controller") - the vendor model number of the device (e.g. "Sony PlayStation3 controller")
.. _udev_info: .. _udev_info:
@ -368,7 +368,7 @@ them.
without someone stepping up to do the work. If you do see this tag, do ask without someone stepping up to do the work. If you do see this tag, do ask
for guidance on how to implement it. for guidance on how to implement it.
- **hw issue**: an issue that affects a specific device and is a hardware - **hw issue**: an issue that affects a specific device and is a hardware
bug, not a software bug. Often these needs to be worked around in libinput bug, not a software bug. Often these need to be worked around in libinput
but there are cases where a hw issue ends up as *cantfix*. but there are cases where a hw issue ends up as *cantfix*.
- **janitor**: a cleanup task that does not substantially affect how - **janitor**: a cleanup task that does not substantially affect how
libinput works. These are usually good bugs for newcomers to start on. libinput works. These are usually good bugs for newcomers to start on.
@ -389,7 +389,7 @@ them.
*cantfix*. *cantfix*.
- **wontfix**: this issue will not get fixed. This tag is usually assigned - **wontfix**: this issue will not get fixed. This tag is usually assigned
to feature requests that are outside the scope of libinput or would put an to feature requests that are outside the scope of libinput or would put an
unreasonable maintenance burdern on the maintainers. unreasonable maintenance burden on the maintainers.
These tags are high-level categories only, always look for the comments in These tags are high-level categories only, always look for the comments in
the issue to get further details. the issue to get further details.

View file

@ -12,7 +12,7 @@ one can be enabled at a time. As a general overview:
- touchpad devices with physical buttons below the touchpad support edge and - touchpad devices with physical buttons below the touchpad support edge and
two-finger scrolling two-finger scrolling
- touchpad devices without physical buttons (:ref:`ClickPads <clickpad_softbuttons>`) - touchpad devices without physical buttons (:ref:`ClickPads <clickpad_softbuttons>`)
support two-finger scrolling only support two-finger scrolling and edge scrolling
- pointing sticks provide on-button scrolling by default - pointing sticks provide on-button scrolling by default
- mice and other pointing devices support on-button scrolling but it is not - mice and other pointing devices support on-button scrolling but it is not
enabled by default enabled by default
@ -124,6 +124,12 @@ button lock, the button is now considered logically held down. Pressing and
releasing the button a second time logically releases the button. While the releasing the button a second time logically releases the button. While the
button is logically held down, motion events are converted to scroll events. button is logically held down, motion events are converted to scroll events.
If the button is held and used to scroll for longer than a short grace
period, releasing the button does not engage the lock. This allows
hold-to-scroll for short, precise adjustments without accidentally toggling
the lock. A quick click or a brief scroll within the grace period still
engages the lock as normal.
.. _scroll_sources: .. _scroll_sources:
------------------------------------------------------------------------------ ------------------------------------------------------------------------------

View file

@ -43,7 +43,7 @@ Thus, devices "Foo" and "Bar" both reference the same struct
The effect of seat assignment The effect of seat assignment
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
A logical set is interpreted as a group of devices that usually belong to a A logical seat is interpreted as a group of devices that usually belong to a
single user that interacts with a computer. Thus, the devices are single user that interacts with a computer. Thus, the devices are
semantically related. This means for devices within the same logical seat: semantically related. This means for devices within the same logical seat:

View file

@ -0,0 +1,245 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="229.5488mm"
height="86.66362mm"
viewBox="0 0 813.36188 307.07582"
id="svg2"
version="1.1"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
sodipodi:docname="tablet-touch-arbitration.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4294"
id="linearGradient4300"
x1="465.81339"
y1="666.13727"
x2="454.82117"
y2="658.65521"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
id="linearGradient4294">
<stop
style="stop-color:#1a1a1a;stop-opacity:1;"
offset="0"
id="stop4296" />
<stop
style="stop-color:#808080;stop-opacity:1"
offset="1"
id="stop4298" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4294"
id="linearGradient3"
gradientUnits="userSpaceOnUse"
x1="465.81339"
y1="666.13727"
x2="454.82117"
y2="658.65521" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8"
inkscape:cx="410.71429"
inkscape:cy="188.57143"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="false"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="3072"
inkscape:window-height="1629"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:showpageshadow="2"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="tablet"
inkscape:groupmode="layer"
id="layer1"
style="display:inline"
transform="translate(67.109152,-133.63374)">
<g
id="g4309"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
transform="translate(0,1.0715222)">
<rect
y="134.15933"
x="75.787216"
height="306.02466"
width="522.19733"
id="rect4136"
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:1.05118;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:4.20473, 1.05118;stroke-dashoffset:0;stroke-opacity:1" />
<rect
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.748138;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:2.99255, 0.748138;stroke-dashoffset:0;stroke-opacity:1"
id="rect4140"
width="357.34042"
height="226.52563"
x="199.33878"
y="175.42407" />
<rect
y="175.72914"
x="103.10225"
height="22.142857"
width="65"
id="rect4142"
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
<rect
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1"
id="rect4148"
width="65"
height="22.142857"
x="103.10225"
y="203.72914" />
<rect
y="231.72913"
x="103.10225"
height="22.142857"
width="65"
id="rect4150"
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
<rect
y="323.72913"
x="103.10225"
height="22.142857"
width="65"
id="rect4154"
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
<rect
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1"
id="rect4156"
width="65"
height="22.142857"
x="103.10225"
y="351.72913" />
<circle
r="22.98097"
cy="287.06125"
cx="135.61298"
id="path4158"
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
<ellipse
ry="12.608653"
rx="11.5985"
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.520431;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:2.08172, 0.520431;stroke-dashoffset:0;stroke-opacity:1"
id="circle4160"
cx="135.61298"
cy="287.06125" />
<rect
y="379.72913"
x="103.10225"
height="22.142857"
width="65"
id="rect4162"
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
</g>
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="area">
<rect
style="display:inline;fill:#a44d4d;fill-opacity:1;stroke:none;stroke-width:0.930358"
id="rect1"
width="139.07858"
height="226.89969"
x="485.08383"
y="42.487785" />
<rect
style="display:inline;fill:#a44d4d;fill-opacity:1;stroke:none;stroke-width:1.02823"
id="rect3"
width="169.87961"
height="226.89969"
x="266.07385"
y="42.487785" />
</g>
<g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="stylus"
style="display:inline"
transform="translate(67.109152,-133.63374)">
<g
id="g4304"
transform="matrix(0.37129971,0.09948946,-0.09618892,0.35898192,369.23868,-8.3227001)"
style="display:inline">
<path
sodipodi:nodetypes="czcc"
inkscape:connector-curvature="0"
id="path4286"
d="m 387.83544,799.76093 c -1.1128,3.61694 -3.2211,13.05163 -1.08543,14.07769 2.13567,1.02606 7.81039,-3.72162 10.99756,-6.69095 z"
style="display:inline;fill:#cccccc;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ssssccssscsssssssssssssssssss"
inkscape:connector-curvature="0"
id="path4283"
d="m 392.64431,804.79039 c -8.52094,-5.90399 -8.49394,-11.01546 0.22879,-43.30647 1.03999,-3.85 2.46829,-9.67602 3.17399,-12.9467 0.99731,-4.62219 2.39455,-7.29497 6.27321,-12 2.74456,-3.32932 5.25157,-6.2783 5.57113,-6.5533 40.78433,-60.97488 80.48307,-125.1652 118.27253,-184 9.86283,-15.675 26.59424,-42.225 37.18089,-59 10.58666,-16.775 34.01422,-53.9 52.06125,-82.5 18.04703,-28.6 35.04505,-55.31677 37.77338,-59.37059 l 4.9606,-7.3706 4.1828,0.57332 c 4.16371,0.5707 4.19706,0.54958 7.30887,-4.62941 3.75631,-6.2516 8.82067,-11.57582 12.2516,-12.88026 5.99391,-2.27888 14.03303,2.9506 14.03303,9.12854 0,3.90203 -2.51704,10.62127 -6.02878,16.09385 -1.63417,2.54664 -2.97122,4.85949 -2.97122,5.13969 0,0.28019 0.9,1.54715 2,2.81546 2.28453,2.63408 2.47267,4.21918 0.86833,7.31574 -1.28218,2.47476 -26.61383,45.18798 -55.85724,94.18426 -10.83283,18.15 -25.72943,43.1137 -33.10357,55.47489 -7.37413,12.3612 -13.69273,23.17153 -14.04131,24.02297 -0.34859,0.85144 -7.50972,12.78774 -15.91363,26.52511 -15.54138,25.40455 -32.24417,52.9052 -70.74345,116.47703 -40.26028,66.47968 -43.66308,72.46026 -49.21634,86.5 -1.74036,4.4 -3.92035,8.675 -4.8444,9.5 -0.92405,0.825 -4.36246,3.75 -7.6409,6.5 -3.27845,2.75 -9.57132,8.3067 -13.98415,12.34823 -10.62726,9.73304 -16.99729,13.87361 -22.52334,14.64034 -3.99187,0.55386 -5.03885,0.251 -9.27207,-2.6821 z"
style="display:inline;fill:#000000" />
<path
sodipodi:nodetypes="scccs"
inkscape:connector-curvature="0"
id="path4292"
d="m 450.89044,688.88586 c 8.71518,5.62513 45.74035,-59.18436 43.57923,-75.43494 l -7.07107,-6.56599 c -29.93081,25.86352 -47.78438,74.72281 -47.78438,74.72281 z"
style="fill:url(#linearGradient4300);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
id="g3"
transform="matrix(-0.37129971,0.09948946,0.09618892,0.35898192,416.04226,-44.344847)"
style="display:inline">
<path
sodipodi:nodetypes="czcc"
inkscape:connector-curvature="0"
id="path1"
d="m 387.83544,799.76093 c -1.1128,3.61694 -3.2211,13.05163 -1.08543,14.07769 2.13567,1.02606 7.81039,-3.72162 10.99756,-6.69095 z"
style="display:inline;fill:#cccccc;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ssssccssscsssssssssssssssssss"
inkscape:connector-curvature="0"
id="path2"
d="m 392.64431,804.79039 c -8.52094,-5.90399 -8.49394,-11.01546 0.22879,-43.30647 1.03999,-3.85 2.46829,-9.67602 3.17399,-12.9467 0.99731,-4.62219 2.39455,-7.29497 6.27321,-12 2.74456,-3.32932 5.25157,-6.2783 5.57113,-6.5533 40.78433,-60.97488 80.48307,-125.1652 118.27253,-184 9.86283,-15.675 26.59424,-42.225 37.18089,-59 10.58666,-16.775 34.01422,-53.9 52.06125,-82.5 18.04703,-28.6 35.04505,-55.31677 37.77338,-59.37059 l 4.9606,-7.3706 4.1828,0.57332 c 4.16371,0.5707 4.19706,0.54958 7.30887,-4.62941 3.75631,-6.2516 8.82067,-11.57582 12.2516,-12.88026 5.99391,-2.27888 14.03303,2.9506 14.03303,9.12854 0,3.90203 -2.51704,10.62127 -6.02878,16.09385 -1.63417,2.54664 -2.97122,4.85949 -2.97122,5.13969 0,0.28019 0.9,1.54715 2,2.81546 2.28453,2.63408 2.47267,4.21918 0.86833,7.31574 -1.28218,2.47476 -26.61383,45.18798 -55.85724,94.18426 -10.83283,18.15 -25.72943,43.1137 -33.10357,55.47489 -7.37413,12.3612 -13.69273,23.17153 -14.04131,24.02297 -0.34859,0.85144 -7.50972,12.78774 -15.91363,26.52511 -15.54138,25.40455 -32.24417,52.9052 -70.74345,116.47703 -40.26028,66.47968 -43.66308,72.46026 -49.21634,86.5 -1.74036,4.4 -3.92035,8.675 -4.8444,9.5 -0.92405,0.825 -4.36246,3.75 -7.6409,6.5 -3.27845,2.75 -9.57132,8.3067 -13.98415,12.34823 -10.62726,9.73304 -16.99729,13.87361 -22.52334,14.64034 -3.99187,0.55386 -5.03885,0.251 -9.27207,-2.6821 z"
style="display:inline;fill:#000000" />
<path
sodipodi:nodetypes="scccs"
inkscape:connector-curvature="0"
id="path3"
d="m 450.89044,688.88586 c 8.71518,5.62513 45.74035,-59.18436 43.57923,-75.43494 l -7.07107,-6.56599 c -29.93081,25.86352 -47.78438,74.72281 -47.78438,74.72281 z"
style="fill:url(#linearGradient3);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -4,9 +4,9 @@
Switches Switches
============================================================================== ==============================================================================
libinput supports the lid and tablet-mode switches. Unlike button events libinput supports the lid, tablet-mode, and keypad slide switches. Unlike
that come in press and release pairs, switches are usually toggled once and button events that come in press and release pairs, switches are usually
left at the setting for an extended period of time. toggled once and left at the setting for an extended period of time.
Only some switches are handled by libinput, see **libinput_switch** for a Only some switches are handled by libinput, see **libinput_switch** for a
list of supported switches. Switch events are exposed to the caller, but list of supported switches. Switch events are exposed to the caller, but
@ -59,3 +59,20 @@ tablet mode is disengaged.
This handling of tablet mode switches is transparent to the user, no This handling of tablet mode switches is transparent to the user, no
notifications are sent and the device appears as enabled at all times. notifications are sent and the device appears as enabled at all times.
.. _switches_keypad_slide:
------------------------------------------------------------------------------
Keypad slide switch handling
------------------------------------------------------------------------------
Where available, libinput listens to devices providing a keypad slide switch.
This is usually available on devices that have an always-attached physical
keyboard which can slide under the screen. An example of such a device is the
Nokia N900.
The event sent by the kernel is ``EV_SW`` ``SW_KEYPAD_SLIDE`` and is provided
as **LIBINPUT_SWITCH_KEYPAD_SLIDE**. The keypad slide switch does not cause any
other input devices to be enabled nor disabled in response, since on some
devices the kernel event is sent while the keyboard is partially visible and
thus usable.

View file

@ -58,7 +58,7 @@ event of type **LIBINPUT_EVENT_TABLET_TOOL_TIP**, and again when the tip
ceases contact with the surface. ceases contact with the surface.
Tablet tools may send button events; these are exclusively for extra buttons Tablet tools may send button events; these are exclusively for extra buttons
unrelated to the tip. A button event is independent of the tip and can while unrelated to the tip. A button event is independent of the tip and can occur while
the tip is down or up. the tip is down or up.
Some tablet tools' pressure detection is too sensitive, causing phantom Some tablet tools' pressure detection is too sensitive, causing phantom
@ -67,7 +67,7 @@ tools are capable of detecting 1 gram of pressure.
libinput uses a device-specific pressure threshold to determine when the tip libinput uses a device-specific pressure threshold to determine when the tip
is considered logically down. As a result, libinput may send a nonzero is considered logically down. As a result, libinput may send a nonzero
pressure value while the tip is logically up. Most application can and pressure value while the tip is logically up. Most applications can and
should ignore pressure information until they receive the event of type should ignore pressure information until they receive the event of type
**LIBINPUT_EVENT_TABLET_TOOL_TIP**. Applications that require extremely **LIBINPUT_EVENT_TABLET_TOOL_TIP**. Applications that require extremely
fine-grained pressure sensitivity should use the pressure data instead of fine-grained pressure sensitivity should use the pressure data instead of
@ -100,7 +100,7 @@ all pen-like tools to absolute mode.
If a tool in relative mode must not use pointer acceleration, callers If a tool in relative mode must not use pointer acceleration, callers
should use the absolute coordinates returned by should use the absolute coordinates returned by
**libinput_event_tablet_tool_get_x()** and libinput_event_tablet_tool_get_y() **libinput_event_tablet_tool_get_x()** and **libinput_event_tablet_tool_get_y()**
and calculate the delta themselves. Callers that require exact physical and calculate the delta themselves. Callers that require exact physical
distance should also use these functions to calculate delta movements. distance should also use these functions to calculate delta movements.
@ -284,7 +284,7 @@ with **libinput_tablet_tool_get_tool_id()** but makes no promises about the
content or format of the ID. content or format of the ID.
libinput currently supports Wacom-style tool IDs as provided on the Wacom libinput currently supports Wacom-style tool IDs as provided on the Wacom
Intuos 3, 4, 5, Wacon Cintiq and Wacom Intuos Pro series. The tool ID can Intuos 3, 4, 5, Wacom Cintiq and Wacom Intuos Pro series. The tool ID can
be used to distinguish between e.g. a Wacom Classic Pen or a Wacom Pro Pen. be used to distinguish between e.g. a Wacom Classic Pen or a Wacom Pro Pen.
It is the caller's responsibility to interpret the tool ID. It is the caller's responsibility to interpret the tool ID.
@ -357,7 +357,7 @@ tablet by 180 degrees to move the tablet pad button area to right side of
the tablet. When left-handed mode is enabled on a tablet device (see the tablet. When left-handed mode is enabled on a tablet device (see
**libinput_device_config_left_handed_set()**) the tablet tool and tablet pad **libinput_device_config_left_handed_set()**) the tablet tool and tablet pad
behavior changes. In left-handed mode, the tools' axes are adjusted behavior changes. In left-handed mode, the tools' axes are adjusted
so that the origin of each axis remains the logical north-east of so that the origin of each axis remains the logical north-west of
the physical tablet. For example, the x and y axes are inverted and the the physical tablet. For example, the x and y axes are inverted and the
positive x/y coordinates are down/right of the top-left corner of the tablet positive x/y coordinates are down/right of the top-left corner of the tablet
in its current orientation. On a tablet pad, the ring and strip are in its current orientation. On a tablet pad, the ring and strip are
@ -401,7 +401,7 @@ caller to decide whether the mode only applies to buttons, rings and strips
or only to rings and strips (this is the case with the Wacom OS X and or only to rings and strips (this is the case with the Wacom OS X and
Windows driver). Windows driver).
The availability of modes on a touchpad usually depends on visual feedback The availability of modes on a tablet pad usually depends on visual feedback
such as LEDs around the touch ring. If no visual feedback is available, only such as LEDs around the touch ring. If no visual feedback is available, only
one mode may be available. one mode may be available.
@ -466,7 +466,21 @@ devices arbitration has to be done in userspace.
libinput uses the **libinput_device_group** to decide on touch arbitration libinput uses the **libinput_device_group** to decide on touch arbitration
and automatically discards touch events whenever a tool is in proximity. and automatically discards touch events whenever a tool is in proximity.
The exact behavior is device-dependent. The exact behavior is device-dependent but typically comes in two forms: full
tablet touch arbitration and partial arbitration.
.. figure:: tablet-touch-arbitration.svg
:align: center
Partial touch arbitration during a pen interaction for left-handed
and right-handed pen tilt.
Full arbitration simply disables touch on the device while the pen is in
proximity. Partial touch arbitration disables the side of the tablet around the
user's hand, starting slightly to the side of the pen tip. If the pen tilts
to the left (pen held in the left hand), the rectangle is to the left of the
pen tip, if the pen tilts to the right (pen held in the right hand) it is to
the right of the pen tip.
.. _tablet-area: .. _tablet-area:
@ -509,7 +523,7 @@ tip of the tool - inverting the tool brings the eraser into proximity.
.. figure:: tablet-eraser-invert.svg .. figure:: tablet-eraser-invert.svg
:align: center :align: center
An pen-like tool used as pen and as eraser by inverting it A pen-like tool used as pen and as eraser by inverting it
Having an eraser as a separate tool is beneficial in many applications as the Having an eraser as a separate tool is beneficial in many applications as the
eraser tool can be assigned different functionality (colors, paint tools, etc.) eraser tool can be assigned different functionality (colors, paint tools, etc.)
@ -524,7 +538,7 @@ into proximity immediately after - as if the tool was physically inverted.
.. figure:: tablet-eraser-button.svg .. figure:: tablet-eraser-button.svg
:align: center :align: center
An pen-like tool used as pen and as eraser by pressing the eraser button A pen-like tool used as pen and as eraser by pressing the eraser button
Microsoft mandates this behavior (see Microsoft mandates this behavior (see
`Windows Pen States <https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-pen-states>`_ `Windows Pen States <https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-pen-states>`_
@ -541,4 +555,4 @@ is disabled, pressing that button will generate a normal tablet tool button
event. event.
This configuration is only available on pens with an eraser button, not on This configuration is only available on pens with an eraser button, not on
with an invert-type eraser. pens with an invert-type eraser.

View file

@ -59,13 +59,16 @@ tap-and-drag enabled by default.
middle-click drag, tap with three fingers followed by a middle-click drag, tap with three fingers followed by a
single-finger drag. single-finger drag.
Also optional is a feature called "drag lock". With drag lock disabled, lifting Also optional is a feature called "drag lock". With drag lock **disabled**,
the finger will stop any drag process. When enabled, the drag lifting the finger will stop any drag process. When **enabled**, the drag
process continues even after lifting a finger but can be ended process continues even after lifting a finger, allowing the user to
with an additional tap. If timeout-based drag-locks are enabled reset the finger position and keep moving without releasing the drag.
the drag process will also automatically end once the finger has
been lifted for an implementation-specific timeout. Drag lock can be libinput supports two variations of this drag lock: "sticky" and "timeout".
enabled and disabled with **libinput_device_config_tap_set_drag_lock_enabled()**. In sticky mode, the drag lock must be ended with an explicit additional tap.
In timeout mode, the drag lock ends automatically if no finger was put back on
the touchpad within a timeout. Drag lock can be enabled and disabled with
**libinput_device_config_tap_set_drag_lock_enabled()**.
Note that drag lock only applies if tap-and-drag is enabled. Note that drag lock only applies if tap-and-drag is enabled.
.. figure:: tap-n-drag.svg .. figure:: tap-n-drag.svg
@ -81,11 +84,13 @@ position can be reset by lifting and quickly setting it down again on the
touchpad (d). This will be interpreted as continuing move and is especially touchpad (d). This will be interpreted as continuing move and is especially
useful on small touchpads or with slow pointer acceleration. useful on small touchpads or with slow pointer acceleration.
If drag lock is enabled, the release of the mouse buttons after the finger If drag lock is enabled, the release of the mouse buttons after the finger
release (e) is triggered by a timeout. To release the button immediately, release (e) is triggered by a timeout (if in timeout mode) or by tapping again (f).
simply tap again (f).
If drag lock is enabled in sticky mode there is no timeout after libinput also supports an "auto drag-lock" feature: if drag lock is **disabled**
releasing a finger and an extra tap is required to release the button. but the dragging finger is released at the very edge of the touchpad,
a drag lock automatically activates for a short timeout. This allows a user to
quickly reset the finger to elsewhere on the touchpad and continue the dragging
motion. If the finger is released elsewhere, no drag lock activates.
If two fingers are supported by the hardware, a second finger can be used to If two fingers are supported by the hardware, a second finger can be used to
drag while the first is held in-place. drag while the first is held in-place.

View file

@ -15,7 +15,7 @@ run to check for behavior changes and/or regressions. For quick iteration,
the number of tests to run can be filtered, see :ref:`test-filtering`. the number of tests to run can be filtered, see :ref:`test-filtering`.
This allows for developers to verify a subset of tests (e.g. This allows for developers to verify a subset of tests (e.g.
touchpad tap-to-click) while hacking on that specific feature and only run touchpad tap-to-click) while hacking on that specific feature and only run
the full suite when development is done finished. the full suite when development is finished.
.. note:: The test suite relies on udev and the kernel, specifically uinput. .. note:: The test suite relies on udev and the kernel, specifically uinput.
It creates virtual input devices and replays the events. This may It creates virtual input devices and replays the events. This may
@ -38,7 +38,7 @@ Job control in the test suite
The test suite runner has a make-like job control enabled by the ``-j`` or The test suite runner has a make-like job control enabled by the ``-j`` or
``--jobs`` flag and will fork off as many parallel processes as given by this ``--jobs`` flag and will fork off as many parallel processes as given by this
flag. The default if unspecified is 8. When debugging a specific test case flag. The default if unspecified is 8. When debugging a specific test case
failure it is recommended to employ test filtures (see :ref:`test-filtering`) failure it is recommended to employ test filters (see :ref:`test-filtering`)
and disable parallel tests. The test suite automatically disables parallel and disable parallel tests. The test suite automatically disables parallel
make when run in gdb. make when run in gdb.
@ -235,7 +235,7 @@ suites as:
:: ::
$ meson test --no-suite=machine # only run container-friendly tests $ meson test --no-suite=hardware # only run container-friendly tests
$ meson test --suite=valgrind --setup=valgrind # run all valgrind-compatible tests $ meson test --suite=valgrind --setup=valgrind # run all valgrind-compatible tests
$ meson test --no-suite=root # run all tests not requiring root $ meson test --no-suite=root # run all tests not requiring root

View file

@ -269,7 +269,7 @@ alphanumeric key shows up as letter "a".
The recording can be replayed with the ``libinput replay`` command: :: The recording can be replayed with the ``libinput replay`` command: ::
$ sudo libinput replay touchpad.yml $ sudo libinput replay touchpad.yml
SynPS/2 Synaptics TouchPad: /dev/input/event19 /dev/input/event19: SynPS/2 Synaptics TouchPad
Hit enter to start replaying Hit enter to start replaying
@ -329,16 +329,13 @@ specific bug. For example, a touchpad may not work in response to keyboard
events. To accurately reproduce this sequence, the timing between multiple events. To accurately reproduce this sequence, the timing between multiple
devices must be correct and we need to record the events in one go. devices must be correct and we need to record the events in one go.
``libinput record`` has a ``--multiple`` argument to record multiple devices at ``libinput record`` can record multiple devices by specifying them on the
once. Unlike the normal invocation, this one requires a number of arguments: :: commandline. Recording multiple devices requires the ``--output-file``
argument: ::
$ sudo libinput record --multiple --output-file=touchpad-bug.yml /dev/input/event17 /dev/input/event3 $ sudo libinput record --output-file=touchpad-bug.yml /dev/input/event17 /dev/input/event3
recording to 'touchpad-bug.yml' recording to 'touchpad-bug.yml'
As seen above, a user must specify ``--multiple`` and the ``--output-file``.
Finally, all devices to be recorded must be specified on the commandline as
well.
Replaying events is the same as for a single recording: :: Replaying events is the same as for a single recording: ::
$ sudo libinput replay touchpad-bug.yml $ sudo libinput replay touchpad-bug.yml
@ -365,7 +362,7 @@ The ``libinput analyze`` tool is a multiplexer for various sub-tools that
can analyze input events previously recorded from a device. can analyze input events previously recorded from a device.
Please see the **libinput-analyze(1)** man page for information about what Please see the **libinput-analyze(1)** man page for information about what
tools are available and the man page for each respective too. tools are available and the man page for each respective tool.
.. _libinput-quirks: .. _libinput-quirks:

View file

@ -11,7 +11,7 @@ libinput has a mechanism called a **hysteresis** to avoid that jitter. When
active, movement within the **hysteresis margin** is discarded. If the active, movement within the **hysteresis margin** is discarded. If the
movement delta is larger than the margin, the movement is passed on as movement delta is larger than the margin, the movement is passed on as
pointer movement. This is a simplified summary, developers should pointer movement. This is a simplified summary, developers should
read the implementation of the hysteresis in ``src/evdev.c``. read the implementation of the hysteresis in ``src/evdev.h``.
libinput uses the kernel ``fuzz`` value to determine the size of the libinput uses the kernel ``fuzz`` value to determine the size of the
hysteresis. Users should override this with a udev hwdb entry where the hysteresis. Users should override this with a udev hwdb entry where the

View file

@ -53,31 +53,38 @@ Example output of the tool is below: ::
with --touch-thresholds=down:up using observed pressure values. with --touch-thresholds=down:up using observed pressure values.
See --help for more options. See --help for more options.
Interactive keys:
q/a - decrease/increase down threshold
w/s - decrease/increase up threshold
e/d - decrease/increase palm threshold
r/f - decrease/increase thumb threshold
Press Ctrl+C to exit Press Ctrl+C to exit
+-------------------------------------------------------------------------------+ ┌───────────────────────────────────────────────────────────────────────────────┐
| Thresh | 70 | 60 | 130 | 100 | | │ Touch │ down │ up │ palm │ thumb │ min │ max │ p │ avg │ median │
+-------------------------------------------------------------------------------+ ├───────────────────────────────────────────────────────────────────────────────┤
| Touch | down | up | palm | thumb | min | max | p | avg | median | │ 178 │ x │ x │ │ │ 75 │ 75 │ 0 │ 75 │ 75 │
+-------------------------------------------------------------------------------+ │ 179 │ x │ x │ │ │ 35 │ 88 │ 0 │ 77 │ 81 │
| 178 | x | x | | | 75 | 75 | 0 | 75 | 75 | │ 180 │ x │ x │ │ x │ 65 │ 113 │ 0 │ 98 │ 98 │
| 179 | x | x | | | 35 | 88 | 0 | 77 | 81 | │ 181 │ x │ x │ │ x │ 50 │ 101 │ 0 │ 86 │ 90 │
| 180 | x | x | | x | 65 | 113 | 0 | 98 | 98 | │ 182 │ x │ x │ │ │ 40 │ 80 │ 0 │ 66 │ 70 │
| 181 | x | x | | x | 50 | 101 | 0 | 86 | 90 | │ 183 │ x │ │ │ │ 43 │ 78 │ 78 │ │
| 182 | x | x | | | 40 | 80 | 0 | 66 | 70 | │ Thresh │ 70 │ 60 │ 130 │ 100 │
| 183 | x | | | | 43 | 78 | 78 | |
... ...
The example output shows five completed touch sequences and one ongoing one. The example output shows five completed touch sequences and one ongoing one.
For each, the respective minimum and maximum pressure values are printed as For each, the respective minimum and maximum pressure values are printed as
well as some statistics. The ``down`` column show that each sequence was well as some statistics. The ``down`` column shows that each sequence was
considered logically down at some point, two of the sequences were considered considered logically down at some point (see the thresholds in the last line),
thumbs. This is an interactive tool and its output may change frequently. Refer two of the sequences were considered thumbs. This is an interactive tool and
to the **libinput-measure-touchpad-pressure(1)** man page for more details. its output may change frequently. Refer to the
**libinput-measure-touchpad-pressure(1)** man page for more details.
By default, this tool uses the :ref:`device-quirks` for the pressure range. To By default, this tool uses the :ref:`device-quirks` for the pressure range. To
narrow down on the best values for your device, specify the 'logically down' narrow down on the best values for your device, adjust the thresholds using
the keys q/a, w/s, e/d and r/f or specify the 'logically down'
and 'logically up' pressure thresholds with the ``--touch-thresholds`` and 'logically up' pressure thresholds with the ``--touch-thresholds``
argument: :: argument: ::
@ -100,12 +107,12 @@ Once the thresholds are decided on (e.g. 10 and 8), they can be enabled with
[Touchpad pressure override] [Touchpad pressure override]
MatchUdevType=touchpad MatchUdevType=touchpad
MatchName=*SynPS/2 Synaptics TouchPad MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX230* MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX230:*
AttrPressureRange=10:8 AttrPressureRange=10:8
AttrPalmPressureThreshold=150 AttrPalmPressureThreshold=150
AttrThumbPressureThreshold=100 AttrThumbPressureThreshold=100
The file name **must** be ``/etc/libinput/local-overrides.quirks``. The The file name **must** be ``/etc/libinput/local-overrides.quirks``.
The first line is the section name and can be free-form. The ``Match`` The first line is the section name and can be free-form. The ``Match``
directives limit the quirk to your touchpad, make sure the device name directives limit the quirk to your touchpad, make sure the device name
matches your device's name (see ``libinput record``'s output). The dmi matches your device's name (see ``libinput record``'s output). The dmi
@ -117,7 +124,7 @@ and product name (pn).
Once in place, run the following command to verify the quirk is valid and Once in place, run the following command to verify the quirk is valid and
works for your device: :: works for your device: ::
$ sudo libinput list-quirks /dev/input/event10 $ sudo libinput quirks list /dev/input/event10
AttrPressureRange=10:8 AttrPressureRange=10:8
Replace the event node with the one from your device. If the Replace the event node with the one from your device. If the
@ -199,7 +206,7 @@ Once the thresholds are decided on (e.g. 10 and 8), they can be enabled with
[Touchpad touch size override] [Touchpad touch size override]
MatchUdevType=touchpad MatchUdevType=touchpad
MatchName=*SynPS/2 Synaptics TouchPad MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX230* MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX230:*
AttrTouchSizeRange=10:8 AttrTouchSizeRange=10:8
The first line is the match line and should be adjusted for the device name The first line is the match line and should be adjusted for the device name
@ -211,7 +218,7 @@ and product name (pn).
Once in place, run the following command to verify the quirk is valid and Once in place, run the following command to verify the quirk is valid and
works for your device: :: works for your device: ::
$ sudo libinput list-quirks /dev/input/event10 $ sudo libinput quirks list /dev/input/event10
AttrTouchSizeRange=10:8 AttrTouchSizeRange=10:8
Replace the event node with the one from your device. If the Replace the event node with the one from your device. If the

View file

@ -50,7 +50,7 @@ touchpads. Some devices can detect multiple fingers but only provide
Some devices provide additional touch size information through Some devices provide additional touch size information through
the ``ABS_MT_TOUCH_MAJOR/ABS_MT_TOUCH_MINOR`` axes and/or the ``ABS_MT_TOUCH_MAJOR/ABS_MT_TOUCH_MINOR`` axes and/or
the ``ABS_MT_WIDTH_MAJOR/ABS_MT_WIDTH_MINOR`` axes. These axes specifcy the ``ABS_MT_WIDTH_MAJOR/ABS_MT_WIDTH_MINOR`` axes. These axes specify
the size of the touch ellipse. While the kernel documentation specifies how the size of the touch ellipse. While the kernel documentation specifies how
these axes are supposed to be mapped, few devices forward reliable these axes are supposed to be mapped, few devices forward reliable
information. libinput uses these values together with a device-specific information. libinput uses these values together with a device-specific

View file

@ -17,7 +17,7 @@ other properties.
Number of buttons Number of buttons
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
.. _touchapds_buttons_phys: .. _touchpads_buttons_phys:
.............................................................................. ..............................................................................
Physically separate buttons Physically separate buttons
@ -25,7 +25,7 @@ Physically separate buttons
Touchpads with physical buttons usually provide two buttons, left and right. Touchpads with physical buttons usually provide two buttons, left and right.
A few touchpads with three buttons exist, and Apple used to have touchpads A few touchpads with three buttons exist, and Apple used to have touchpads
with a single physical buttons until ca 2008. Touchpads with only two with a single physical button until ca 2008. Touchpads with only two
buttons require the software stack to emulate a middle button. libinput does buttons require the software stack to emulate a middle button. libinput does
this when both buttons are pressed simultaneously. this when both buttons are pressed simultaneously.
@ -57,7 +57,7 @@ property.
.. _touchpads_buttons_forcepads: .. _touchpads_buttons_forcepads:
.............................................................................. ..............................................................................
Forcepads Forcepads/Pressurepads
.............................................................................. ..............................................................................
Forcepads are Clickpads without a physical button underneath the hardware. Forcepads are Clickpads without a physical button underneath the hardware.
@ -65,6 +65,7 @@ They provide pressure and may have a vibration element that is
software-controlled. This element can simulate the feel of a physical software-controlled. This element can simulate the feel of a physical
click or be co-opted for other tasks. click or be co-opted for other tasks.
Forcepads are also called pressurepads or haptic touchpads.
.. _touchpads_touch: .. _touchpads_touch:
@ -79,7 +80,7 @@ device can **track**, i.e. provide reliable positional information for.
In the kernel each finger is tracked in a so-called "slot", the number of In the kernel each finger is tracked in a so-called "slot", the number of
slots thus equals the number of simultaneous touches a device can track. slots thus equals the number of simultaneous touches a device can track.
.. _touchapds_touch_st: .. _touchpads_touch_st:
.............................................................................. ..............................................................................
Single-touch touchpads Single-touch touchpads

View file

@ -131,7 +131,7 @@ variation of the following is sufficient:
[Trackpoint Override] [Trackpoint Override]
MatchUdevType=pointingstick MatchUdevType=pointingstick
MatchName=*TPPS/2 IBM TrackPoint* MatchName=*TPPS/2 IBM TrackPoint*
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT440p* MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadT440p:*
AttrTrackpointMultiplier=1.0 AttrTrackpointMultiplier=1.0

View file

@ -25,7 +25,7 @@ Button scrolling on trackpoints
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
Trackpoint devices have :ref:`button_scrolling` enabled by default. This may Trackpoint devices have :ref:`button_scrolling` enabled by default. This may
interfer with middle-button dragging, if middle-button dragging is required interfere with middle-button dragging, if middle-button dragging is required
by a user then button scrolling must be disabled. by a user then button scrolling must be disabled.
.. _trackpoint_range: .. _trackpoint_range:

View file

@ -131,7 +131,7 @@ Handled device types
- Mice - Mice
- Keyboards - Keyboards
- Virtual absolute pointing devices such as those used by QEMU or VirtualBox - Virtual absolute pointing devices such as those used by QEMU or VirtualBox
- Switches (Lid Switch and Tablet Mode switch) - Switches (Lid Switch, Tablet Mode switch, and Keypad Slide switch)
- Graphics tablets - Graphics tablets
- :ref:`Trackpoints` - :ref:`Trackpoints`

View file

@ -45,7 +45,7 @@ Both events have their own set of APIs to access the data within:
- ``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL`` available since libinput 1.19. - ``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL`` available since libinput 1.19.
* ``libinput_event_pointer_get_scroll_value_v120()`` returns a value * ``libinput_event_pointer_get_scroll_value_v120()`` returns a value
normalized into the 0..120 range, see below. Any multiple of 120 should normalized into multiples of 120, see below. Any multiple of 120 should
be treated as one full wheel click. be treated as one full wheel click.
.. note:: Where possible, the ``libinput_event_pointer_get_axis_value()``, .. note:: Where possible, the ``libinput_event_pointer_get_axis_value()``,
@ -77,7 +77,7 @@ wheel:
| 20 | 20 | 1 | 120 | | 20 | 20 | 1 | 120 |
+-------------+------------+---------------+------+ +-------------+------------+---------------+------+
Fast scrolling may trigger cover than one detent per event and thus each Fast scrolling may trigger more than one detent per event and thus each
event may contain multiples of the value, discrete or v120 value: event may contain multiples of the value, discrete or v120 value:
+-------------+------------+---------------+------+ +-------------+------------+---------------+------+

View file

@ -27,6 +27,7 @@
#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */ #define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */ #define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */
#define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */ #define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */
#define INPUT_PROP_PRESSUREPAD 0x07 /* pressure triggers clicks */
#define INPUT_PROP_MAX 0x1f #define INPUT_PROP_MAX 0x1f
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1) #define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
@ -278,7 +279,8 @@
#define KEY_PAUSECD 201 #define KEY_PAUSECD 201
#define KEY_PROG3 202 #define KEY_PROG3 202
#define KEY_PROG4 203 #define KEY_PROG4 203
#define KEY_DASHBOARD 204 /* AL Dashboard */ #define KEY_ALL_APPLICATIONS 204 /* AC Desktop Show All Applications */
#define KEY_DASHBOARD KEY_ALL_APPLICATIONS
#define KEY_SUSPEND 205 #define KEY_SUSPEND 205
#define KEY_CLOSE 206 /* AC Close */ #define KEY_CLOSE 206 /* AC Close */
#define KEY_PLAY 207 #define KEY_PLAY 207
@ -515,6 +517,10 @@
#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */ #define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */
#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */ #define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */
#define KEY_IMAGES 0x1ba /* AL Image Browser */ #define KEY_IMAGES 0x1ba /* AL Image Browser */
#define KEY_NOTIFICATION_CENTER 0x1bc /* Show/hide the notification center */
#define KEY_PICKUP_PHONE 0x1bd /* Answer incoming call */
#define KEY_HANGUP_PHONE 0x1be /* Decline incoming call */
#define KEY_LINK_PHONE 0x1bf /* AL Phone Syncing */
#define KEY_DEL_EOL 0x1c0 #define KEY_DEL_EOL 0x1c0
#define KEY_DEL_EOS 0x1c1 #define KEY_DEL_EOS 0x1c1
@ -542,6 +548,7 @@
#define KEY_FN_F 0x1e2 #define KEY_FN_F 0x1e2
#define KEY_FN_S 0x1e3 #define KEY_FN_S 0x1e3
#define KEY_FN_B 0x1e4 #define KEY_FN_B 0x1e4
#define KEY_FN_RIGHT_SHIFT 0x1e5
#define KEY_BRL_DOT1 0x1f1 #define KEY_BRL_DOT1 0x1f1
#define KEY_BRL_DOT2 0x1f2 #define KEY_BRL_DOT2 0x1f2
@ -595,8 +602,14 @@
#define BTN_DPAD_LEFT 0x222 #define BTN_DPAD_LEFT 0x222
#define BTN_DPAD_RIGHT 0x223 #define BTN_DPAD_RIGHT 0x223
#define BTN_GRIPL 0x224
#define BTN_GRIPR 0x225
#define BTN_GRIPL2 0x226
#define BTN_GRIPR2 0x227
#define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */ #define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */
#define KEY_ROTATE_LOCK_TOGGLE 0x231 /* Display rotation lock */ #define KEY_ROTATE_LOCK_TOGGLE 0x231 /* Display rotation lock */
#define KEY_REFRESH_RATE_TOGGLE 0x232 /* Display refresh rate toggle */
#define KEY_BUTTONCONFIG 0x240 /* AL Button Configuration */ #define KEY_BUTTONCONFIG 0x240 /* AL Button Configuration */
#define KEY_TASKMANAGER 0x241 /* AL Task/Project Manager */ #define KEY_TASKMANAGER 0x241 /* AL Task/Project Manager */
@ -607,10 +620,29 @@
#define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */ #define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */
#define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */ #define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */
#define KEY_KBD_LAYOUT_NEXT 0x248 /* AC Next Keyboard Layout Select */ #define KEY_KBD_LAYOUT_NEXT 0x248 /* AC Next Keyboard Layout Select */
#define KEY_EMOJI_PICKER 0x249 /* Show/hide emoji picker (HUTRR101) */
#define KEY_DICTATE 0x24a /* Start or Stop Voice Dictation Session (HUTRR99) */
#define KEY_CAMERA_ACCESS_ENABLE 0x24b /* Enables programmatic access to camera devices. (HUTRR72) */
#define KEY_CAMERA_ACCESS_DISABLE 0x24c /* Disables programmatic access to camera devices. (HUTRR72) */
#define KEY_CAMERA_ACCESS_TOGGLE 0x24d /* Toggles the current state of the camera access control. (HUTRR72) */
#define KEY_ACCESSIBILITY 0x24e /* Toggles the system bound accessibility UI/command (HUTRR116) */
#define KEY_DO_NOT_DISTURB 0x24f /* Toggles the system-wide "Do Not Disturb" control (HUTRR94)*/
#define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */ #define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */
#define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */ #define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */
/*
* Keycodes for hotkeys toggling the electronic privacy screen found on some
* laptops on/off. Note when the embedded-controller turns on/off the eprivacy
* screen itself then the state should be reported through drm connecter props:
* https://www.kernel.org/doc/html/latest/gpu/drm-kms.html#standard-connector-properties
* Except when implementing the drm connecter properties API is not possible
* because e.g. the firmware does not allow querying the presence and/or status
* of the eprivacy screen at boot.
*/
#define KEY_EPRIVACY_SCREEN_ON 0x252
#define KEY_EPRIVACY_SCREEN_OFF 0x253
#define KEY_KBDINPUTASSIST_PREV 0x260 #define KEY_KBDINPUTASSIST_PREV 0x260
#define KEY_KBDINPUTASSIST_NEXT 0x261 #define KEY_KBDINPUTASSIST_NEXT 0x261
#define KEY_KBDINPUTASSIST_PREVGROUP 0x262 #define KEY_KBDINPUTASSIST_PREVGROUP 0x262
@ -655,6 +687,27 @@
/* Select an area of screen to be copied */ /* Select an area of screen to be copied */
#define KEY_SELECTIVE_SCREENSHOT 0x27a #define KEY_SELECTIVE_SCREENSHOT 0x27a
/* Move the focus to the next or previous user controllable element within a UI container */
#define KEY_NEXT_ELEMENT 0x27b
#define KEY_PREVIOUS_ELEMENT 0x27c
/* Toggle Autopilot engagement */
#define KEY_AUTOPILOT_ENGAGE_TOGGLE 0x27d
/* Shortcut Keys */
#define KEY_MARK_WAYPOINT 0x27e
#define KEY_SOS 0x27f
#define KEY_NAV_CHART 0x280
#define KEY_FISHING_CHART 0x281
#define KEY_SINGLE_RANGE_RADAR 0x282
#define KEY_DUAL_RANGE_RADAR 0x283
#define KEY_RADAR_OVERLAY 0x284
#define KEY_TRADITIONAL_SONAR 0x285
#define KEY_CLEARVU_SONAR 0x286
#define KEY_SIDEVU_SONAR 0x287
#define KEY_NAV_INFO 0x288
#define KEY_BRIGHTNESS_MENU 0x289
/* /*
* Some keyboards have keys which do not have a defined meaning, these keys * Some keyboards have keys which do not have a defined meaning, these keys
* are intended to be programmed / bound to macros by the user. For most * are intended to be programmed / bound to macros by the user. For most
@ -730,6 +783,9 @@
#define KEY_KBD_LCD_MENU4 0x2bb #define KEY_KBD_LCD_MENU4 0x2bb
#define KEY_KBD_LCD_MENU5 0x2bc #define KEY_KBD_LCD_MENU5 0x2bc
/* Performance Boost key (Alienware)/G-Mode key (Dell) */
#define KEY_PERFORMANCE 0x2bd
#define BTN_TRIGGER_HAPPY 0x2c0 #define BTN_TRIGGER_HAPPY 0x2c0
#define BTN_TRIGGER_HAPPY1 0x2c0 #define BTN_TRIGGER_HAPPY1 0x2c0
#define BTN_TRIGGER_HAPPY2 0x2c1 #define BTN_TRIGGER_HAPPY2 0x2c1
@ -834,6 +890,7 @@
#define ABS_TOOL_WIDTH 0x1c #define ABS_TOOL_WIDTH 0x1c
#define ABS_VOLUME 0x20 #define ABS_VOLUME 0x20
#define ABS_PROFILE 0x21
#define ABS_MISC 0x28 #define ABS_MISC 0x28
@ -889,7 +946,8 @@
#define SW_MUTE_DEVICE 0x0e /* set = device disabled */ #define SW_MUTE_DEVICE 0x0e /* set = device disabled */
#define SW_PEN_INSERTED 0x0f /* set = pen inserted */ #define SW_PEN_INSERTED 0x0f /* set = pen inserted */
#define SW_MACHINE_COVER 0x10 /* set = cover closed */ #define SW_MACHINE_COVER 0x10 /* set = cover closed */
#define SW_MAX 0x10 #define SW_USB_INSERT 0x11 /* set = USB audio device connected */
#define SW_MAX 0x11
#define SW_CNT (SW_MAX+1) #define SW_CNT (SW_MAX+1)
/* /*

View file

@ -27,6 +27,7 @@
#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */ #define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */ #define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */
#define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */ #define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */
#define INPUT_PROP_PRESSUREPAD 0x07 /* pressure triggers clicks */
#define INPUT_PROP_MAX 0x1f #define INPUT_PROP_MAX 0x1f
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1) #define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
@ -278,7 +279,8 @@
#define KEY_PAUSECD 201 #define KEY_PAUSECD 201
#define KEY_PROG3 202 #define KEY_PROG3 202
#define KEY_PROG4 203 #define KEY_PROG4 203
#define KEY_DASHBOARD 204 /* AL Dashboard */ #define KEY_ALL_APPLICATIONS 204 /* AC Desktop Show All Applications */
#define KEY_DASHBOARD KEY_ALL_APPLICATIONS
#define KEY_SUSPEND 205 #define KEY_SUSPEND 205
#define KEY_CLOSE 206 /* AC Close */ #define KEY_CLOSE 206 /* AC Close */
#define KEY_PLAY 207 #define KEY_PLAY 207
@ -515,6 +517,10 @@
#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */ #define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */
#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */ #define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */
#define KEY_IMAGES 0x1ba /* AL Image Browser */ #define KEY_IMAGES 0x1ba /* AL Image Browser */
#define KEY_NOTIFICATION_CENTER 0x1bc /* Show/hide the notification center */
#define KEY_PICKUP_PHONE 0x1bd /* Answer incoming call */
#define KEY_HANGUP_PHONE 0x1be /* Decline incoming call */
#define KEY_LINK_PHONE 0x1bf /* AL Phone Syncing */
#define KEY_DEL_EOL 0x1c0 #define KEY_DEL_EOL 0x1c0
#define KEY_DEL_EOS 0x1c1 #define KEY_DEL_EOS 0x1c1
@ -542,6 +548,7 @@
#define KEY_FN_F 0x1e2 #define KEY_FN_F 0x1e2
#define KEY_FN_S 0x1e3 #define KEY_FN_S 0x1e3
#define KEY_FN_B 0x1e4 #define KEY_FN_B 0x1e4
#define KEY_FN_RIGHT_SHIFT 0x1e5
#define KEY_BRL_DOT1 0x1f1 #define KEY_BRL_DOT1 0x1f1
#define KEY_BRL_DOT2 0x1f2 #define KEY_BRL_DOT2 0x1f2
@ -595,8 +602,14 @@
#define BTN_DPAD_LEFT 0x222 #define BTN_DPAD_LEFT 0x222
#define BTN_DPAD_RIGHT 0x223 #define BTN_DPAD_RIGHT 0x223
#define BTN_GRIPL 0x224
#define BTN_GRIPR 0x225
#define BTN_GRIPL2 0x226
#define BTN_GRIPR2 0x227
#define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */ #define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */
#define KEY_ROTATE_LOCK_TOGGLE 0x231 /* Display rotation lock */ #define KEY_ROTATE_LOCK_TOGGLE 0x231 /* Display rotation lock */
#define KEY_REFRESH_RATE_TOGGLE 0x232 /* Display refresh rate toggle */
#define KEY_BUTTONCONFIG 0x240 /* AL Button Configuration */ #define KEY_BUTTONCONFIG 0x240 /* AL Button Configuration */
#define KEY_TASKMANAGER 0x241 /* AL Task/Project Manager */ #define KEY_TASKMANAGER 0x241 /* AL Task/Project Manager */
@ -607,10 +620,29 @@
#define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */ #define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */
#define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */ #define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */
#define KEY_KBD_LAYOUT_NEXT 0x248 /* AC Next Keyboard Layout Select */ #define KEY_KBD_LAYOUT_NEXT 0x248 /* AC Next Keyboard Layout Select */
#define KEY_EMOJI_PICKER 0x249 /* Show/hide emoji picker (HUTRR101) */
#define KEY_DICTATE 0x24a /* Start or Stop Voice Dictation Session (HUTRR99) */
#define KEY_CAMERA_ACCESS_ENABLE 0x24b /* Enables programmatic access to camera devices. (HUTRR72) */
#define KEY_CAMERA_ACCESS_DISABLE 0x24c /* Disables programmatic access to camera devices. (HUTRR72) */
#define KEY_CAMERA_ACCESS_TOGGLE 0x24d /* Toggles the current state of the camera access control. (HUTRR72) */
#define KEY_ACCESSIBILITY 0x24e /* Toggles the system bound accessibility UI/command (HUTRR116) */
#define KEY_DO_NOT_DISTURB 0x24f /* Toggles the system-wide "Do Not Disturb" control (HUTRR94)*/
#define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */ #define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */
#define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */ #define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */
/*
* Keycodes for hotkeys toggling the electronic privacy screen found on some
* laptops on/off. Note when the embedded-controller turns on/off the eprivacy
* screen itself then the state should be reported through drm connecter props:
* https://www.kernel.org/doc/html/latest/gpu/drm-kms.html#standard-connector-properties
* Except when implementing the drm connecter properties API is not possible
* because e.g. the firmware does not allow querying the presence and/or status
* of the eprivacy screen at boot.
*/
#define KEY_EPRIVACY_SCREEN_ON 0x252
#define KEY_EPRIVACY_SCREEN_OFF 0x253
#define KEY_KBDINPUTASSIST_PREV 0x260 #define KEY_KBDINPUTASSIST_PREV 0x260
#define KEY_KBDINPUTASSIST_NEXT 0x261 #define KEY_KBDINPUTASSIST_NEXT 0x261
#define KEY_KBDINPUTASSIST_PREVGROUP 0x262 #define KEY_KBDINPUTASSIST_PREVGROUP 0x262
@ -655,6 +687,27 @@
/* Select an area of screen to be copied */ /* Select an area of screen to be copied */
#define KEY_SELECTIVE_SCREENSHOT 0x27a #define KEY_SELECTIVE_SCREENSHOT 0x27a
/* Move the focus to the next or previous user controllable element within a UI container */
#define KEY_NEXT_ELEMENT 0x27b
#define KEY_PREVIOUS_ELEMENT 0x27c
/* Toggle Autopilot engagement */
#define KEY_AUTOPILOT_ENGAGE_TOGGLE 0x27d
/* Shortcut Keys */
#define KEY_MARK_WAYPOINT 0x27e
#define KEY_SOS 0x27f
#define KEY_NAV_CHART 0x280
#define KEY_FISHING_CHART 0x281
#define KEY_SINGLE_RANGE_RADAR 0x282
#define KEY_DUAL_RANGE_RADAR 0x283
#define KEY_RADAR_OVERLAY 0x284
#define KEY_TRADITIONAL_SONAR 0x285
#define KEY_CLEARVU_SONAR 0x286
#define KEY_SIDEVU_SONAR 0x287
#define KEY_NAV_INFO 0x288
#define KEY_BRIGHTNESS_MENU 0x289
/* /*
* Some keyboards have keys which do not have a defined meaning, these keys * Some keyboards have keys which do not have a defined meaning, these keys
* are intended to be programmed / bound to macros by the user. For most * are intended to be programmed / bound to macros by the user. For most
@ -730,6 +783,9 @@
#define KEY_KBD_LCD_MENU4 0x2bb #define KEY_KBD_LCD_MENU4 0x2bb
#define KEY_KBD_LCD_MENU5 0x2bc #define KEY_KBD_LCD_MENU5 0x2bc
/* Performance Boost key (Alienware)/G-Mode key (Dell) */
#define KEY_PERFORMANCE 0x2bd
#define BTN_TRIGGER_HAPPY 0x2c0 #define BTN_TRIGGER_HAPPY 0x2c0
#define BTN_TRIGGER_HAPPY1 0x2c0 #define BTN_TRIGGER_HAPPY1 0x2c0
#define BTN_TRIGGER_HAPPY2 0x2c1 #define BTN_TRIGGER_HAPPY2 0x2c1
@ -834,6 +890,7 @@
#define ABS_TOOL_WIDTH 0x1c #define ABS_TOOL_WIDTH 0x1c
#define ABS_VOLUME 0x20 #define ABS_VOLUME 0x20
#define ABS_PROFILE 0x21
#define ABS_MISC 0x28 #define ABS_MISC 0x28
@ -889,7 +946,8 @@
#define SW_MUTE_DEVICE 0x0e /* set = device disabled */ #define SW_MUTE_DEVICE 0x0e /* set = device disabled */
#define SW_PEN_INSERTED 0x0f /* set = pen inserted */ #define SW_PEN_INSERTED 0x0f /* set = pen inserted */
#define SW_MACHINE_COVER 0x10 /* set = cover closed */ #define SW_MACHINE_COVER 0x10 /* set = cover closed */
#define SW_MAX 0x10 #define SW_USB_INSERT 0x11 /* set = USB audio device connected */
#define SW_MAX 0x11
#define SW_CNT (SW_MAX+1) #define SW_CNT (SW_MAX+1)
/* /*

View file

@ -1,8 +1,8 @@
project('libinput', 'c', project('libinput', 'c',
version : '1.28.902', version : '1.31.0',
license : 'MIT/Expat', license : 'MIT/Expat',
default_options : [ 'c_std=gnu99', 'warning_level=2' ], default_options : [ 'c_std=gnu99', 'warning_level=2' ],
meson_version : '>= 0.56.0') meson_version : '>= 0.64.0')
libinput_version = meson.project_version().split('.') libinput_version = meson.project_version().split('.')
@ -80,10 +80,11 @@ endif
config_h.set_quoted('HTTP_DOC_LINK', doc_url) config_h.set_quoted('HTTP_DOC_LINK', doc_url)
config_h.set('_GNU_SOURCE', '1') config_h.set('_GNU_SOURCE', '1')
if get_option('buildtype') == 'debug' or get_option('buildtype') == 'debugoptimized'
is_debug_build = get_option('buildtype') == 'debug' or get_option('buildtype') == 'debugoptimized'
if is_debug_build
config_h.set('IS_DEBUG_BUILD', '1')
config_h.set_quoted('MESON_BUILD_ROOT', meson.current_build_dir()) config_h.set_quoted('MESON_BUILD_ROOT', meson.current_build_dir())
else
config_h.set_quoted('MESON_BUILD_ROOT', '')
endif endif
prefix = '''#define _GNU_SOURCE 1 prefix = '''#define _GNU_SOURCE 1
@ -156,8 +157,9 @@ if not cc.has_header_symbol('sys/ptrace.h', 'PTRACE_ATTACH', prefix : prefix)
config_h.set('PTRACE_CONT', 'PT_CONTINUE') config_h.set('PTRACE_CONT', 'PT_CONTINUE')
config_h.set('PTRACE_DETACH', 'PT_DETACH') config_h.set('PTRACE_DETACH', 'PT_DETACH')
endif endif
if get_option('install-tests')
config_h.set10('HAVE_INSTALLED_TESTS', get_option('install-tests')) config_h.set('HAVE_INSTALLED_TESTS', 1)
endif
# Dependencies # Dependencies
pkgconfig = import('pkgconfig') pkgconfig = import('pkgconfig')
@ -167,6 +169,32 @@ dep_libevdev = dependency('libevdev', version: '>= 1.10.0')
dep_lm = cc.find_library('m', required : false) dep_lm = cc.find_library('m', required : false)
dep_rt = cc.find_library('rt', required : false) dep_rt = cc.find_library('rt', required : false)
dep_lua = dependency('lua-5.4', 'lua5.4', 'lua',
version : '>= 5.4',
required : get_option('lua-plugins'))
have_lua = dep_lua.found()
if have_lua
config_h.set('HAVE_LUA', 1)
endif
have_plugins = dep_lua.found()
if have_plugins
config_h.set('HAVE_PLUGINS', 1)
endif
autoload_plugins = get_option('autoload-plugins')
if autoload_plugins
config_h.set('AUTOLOAD_PLUGINS', 1)
endif
summary({
'Plugins enabled' : have_plugins,
'Autoload plugins' : autoload_plugins,
'Lua Plugin support' : have_lua,
},
section : 'Plugins',
bool_yn : true)
# Include directories # Include directories
includes_include = include_directories('include') includes_include = include_directories('include')
includes_src = include_directories('src') includes_src = include_directories('src')
@ -174,8 +202,8 @@ includes_src = include_directories('src')
############ mtdev configuration ############ ############ mtdev configuration ############
have_mtdev = get_option('mtdev') have_mtdev = get_option('mtdev')
config_h.set10('HAVE_MTDEV', have_mtdev)
if have_mtdev if have_mtdev
config_h.set('HAVE_MTDEV', 1)
dep_mtdev = dependency('mtdev', version : '>= 1.1.0') dep_mtdev = dependency('mtdev', version : '>= 1.1.0')
else else
dep_mtdev = declare_dependency() dep_mtdev = declare_dependency()
@ -184,8 +212,8 @@ endif
############ libwacom configuration ############ ############ libwacom configuration ############
have_libwacom = get_option('libwacom') have_libwacom = get_option('libwacom')
config_h.set10('HAVE_LIBWACOM', have_libwacom)
if have_libwacom if have_libwacom
config_h.set('HAVE_LIBWACOM', 1)
dep_libwacom = dependency('libwacom', version : '>= 0.27') dep_libwacom = dependency('libwacom', version : '>= 0.27')
if cc.has_header_symbol('libwacom/libwacom.h', 'WACOM_BUTTON_DIAL_MODESWITCH', if cc.has_header_symbol('libwacom/libwacom.h', 'WACOM_BUTTON_DIAL_MODESWITCH',
dependencies : dep_libwacom) dependencies : dep_libwacom)
@ -195,6 +223,10 @@ if have_libwacom
dependencies: dep_libwacom) dependencies: dep_libwacom)
config_h.set('HAVE_LIBWACOM_BUTTON_MODESWITCH_MODE', '1') config_h.set('HAVE_LIBWACOM_BUTTON_MODESWITCH_MODE', '1')
endif endif
if cc.has_function('libwacom_stylus_is_generic',
dependencies: dep_libwacom)
config_h.set('HAVE_LIBWACOM_STYLUS_IS_GENERIC', '1')
endif
else else
dep_libwacom = declare_dependency() dep_libwacom = declare_dependency()
endif endif
@ -206,6 +238,7 @@ executable('libinput-device-group',
dependencies : [dep_udev, dep_libwacom], dependencies : [dep_udev, dep_libwacom],
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install : true, install : true,
install_tag : 'runtime',
install_dir : dir_udev_callouts) install_dir : dir_udev_callouts)
executable('libinput-fuzz-extract', executable('libinput-fuzz-extract',
'udev/libinput-fuzz-extract.c', 'udev/libinput-fuzz-extract.c',
@ -214,16 +247,18 @@ executable('libinput-fuzz-extract',
dependencies : [dep_udev, dep_libevdev, dep_lm], dependencies : [dep_udev, dep_libevdev, dep_lm],
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install : true, install : true,
install_tag : 'runtime',
install_dir : dir_udev_callouts) install_dir : dir_udev_callouts)
executable('libinput-fuzz-to-zero', executable('libinput-fuzz-to-zero',
'udev/libinput-fuzz-to-zero.c', 'udev/libinput-fuzz-to-zero.c',
dependencies : [dep_udev, dep_libevdev], dependencies : [dep_udev, dep_libevdev],
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install : true, install : true,
install_tag : 'runtime',
install_dir : dir_udev_callouts) install_dir : dir_udev_callouts)
udev_rules_config = configuration_data() udev_rules_config = configuration_data()
udev_rules_config.set('UDEV_TEST_PATH', '') udev_rules_config.set('UDEV_TEST_PATH', dir_udev_callouts + '/')
configure_file(input : 'udev/80-libinput-device-groups.rules.in', configure_file(input : 'udev/80-libinput-device-groups.rules.in',
output : '80-libinput-device-groups.rules', output : '80-libinput-device-groups.rules',
install_dir : dir_udev_rules, install_dir : dir_udev_rules,
@ -369,14 +404,15 @@ libquirks = static_library('quirks', src_libquirks,
dep_libquirks = declare_dependency(link_with : libquirks) dep_libquirks = declare_dependency(link_with : libquirks)
# Create /etc/libinput # Create /etc/libinput
if meson.version().version_compare('>= 0.60')
install_emptydir(dir_etc / 'libinput') install_emptydir(dir_etc / 'libinput')
else
install_subdir('libinput', install_dir : dir_etc)
endif
############ libinput.so ############ ############ libinput.so ############
config_h.set10('EVENT_DEBUGGING', get_option('internal-event-debugging')) if get_option('internal-event-debugging')
config_h.set('EVENT_DEBUGGING', 1)
endif
config_h.set_quoted('LIBINPUT_PLUGIN_LIBDIR', dir_lib / 'libinput' / 'plugins')
config_h.set_quoted('LIBINPUT_PLUGIN_ETCDIR', dir_etc / 'libinput' / 'plugins')
install_headers('src/libinput.h') install_headers('src/libinput.h')
src_libinput = src_libfilter + [ src_libinput = src_libfilter + [
@ -409,10 +445,17 @@ src_libinput = src_libfilter + [
'src/timer.c', 'src/timer.c',
'src/util-libinput.c', 'src/util-libinput.c',
] ]
if have_mtdev if have_mtdev
src_libinput += ['src/libinput-plugin-mtdev.c'] src_libinput += ['src/libinput-plugin-mtdev.c']
endif endif
if dep_lua.found()
src_libinput += [
'src/libinput-plugin-lua.c',
]
endif
deps_libinput = [ deps_libinput = [
dep_mtdev, dep_mtdev,
dep_udev, dep_udev,
@ -422,7 +465,8 @@ deps_libinput = [
dep_rt, dep_rt,
dep_libwacom, dep_libwacom,
dep_libinput_util, dep_libinput_util,
dep_libquirks dep_libquirks,
dep_lua,
] ]
libinput_version_h_config = configuration_data() libinput_version_h_config = configuration_data()
@ -453,9 +497,7 @@ dep_libinput = declare_dependency(
link_with : lib_libinput, link_with : lib_libinput,
dependencies : deps_libinput) dependencies : deps_libinput)
if meson.version().version_compare('>= 0.54.0')
meson.override_dependency('libinput', dep_libinput) meson.override_dependency('libinput', dep_libinput)
endif
pkgconfig.generate( pkgconfig.generate(
filebase : 'libinput', filebase : 'libinput',
@ -464,6 +506,9 @@ pkgconfig.generate(
version : meson.project_version(), version : meson.project_version(),
libraries : lib_libinput, libraries : lib_libinput,
requires_private : dep_udev, requires_private : dep_udev,
variables : [
'plugindir=${libdir}/libinput/plugins'
]
) )
git_version_h = vcs_tag(command : ['git', 'describe'], git_version_h = vcs_tag(command : ['git', 'describe'],
@ -471,6 +516,8 @@ git_version_h = vcs_tag(command : ['git', 'describe'],
input : 'src/libinput-git-version.h.in', input : 'src/libinput-git-version.h.in',
output :'libinput-git-version.h') output :'libinput-git-version.h')
subdir('plugins')
############ documentation ############ ############ documentation ############
if get_option('documentation') if get_option('documentation')
@ -516,6 +563,7 @@ executable('libinput-debug-events',
dependencies : deps_tools, dependencies : deps_tools,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path, install_dir : libinput_tool_path,
install_tag : 'bin',
install : true install : true
) )
@ -525,8 +573,17 @@ executable('libinput-debug-tablet',
dependencies : deps_tools, dependencies : deps_tools,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path, install_dir : libinput_tool_path,
install_tag : 'bin',
install : true) install : true)
libinput_debug_tablet_pad_sources = [ 'tools/libinput-debug-tablet-pad.c' ]
executable('libinput-debug-tablet-pad',
libinput_debug_tablet_pad_sources,
dependencies : deps_tools,
include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path,
install_tag : 'bin',
install : true)
libinput_quirks_sources = [ 'tools/libinput-quirks.c' ] libinput_quirks_sources = [ 'tools/libinput-quirks.c' ]
libinput_quirks = executable('libinput-quirks', libinput_quirks = executable('libinput-quirks',
@ -534,6 +591,7 @@ libinput_quirks = executable('libinput-quirks',
dependencies : [dep_libquirks, dep_tools_shared, dep_libinput], dependencies : [dep_libquirks, dep_tools_shared, dep_libinput],
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path, install_dir : libinput_tool_path,
install_tag : 'bin',
install : true install : true
) )
test('validate-quirks', test('validate-quirks',
@ -555,6 +613,7 @@ libinput_list_devices = executable('libinput-list-devices',
dependencies : deps_tools, dependencies : deps_tools,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path, install_dir : libinput_tool_path,
install_tag : 'bin',
install : true, install : true,
) )
test('list-devices', test('list-devices',
@ -567,6 +626,7 @@ executable('libinput-measure',
dependencies : deps_tools, dependencies : deps_tools,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path, install_dir : libinput_tool_path,
install_tag : 'bin',
install : true, install : true,
) )
@ -576,6 +636,7 @@ executable('libinput-analyze',
dependencies : deps_tools, dependencies : deps_tools,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path, install_dir : libinput_tool_path,
install_tag : 'bin',
install : true, install : true,
) )
@ -607,23 +668,23 @@ executable('libinput-record',
dependencies : deps_tools + [dep_udev], dependencies : deps_tools + [dep_udev],
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path, install_dir : libinput_tool_path,
install_tag : 'bin',
install : true, install : true,
) )
config_h.set10('HAVE_DEBUG_GUI', get_option('debug-gui'))
if get_option('debug-gui') if get_option('debug-gui')
config_h.set('HAVE_DEBUG_GUI', 1)
dep_gtk = dependency('gtk4', version : '>= 4.0', required : false) dep_gtk = dependency('gtk4', version : '>= 4.0', required : false)
config_h.set10('HAVE_GTK4', dep_gtk.found()) if dep_gtk.found()
if not dep_gtk.found() config_h.set('HAVE_GTK4', 1)
else
dep_gtk = dependency('gtk+-3.0', version : '>= 3.20') dep_gtk = dependency('gtk+-3.0', version : '>= 3.20')
config_h.set10('HAVE_GTK3', dep_gtk.found()) if dep_gtk.found()
config_h.set('HAVE_GTK3', 1)
endif
endif endif
if meson.version().version_compare('>= 0.58')
gtk_targets = dep_gtk.get_variable('targets') gtk_targets = dep_gtk.get_variable('targets')
else
gtk_targets = dep_gtk.get_pkgconfig_variable('targets')
endif
have_gtk_wayland = gtk_targets.contains('wayland') have_gtk_wayland = gtk_targets.contains('wayland')
have_gtk_x11 = gtk_targets.contains('x11') have_gtk_x11 = gtk_targets.contains('x11')
@ -634,18 +695,15 @@ if get_option('debug-gui')
dep_wayland_client = dependency('wayland-client', required : false) dep_wayland_client = dependency('wayland-client', required : false)
dep_wayland_protocols = dependency('wayland-protocols', required : false) dep_wayland_protocols = dependency('wayland-protocols', required : false)
config_h.set10('HAVE_GTK_X11', have_gtk_x11 and dep_x11.found()) if have_gtk_x11 and dep_x11.found()
config_h.set10('HAVE_GTK_WAYLAND', false) config_h.set('HAVE_GTK_X11', 1)
endif
debug_gui_sources = [ 'tools/libinput-debug-gui.c' ] debug_gui_sources = [ 'tools/libinput-debug-gui.c' ]
if have_gtk_wayland and dep_wayland_client.found() and dep_wayland_protocols.found() if have_gtk_wayland and dep_wayland_client.found() and dep_wayland_protocols.found()
wayland_scanner = find_program('wayland-scanner') wayland_scanner = find_program('wayland-scanner')
if meson.version().version_compare('>= 0.58')
wlproto_dir = dep_wayland_protocols.get_variable('pkgdatadir') wlproto_dir = dep_wayland_protocols.get_variable('pkgdatadir')
else
wlproto_dir = dep_wayland_protocols.get_pkgconfig_variable('pkgdatadir')
endif
proto_name = 'pointer-constraints-unstable-v1' proto_name = 'pointer-constraints-unstable-v1'
input = files(wlproto_dir / 'unstable' / 'pointer-constraints' / '@0@.xml'.format(proto_name)) input = files(wlproto_dir / 'unstable' / 'pointer-constraints' / '@0@.xml'.format(proto_name))
@ -663,7 +721,7 @@ if get_option('debug-gui')
) )
debug_gui_sources += [ wayland_headers, wayland_sources ] debug_gui_sources += [ wayland_headers, wayland_sources ]
config_h.set10('HAVE_GTK_WAYLAND', true) config_h.set('HAVE_GTK_WAYLAND', 1)
endif endif
deps_debug_gui = [ deps_debug_gui = [
@ -679,6 +737,7 @@ if get_option('debug-gui')
dependencies : deps_debug_gui, dependencies : deps_debug_gui,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path, install_dir : libinput_tool_path,
install_tag : 'bin',
install : true install : true
) )
src_man += files('tools/libinput-debug-gui.man') src_man += files('tools/libinput-debug-gui.man')
@ -690,6 +749,7 @@ libinput_tool = executable('libinput',
libinput_sources, libinput_sources,
dependencies : deps_tools, dependencies : deps_tools,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install_tag : 'bin',
install : true install : true
) )
@ -703,10 +763,10 @@ executable('ptraccel-debug',
# Don't run the test during a release build because we rely on the magic # Don't run the test during a release build because we rely on the magic
# subtool lookup # subtool lookup
if get_option('buildtype') == 'debug' or get_option('buildtype') == 'debugoptimized' if is_debug_build
config_tool_option_test = configuration_data() config_tool_option_test = configuration_data()
config_tool_option_test.set('DISABLE_WARNING', 'yes') config_tool_option_test.set('DISABLE_WARNING', 'yes')
config_tool_option_test.set('MESON_ENABLED_DEBUG_GUI', get_option('debug-gui')) config_tool_option_test.set('MESON_ENABLED_DEBUG_GUI', get_option('debug-gui').to_string())
config_tool_option_test.set('MESON_BUILD_ROOT', meson.current_build_dir()) config_tool_option_test.set('MESON_BUILD_ROOT', meson.current_build_dir())
config_tool_option_test.set('TOOL_PATH', libinput_tool.full_path()) config_tool_option_test.set('TOOL_PATH', libinput_tool.full_path())
tool_option_test = configure_file(input: 'tools/test_tool_option_parsing.py', tool_option_test = configure_file(input: 'tools/test_tool_option_parsing.py',
@ -740,6 +800,13 @@ test('tools-builddir-lookup-installed',
############ tests ############ ############ tests ############
summary({
'Tests enabled' : get_option('tests'),
'Install tests' : get_option('install-tests'),
},
section : 'Tests',
bool_yn : true)
test('symbols-leak-test', test('symbols-leak-test',
find_program('test/symbols-leak-test'), find_program('test/symbols-leak-test'),
args : [ dir_src / 'libinput.sym', dir_src], args : [ dir_src / 'libinput.sym', dir_src],
@ -780,6 +847,7 @@ executable('libinput-test',
dependencies : deps_tools, dependencies : deps_tools,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path, install_dir : libinput_tool_path,
install_tag : 'tests',
install : true, install : true,
) )
@ -789,11 +857,15 @@ if get_option('tests')
dep_check = dependency('check', version : '>= 0.9.10', required: false) dep_check = dependency('check', version : '>= 0.9.10', required: false)
gstack = find_program('gstack', required : false) gstack = find_program('gstack', required : false)
config_h.set10('HAVE_GSTACK', gstack.found()) if gstack.found()
config_h.set('HAVE_GSTACK', 1)
endif
# for inhibit support during test run # for inhibit support during test run
dep_libsystemd = dependency('libsystemd', version : '>= 221', required : false) dep_libsystemd = dependency('libsystemd', version : '>= 221', required : false)
config_h.set10('HAVE_LIBSYSTEMD', dep_libsystemd.found()) if dep_libsystemd.found()
config_h.set('HAVE_LIBSYSTEMD', 1)
endif
litest_sources = [ litest_sources = [
'src/libinput-private-config.c', 'src/libinput-private-config.c',
@ -820,6 +892,8 @@ if get_option('tests')
'test/litest-device-format-string.c', 'test/litest-device-format-string.c',
'test/litest-device-generic-pressurepad.c', 'test/litest-device-generic-pressurepad.c',
'test/litest-device-generic-singletouch.c', 'test/litest-device-generic-singletouch.c',
'test/litest-device-generic-usb-keyboard.c',
'test/litest-device-generic-usb-touchpad.c',
'test/litest-device-gpio-keys.c', 'test/litest-device-gpio-keys.c',
'test/litest-device-huion-pentablet.c', 'test/litest-device-huion-pentablet.c',
'test/litest-device-huion-q620m-dial.c', 'test/litest-device-huion-q620m-dial.c',
@ -831,6 +905,7 @@ if get_option('tests')
'test/litest-device-keyboard-razer-blackwidow.c', 'test/litest-device-keyboard-razer-blackwidow.c',
'test/litest-device-keyboard-razer-blade-stealth.c', 'test/litest-device-keyboard-razer-blade-stealth.c',
'test/litest-device-keyboard-razer-blade-stealth-videoswitch.c', 'test/litest-device-keyboard-razer-blade-stealth-videoswitch.c',
'test/litest-device-keypad-slide-switch.c',
'test/litest-device-lenovo-scrollpoint.c', 'test/litest-device-lenovo-scrollpoint.c',
'test/litest-device-lid-switch.c', 'test/litest-device-lid-switch.c',
'test/litest-device-lid-switch-surface3.c', 'test/litest-device-lid-switch-surface3.c',
@ -840,6 +915,7 @@ if get_option('tests')
'test/litest-device-magic-trackpad.c', 'test/litest-device-magic-trackpad.c',
'test/litest-device-mouse.c', 'test/litest-device-mouse.c',
'test/litest-device-mouse-wheel-tilt.c', 'test/litest-device-mouse-wheel-tilt.c',
'test/litest-device-mouse-wheel-hires-disabled.c',
'test/litest-device-mouse-ps2.c', 'test/litest-device-mouse-ps2.c',
'test/litest-device-mouse-roccat.c', 'test/litest-device-mouse-roccat.c',
'test/litest-device-mouse-low-dpi.c', 'test/litest-device-mouse-low-dpi.c',
@ -1000,6 +1076,10 @@ if get_option('tests')
'test/test-switch.c', 'test/test-switch.c',
'test/test-quirks.c', 'test/test-quirks.c',
] ]
if have_plugins and have_lua
tests_sources += ['test/test-plugins-lua.c']
endif
libinput_test_runner_sources = litest_sources + tests_sources libinput_test_runner_sources = litest_sources + tests_sources
libinput_test_runner = executable('libinput-test-suite', libinput_test_runner = executable('libinput-test-suite',
libinput_test_runner_sources, libinput_test_runner_sources,
@ -1041,6 +1121,9 @@ if get_option('tests')
'trackpoint', 'trackpoint',
'udev', 'udev',
] ]
if have_plugins and have_lua
collections += ['lua']
endif
foreach group : collections foreach group : collections
test('libinput-test-suite-@0@'.format(group), test('libinput-test-suite-@0@'.format(group),
@ -1101,6 +1184,7 @@ src_man += files(
'tools/libinput-analyze-touch-down-state.man', 'tools/libinput-analyze-touch-down-state.man',
'tools/libinput-debug-events.man', 'tools/libinput-debug-events.man',
'tools/libinput-debug-tablet.man', 'tools/libinput-debug-tablet.man',
'tools/libinput-debug-tablet-pad.man',
'tools/libinput-list-devices.man', 'tools/libinput-list-devices.man',
'tools/libinput-list-kernel-devices.man', 'tools/libinput-list-kernel-devices.man',
'tools/libinput-measure.man', 'tools/libinput-measure.man',

View file

@ -42,3 +42,11 @@ option('internal-event-debugging',
type: 'boolean', type: 'boolean',
value: false, value: false,
description: 'Enable additional internal event debug tracing. This will print key values to the logs and thus must never be enabled in a release build') description: 'Enable additional internal event debug tracing. This will print key values to the logs and thus must never be enabled in a release build')
option('autoload-plugins',
type: 'boolean',
value: false,
description: 'Always load plugins from default plugin paths (only if the caller does not do so)')
option('lua-plugins',
type: 'feature',
value: 'auto',
description: 'Enable support for Lua plugins')

View file

@ -0,0 +1,71 @@
-- SPDX-License-Identifier: MIT
--
-- This is an example libinput plugin
--
-- This plugin detects the Copilot key on the keyboard with
-- the given VID/PID and replaces it with a different key (sequence).
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
-- libinput:register({1})
-- Replace this with your keyboard's VID/PID
KEYBOARD_VID = 0x046d
KEYBOARD_PID = 0x4088
meta_is_down = false
shift_is_down = false
-- shift-A, because you can never have enough screaming
replacement_sequence = { evdev.KEY_LEFTSHIFT, evdev.KEY_A }
function frame(device, frame, _)
for _, v in ipairs(frame) do
if v.value ~= 2 then -- ignore key repeats
if v.usage == evdev.KEY_LEFTMETA then
meta_is_down = v.value == 1
elseif v.usage == evdev.KEY_LEFTSHIFT then
shift_is_down = v.value == 1
elseif v.usage == evdev.KEY_F23 and meta_is_down and shift_is_down then
-- We know from the MS requirements that F23 for copilot is
-- either last key (on press) or the first key (on release)
-- of the three-key sequence, and no other keys are
-- within this frame.
if v.value == 1 then
-- Release our modifiers first
device:prepend_frame({
{ usage = evdev.KEY_LEFTSHIFT, value = 0 },
{ usage = evdev.KEY_LEFTMETA, value = 0 },
})
-- Insert our replacement press sequence
local replacement_frame = {}
for _, rv in ipairs(replacement_sequence) do
table.insert(replacement_frame, { usage = rv, value = 1 })
end
device:append_frame(replacement_frame)
else
-- Insert our replacement release sequence
local replacement_frame = {}
for idx = #replacement_sequence, 1, -1 do
table.insert(replacement_frame, { usage = replacement_sequence[idx], value = 0 })
end
device:append_frame(replacement_frame)
-- we don't care about re-pressing shift/meta because the
-- rest of the stack will filter the release for an
-- unpressed key anyway.
end
return {} -- discard this frame
end
end
end
end
function device_new(device)
local info = device:info()
if info.vid == KEYBOARD_VID and info.pid == KEYBOARD_PID then
device:connect("evdev-frame", frame)
end
end
libinput:connect("new-evdev-device", device_new)

View file

@ -0,0 +1,64 @@
-- SPDX-License-Identifier: MIT
--
-- This is an example libinput plugin
--
-- This plugin delays any event with relative motion by the given DELAY
-- by storing it in a table and replaying it via a timer callback later.
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
-- libinput:register({1})
DELAY = 1500 * 1000 -- 1.5s
next_timer_expiry = 0
devices = {}
function timer_expired(time_in_microseconds)
next_timer_expiry = 0
for device, frames in pairs(devices) do
while #frames > 0 and frames[1].time <= time_in_microseconds do
--- we don't have a current frame so it doesn't matter
--- whether we prepend or append
device:prepend_frame(frames[1].frame)
table.remove(frames, 1)
end
local next_frame = frames[1]
if next_frame and (next_timer_expiry == 0 or next_frame.time < next_timer_expiry) then
next_timer_expiry = next_frame.time
end
end
if next_timer_expiry ~= 0 then
libinput:timer_set_absolute(next_timer_expiry)
end
end
function frame(device, frame, timestamp)
for _, v in ipairs(frame) do
if v.usage == evdev.REL_X or v.usage == evdev.REL_Y then
local next_time = timestamp + DELAY
table.insert(devices[device], {
time = next_time,
frame = frame
})
if next_timer_expiry == 0 then
next_timer_expiry = next_time
libinput:timer_set_absolute(next_timer_expiry)
end
return {} -- discard frame
end
end
return nil
end
function device_new(device)
local usages = device:usages()
if usages[evdev.REL_X] then
devices[device] = {}
device:connect("evdev-frame", frame)
device:connect("device-removed", function(dev)
devices[dev] = nil
end)
end
end
libinput:connect("new-evdev-device", device_new)
libinput:connect("timer-expired", timer_expired)

View file

@ -0,0 +1,16 @@
-- SPDX-License-Identifier: MIT
--
-- An example plugin to show how to disable an internal feature.
--
-- Typically one would expect the plugin to re-implement the feature
-- in a more device-specific manner but that's not done here.
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
-- libinput:register({1})
libinput:connect("new-evdev-device", function(device)
local udev_info = device:udev_properties()
if udev_info["ID_INPUT_TOUCHPAD"] then
libinput:log_info("Disabling palm detection on " .. device:name())
device:disable_feature("touchpad-palm-detection")
end
end)

40
plugins/10-dwt.lua Normal file
View file

@ -0,0 +1,40 @@
-- SPDX-License-Identifier: MIT
--
-- This plugin implements a very simple version of disable-while-typing.
-- It monitors all keyboard devices and if any of them send an event,
-- any touchpad device is disabled for 2 seconds.
-- And "disabled" means any event from that touchpad is simply
-- discarded.
--
-- Install this file in /etc/libinput/plugins and
--
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
-- libinput:register({1})
tp_enabled = true
libinput:connect("timer-expired", function(now)
libinput:log_debug("touchpad enabled")
tp_enabled = true
end)
libinput:connect("new-evdev-device", function (device)
local props = device:udev_properties()
if props.ID_INPUT_KEYBOARD then
device:connect("evdev-frame", function (device, frame, timestamp)
libinput:timer_set_relative(2000000)
if tp_enabled then
libinput:log_debug("touchpad disabled")
tp_enabled = false
end
end)
elseif props.ID_INPUT_TOUCHPAD then
libinput:log_debug("Touchpad detected: " .. device:name())
device:connect("evdev-frame", function (device, frame, timestamp)
if not tp_enabled then
-- Returning an empty table discards the event.
return {}
end
end)
end
end)

87
plugins/10-example.lua Normal file
View file

@ -0,0 +1,87 @@
-- SPDX-License-Identifier: MIT
--
-- This is an example libinput plugin
--
-- This plugin swaps left and right buttons on any device that has both buttons.
-- Let's create a plugin. A single Lua script may create more than one
-- plugin instance but that's a bit of a nice use-case. Most scripts
-- should be a single plugin.
-- A plugin needs to be registered to activate. If it isn't, it is
-- cleaned up immediately. In the register call we supply
-- the list of plugin versions we support. Currently we only
-- have version 1.
--
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
-- libinput:register({1})
-- Note to the reader: it will be easier to understand this example
-- if you read it bottom-up from here on.
-- The callback for our "evdev-frame" signal.
-- These frames are sent *before* libinput gets to handle them so
-- any modifications will affect libinput.
function frame(device, frame, time_in_microseconds)
-- Frame is a table in the form
-- { { usage: 123, value: 3 }, ... }
-- Let's use the evdev module to make it more readable, evdev.KEY_A
-- is simply the value (0x1 << 16) | 0x1 (see linux/input-event-codes.h)
for _, v in ipairs(frame) do
-- If we get a right button event, change it to left, and
-- vice versa. Because this happens before libinput (or the next
-- plugin in the precedence order) sees the
-- frame it doesn't know that the swap happened.
if v.usage == evdev.BTN_RIGHT then
v.usage = evdev.BTN_LEFT
elseif v.usage == evdev.BTN_LEFT then
v.usage = evdev.BTN_RIGHT
end
end
-- We changed the frame, let's return it. If we return nil
-- the original frame is being used as-is.
return frame
end
-- This is a timer callback. It is invoked after one second
-- (see below) but only once - re-set the timer so
-- it goes off every second.
function timer_expired(time_in_microseconds)
libinput:timer_set_absolute(time_in_microseconds + 1000000)
end
-- Callback for the "new-evdev-device" signal, see below
-- The argument is the EvdevDevice object, see the documentation.
function device_new(device)
-- A table of evdev usages available on our device.
-- Using the evdev module makes it more readable but you can
-- use numbers (which is what evdev.EV_KEY and
-- friends resolve to anyway).
local usages = device:usages()
if usages[evdev.BTN_LEFT] and usages[evdev.BTN_RIGHT] then
-- The "evdev-frame" callback is invoked whenever the device
-- provided us with one evdev frame, i.e. a bunch of events up
-- to excluding EV_SYN SYN_REPORT.
device:connect("evdev-frame", frame)
end
-- The device has udev information, let's print it out. Right
-- now all we get are the ID_INPUT_ bits.
-- If this is empty we know libinput will ignore this device anyway
local udev_info = device:udev_properties()
for k, v in pairs(udev_info) do
libinput:log_debug(k .. "=" .. v)
end
end
-- Let's connect to the "new-evdev-device" signal. This function
-- is invoked when libinput detects a new evdev device (but before
-- that device is actually available to libinput as libinput device).
-- This allows us to e.g. change properties on the device.
libinput:connect("new-evdev-device", device_new)
-- Set our timer to expire 1s from now (in microseconds).
-- Timers are absolute, so they need to be added to the
-- current time
libinput:connect("timer-expired", timer_expired)
libinput:timer_set_relative(1000000)

View file

@ -0,0 +1,32 @@
-- SPDX-License-Identifier: MIT
--
-- This plugin inverts the horizontal scroll direction of
-- the Logitech MX Master mouse. OOTB the mouse scrolls
-- in the opposite direction to all other mice out there.
--
-- This plugin is only needed when the mouse is connected
-- to the Logitech Bolt receiver - on that receiver we cannot
-- tell which device is connected.
--
-- For the Logitech Unifying receiver and Bluetooth please
-- add the ModelInvertHorizontalScrolling=1 quirk
-- in quirks/30-vendor-logitech.quirks.
--
--
-- Install this file in /etc/libinput/plugins and
--
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
-- libinput:register({1})
libinput:connect("new-evdev-device", function (device)
local info = device:info()
if info.vid == 0x046D and info.pid == 0xC548 then
device:connect("evdev-frame", function (device, frame, timestamp)
for _, event in ipairs(frame) do
if event.usage == evdev.REL_HWHEEL or event.usage == evdev.REL_HWHEEL_HI_RES then
event.value = -event.value
end
end
return frame
end)
end
end)

View file

@ -0,0 +1,22 @@
-- SPDX-License-Identifier: MIT
--
-- An example plugin to make the pointer go three times as fast
--
-- Install this file in /etc/libinput/plugins and
--
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
-- libinput:register({1})
libinput:connect("new-evdev-device", function(device)
local usages = device:usages()
if usages[evdev.REL_X] then
device:connect("evdev-frame", function(device, frame, timestamp)
for _, v in ipairs(frame) do
if v.usage == evdev.REL_X or v.usage == evdev.REL_Y then
-- Multiply the relative motion by 3
v.value = v.value * 3
end
end
return frame
end)
end
end)

View file

@ -0,0 +1,56 @@
-- SPDX-License-Identifier: MIT
--
-- An example plugin to make the pointer go three times as slow
--
-- Install this file in /etc/libinput/plugins and
--
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
-- libinput:register({1})
remainders = {}
function split(v)
if math.abs(v) >= 1.0 then
local i = math.floor(math.abs(v))
local r = math.abs(v) % 1.0
if v < 0.0 then
i = -i
r = -r
end
return i, r
else
return 0, v
end
end
function decelerate(device, x, y)
local remainder = remainders[device]
local rx, ry = 0, 0
if x ~= 0.0 then
rx, remainder.x = split(remainder.x + x/3.0)
end
if y ~= 0.0 then
ry, remainder.y = split(remainder.y + y/3.0)
end
return rx, ry
end
libinput:connect("new-evdev-device", function(device)
local usages = device:usages()
if usages[evdev.REL_X] then
remainders[device] = { x = 0.0, y = 0.0 }
device:connect("evdev-frame", function(device, frame, timestamp)
for _, v in ipairs(frame) do
if v.usage == evdev.REL_X then
v.value, _ = decelerate(device, v.value, 0.0)
elseif v.usage == evdev.REL_Y then
_, v.value = decelerate(device, 0.0, v.value)
end
end
return frame
end)
device:connect("device-removed", function(dev)
remainders[dev] = nil
end)
end
end)

View file

@ -0,0 +1,121 @@
-- SPDX-License-Identifier: MIT
--
-- This is an example libinput plugin
--
-- This plugin controls a mouse/pointer from a tablet device. This
-- effectively hides stylus interactions and sends pointer events
-- instead. In other words: mouse emulation for tablets, implemented
-- by (remote) controlling a mouse device. This allows using a
-- tablet stylus as a mouse replacement without tablet limitations
-- from compositors or clients. Note that axis usually needed for
-- drawing (like pressure, tilt or distance) are no longer emitted
-- when this plugin is active and a mouse is connected. When no
-- mouse is connected, this plugin doesn't change tablet events,
-- thus the stylus works like a normal stylus.
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
-- libinput:register({1})
-- globals
pointer_device = nil
tablet_device = nil
maximum_x = nil
maximum_y = nil
function adjust_for_aspect_ratio(y)
-- adjust y to match monitor 21:9 aspect ratio
local adj_maximum_y = maximum_x * 1440 / 3440
return math.floor(math.min(y * maximum_y / adj_maximum_y, maximum_y + 1))
end
function on_tablet_frame(device, frame, time_in_microseconds)
-- emit tablet frame when there is no pointer device
if not pointer_device then return nil end
-- map tablet frame to pointer frame
local events = {}
for _, v in ipairs(frame) do
if v.usage == evdev.ABS_MISC then
-- save a few cycles on Wacom tablets by discarding a
-- proximity in / out frame early, non-Wacom tablets should
-- use BTN_TOOL_PEN/RUBBER/... instead
return {}
elseif v.usage == evdev.ABS_X then
table.insert(events, { usage = evdev.ABS_X, value = v.value })
elseif v.usage == evdev.ABS_Y then
-- uncomment the next two lines and comment the original line
-- for configuring aspect correction, see
-- adjust_for_aspect_ratio() for details and configuration
-- local adj_value = adjust_for_aspect_ratio(v.value)
-- table.insert(events, { usage = evdev.ABS_Y, value = adj_value })
table.insert(events, { usage = evdev.ABS_Y, value = v.value })
elseif v.usage == evdev.BTN_TOUCH then
table.insert(events, { usage = evdev.BTN_LEFT, value = v.value })
elseif v.usage == evdev.BTN_STYLUS then
table.insert(events, { usage = evdev.BTN_RIGHT, value = v.value })
elseif v.usage == evdev.BTN_STYLUS2 then
table.insert(events, { usage = evdev.BTN_MIDDLE, value = v.value })
end
end
-- emit pointer frame, if any
if #events > 0 then pointer_device:append_frame(events) end
-- discard tablet frame
return {}
end
function on_tablet_removed(device)
libinput:log_info("Remove tablet device")
tablet_device = nil
end
function on_pointer_removed(device)
libinput:log_info("Remove pointer device")
pointer_device = nil
end
function setup()
if not pointer_device or not tablet_device then return end
libinput:log_info("Controlling '" .. pointer_device:name() .. "' with '" .. tablet_device:name() .. "'")
-- fetch absinfos from tablet
local absinfo_x = {}
local absinfo_y = {}
for a, b in pairs(tablet_device:absinfos()) do
if a == evdev.ABS_X then absinfo_x = b end
if a == evdev.ABS_Y then absinfo_y = b end
end
-- copy max values for aspect ratio correction later on
maximum_x = absinfo_x.maximum
maximum_y = absinfo_y.maximum
-- copy absinfos to pointer device
pointer_device:set_absinfo(evdev.ABS_X, absinfo_x)
pointer_device:set_absinfo(evdev.ABS_Y, absinfo_y)
-- setup listeners
pointer_device:connect("device-removed", on_pointer_removed)
tablet_device:connect("device-removed", on_tablet_removed)
tablet_device:connect("evdev-frame", on_tablet_frame)
end
function on_new_device(device)
local udev = device:udev_properties()
if udev["ID_INPUT_TABLET"] and not udev["ID_INPUT_TABLET_PAD"] then
libinput:log_info("Found tablet device")
tablet_device = device
setup()
end
if udev["ID_INPUT_MOUSE"] then
libinput:log_info("Found pointer device")
pointer_device = device
setup()
end
end
-- setup listener
libinput:connect("new-evdev-device", on_new_device)

View file

@ -0,0 +1,64 @@
-- SPDX-License-Identifier: MIT
--
-- This is an example libinput plugin
--
-- This plugin maps a downwards mouse wheel to a button down event and
-- an upwards wheel movement to a button up event.
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
-- libinput:register({1})
-- The button we want to press on wheel events
local wheel_button = evdev.BTN_EXTRA
local button_states = {}
local function evdev_frame(device, frame, timestamp)
local events = {}
local modified = false
for _, v in ipairs(frame) do
if v.usage == evdev.REL_WHEEL then
-- REL_WHEEL is inverted, neg value -> down, pos value -> up
if v.value < 0 then
if not button_states[device] then
table.insert(events, { usage = wheel_button, value = 1 })
button_states[device] = true
end
else
if button_states[device] then
table.insert(events, { usage = wheel_button, value = 0 })
button_states[device] = false
end
end
modified = true
-- Because REL_WHEEL is no longer a wheel, the high-res
-- events are dropped
elseif v.usage == evdev.REL_WHEEL_HI_RES then
modified = true
else
table.insert(events, v)
end
end
if modified then
return events
else
return nil
end
end
local function device_new(device)
local usages = device:usages()
if usages[evdev.REL_WHEEL] then
button_states[device] = false
if not usages[wheel_button] then
device:enable_evdev_usage(wheel_button)
end
device:connect("evdev-frame", evdev_frame)
device:connect("device-removed", function(dev)
button_states[dev] = nil
end)
end
end
libinput:connect("new-evdev-device", device_new)

17
plugins/meson.build Normal file
View file

@ -0,0 +1,17 @@
plugins = [
'10-example.lua',
'10-dwt.lua',
'10-logitech-mx-master-horiz-scroll.lua',
'10-pointer-go-faster.lua',
'10-pointer-go-slower.lua',
'10-delay-motion.lua',
'10-disable-feature.lua',
'10-copilot-key-override.lua',
'10-wheel-to-button.lua',
'10-tablet-mouse-control.lua',
]
fs = import('fs')
foreach plugin : plugins
fs.copyfile(plugin)
endforeach

View file

@ -9,3 +9,23 @@ AttrKeyboardIntegration=internal
MatchUdevType=keyboard MatchUdevType=keyboard
MatchBus=bluetooth MatchBus=bluetooth
AttrKeyboardIntegration=external AttrKeyboardIntegration=external
# Detachable devices usually have the tablet part buttons wired as ps2 keyboard,
# don't disable them when tablet-mode switch is in effect.
# DMI Chassis Type 20h (32 decimal) is Detachable as per SMBIOS specification.
[Detachable Device Buttons]
MatchBus=ps2
MatchUdevType=keyboard
MatchDMIModalias=dmi:*:ct32:*
ModelTabletModeNoSuspend=1
# Tablet devices usually have the tablet part buttons wired as ps2 keyboard,
# despite being tablets some of them, e.g. Microsoft Surface Laptop Studio,
# expose tablet-mode switch, so don't disable the ps2 keyboard.
# Tablets that don't expose tablet-mode switch won't have any diference.
# DMI Chassis Type 1Eh (30 decimal) is Tablet as per SMBIOS specification.
[Tablet Device Buttons]
MatchBus=ps2
MatchUdevType=keyboard
MatchDMIModalias=dmi:*:ct30:*
ModelTabletModeNoSuspend=1

View file

@ -1,5 +1,8 @@
# Do not edit this file, it will be overwritten on update
[A4TECH USB X-710BK] [A4TECH USB X-710BK]
MatchUdevType=mouse
MatchBus=usb
MatchVendor=0x09DA MatchVendor=0x09DA
MatchProduct=0x9090 MatchProduct=0x9090
MatchUdevType=mouse
ModelBouncingKeys=1 ModelBouncingKeys=1

View file

@ -0,0 +1,11 @@
# Do not edit this file, it will be overwritten on update
# Touchpad is not a clickpad but INPUT_PROP_BUTTONPAD is set,
# causing libinput to drop physical button events.
[Clevetura CLVX S Touchpad]
MatchUdevType=touchpad
MatchBus=bluetooth
MatchVendor=0x36F7
MatchProduct=0x5755
AttrInputProp=-INPUT_PROP_BUTTONPAD
AttrEventCode=+BTN_RIGHT

View file

@ -1,35 +1,43 @@
# Do not edit this file, it will be overwritten on update
[Contour Design RollerMouse Free 2] [Contour Design RollerMouse Free 2]
MatchUdevType=mouse
MatchBus=usb
MatchVendor=0x0B33 MatchVendor=0x0B33
MatchProduct=0x0401 MatchProduct=0x0401
MatchUdevType=mouse
ModelBouncingKeys=1 ModelBouncingKeys=1
[Contour Design RollerMouse Free 3] [Contour Design RollerMouse Free 3]
MatchUdevType=mouse
MatchBus=usb
MatchVendor=0x0B33 MatchVendor=0x0B33
MatchProduct=0x0404 MatchProduct=0x0404
MatchUdevType=mouse
ModelBouncingKeys=1 ModelBouncingKeys=1
[Contour Design RollerMouse Re:d] [Contour Design RollerMouse Re:d]
MatchUdevType=mouse
MatchBus=usb
MatchVendor=0x0B33 MatchVendor=0x0B33
MatchProduct=0x1000 MatchProduct=0x1000
MatchUdevType=mouse
ModelBouncingKeys=1 ModelBouncingKeys=1
[Contour Design RollerMouse Red v3] [Contour Design RollerMouse Red v3]
MatchUdevType=mouse
MatchBus=usb
MatchVendor=0x0B33 MatchVendor=0x0B33
MatchProduct=0x1004 MatchProduct=0x1004
MatchUdevType=mouse
ModelBouncingKeys=1 ModelBouncingKeys=1
[Contour Design RollerMouse Pro3] [Contour Design RollerMouse Pro3]
MatchUdevType=mouse
MatchBus=usb
MatchVendor=0x0B33 MatchVendor=0x0B33
MatchProduct=0x0703 MatchProduct=0x0703
MatchUdevType=mouse
ModelBouncingKeys=1 ModelBouncingKeys=1
[Contour Design RollerMouse USB Receiver] [Contour Design RollerMouse USB Receiver]
MatchUdevType=mouse
MatchBus=usb
MatchVendor=0x0B33 MatchVendor=0x0B33
MatchProduct=0x2000 MatchProduct=0x2000
MatchUdevType=mouse
ModelBouncingKeys=1 ModelBouncingKeys=1

View file

@ -1,10 +1,13 @@
# Do not edit this file, it will be overwritten on update # Do not edit this file, it will be overwritten on update
[Cyapa Touchpads] [Cyapa Touchpads]
MatchBus=i2c
MatchUdevType=touchpad
MatchName=*Cypress APA Trackpad ?cyapa? MatchName=*Cypress APA Trackpad ?cyapa?
AttrPressureRange=10:8 AttrPressureRange=10:8
[Cypress Touchpads] [Cypress Touchpads]
MatchBus=ps2
MatchUdevType=touchpad MatchUdevType=touchpad
MatchName=*CyPS/2 Cypress Trackpad MatchName=*CyPS/2 Cypress Trackpad
AttrPressureRange=10:8 AttrPressureRange=10:8

View file

@ -9,3 +9,11 @@ AttrPressureRange=10:8
MatchName=*Elan Touchpad* MatchName=*Elan Touchpad*
AttrResolutionHint=31x31 AttrResolutionHint=31x31
AttrPressureRange=10:8 AttrPressureRange=10:8
# Elan Hapticpad mostly used in Lenovo laptops.
[Elan Haptic Touchpad (04F3:3355)]
MatchBus=i2c
MatchVendor=0x04F3
MatchProduct=0x3355
MatchUdevType=touchpad
AttrInputProp=+INPUT_PROP_PRESSUREPAD

View file

@ -1,3 +1,5 @@
# Do not edit this file, it will be overwritten on update
[Glorious Model O] [Glorious Model O]
MatchUdevType=mouse MatchUdevType=mouse
MatchBus=usb MatchBus=usb

View file

@ -0,0 +1,72 @@
# Do not edit this file, it will be overwritten on update
# "GXTP5100 Touchpad": pressure touchpad mostly used in Lenovo laptops.
# Match vid and pid as it can have other names.
[Goodix Haptic Touchpad (27C6:01E7)]
MatchBus=i2c
MatchVendor=0x27C6
MatchProduct=0x01E7
MatchUdevType=touchpad
AttrInputProp=+INPUT_PROP_PRESSUREPAD
# "GXTP5100 Touchpad": pressure touchpad mostly used in Lenovo laptops.
# GXTP5100:00 27C6:01E8 Touchpad
[Goodix Haptic Touchpad (27C6:01E8)]
MatchBus=i2c
MatchVendor=0x27C6
MatchProduct=0x01E8
MatchUdevType=touchpad
AttrInputProp=+INPUT_PROP_PRESSUREPAD
# "GXTP5100 Touchpad": pressure touchpad mostly used in Lenovo laptops.
# GXTP5100:00 27C6:01E9 Touchpad
[Goodix Haptic Touchpad (27C6:01E9)]
MatchBus=i2c
MatchVendor=0x27C6
MatchProduct=0x01E9
MatchUdevType=touchpad
AttrInputProp=+INPUT_PROP_PRESSUREPAD
# "GXTP5100 Touchpad": pressure touchpad mostly used in Lenovo laptops.
# GXTP5100:00 27C6:01EA Touchpad
[Goodix Haptic Touchpad (27C6:01EA)]
MatchBus=i2c
MatchVendor=0x27C6
MatchProduct=0x01EA
MatchUdevType=touchpad
AttrInputProp=+INPUT_PROP_PRESSUREPAD
# "GXTP5100 Touchpad": pressure touchpad mostly used in Lenovo laptops.
# GXTP5100:00 27C6:01EB Touchpad
[Goodix Haptic Touchpad (27C6:01EB)]
MatchBus=i2c
MatchVendor=0x27C6
MatchProduct=0x01EB
MatchUdevType=touchpad
AttrInputProp=+INPUT_PROP_PRESSUREPAD
# "GXTP5400 Touchpad": pressure touchpad mostly used in Lenovo laptops.
# GXTP5400:00 27C6:0F96 Touchpad
[Goodix Haptic Touchpad (27C6:0F96)]
MatchBus=i2c
MatchVendor=0x27C6
MatchProduct=0x0F96
MatchUdevType=touchpad
AttrInputProp=+INPUT_PROP_PRESSUREPAD
# "GXTP5420 Touchpad": pressure touchpad mostly used in Lenovo laptops.
# GXTP5420:00 27C6:0F95 Touchpad
[Goodix Haptic Touchpad (27C6:0F95)]
MatchBus=i2c
MatchVendor=0x27C6
MatchProduct=0x0F95
MatchUdevType=touchpad
AttrInputProp=+INPUT_PROP_PRESSUREPAD
# "GXTP5420 Touchpad": pressure touchpad mostly used in Lenovo laptops.
[Goodix Haptic Touchpad (27C6:0F90)]
MatchBus=i2c
MatchVendor=0x27C6
MatchProduct=0x0F90
MatchUdevType=touchpad
AttrInputProp=+INPUT_PROP_PRESSUREPAD

View file

@ -0,0 +1,22 @@
# Do not edit this file, it will be overwritten on update
# HTIX3602:00 0911:5288 touchpad, clickpad pretending it has a right button.
# Integrated into several systems, including
# Purism Librem 14v1
# Prestigio Smartbook 141 C2
# StarLite Mk II
# Iota IOTA2320
# with different names
# ALPS0001:00 0911:5288
# HTIX3602:00 0911:5288
# PCT2342:00 0911:5288
# SP3105FT:00 0911:5288
# SYNA3602:00 0911:5288
# Also exist FTSC1000:00 0911:5288 Mouse, so match in type
# is needed to leave mouse button untouched.
[Hantick 0911:5288 Touchpad]
MatchBus=i2c
MatchVendor=0x0911
MatchProduct=0x5288
MatchUdevType=touchpad
AttrEventCode=-BTN_RIGHT

View file

@ -3,5 +3,7 @@
# This will match several vendors that all # This will match several vendors that all
# re-use the same vendor ID 256C. # re-use the same vendor ID 256C.
[Huion/Gaomon Tablets] [Huion/Gaomon Tablets]
MatchUdevType=tablet
MatchBus=usb
MatchVendor=0x256C MatchVendor=0x256C
AttrResolutionHint=205x328 AttrResolutionHint=205x328

View file

@ -1,47 +0,0 @@
# Do not edit this file, it will be overwritten on update
# IBM/Lenovo Scrollpoint mouse. Instead of a scroll wheel these mice
# feature trackpoint-like sticks which generate a huge amount of scroll
# events that need to be handled differently than scroll wheel events
[IBM ScrollPoint Mouse 3100]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3100
ModelLenovoScrollPoint=1
[IBM ScrollPoint Mouse 3103]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3103
ModelLenovoScrollPoint=1
[IBM ScrollPoint Mouse 3105]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3105
ModelLenovoScrollPoint=1
[IBM ScrollPoint Mouse 3108]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3108
ModelLenovoScrollPoint=1
[IBM ScrollPoint Mouse 3109]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3109
ModelLenovoScrollPoint=1
[IBM ScrollPoint Mouse 6049]
MatchUdevType=mouse
MatchVendor=0x17EF
MatchProduct=0x6049
ModelLenovoScrollPoint=1
[IBM USB Travel Keyboard with Ultra Nav Mouse]
MatchUdevType=pointingstick
MatchVendor=0x04B3
MatchProduct=0x301E
AttrTrackpointMultiplier=1.50

View file

@ -1,9 +1,41 @@
# Do not edit this file, it will be overwritten on update # Do not edit this file, it will be overwritten on update
# Tested on PCSpecialist Recoil 17 # ITE keyboards are usb keyboards mostly used in notebook and laptops,
[ITE Device(8176) Keyboard] # set as internal.
[ITE Device(8???) Keyboard]
MatchUdevType=keyboard MatchUdevType=keyboard
MatchBus=usb MatchBus=usb
MatchVendor=0x048D MatchVendor=0x048D
MatchProduct=0x5000
AttrKeyboardIntegration=internal AttrKeyboardIntegration=internal
# Exception used in desktops (external)
[ITE Device(8595) Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0x8295
AttrKeyboardIntegration=external
# Exception used in some desktops and few laptops (external)
[ITE Device(8911) Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0x8911
AttrKeyboardIntegration=external
# Exception used in desktops (external)
[IT8297 RGB LED Controller Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0x8297
AttrKeyboardIntegration=external
# Exception used in desktops (external)
[Corsair Gaming K95 RGB PLATINUM Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0xC935
AttrKeyboardIntegration=external

View file

@ -1,3 +1,5 @@
# Do not edit this file, it will be overwritten on update
# Kensington Orbit claims to have a middle button, same for # Kensington Orbit claims to have a middle button, same for
[Kensington Orbit Scroll Wheel] [Kensington Orbit Scroll Wheel]
MatchBus=usb MatchBus=usb

View file

@ -55,10 +55,12 @@ AttrPalmPressureThreshold=400
MatchVendor=0x046D MatchVendor=0x046D
MatchProduct=0x4041 MatchProduct=0x4041
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
[Logitech MX Master (4060)] [Logitech MX Master (4060)]
MatchVendor=0x046D MatchVendor=0x046D
MatchProduct=0x4060 MatchProduct=0x4060
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
[Logitech MX Master (4071)] [Logitech MX Master (4071)]
MatchVendor=0x046D MatchVendor=0x046D
MatchProduct=0x4071 MatchProduct=0x4071
@ -69,10 +71,12 @@ ModelInvertHorizontalScrolling=1
MatchVendor=0x046D MatchVendor=0x046D
MatchProduct=0xB012 MatchProduct=0xB012
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
[Logitech MX Master (Bluetooth B017)] [Logitech MX Master (Bluetooth B017)]
MatchVendor=0x046D MatchVendor=0x046D
MatchProduct=0xB017 MatchProduct=0xB017
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
[Logitech MX Master (Bluetooth B01E)] [Logitech MX Master (Bluetooth B01E)]
MatchVendor=0x046D MatchVendor=0x046D
MatchProduct=0xB01E MatchProduct=0xB01E
@ -82,37 +86,45 @@ ModelInvertHorizontalScrolling=1
MatchVendor=0x046D MatchVendor=0x046D
MatchProduct=0x4069 MatchProduct=0x4069
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
ModelScrollOnMiddleClick=1
# MX Master 2S has a different PID on bluetooth # MX Master 2S has a different PID on bluetooth
[Logitech MX Master 2S Bluetooth] [Logitech MX Master 2S Bluetooth]
MatchVendor=0x046D MatchVendor=0x046D
MatchProduct=0xB019 MatchProduct=0xB019
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
ModelScrollOnMiddleClick=1
[Logitech MX Master 3 USB] [Logitech MX Master 3 USB]
MatchVendor=0x046D MatchVendor=0x046D
MatchProduct=0x4082 MatchProduct=0x4082
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
ModelLogitechMXMaster3=1 ModelScrollOnMiddleClick=1
# MX Master 3 has a different PID on bluetooth # MX Master 3 has a different PID on bluetooth
[Logitech MX Master 3 Bluetooth] [Logitech MX Master 3 Bluetooth]
MatchVendor=0x046D MatchVendor=0x046D
MatchProduct=0xB023 MatchProduct=0xB023
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
ModelLogitechMXMaster3=1 ModelScrollOnMiddleClick=1
[Logitech MX Master 3S] [Logitech MX Master 3S]
MatchVendor=0x046D MatchVendor=0x046D
MatchProduct=0xB034 MatchProduct=0xB034
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
ModelLogitechMXMaster3=1 ModelScrollOnMiddleClick=1
[Logitech MX Master 3B] [Logitech MX Master 3B]
MatchVendor=0x046D MatchVendor=0x046D
MatchProduct=0xB028 MatchProduct=0xB028
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
ModelLogitechMXMaster3=1 ModelScrollOnMiddleClick=1
[Logitech MX Master 4]
MatchVendor=0x046D
MatchProduct=0xB042
ModelInvertHorizontalScrolling=1
ModelScrollOnMiddleClick=1
# Don't add quirks for the Logitech Bolt Receiver: # Don't add quirks for the Logitech Bolt Receiver:
# MatchVendor=0x046D # MatchVendor=0x046D

View file

@ -2,7 +2,7 @@
[Microsoft Surface 3 Lid Switch] [Microsoft Surface 3 Lid Switch]
MatchName=*Lid Switch* MatchName=*Lid Switch*
MatchDMIModalias=dmi:*svnMicrosoftCorporation:pnSurface3:* MatchDMIModalias=dmi:*:svnMicrosoftCorporation:pnSurface3:*
AttrLidSwitchReliability=write_open AttrLidSwitchReliability=write_open
# Matches both Surface Laptop keyboards as well as type covers. # Matches both Surface Laptop keyboards as well as type covers.
@ -11,13 +11,9 @@ AttrLidSwitchReliability=write_open
# - Surface Laptop 3: Microsoft Surface 045E:09AE Keyboard # - Surface Laptop 3: Microsoft Surface 045E:09AE Keyboard
# - Surface Book 2: Microsoft Surface Keyboard # - Surface Book 2: Microsoft Surface Keyboard
[Microsoft Surface Keyboard] [Microsoft Surface Keyboard]
MatchName=*Microsoft Surface *Keyboard* MatchName=Microsoft Surface *Keyboard
MatchDMIModalias=dmi:*svnMicrosoftCorporation:* MatchDMIModalias=dmi:*:svnMicrosoftCorporation:*
AttrKeyboardIntegration=internal AttrEventCode=-BTN_0;
[Microsoft Surface Cover]
MatchName=*Microsoft Surface *Cover*
MatchDMIModalias=dmi:*svnMicrosoftCorporation:*
AttrKeyboardIntegration=internal AttrKeyboardIntegration=internal
[Microsoft Surface Laptop Studio Touchpad] [Microsoft Surface Laptop Studio Touchpad]
@ -27,11 +23,6 @@ MatchUdevType=touchpad
AttrPressureRange=25:10 AttrPressureRange=25:10
AttrPalmPressureThreshold=500 AttrPalmPressureThreshold=500
[Microsoft Surface Laptop Studio Built-In Peripherals]
MatchName=*Microsoft Surface*
MatchDMIModalias=dmi:*svnMicrosoftCorporation:*pnSurfaceLaptopStudio
ModelTabletModeNoSuspend=1
[Microsoft Nano Transceiver v2.0] [Microsoft Nano Transceiver v2.0]
MatchUdevType=mouse MatchUdevType=mouse
MatchBus=usb MatchBus=usb

View file

@ -0,0 +1,10 @@
# Do not edit this file, it will be overwritten on update
# Nulea M501 does not name itself as a "Trackball"
# In USB mode, it shares a generic dongle and name with other non-trackball
# mice. As such, trackball quirks are enabled only for bluetooth modes.
[Nulea M501 Bluetooth Trackball]
MatchBus=bluetooth
MatchVendor=0x000E
MatchProduct=0x3412
ModelTrackball=1

View file

@ -1,3 +1,5 @@
# Do not edit this file, it will be overwritten on update
[VirtualBox mouse integration] [VirtualBox mouse integration]
MatchName=*VirtualBox mouse integration* MatchName=*VirtualBox mouse integration*
ModelBouncingKeys=1 AttrIsVirtual=1

View file

@ -0,0 +1,28 @@
# Do not edit this file, it will be overwritten on update
# GPD Win Max - All versions
# TongFang GX4 (X4SP4NAL)
[Pixart Touchpad (093A:0255)]
MatchBus=i2c
MatchUdevType=touchpad
MatchVendor=0x093A
MatchProduct=0x0255
AttrEventCode=-BTN_RIGHT
# Framework Laptop
# PCSpecialist Recoil 17
[Pixart Touchpad (093A:0274)]
MatchBus=i2c
MatchUdevType=touchpad
MatchVendor=0x093A
MatchProduct=0x0274
AttrEventCode=-BTN_RIGHT
# Chuwi AeroBook Plus
# Chuwi Gemibook
[Pixart Touchpad (093A:1336)]
MatchBus=i2c
MatchUdevType=touchpad
MatchVendor=0x093A
MatchProduct=0x1336
AttrEventCode=-BTN_RIGHT

View file

@ -1,3 +1,5 @@
# Do not edit this file, it will be overwritten on update
[QEMU/KVM mouse integration] [QEMU/KVM mouse integration]
MatchName=*spice vdagent tablet* MatchName=*spice vdagent tablet*
ModelBouncingKeys=1 AttrIsVirtual=1

View file

@ -2,7 +2,7 @@
[Razer Blade Lid Switch] [Razer Blade Lid Switch]
MatchName=*Lid Switch* MatchName=*Lid Switch*
MatchDMIModalias=dmi:*svnRazer:pnBlade* MatchDMIModalias=dmi:*:svnRazer:pnBlade*:*
AttrLidSwitchReliability=write_open AttrLidSwitchReliability=write_open
# Manually added entries must go above this line. # Manually added entries must go above this line.
@ -309,3 +309,24 @@ MatchBus=usb
MatchVendor=0x1532 MatchVendor=0x1532
MatchProduct=0x02B8 MatchProduct=0x02B8
AttrKeyboardIntegration=internal AttrKeyboardIntegration=internal
[RazerBlade142025 Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x1532
MatchProduct=0x02C5
AttrKeyboardIntegration=internal
[RazerBlade162025 Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x1532
MatchProduct=0x02C6
AttrKeyboardIntegration=internal
[RazerBlade182025 Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x1532
MatchProduct=0x02C7
AttrKeyboardIntegration=internal

View file

@ -7,13 +7,22 @@ MatchVendor=0x0002
MatchProduct=0x0007 MatchProduct=0x0007
ModelSynapticsSerialTouchpad=1 ModelSynapticsSerialTouchpad=1
# SYNA3602:00 0911:5288 touchpad, clickpad pretending it has a right button. # "SYNA2B31:00 06CB:CE37 Touchpad": pressure touchpad used in Lenovo laptops.
# Integrated into several systems, including # also known as
# Purism Librem 14v1 # MSFT0001:00 06CB:CE37
# Prestigio Smartbook 141 C2 # MSFT0001:01 06CB:CE37
# StarLite Mk II # PNP0C50:01 06CB:CE37
# Iota IOTA2320 [Synaptics 06CB:CE37 Touchpad]
[Synaptics 0911:5288 Touchpad] MatchBus=i2c
MatchVendor=0x06CB
MatchProduct=0xCE37
MatchUdevType=touchpad MatchUdevType=touchpad
MatchName=* 0911:5288 Touchpad AttrInputProp=+INPUT_PROP_PRESSUREPAD
AttrEventCode=-BTN_RIGHT
# "SYNA3580:00 06CB:CFD2 Touchpad": pressure touchpad mostly used in HP laptops.
[Synaptics 06CB:CFD2 Touchpad]
MatchBus=i2c
MatchVendor=0x06CB
MatchProduct=0xCFD2
MatchUdevType=touchpad
AttrInputProp=+INPUT_PROP_PRESSUREPAD

View file

@ -1,3 +1,5 @@
# Do not edit this file, it will be overwritten on update
[Trust GXT 25 Gaming Mouse] [Trust GXT 25 Gaming Mouse]
MatchUdevType=mouse MatchUdevType=mouse
MatchBus=usb MatchBus=usb

View file

@ -1,9 +0,0 @@
# Do not edit this file, it will be overwritten on update
# Tested on PCSpecialist Recoil 17
[Uniwill Touchpad]
MatchUdevType=touchpad
MatchBus=i2c
MatchVendor=0x093A
MatchProduct=0x0274
AttrEventCode=-BTN_RIGHT

View file

@ -2,8 +2,8 @@
[VMWare Virtual PS/2 Mouse] [VMWare Virtual PS/2 Mouse]
MatchName=*VirtualPS/2 VMware VMMouse* MatchName=*VirtualPS/2 VMware VMMouse*
ModelBouncingKeys=1 AttrIsVirtual=1
[VMware VMware Virtual USB Mouse] [VMware VMware Virtual USB Mouse]
MatchName=*VMware VMware Virtual USB Mouse* MatchName=*VMware VMware Virtual USB Mouse*
ModelBouncingKeys=1 AttrIsVirtual=1

View file

@ -1,9 +1,38 @@
[Acer Switch Alpha 12] # Do not edit this file, it will be overwritten on update
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*svnAcer:pnSwitchSA5-271:* [Acer Spin 5 (SP513-52N)]
MatchBus=ps2
MatchUdevType=keyboard
MatchDMIModalias=dmi:*:svnAcer:pnSpinSP513-52N:*
ModelTabletModeNoSuspend=1 ModelTabletModeNoSuspend=1
[Acer Spin 5] # Input devices
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*svnAcer:pnSpinSP513-52N:* # These ones are detachable keyboard+touchpad combos, set internal to allow DWT
ModelTabletModeNoSuspend=1
# Acer Switch Alpha 12 (SA5-271) and (SA5-271P)
# Acer Switch 3 (SW312-31)
[Acer Detachable Keyboard (04F2:1558)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x04F2
MatchProduct=0x1558
AttrKeyboardIntegration=internal
# Acer Switch 7 (SW713-51GNP)
[Acer Detachable Keyboard (06CB:819E)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x06CB
MatchProduct=0x819E
AttrKeyboardIntegration=internal
# Acer Switch Alpha 12 (SA5-271P)
# Acer Switch 3 (SW312-31)
# Acer Switch 5 (SW512-52) and (SW512-52P)
[Acer Detachable Keyboard (06CB:81A7)]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x06CB
MatchProduct=0x81A7
AttrKeyboardIntegration=internal

View file

@ -88,6 +88,7 @@ AttrThumbSizeThreshold=700
MatchBus=usb MatchBus=usb
MatchVendor=0x05AC MatchVendor=0x05AC
MatchProduct=0x0324 MatchProduct=0x0324
AttrSizeHint=162x115
AttrTouchSizeRange=20:10 AttrTouchSizeRange=20:10
AttrPressureRange=3:0 AttrPressureRange=3:0
AttrPalmSizeThreshold=900 AttrPalmSizeThreshold=900

View file

@ -2,12 +2,12 @@
[Asus X555LAB] [Asus X555LAB]
MatchName=*ETPS/2 Elantech Touchpad* MatchName=*ETPS/2 Elantech Touchpad*
MatchDMIModalias=dmi:*svnASUSTeKCOMPUTERINC.:pnX555LAB:* MatchDMIModalias=dmi:*:svnASUSTeKCOMPUTERINC.:pnX555LAB:*
ModelTouchpadVisibleMarker=1 ModelTouchpadVisibleMarker=1
[Asus UX21E] [Asus UX21E]
MatchName=*ETPS/2 Elantech Touchpad* MatchName=*ETPS/2 Elantech Touchpad*
MatchDMIModalias=dmi:*svnASUSTeKComputerInc.:pnUX21E:* MatchDMIModalias=dmi:*:svnASUSTeKComputerInc.:pnUX21E:*
AttrPressureRange=24:10 AttrPressureRange=24:10
# Asus UX302LA touchpad doesn't update the pressure values once two # Asus UX302LA touchpad doesn't update the pressure values once two
@ -15,35 +15,39 @@ AttrPressureRange=24:10
# at all. https://gitlab.freedesktop.org/libinput/libinput/issues/145 # at all. https://gitlab.freedesktop.org/libinput/libinput/issues/145
[Asus UX302LA] [Asus UX302LA]
MatchName=*ETPS/2 Elantech Touchpad* MatchName=*ETPS/2 Elantech Touchpad*
MatchDMIModalias=dmi:*svnASUSTeKCOMPUTERINC.:pnUX302LA:* MatchDMIModalias=dmi:*:svnASUSTeKCOMPUTERINC.:pnUX302LA:*
AttrEventCode=-ABS_MT_PRESSURE;-ABS_PRESSURE; AttrEventCode=-ABS_MT_PRESSURE;-ABS_PRESSURE;
# Asus VivoBook Flip 14 TP412UA tablet switch seems misbehaving, always # Asus VivoBook Flip 14 TP412UA tablet switch seems misbehaving, always
# indicating tablet position # indicating tablet position
[Asus TP412UA Tablet Mode Switch] [Asus TP412UA Tablet Mode Switch]
MatchName=*Intel Virtual Button* MatchName=*Intel Virtual Button*
MatchDMIModalias=dmi:*svnASUSTeKCOMPUTERINC.:pnVivoBookFlip14_ASUSFlipTP412UA:* MatchDMIModalias=dmi:*:svnASUSTeKCOMPUTERINC.:pnVivoBookFlip14_ASUSFlipTP412UA:*
ModelTabletModeSwitchUnreliable=1 ModelTabletModeSwitchUnreliable=1
# keyboard has a different vid/pid to the touchpad # keyboard has a different vid/pid to the touchpad
# so libinput won't pair the two together and dwt isn't active. # so libinput won't pair the two together and dwt isn't active.
# see: https://gitlab.freedesktop.org/libinput/libinput/-/issues/615 # see: https://gitlab.freedesktop.org/libinput/libinput/-/issues/615
[Asus ROG Zephyrus G15 2021 keyboard] [Asus ROG Zephyrus G15 2021 keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x0B05 MatchVendor=0x0B05
MatchProduct=0x19B6 MatchProduct=0x19B6
MatchUdevType=keyboard
AttrKeyboardIntegration=internal AttrKeyboardIntegration=internal
# keyboard has a different vid/pid to the touchpad # keyboard has a different vid/pid to the touchpad
# so libinput won't pair the two together and dwt isn't active. # so libinput won't pair the two together and dwt isn't active.
[Asus ROG Strix G15 2021 keyboard] [Asus ROG Strix G15 2021 keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x0B05 MatchVendor=0x0B05
MatchProduct=0x1866 MatchProduct=0x1866
MatchUdevType=keyboard
AttrKeyboardIntegration=internal AttrKeyboardIntegration=internal
# don't disable volume buttons in tablet mode # enable "disable touchpad while typing" to work with z13 keyboard
[Asus ROG Flow Z13 2025 volume buttons] [Asus ROG FLow Z13 2025 keyboard]
MatchName=AT Translated Set 2 keyboard MatchUdevType=keyboard
MatchDMIModalias=dmi:*svnASUSTeKCOMPUTERINC.:pnROGFlowZ13GZ302EA_GZ302EA:* MatchBus=usb
ModelTabletModeNoSuspend=1 MatchVendor=0x0B05
MatchProduct=0x1A30
AttrKeyboardIntegration=internal

View file

@ -1,17 +0,0 @@
# Do not edit this file, it will be overwritten on update
# Acer Hawaii Keyboard, uses Chicony VID
[Acer Hawaii Keyboard]
MatchUdevType=touchpad
MatchBus=usb
MatchVendor=0x04F2
MatchProduct=0x1558
AttrTPKComboLayout=below
# Lenovo MIIX 720 comes with a detachable touchpad-keyboard combo
[Chicony Lenovo MIIX 720 Touchpad]
MatchUdevType=touchpad
MatchBus=usb
MatchVendor=0x17EF
MatchProduct=0x60A6
AttrTPKComboLayout=below

View file

@ -1,9 +0,0 @@
[Chuwi Gemibook]
MatchName=HTIX5288:00 093A:1336 Touchpad
MatchUdevType=touchpad
AttrEventCode=-BTN_RIGHT
[Chuwi AeroBook Plus]
MatchName=SYNA3602:01 093A:1336 Touchpad
MatchUdevType=touchpad
AttrEventCode=-BTN_RIGHT

View file

@ -2,108 +2,104 @@
[Dell Touchpads] [Dell Touchpads]
MatchName=* Touchpad MatchName=* Touchpad
MatchDMIModalias=dmi:*svnDellInc.:* MatchDMIModalias=dmi:*:svnDellInc.:*
ModelTouchpadVisibleMarker=1 ModelTouchpadVisibleMarker=1
[Dell i2c Touchpads] [Dell i2c Touchpads]
MatchBus=i2c MatchBus=i2c
MatchUdevType=touchpad MatchUdevType=touchpad
MatchDMIModalias=dmi:*svnDellInc.:* MatchDMIModalias=dmi:*:svnDellInc.:*
AttrMscTimestamp=watch AttrMscTimestamp=watch
[Dell Inspiron 15R N5110 Touchpad] [Dell Inspiron 15R N5110 Touchpad]
MatchUdevType=touchpad MatchUdevType=touchpad
MatchName=*AlpsPS/2 ALPS GlidePoint MatchName=*AlpsPS/2 ALPS GlidePoint
MatchVersion=0x0300 MatchVersion=0x0300
MatchDMIModalias=dmi:*svnDellInc.:*pnInspironN5110* MatchDMIModalias=dmi:*:svnDellInc.:pnInspironN5110:*
AttrPressureRange=100:95 AttrPressureRange=100:95
[Dell Latitude E5510 Touchpad] [Dell Latitude E5510 Touchpad]
MatchUdevType=touchpad MatchUdevType=touchpad
MatchName=*AlpsPS/2 ALPS GlidePoint MatchName=*AlpsPS/2 ALPS GlidePoint
MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeE5510:* MatchDMIModalias=dmi:*:svnDellInc.:pnLatitudeE5510:*
AttrPressureRange=100:90 AttrPressureRange=100:90
[Dell Latitude E6220 Touchpad] [Dell Latitude E6220 Touchpad]
MatchName=*AlpsPS/2 ALPS GlidePoint MatchName=*AlpsPS/2 ALPS GlidePoint
MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeE6220:* MatchDMIModalias=dmi:*:svnDellInc.:pnLatitudeE6220:*
AttrPressureRange=100:90 AttrPressureRange=100:90
[Dell XPS L322X Touchpad] [Dell XPS L322X Touchpad]
MatchName=*CyPS/2 Cypress Trackpad MatchName=*CyPS/2 Cypress Trackpad
MatchDMIModalias=dmi:*svnDell*:*XPSL322X* # pn can be "XPS L322X" and "Dell System XPS L322X", match both :pn*XPSL322X:.
MatchDMIModalias=dmi:*:svnDellInc.:pn*XPSL322X:*
AttrPressureRange=30:20 AttrPressureRange=30:20
AttrPalmPressureThreshold=254 AttrPalmPressureThreshold=254
[Dell XPS13 9333 Touchpad] [Dell XPS13 9333 Touchpad]
MatchName=*Synaptics s3203 MatchName=*Synaptics s3203
MatchDMIModalias=dmi:*svnDellInc.:*pnXPS139333* MatchDMIModalias=dmi:*:svnDellInc.:pnXPS139333:*
AttrPressureRange=15:10 AttrPressureRange=15:10
AttrPalmPressureThreshold=150 AttrPalmPressureThreshold=150
[Dell XPS 15 9500 Touchpad] [Dell XPS 15 9500 Touchpad]
MatchName=* Touchpad MatchName=* Touchpad
MatchDMIModalias=dmi:*svnDellInc.:pnXPS159500:* MatchDMIModalias=dmi:*:svnDellInc.:pnXPS159500:*
ModelTouchpadVisibleMarker=0 ModelTouchpadVisibleMarker=0
ModelTouchpadPhantomClicks=1 ModelTouchpadPhantomClicks=1
[Dell Latitude D620 Trackpoint] [Dell Latitude D620 Trackpoint]
MatchName=*DualPoint Stick MatchName=*DualPoint Stick
MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeD620* MatchDMIModalias=dmi:*:svnDellInc.:pnLatitudeD620:*
AttrTrackpointMultiplier=0.5 AttrTrackpointMultiplier=0.5
[Latitude E5480 Trackpoint] [Latitude E5480 Trackpoint]
MatchName=*DualPoint Stick MatchName=*DualPoint Stick
MatchUdevType=pointingstick MatchUdevType=pointingstick
MatchDMIModalias=dmi:**bvnDellInc.:*:pnLatitude5480* MatchDMIModalias=dmi:*:svnDellInc.:pnLatitude5480:*
AttrTrackpointMultiplier=0.5 AttrTrackpointMultiplier=0.5
[Latitude 5580 Trackpoint] [Latitude 5580 Trackpoint]
MatchName=*DualPoint Stick MatchName=*DualPoint Stick
MatchUdevType=pointingstick MatchUdevType=pointingstick
MatchDMIModalias=dmi:**bvnDellInc.:*:pnLatitude5580* MatchDMIModalias=dmi:*:svnDellInc.:pnLatitude5580:*
AttrTrackpointMultiplier=0.5 AttrTrackpointMultiplier=0.5
[Latitude E5570 Trackpoint] [Latitude E5570 Trackpoint]
MatchName=*DualPoint Stick MatchName=*DualPoint Stick
MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeE5570* MatchDMIModalias=dmi:*:svnDellInc.:pnLatitudeE5570:*
AttrTrackpointMultiplier=0.1 AttrTrackpointMultiplier=0.1
[Latitude E6320 Trackpoint] [Latitude E6320 Trackpoint]
MatchName=*DualPoint Stick MatchName=*DualPoint Stick
MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeE6320* MatchDMIModalias=dmi:*:svnDellInc.:pnLatitudeE6320:*
AttrTrackpointMultiplier=2.0 AttrTrackpointMultiplier=2.0
[Latitude E6400 Trackpoint] [Latitude E6400 Trackpoint]
MatchName=*DualPoint Stick MatchName=*DualPoint Stick
MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeE6400* MatchDMIModalias=dmi:*:svnDellInc.:pnLatitudeE6400:*
AttrTrackpointMultiplier=1.5 AttrTrackpointMultiplier=1.5
[Latitude E7470 Trackpoint] [Latitude E7470 Trackpoint]
MatchName=*DualPoint Stick MatchName=*DualPoint Stick
MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeE7470* MatchDMIModalias=dmi:*:svnDellInc.:pnLatitudeE7470:*
AttrTrackpointMultiplier=0.125 AttrTrackpointMultiplier=0.125
[Latitude 7275]
MatchName=*AT Translated Set 2 keyboard*
MatchDMIModalias=dmi:*:svnDellInc.:pnLatitude7275:*
ModelTabletModeNoSuspend=1
[Latitude 7480 Touchpad] [Latitude 7480 Touchpad]
MatchName=DLL07A0* MatchName=DLL07A0*
MatchDMIModalias=dmi:**bvnDellInc.:*:pnLatitude7480* MatchDMIModalias=dmi:*:svnDellInc.:pnLatitude7480:*
AttrPressureRange=35:34 AttrPressureRange=35:34
[Latitude 7490 Trackpoint] [Latitude 7490 Trackpoint]
MatchName=*Mouse MatchName=*Mouse
MatchUdevType=pointingstick MatchUdevType=pointingstick
MatchDMIModalias=dmi:**bvnDellInc.:*:pnLatitude7490* MatchDMIModalias=dmi:*:svnDellInc.:pnLatitude7490:*
AttrTrackpointMultiplier=0.3 AttrTrackpointMultiplier=0.3
[Precision 7x50 Touchpad] [Precision 7x50 Touchpad]
MatchBus=i2c MatchBus=i2c
MatchUdevType=touchpad MatchUdevType=touchpad
MatchDMIModalias=dmi:*svnDellInc.:pnPrecision7?50* MatchDMIModalias=dmi:*:svnDellInc.:pnPrecision7?50:*
AttrInputProp=-INPUT_PROP_BUTTONPAD AttrInputProp=-INPUT_PROP_BUTTONPAD
# The touch device has the same vid/pid as the totem, the MatchName # The touch device has the same vid/pid as the totem, the MatchName
@ -115,9 +111,14 @@ MatchVendor=0x2575
MatchProduct=0x0204 MatchProduct=0x0204
ModelDellCanvasTotem=1 ModelDellCanvasTotem=1
[Dell 2-in-1 Models] # Dell 2-in-1s have DMI Chassis Type Convertible, match it as by name can be
MatchName=AT Translated Set 2 keyboard # 2-in-1, 2n1 or even some models miss it in name. Also Dell respect this, even
MatchDMIModalias=dmi:*:svnDellInc.:pn*2-in-1:* # if they made a mistake they tend to fix it in firmware updates.
# DMI Chassis Type 1Fh (31 decimal) is Convertible as per SMBIOS specification.
[Dell 2-in-1 Model Buttons]
MatchBus=ps2
MatchUdevType=keyboard
MatchDMIModalias=dmi:*:svnDellInc.:*:ct31:*
ModelTabletModeNoSuspend=1 ModelTabletModeNoSuspend=1
# This is a true pressurepad so disable pressure for contact size # This is a true pressurepad so disable pressure for contact size
@ -126,42 +127,78 @@ ModelTabletModeNoSuspend=1
MatchBus=i2c MatchBus=i2c
MatchVendor=0x27C6 MatchVendor=0x27C6
MatchProduct=0x0F60 MatchProduct=0x0F60
ModelPressurePad=1 AttrInputProp=+INPUT_PROP_PRESSUREPAD
[Dell Mayabay Touchpad] [Dell Mayabay Touchpad]
MatchBus=i2c MatchBus=i2c
MatchVendor=0x06CB MatchVendor=0x06CB
MatchProduct=0xCFA0 MatchProduct=0xCFA0
ModelPressurePad=1 AttrInputProp=+INPUT_PROP_PRESSUREPAD
[Dell Precision 5480] [Dell Precision 5480]
MatchBus=i2c MatchBus=i2c
MatchVendor=0x0488 MatchVendor=0x0488
MatchProduct=0x1063 MatchProduct=0x1063
MatchUdevType=touchpad MatchUdevType=touchpad
MatchDMIModalias=dmi:*svnDellInc.:pnPrecision5480* MatchDMIModalias=dmi:*:svnDellInc.:pnPrecision5480:*
ModelTouchpadVisibleMarker=0 ModelTouchpadVisibleMarker=0
[Dell laptop 14 Synaptics touchpad] [Dell laptop 14 Synaptics touchpad]
MatchBus=i2c MatchBus=i2c
MatchVendor=0x06CB MatchVendor=0x06CB
MatchProduct=0xCFF8 MatchProduct=0xCFF8
ModelPressurePad=1 AttrInputProp=+INPUT_PROP_PRESSUREPAD
[Dell laptop 16 Synaptics touchpad] [Dell laptop 16 Synaptics touchpad]
MatchBus=i2c MatchBus=i2c
MatchVendor=0x06CB MatchVendor=0x06CB
MatchProduct=0xCFF9 MatchProduct=0xCFF9
ModelPressurePad=1 AttrInputProp=+INPUT_PROP_PRESSUREPAD
[Dell laptop 14 Goodix touchpad] [Dell laptop 14 Goodix touchpad]
MatchBus=i2c MatchBus=i2c
MatchVendor=0x27C6 MatchVendor=0x27C6
MatchProduct=0x0F61 MatchProduct=0x0F61
ModelPressurePad=1 AttrInputProp=+INPUT_PROP_PRESSUREPAD
[Dell laptop 16 Goodix touchpad] [Dell laptop 16 Goodix touchpad]
MatchBus=i2c MatchBus=i2c
MatchVendor=0x27C6 MatchVendor=0x27C6
MatchProduct=0x0F62 MatchProduct=0x0F62
ModelPressurePad=1 AttrInputProp=+INPUT_PROP_PRESSUREPAD
[Dell 14 Premium DA14250 touchpad]
MatchBus=i2c
MatchVendor=0x0488
MatchProduct=0x108C
AttrInputProp=+INPUT_PROP_PRESSUREPAD
[Dell 16 Premium DA16250 touchpad]
MatchBus=i2c
MatchVendor=0x0488
MatchProduct=0x108D
AttrInputProp=+INPUT_PROP_PRESSUREPAD
[Dell laptop 14_1 Synaptics touchpad]
MatchBus=i2c
MatchVendor=0x06CB
MatchProduct=0xD01D
AttrInputProp=+INPUT_PROP_PRESSUREPAD
[Dell laptop 16_1 Synaptics touchpad]
MatchBus=i2c
MatchVendor=0x06CB
MatchProduct=0xD01A
AttrInputProp=+INPUT_PROP_PRESSUREPAD
[Dell laptop 14 Sensel touchpad]
MatchBus=i2c
MatchVendor=0x2C2F
MatchProduct=0x0034
AttrInputProp=+INPUT_PROP_PRESSUREPAD
[Dell laptop 16 Sensel touchpad]
MatchBus=i2c
MatchVendor=0x2C2F
MatchProduct=0x0033
AttrInputProp=+INPUT_PROP_PRESSUREPAD

View file

@ -1,11 +1,7 @@
[Framework Laptop Touchpad] # Do not edit this file, it will be overwritten on update
MatchName=PIXA3854:00 093A:0274 Touchpad
MatchUdevType=touchpad
MatchDMIModalias=dmi:*svnFramework:pnLaptop*
AttrEventCode=-BTN_RIGHT
[Framework Laptop 16 Keyboard Module] [Framework Laptop 16 Keyboard Module]
MatchName=Framework Laptop 16 Keyboard Module* MatchName=Framework Laptop 16 Keyboard Module*
MatchUdevType=keyboard MatchUdevType=keyboard
MatchDMIModalias=dmi:*svnFramework:pnLaptop16* MatchDMIModalias=dmi:*:svnFramework:pnLaptop16*:*
AttrKeyboardIntegration=internal AttrKeyboardIntegration=internal

View file

@ -1,5 +1,15 @@
# Do not edit this file, it will be overwritten on update
[Gigabyte Aero 15 touchpad] [Gigabyte Aero 15 touchpad]
MatchUdevType=touchpad MatchUdevType=touchpad
MatchName=ETPS/2 Elantech Touchpad MatchName=ETPS/2 Elantech Touchpad
MatchDMIModalias=dmi:*svnGIGABYTE:pnAERO15-XA* MatchDMIModalias=dmi:*:svnGIGABYTE:pnAERO15-XA:*
AttrPalmSizeThreshold=800 AttrPalmSizeThreshold=800
[Gigabyte Aorus15BKF keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x0414
MatchProduct=0x7A44
MatchDMIModalias=dmi:*:svnGIGABYTE:pnAORUS15BKF:*
AttrKeyboardIntegration=internal

View file

@ -178,3 +178,17 @@ ModelChromebook=1
AttrPressureRange=0:-2 AttrPressureRange=0:-2
AttrThumbPressureThreshold=45 AttrThumbPressureThreshold=45
AttrPalmPressureThreshold=0 AttrPalmPressureThreshold=0
[Google Chromebook Roric]
MatchUdevType=touchpad
MatchName=PNP0C50:00 093A:3307 Touchpad
MatchDMIModalias=dmi:*svnGoogle:pnRoric*
ModelChromebook=1
AttrPressureRange=20:10
[Google Chromebook Rull]
MatchUdevType=touchpad
MatchName=PNP0C50:00 093A:3307 Touchpad
MatchDMIModalias=dmi:*svnGoogle:pnRull*
ModelChromebook=1
AttrPressureRange=20:10

View file

@ -1,5 +1,7 @@
[GPD Win Max - All versions] # Do not edit this file, it will be overwritten on update
MatchName=HTIX5288:00 093A:0255 Touchpad
[GPD MicroPC 2 Touchpad]
MatchName=ALPS0001:00 36B6:C001 Touchpad
MatchUdevType=touchpad MatchUdevType=touchpad
MatchDMIModalias=dmi:*svnGPD:*pnG1619-* MatchDMIModalias=dmi:*:svnGPD:pnG1688-08:*
AttrEventCode=-BTN_RIGHT AttrInputProp=-INPUT_PROP_BUTTONPAD

View file

@ -1,14 +1,16 @@
# Do not edit this file, it will be overwritten on update
# Touchpad is not a clickpad but INPUT_PROP_BUTTONPAD is set # Touchpad is not a clickpad but INPUT_PROP_BUTTONPAD is set
[Synaptics ALPS0001:00 0911:5288 Touchpad] [Synaptics ALPS0001:00 0911:5288 Touchpad]
MatchUdevType=touchpad MatchUdevType=touchpad
MatchName=ALPS0001:00 0911:5288 Touchpad MatchName=ALPS0001:00 0911:5288 Touchpad
MatchDMIModalias=dmi:*svn3LogicGroup:*:pnGravitonN15i-K2*:* MatchDMIModalias=dmi:*:svn3LogicGroup:pnGravitonN15i-K2:*
AttrInputProp=-INPUT_PROP_BUTTONPAD AttrInputProp=-INPUT_PROP_BUTTONPAD
AttrEventCode=+BTN_RIGHT AttrEventCode=+BTN_RIGHT
[PCTel PCT2342:00 0911:5288 Touchpad] [PCTel PCT2342:00 0911:5288 Touchpad]
MatchUdevType=touchpad MatchUdevType=touchpad
MatchName=PCT2342:00 0911:5288 Touchpad MatchName=PCT2342:00 0911:5288 Touchpad
MatchDMIModalias=dmi:*svn3LogicGroup:pnGravitonN15i:* MatchDMIModalias=dmi:*:svn3LogicGroup:pnGravitonN15i:*
AttrInputProp=-INPUT_PROP_BUTTONPAD AttrInputProp=-INPUT_PROP_BUTTONPAD
AttrEventCode=+BTN_RIGHT AttrEventCode=+BTN_RIGHT

View file

@ -1,8 +1,10 @@
# Do not edit this file, it will be overwritten on update
# Clickpad that announces BTN_RIGHT # Clickpad that announces BTN_RIGHT
# requires ModelPressurePad=1 # requires AttrInputProp=+INPUT_PROP_PRESSUREPAD
[HONOR MagicBook Art 14] [HONOR MagicBook Art 14]
MatchName=*TOPS0102* MatchName=*TOPS0102*
MatchDMIModalias=dmi:*svnHONOR:*pnMRA-XXX* MatchDMIModalias=dmi:*:svnHONOR:pnMRA-XXX:*
MatchUdevType=touchpad MatchUdevType=touchpad
AttrEventCode=-BTN_RIGHT AttrEventCode=-BTN_RIGHT
ModelPressurePad=1 AttrInputProp=+INPUT_PROP_PRESSUREPAD

View file

@ -1,29 +1,90 @@
# Do not edit this file, it will be overwritten on update # Do not edit this file, it will be overwritten on update
#
[HP Chromebook 14]
MatchName=*Cypress APA Trackpad *cyapa*
MatchDMIModalias=dmi:*:svnHewlett-Packard:pnFalco:*
AttrPressureRange=12:8
# Claims to have double/tripletap but doesn't actually send it # Claims to have double/tripletap but doesn't actually send it
# https://bugs.freedesktop.org/show_bug.cgi?id=98538 # https://bugs.freedesktop.org/show_bug.cgi?id=98538
[HP Compaq 6910p] [HP Compaq 6910p]
MatchName=*SynPS/2 Synaptics TouchPad MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnHewlett-Packard:*pnHPCompaq6910p* MatchDMIModalias=dmi:*:svnHewlett-Packard:pnHPCompaq6910p*:*
AttrEventCode=-BTN_TOOL_DOUBLETAP;-BTN_TOOL_TRIPLETAP; AttrEventCode=-BTN_TOOL_DOUBLETAP;-BTN_TOOL_TRIPLETAP;
# Claims to have double/tripletap but doesn't actually send it # Claims to have double/tripletap but doesn't actually send it
# https://bugzilla.redhat.com/show_bug.cgi?id=1351285 and # https://bugzilla.redhat.com/show_bug.cgi?id=1351285 and
[HP Compaq 8510w] [HP Compaq 8510w]
MatchName=*SynPS/2 Synaptics TouchPad MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnHewlett-Packard:*pnHPCompaq8510w* MatchDMIModalias=dmi:*:svnHewlett-Packard:pnHPCompaq8510w*:*
AttrEventCode=-BTN_TOOL_DOUBLETAP;-BTN_TOOL_TRIPLETAP; AttrEventCode=-BTN_TOOL_DOUBLETAP;-BTN_TOOL_TRIPLETAP;
[HP Pavilion dmi4] [HP Elite x2 1013 G3 Tablet Mode Switch]
MatchName=*Intel Virtual Button*
MatchDMIModalias=dmi:*:svnHP:pnHPElitex21013G3:*
ModelTabletModeSwitchUnreliable=1
# The HP OmniBook Ultra Flip 14 toggles tablet mode at a little less than 180
# degrees and hardware switches off inputs at a little more than 180 degrees.
# We don't suspend ourselves to allow using them in flat position. It is
# possible that HP fixes this in the future (i.e. so tablet mode toggles
# after 180 degrees) so check before removing these rules.
# This rule is for the keyboard and...
[HP OmniBook Ultra Flip Laptop 14-fh0xxx and 14t-fh000 Keyboard]
MatchBus=ps2
MatchUdevType=keyboard
MatchDMIModalias=dmi:*:svnHP:*:rn8CDE:*
ModelTabletModeNoSuspend=1
# ...this rule is for the touchpad.
[HP OmniBook Ultra Flip Laptop 14-fh0xxx and 14t-fh000 Touchpad]
MatchBus=i2c
MatchUdevType=touchpad
MatchDMIModalias=dmi:*:svnHP:*:rn8CDE:*
ModelTabletModeNoSuspend=1
AttrPressureRange=15:5
AttrThumbPressureThreshold=80
AttrPalmPressureThreshold=125
[HP Pavilion dm4]
MatchName=*SynPS/2 Synaptics TouchPad MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnHewlett-Packard:*pnHPPaviliondm4NotebookPC* MatchDMIModalias=dmi:*:svnHewlett-Packard:pnHPPaviliondm4NotebookPC:*
ModelHPPavilionDM4Touchpad=1 ModelHPPavilionDM4Touchpad=1
[HP Spectre x360 Convertible 15-bl000]
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*:svnHP:pnHPSpectrex360Convertible15-bl0XX:*
ModelTabletModeNoSuspend=1
[HP Spectre x360 Convertible 15-bl1xx]
MatchUdevType=touchpad
MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*:svnHP:pnHPSpectrex360Convertible15-bl1XX:*
AttrPressureRange=55:40
AttrThumbPressureThreshold=90
AttrPalmPressureThreshold=100
[HP Spectre x360 Convertible 15-ch0xx]
MatchUdevType=touchpad
MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*:svnHP:pnHPSpectrex360Convertible15-ch0xx:*
AttrThumbPressureThreshold=90
AttrPalmPressureThreshold=100
# The HP stream x360's embedded-controller filters out events form its builtin
# keyboard when in tablet-mode itself; and it has a volume up/down on the side.
# Do not suspend the keyboard when in tablet-mode so that the volume up/down
# button keeps working when in tablet-mode.
[HP Spectre x360 Convertible 15-ch0xx Tablet Mode Switch]
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*:svnHP:pnHPSpectrex360Convertible15-ch0xx:*
ModelTabletModeNoSuspend=1
# Touchpad is a clickpad but INPUT_PROP_BUTTONPAD is not set, see # Touchpad is a clickpad but INPUT_PROP_BUTTONPAD is not set, see
# https://bugs.freedesktop.org/show_bug.cgi?id=97147 # https://bugs.freedesktop.org/show_bug.cgi?id=97147
[HP Stream 11] [HP Stream 11]
MatchName=SYN1EDE:00 06CB:7442* MatchName=SYN1EDE:00 06CB:7442*
MatchDMIModalias=dmi:*svnHewlett-Packard:pnHPStreamNotebookPC11* MatchDMIModalias=dmi:*:svnHewlett-Packard:pnHPStreamNotebookPC11:*
AttrInputProp=+INPUT_PROP_BUTTONPAD AttrInputProp=+INPUT_PROP_BUTTONPAD
# The HP stream x360's embedded-controller filters out events form its builtin # The HP stream x360's embedded-controller filters out events form its builtin
@ -36,65 +97,7 @@ MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*:svnHewlett-Packard:pnHPStreamx360ConvertiblePC11:* MatchDMIModalias=dmi:*:svnHewlett-Packard:pnHPStreamx360ConvertiblePC11:*
ModelTabletModeNoSuspend=1 ModelTabletModeNoSuspend=1
[HP Spectre x360 Convertible 15-bl000]
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*:svnHP:pnHPSpectrex360Convertible15-bl0XX:*
ModelTabletModeNoSuspend=1
[HP ZBook Studio G3] [HP ZBook Studio G3]
MatchName=AlpsPS/2 ALPS GlidePoint MatchName=AlpsPS/2 ALPS GlidePoint
MatchDMIModalias=dmi:*svnHP:pnHPZBookStudioG3:* MatchDMIModalias=dmi:*:svnHP:pnHPZBookStudioG3:*
ModelHPZBookStudioG3=1 ModelHPZBookStudioG3=1
[HP Chromebook 14]
MatchName=*Cypress APA Trackpad *cyapa*
MatchDMIModalias=dmi:*svnHewlett-Packard*:pnFalco*
AttrPressureRange=12:8
[HP Spectre x360 Convertible 15-bl1xx]
MatchUdevType=touchpad
MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnHP:pnHPSpectrex360Convertible15-bl1XX:*
AttrPressureRange=55:40
AttrThumbPressureThreshold=90
AttrPalmPressureThreshold=100
[HP Spectre x360 Convertible 15-ch0xx]
MatchUdevType=touchpad
MatchName=*SynPS/2 Synaptics TouchPad
MatchDMIModalias=dmi:*svnHP:pnHPSpectrex360Convertible15-ch0xx:*
AttrThumbPressureThreshold=90
AttrPalmPressureThreshold=100
# The HP stream x360's embedded-controller filters out events form its builtin
# keyboard when in tablet-mode itself; and it has a volume up/down on the side.
# Do not suspend the keyboard when in tablet-mode so that the volume up/down
# button keeps working when in tablet-mode.
[HP Spectre x360 Convertible 15-ch0xx Tablet Mode Switch]
MatchName=AT Translated Set 2 keyboard
MatchDMIModalias=dmi:*svnHP:pnHPSpectrex360Convertible15-ch0xx:*
ModelTabletModeNoSuspend=1
[HP Elite x2 1013 G3 Tablet Mode Switch]
MatchName=*Intel Virtual Button*
MatchDMIModalias=dmi:*svnHP:pnHPElitex21013G3:*
ModelTabletModeSwitchUnreliable=1
[HP Elite x2 1013 G3 Touchpad]
MatchUdevType=touchpad
MatchBus=usb
MatchVendor=0x044E
MatchProduct=0x1221
AttrTPKComboLayout=below
[HP Elite x2 1013 G3 Keyboard]
MatchUdevType=keyboard
MatchBus=ps2
MatchDMIModalias=dmi:*svnHP:pnHPElitex21013G3:*
AttrKeyboardIntegration=external
[HP Haptics Touchpad CFD2]
MatchBus=i2c
MatchVendor=0x06CB
MatchProduct=0xCFD2
ModelPressurePad=1

View file

@ -1,21 +1,23 @@
# Do not edit this file, it will be overwritten on update
# Clickpad that announces BTN_RIGHT # Clickpad that announces BTN_RIGHT
# https://bugzilla.redhat.com/show_bug.cgi?id=1972370 # https://bugzilla.redhat.com/show_bug.cgi?id=1972370
[Huawei MateBook 2020 Touchpad] [Huawei MateBook X 2020 Touchpad]
MatchName=ELAN2604:00 04F3:3114 Touchpad MatchName=ELAN2604:00 04F3:3114 Touchpad
MatchUdevType=touchpad MatchUdevType=touchpad
MatchDMIModalias=dmi:*svnHUAWEI:*pvrM1010* MatchDMIModalias=dmi:*:svnHUAWEI:pnEUL-WX9:*
AttrEventCode=-BTN_RIGHT AttrEventCode=-BTN_RIGHT
[Huawei MateBook X Pro 2022 Touchpad] [Huawei MateBook X Pro 2022 Touchpad]
MatchName=GXTP7863:00 27C6:01E0 Touchpad MatchName=GXTP7863:00 27C6:01E0 Touchpad
MatchUdevType=touchpad MatchUdevType=touchpad
MatchDMIModalias=dmi:*svnHUAWEI:*pnMRGF-XX* MatchDMIModalias=dmi:*:svnHUAWEI:pnMRGF-XX:*
AttrEventCode=-BTN_RIGHT AttrEventCode=-BTN_RIGHT
# 2024 model requires ModelPressurePad=1 # 2024 model requires AttrInputProp=+INPUT_PROP_PRESSUREPAD
[Huawei MateBook X Pro 2024 Touchpad] [Huawei MateBook X Pro 2024 Touchpad]
MatchName=GXTP7863:00 27C6:01E0 Touchpad MatchName=GXTP7863:00 27C6:01E0 Touchpad
MatchUdevType=touchpad MatchUdevType=touchpad
MatchDMIModalias=dmi:*svnHUAWEI:*pnVGHH-XX* MatchDMIModalias=dmi:*:svnHUAWEI:pnVGHH-XX:*
AttrEventCode=-BTN_RIGHT AttrEventCode=-BTN_RIGHT
ModelPressurePad=1 AttrInputProp=+INPUT_PROP_PRESSUREPAD

Some files were not shown because too many files have changed in this diff Show more