mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-04-01 17:30:50 +02:00
Compare commits
12 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b909846c1 | ||
|
|
4386453716 | ||
|
|
5582a13eba | ||
|
|
63c9d2dcb0 | ||
|
|
cb7cef6f4b | ||
|
|
865fc1fa65 | ||
|
|
23388c99c3 | ||
|
|
657c087286 | ||
|
|
6614604e9a | ||
|
|
d7d64d9871 | ||
|
|
33a6613671 | ||
|
|
92be97b045 |
9 changed files with 161 additions and 12 deletions
17
README.txt
17
README.txt
|
|
@ -67,6 +67,23 @@ http://wayland.freedesktop.org/libinput/doc/latest/modules.html
|
||||||
High-level documentation about libinput's features:
|
High-level documentation about libinput's features:
|
||||||
http://wayland.freedesktop.org/libinput/doc/latest/pages.html
|
http://wayland.freedesktop.org/libinput/doc/latest/pages.html
|
||||||
|
|
||||||
|
Examples of how to use libinput are the debugging tools in the libinput
|
||||||
|
repository. Developers are encouraged to look at those tools for a
|
||||||
|
real-world (yet simple) example on how to use libinput.
|
||||||
|
|
||||||
|
- A commandline debugging tool: https://cgit.freedesktop.org/wayland/libinput/tree/tools/event-debug.c
|
||||||
|
- A GTK application that draws cursor/touch/tablet positions: https://cgit.freedesktop.org/wayland/libinput/tree/tools/event-gui.c
|
||||||
|
|
||||||
|
libinput provides a
|
||||||
|
[pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/) file.
|
||||||
|
Usually a program will use the `PKG_CHECK_MODULES` autoconf macro.
|
||||||
|
Otherwise, the most rudimentary way to compile and link a program against
|
||||||
|
libinput is:
|
||||||
|
|
||||||
|
gcc -o myprogram myprogram.c `pkg-config --cflags --libs libinput`
|
||||||
|
|
||||||
|
For further information on using pkgconfig see the pkg-config documentation.
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ AC_PREREQ([2.64])
|
||||||
|
|
||||||
m4_define([libinput_major_version], [1])
|
m4_define([libinput_major_version], [1])
|
||||||
m4_define([libinput_minor_version], [4])
|
m4_define([libinput_minor_version], [4])
|
||||||
m4_define([libinput_micro_version], [0])
|
m4_define([libinput_micro_version], [2])
|
||||||
m4_define([libinput_version],
|
m4_define([libinput_version],
|
||||||
[libinput_major_version.libinput_minor_version.libinput_micro_version])
|
[libinput_major_version.libinput_minor_version.libinput_micro_version])
|
||||||
|
|
||||||
|
|
@ -35,7 +35,7 @@ AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz])
|
||||||
# b) If interfaces have been changed or added, but binary compatibility has
|
# b) If interfaces have been changed or added, but binary compatibility has
|
||||||
# been preserved, change to C+1:0:A+1
|
# been preserved, change to C+1:0:A+1
|
||||||
# c) If the interface is the same as the previous version, change to C:R+1:A
|
# c) If the interface is the same as the previous version, change to C:R+1:A
|
||||||
LIBINPUT_LT_VERSION=19:1:9
|
LIBINPUT_LT_VERSION=19:3:9
|
||||||
AC_SUBST(LIBINPUT_LT_VERSION)
|
AC_SUBST(LIBINPUT_LT_VERSION)
|
||||||
|
|
||||||
AM_SILENT_RULES([yes])
|
AM_SILENT_RULES([yes])
|
||||||
|
|
|
||||||
48
doc/faqs.dox
48
doc/faqs.dox
|
|
@ -54,6 +54,52 @@ option is not exposed by the intermediary, it cannot be configured by the
|
||||||
client. Also some configuration options that are provided by the
|
client. Also some configuration options that are provided by the
|
||||||
intermediary may not be libinput-specific configuration options.
|
intermediary may not be libinput-specific configuration options.
|
||||||
|
|
||||||
|
@section faq_configure_wayland How do I configure my device on Wayland?
|
||||||
|
|
||||||
|
See @ref faq_config_options Use the configuration tool provided by your
|
||||||
|
desktop environment (e.g. gnome-control-center) or direct access to your
|
||||||
|
desktop environment's configuration storage (e.g. gsettings).
|
||||||
|
|
||||||
|
@section faq_configure_xorg How do I configure my device on X?
|
||||||
|
|
||||||
|
See @ref faq_config_options If your desktop environment does not provide a
|
||||||
|
graphical configuration tool you can use an
|
||||||
|
<a href="https://www.x.org/archive/current/doc/man/man5/xorg.conf.5.xhtml">xorg.conf.d snippet</a>.
|
||||||
|
Usually, such a snippet looks like this:
|
||||||
|
<pre>
|
||||||
|
$> cat /etc/X11/xorg.conf.d/99-libinput-custom-config.conf
|
||||||
|
Section "InputClass"
|
||||||
|
Identifier "something to identify this snippet"
|
||||||
|
MatchDriver "libinput"
|
||||||
|
MatchProduct "substring of the device name"
|
||||||
|
Option "some option name" "the option value"
|
||||||
|
EndSection
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
The identifier is merely a human-readable string that shows up in the log
|
||||||
|
file. The MatchProduct line should contain the device name or a substring of
|
||||||
|
the device name that the snippet should apply to. For a full list of option
|
||||||
|
names and permitted values, see the
|
||||||
|
<a href="https://www.mankier.com/4/libinput">libinput man page</a>.
|
||||||
|
xorg.conf.d snippets like the above apply to hotplugged devices but can be
|
||||||
|
overwritten at runtime by desktop tools. Multiple snippets may be placed
|
||||||
|
into the same file.
|
||||||
|
|
||||||
|
For run-time configuration and testing, the
|
||||||
|
<a href="https://www.x.org/archive/X11R7.5/doc/man/man1/xinput.1.html">xinput</a>
|
||||||
|
debugging tool can modify a devices' properties. See the
|
||||||
|
<a href="https://www.mankier.com/4/libinput">libinput man page</a>
|
||||||
|
for supported property names and values. Usually, an invocation looks like
|
||||||
|
this:
|
||||||
|
<pre>
|
||||||
|
$> xinput set-prop "the device name" "the property name" value [value2] [value3]
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
@note
|
||||||
|
Changes performed by xinput do not persist across device hotplugs. xinput is
|
||||||
|
considered a debugging and testing tool only and should not be used for
|
||||||
|
permanent configurations.
|
||||||
|
|
||||||
@section faq_hwdb_changes How to apply hwdb changes
|
@section faq_hwdb_changes How to apply hwdb changes
|
||||||
|
|
||||||
Sometimes users are asked to test updates to the <a
|
Sometimes users are asked to test updates to the <a
|
||||||
|
|
@ -74,7 +120,7 @@ commands below.
|
||||||
|
|
||||||
Rebuild the hwdb and load the new set on your device:
|
Rebuild the hwdb and load the new set on your device:
|
||||||
|
|
||||||
sudo udevadm hwdb --reload
|
sudo udevadm hwdb --update
|
||||||
sudo udevadm trigger /sys/class/input/eventX
|
sudo udevadm trigger /sys/class/input/eventX
|
||||||
sudo udevadm test /sys/class/input/eventX
|
sudo udevadm test /sys/class/input/eventX
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -339,6 +339,9 @@ tp_edge_scroll_handle_state(struct tp_dispatch *tp, uint64_t time)
|
||||||
if (t->state == TOUCH_BEGIN)
|
if (t->state == TOUCH_BEGIN)
|
||||||
t->scroll.edge_state =
|
t->scroll.edge_state =
|
||||||
EDGE_SCROLL_TOUCH_STATE_AREA;
|
EDGE_SCROLL_TOUCH_STATE_AREA;
|
||||||
|
else if (t->state == TOUCH_END)
|
||||||
|
t->scroll.edge_state =
|
||||||
|
EDGE_SCROLL_TOUCH_STATE_NONE;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -955,8 +955,11 @@ tp_need_motion_history_reset(struct tp_dispatch *tp)
|
||||||
{
|
{
|
||||||
bool rc = false;
|
bool rc = false;
|
||||||
|
|
||||||
/* semi-mt finger postions may "jump" when nfingers changes */
|
/* Changing the numbers of fingers can cause a jump in the
|
||||||
if (tp->semi_mt && tp->nfingers_down != tp->old_nfingers_down)
|
* coordinates, always reset the motion history for all touches when
|
||||||
|
* that happens.
|
||||||
|
*/
|
||||||
|
if (tp->nfingers_down != tp->old_nfingers_down)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* if we're transitioning between slots and fake touches in either
|
/* if we're transitioning between slots and fake touches in either
|
||||||
|
|
@ -1589,6 +1592,24 @@ evdev_tag_touchpad(struct evdev_device *device,
|
||||||
struct udev_device *udev_device)
|
struct udev_device *udev_device)
|
||||||
{
|
{
|
||||||
int bustype, vendor;
|
int bustype, vendor;
|
||||||
|
const char *prop;
|
||||||
|
|
||||||
|
prop = udev_device_get_property_value(udev_device,
|
||||||
|
"ID_INPUT_TOUCHPAD_INTEGRATION");
|
||||||
|
if (prop) {
|
||||||
|
if (streq(prop, "internal")) {
|
||||||
|
evdev_tag_touchpad_internal(device);
|
||||||
|
return;
|
||||||
|
} else if (streq(prop, "external")) {
|
||||||
|
evdev_tag_touchpad_external(device);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
log_info(evdev_libinput_context(device),
|
||||||
|
"%s: tagged as unknown value %s\n",
|
||||||
|
device->devname,
|
||||||
|
prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* simple approach: touchpads on USB or Bluetooth are considered
|
/* simple approach: touchpads on USB or Bluetooth are considered
|
||||||
* external, anything else is internal. Exception is Apple -
|
* external, anything else is internal. Exception is Apple -
|
||||||
|
|
|
||||||
|
|
@ -3038,7 +3038,9 @@ evdev_tablet_has_left_handed(struct evdev_device *device)
|
||||||
if (libwacom_is_reversible(d))
|
if (libwacom_is_reversible(d))
|
||||||
has_left_handed = true;
|
has_left_handed = true;
|
||||||
} else if (libwacom_error_get_code(error) == WERROR_UNKNOWN_MODEL) {
|
} else if (libwacom_error_get_code(error) == WERROR_UNKNOWN_MODEL) {
|
||||||
log_info(libinput, "Tablet unknown to libwacom\n");
|
log_info(libinput,
|
||||||
|
"%s: tablet unknown to libwacom\n",
|
||||||
|
device->devname);
|
||||||
} else {
|
} else {
|
||||||
log_error(libinput,
|
log_error(libinput,
|
||||||
"libwacom error: %s\n",
|
"libwacom error: %s\n",
|
||||||
|
|
|
||||||
|
|
@ -607,7 +607,7 @@ START_TEST(touchpad_1fg_tap_n_drag)
|
||||||
litest_touch_down(dev, 0, 50, 50);
|
litest_touch_down(dev, 0, 50, 50);
|
||||||
litest_touch_up(dev, 0);
|
litest_touch_up(dev, 0);
|
||||||
litest_touch_down(dev, 0, 50, 50);
|
litest_touch_down(dev, 0, 50, 50);
|
||||||
litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5, 40);
|
litest_touch_move_to(dev, 0, 50, 50, 80, 80, 20, 2);
|
||||||
|
|
||||||
libinput_dispatch(li);
|
libinput_dispatch(li);
|
||||||
|
|
||||||
|
|
@ -649,7 +649,7 @@ START_TEST(touchpad_1fg_tap_n_drag_draglock)
|
||||||
litest_touch_down(dev, 0, 50, 50);
|
litest_touch_down(dev, 0, 50, 50);
|
||||||
litest_touch_up(dev, 0);
|
litest_touch_up(dev, 0);
|
||||||
litest_touch_down(dev, 0, 50, 50);
|
litest_touch_down(dev, 0, 50, 50);
|
||||||
litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5, 40);
|
litest_touch_move_to(dev, 0, 50, 50, 80, 80, 20, 2);
|
||||||
litest_touch_up(dev, 0);
|
litest_touch_up(dev, 0);
|
||||||
|
|
||||||
libinput_dispatch(li);
|
libinput_dispatch(li);
|
||||||
|
|
@ -663,7 +663,7 @@ START_TEST(touchpad_1fg_tap_n_drag_draglock)
|
||||||
|
|
||||||
/* lift finger, set down again, should continue dragging */
|
/* lift finger, set down again, should continue dragging */
|
||||||
litest_touch_down(dev, 0, 50, 50);
|
litest_touch_down(dev, 0, 50, 50);
|
||||||
litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5, 40);
|
litest_touch_move_to(dev, 0, 50, 50, 80, 80, 20, 2);
|
||||||
litest_touch_up(dev, 0);
|
litest_touch_up(dev, 0);
|
||||||
|
|
||||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
|
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
|
||||||
|
|
@ -690,7 +690,7 @@ START_TEST(touchpad_1fg_tap_n_drag_draglock_tap)
|
||||||
litest_touch_down(dev, 0, 50, 50);
|
litest_touch_down(dev, 0, 50, 50);
|
||||||
litest_touch_up(dev, 0);
|
litest_touch_up(dev, 0);
|
||||||
litest_touch_down(dev, 0, 50, 50);
|
litest_touch_down(dev, 0, 50, 50);
|
||||||
litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5, 40);
|
litest_touch_move_to(dev, 0, 50, 50, 80, 80, 20, 2);
|
||||||
litest_touch_up(dev, 0);
|
litest_touch_up(dev, 0);
|
||||||
|
|
||||||
libinput_dispatch(li);
|
libinput_dispatch(li);
|
||||||
|
|
@ -704,7 +704,7 @@ START_TEST(touchpad_1fg_tap_n_drag_draglock_tap)
|
||||||
|
|
||||||
/* lift finger, set down again, should continue dragging */
|
/* lift finger, set down again, should continue dragging */
|
||||||
litest_touch_down(dev, 0, 50, 50);
|
litest_touch_down(dev, 0, 50, 50);
|
||||||
litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5, 40);
|
litest_touch_move_to(dev, 0, 50, 50, 80, 80, 20, 2);
|
||||||
|
|
||||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
|
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
|
||||||
|
|
||||||
|
|
@ -732,7 +732,7 @@ START_TEST(touchpad_1fg_tap_n_drag_draglock_tap_click)
|
||||||
litest_touch_down(dev, 0, 50, 50);
|
litest_touch_down(dev, 0, 50, 50);
|
||||||
litest_touch_up(dev, 0);
|
litest_touch_up(dev, 0);
|
||||||
litest_touch_down(dev, 0, 50, 50);
|
litest_touch_down(dev, 0, 50, 50);
|
||||||
litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5, 40);
|
litest_touch_move_to(dev, 0, 50, 50, 80, 80, 20, 2);
|
||||||
libinput_dispatch(li);
|
libinput_dispatch(li);
|
||||||
|
|
||||||
litest_assert_button_event(li, BTN_LEFT,
|
litest_assert_button_event(li, BTN_LEFT,
|
||||||
|
|
|
||||||
|
|
@ -429,6 +429,10 @@ START_TEST(touchpad_edge_scroll_vert)
|
||||||
struct litest_device *dev = litest_current_device();
|
struct litest_device *dev = litest_current_device();
|
||||||
struct libinput *li = dev->libinput;
|
struct libinput *li = dev->libinput;
|
||||||
|
|
||||||
|
litest_touch_down(dev, 0, 99, 20);
|
||||||
|
litest_touch_move_to(dev, 0, 99, 20, 99, 80, 10, 0);
|
||||||
|
litest_touch_up(dev, 0);
|
||||||
|
|
||||||
litest_drain_events(li);
|
litest_drain_events(li);
|
||||||
litest_enable_edge_scroll(dev);
|
litest_enable_edge_scroll(dev);
|
||||||
|
|
||||||
|
|
@ -466,6 +470,10 @@ START_TEST(touchpad_edge_scroll_horiz)
|
||||||
struct litest_device *dev = litest_current_device();
|
struct litest_device *dev = litest_current_device();
|
||||||
struct libinput *li = dev->libinput;
|
struct libinput *li = dev->libinput;
|
||||||
|
|
||||||
|
litest_touch_down(dev, 0, 99, 20);
|
||||||
|
litest_touch_move_to(dev, 0, 99, 20, 99, 80, 10, 0);
|
||||||
|
litest_touch_up(dev, 0);
|
||||||
|
|
||||||
if (!touchpad_has_horiz_edge_scroll_size(dev))
|
if (!touchpad_has_horiz_edge_scroll_size(dev))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -4064,6 +4072,56 @@ START_TEST(touchpad_tool_tripletap_touch_count)
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(touchpad_slot_swap)
|
||||||
|
{
|
||||||
|
struct litest_device *dev = litest_current_device();
|
||||||
|
struct libinput *li = dev->libinput;
|
||||||
|
struct libinput_event *event;
|
||||||
|
struct libinput_event_pointer *ptrev;
|
||||||
|
int first, second;
|
||||||
|
|
||||||
|
/* Synaptics touchpads sometimes end the wrong touchpoint on finger
|
||||||
|
* up, causing the remaining slot to continue with the other slot's
|
||||||
|
* coordinates.
|
||||||
|
* https://bugs.freedesktop.org/show_bug.cgi?id=91352
|
||||||
|
*/
|
||||||
|
litest_drain_events(li);
|
||||||
|
|
||||||
|
for (first = 0; first <= 1; first++) {
|
||||||
|
second = 1 - first;
|
||||||
|
|
||||||
|
litest_touch_down(dev, 0, 50, 50);
|
||||||
|
libinput_dispatch(li);
|
||||||
|
litest_touch_down(dev, 1, 70, 70);
|
||||||
|
libinput_dispatch(li);
|
||||||
|
|
||||||
|
litest_touch_move_to(dev, first, 50, 50, 50, 30, 10, 1);
|
||||||
|
litest_drain_events(li);
|
||||||
|
|
||||||
|
/* release touch 0, continue other slot with 0's coords */
|
||||||
|
litest_push_event_frame(dev);
|
||||||
|
litest_touch_up(dev, first);
|
||||||
|
litest_touch_move(dev, second, 50, 30.1);
|
||||||
|
litest_pop_event_frame(dev);
|
||||||
|
libinput_dispatch(li);
|
||||||
|
litest_touch_move_to(dev, second, 50, 30, 50, 11, 10, 1);
|
||||||
|
libinput_dispatch(li);
|
||||||
|
event = libinput_get_event(li);
|
||||||
|
do {
|
||||||
|
ptrev = litest_is_motion_event(event);
|
||||||
|
ck_assert_double_eq(libinput_event_pointer_get_dx(ptrev), 0.0);
|
||||||
|
ck_assert_double_lt(libinput_event_pointer_get_dy(ptrev), 1.0);
|
||||||
|
|
||||||
|
libinput_event_destroy(event);
|
||||||
|
event = libinput_get_event(li);
|
||||||
|
} while (event);
|
||||||
|
litest_assert_empty_queue(li);
|
||||||
|
|
||||||
|
litest_touch_up(dev, second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
START_TEST(touchpad_time_usec)
|
START_TEST(touchpad_time_usec)
|
||||||
{
|
{
|
||||||
struct litest_device *dev = litest_current_device();
|
struct litest_device *dev = litest_current_device();
|
||||||
|
|
@ -4257,6 +4315,7 @@ litest_setup_tests(void)
|
||||||
litest_add("touchpad:thumb", touchpad_thumb_tap_hold_2ndfg_tap, LITEST_CLICKPAD, LITEST_SINGLE_TOUCH);
|
litest_add("touchpad:thumb", touchpad_thumb_tap_hold_2ndfg_tap, LITEST_CLICKPAD, LITEST_SINGLE_TOUCH);
|
||||||
|
|
||||||
litest_add_for_device("touchpad:bugs", touchpad_tool_tripletap_touch_count, LITEST_SYNAPTICS_TOPBUTTONPAD);
|
litest_add_for_device("touchpad:bugs", touchpad_tool_tripletap_touch_count, LITEST_SYNAPTICS_TOPBUTTONPAD);
|
||||||
|
litest_add_for_device("touchpad:bugs", touchpad_slot_swap, LITEST_SYNAPTICS_TOPBUTTONPAD);
|
||||||
|
|
||||||
litest_add("touchpad:time", touchpad_time_usec, LITEST_TOUCHPAD, LITEST_ANY);
|
litest_add("touchpad:time", touchpad_time_usec, LITEST_TOUCHPAD, LITEST_ANY);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ ACTION!="add|change", GOTO="libinput_device_group_end"
|
||||||
KERNEL!="event[0-9]*", GOTO="libinput_device_group_end"
|
KERNEL!="event[0-9]*", GOTO="libinput_device_group_end"
|
||||||
|
|
||||||
ATTRS{phys}=="?*", \
|
ATTRS{phys}=="?*", \
|
||||||
|
ENV{LIBINPUT_DEVICE_GROUP}=="", \
|
||||||
PROGRAM="@UDEV_TEST_PATH@libinput-device-group %S%p", \
|
PROGRAM="@UDEV_TEST_PATH@libinput-device-group %S%p", \
|
||||||
ENV{LIBINPUT_DEVICE_GROUP}="%c"
|
ENV{LIBINPUT_DEVICE_GROUP}="%c"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue