Compare commits

...

14 commits
main ... 1.9.2

Author SHA1 Message Date
Peter Hutterer
56bcb2999e libinput 1.9.2
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-11-15 14:17:51 +10:00
Peter Hutterer
4ec04fa960 man: add --enable-middlebutton to debug-events man page
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 13c9ef07a2)
2017-11-15 13:37:21 +10:00
Peter Hutterer
e35c202df7 tools: handle missing evdev/pyudev modules with a better error message
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 67bfb5cf2e)
2017-11-15 13:26:10 +10:00
Peter Hutterer
1593d7da32 tools: when the command isn't installed, print that
Makes it more user-friendly to be able to split the tools into multiple
packages

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 92aa1d1418)
2017-11-15 13:26:06 +10:00
Peter Hutterer
73c9ed2cd9 tools: fix missing words in man page
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit be344a3afb)
2017-11-15 13:26:03 +10:00
Peter Hutterer
ed17f8b637 doc: add a FAQ regarding "please add a configuration option"
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit c67b74b45e)
2017-11-14 14:29:30 +10:00
Stefan Brüns
15e40a42e7 tools: Handle LIBINPUT_SWITCH_TABLET_MODE
Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 48fd22def7)
2017-11-14 14:29:17 +10:00
Stefan Brüns
5c989940b6 tools: Show gesture/switch capabilities in list-devices output
Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 5ea84fa7da)
2017-11-14 14:29:16 +10:00
Peter Hutterer
edd83fe99e test: mkdir -p the udev rules and hwdb directories
Especially /run/udev/rules.d may not exist, causing a test suite failure.

https://bugs.freedesktop.org/show_bug.cgi?id=103527

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit d332a64df8)
2017-11-14 14:29:09 +10:00
Peter Hutterer
e7be909838 doc: update test suite page for ninja and other recent changes
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit b15b66616e)
2017-11-14 14:29:07 +10:00
Peter Hutterer
03cd377e00 test: fix the device name for the magic mouse test device
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 04c6439449)
2017-11-14 14:29:01 +10:00
Peter Hutterer
89660005a8 doc: quote all paths in the doxygen file
https://bugs.freedesktop.org/show_bug.cgi?id=103532

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit fb467dce8f)
2017-11-14 14:28:57 +10:00
Peter Hutterer
5b862de70d circle.yml: add ninja dist to tests
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit e182489ce7)
2017-11-14 14:28:55 +10:00
Peter Hutterer
a83085e4f9 touchpad: allow for multiple paired keyboards
needed for the razer blade keybard which provides multiple event nodes for
one physical device but it's hard/impossible to identify which one is the real
event node we care about.

https://bugs.freedesktop.org/show_bug.cgi?id=103156

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 4d7592066a)
2017-11-14 14:28:29 +10:00
18 changed files with 378 additions and 95 deletions

View file

@ -41,6 +41,12 @@ libinput_jobs:
name: Build - No docs name: Build - No docs
environment: environment:
MESON_PARAMS: -Ddocumentation=false MESON_PARAMS: -Ddocumentation=false
build_dist: &build_dist
run:
<<: *build_and_test_default
name: Build - ninja dist
environment:
NINJA_ARGS: dist
ninja_scan_build: &ninja_scan_build ninja_scan_build: &ninja_scan_build
run: run:
<<: *build_and_test_default <<: *build_and_test_default
@ -88,6 +94,7 @@ fedora_build_all: &fedora_build_all
- *build_no_debug_gui - *build_no_debug_gui
- *build_no_tests - *build_no_tests
- *build_no_docs - *build_no_docs
- *build_dist
ubuntu_install: &ubuntu_install ubuntu_install: &ubuntu_install
run: run:
@ -112,6 +119,7 @@ ubuntu_build_all: &ubuntu_build_all
- *build_no_debug_gui - *build_no_debug_gui
- *build_no_tests - *build_no_tests
- *build_no_docs - *build_no_docs
- *build_dist
scan_build_run: &scan_build_run scan_build_run: &scan_build_run
<<: *default_settings <<: *default_settings

View file

@ -125,6 +125,20 @@ 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 considered a debugging and testing tool only and should not be used for
permanent configurations. permanent configurations.
@section faq_configuration Can you add a configuration option for $FEATURE?
No. At least that's going to be the initial answer. Read <a
href="http://who-t.blogspot.com/2016/04/why-libinput-doesnt-have-lot-of-config.html">Why
libinput doesn't have a lot of configuration options</a> first.
Configuration options for most features are a signal that we are incapable
of handling it correctly. To get to that point, we want to be sure we're
truly incapable of doing so. libinput has several features that
are handled automatically (and correctly) that users wanted to have
configuration options for initially.
So the answer to this question will almost always be 'no'. A configuration
option is, in most cases, a cop-out.
@section faq_synclient Why don't synclient and syndaemon work with libinput? @section faq_synclient Why don't synclient and syndaemon work with libinput?
Synclient and syndaemon rely on X input device properties that are specific Synclient and syndaemon rely on X input device properties that are specific

View file

@ -9,8 +9,8 @@ EXTRACT_STATIC = YES
MAX_INITIALIZER_LINES = 0 MAX_INITIALIZER_LINES = 0
QUIET = YES QUIET = YES
INPUT = @INPUT@ INPUT = @INPUT@
IMAGE_PATH = @top_srcdir@/doc/svg \ IMAGE_PATH = "@top_srcdir@/doc/svg" \
@top_srcdir@/doc/dot "@top_srcdir@/doc/dot"
GENERATE_HTML = YES GENERATE_HTML = YES
SEARCHENGINE = NO SEARCHENGINE = NO
USE_MATHJAX = YES USE_MATHJAX = YES
@ -20,11 +20,11 @@ MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES EXPAND_ONLY_PREDEF = YES
PREDEFINED = LIBINPUT_ATTRIBUTE_PRINTF(f, a)= \ PREDEFINED = LIBINPUT_ATTRIBUTE_PRINTF(f, a)= \
LIBINPUT_ATTRIBUTE_DEPRECATED LIBINPUT_ATTRIBUTE_DEPRECATED
DOTFILE_DIRS = @top_srcdir@/doc/dot DOTFILE_DIRS = "@top_srcdir@/doc/dot"
HTML_HEADER = @top_srcdir@/doc/style/header.html HTML_HEADER = "@top_srcdir@/doc/style/header.html"
HTML_FOOTER = @top_srcdir@/doc/style/footer.html HTML_FOOTER = "@top_srcdir@/doc/style/footer.html"
HTML_EXTRA_STYLESHEET = @top_srcdir@/doc/style/bootstrap.css \ HTML_EXTRA_STYLESHEET = "@top_srcdir@/doc/style/bootstrap.css" \
@top_srcdir@/doc/style/customdoxygen.css \ "@top_srcdir@/doc/style/customdoxygen.css" \
@top_srcdir@/doc/style/libinputdoxygen.css "@top_srcdir@/doc/style/libinputdoxygen.css"
USE_MDFILE_AS_MAINPAGE = @top_srcdir@/README.md USE_MDFILE_AS_MAINPAGE = "@top_srcdir@/README.md"

View file

@ -1,18 +1,21 @@
/** /**
@page test-suite libinput test suite @page test-suite libinput test suite
The libinput test suite is based on libinput ships with a number of tests all run automatically on `ninja test`.
[Check](http://check.sourceforge.net/doc/check_html/) and runs automatically The primary test suite is the `libinput-test-suite-runner`. When testing,
during `make check`. Check itself is wrapped into a libinput-specific test the `libinput-test-suite-runner` should always be invoked to check for
suite called *litest*. Tests are found in `$srcdir/test/`, the main test behavior changes.
suite is `libinput-test-suite-runner`.
The test suite has a make-like job control enabled by the `-j` or `--jobs` The test suite runner uses
flag and will fork off as many parallel processes as given by this flag. The [Check](http://check.sourceforge.net/doc/check_html/) underneath the hood
default if unspecified is 8. When debugging a specific test case failure it but most of the functionality is abstracted into *litest* wrappers.
is recommended to employ test filtures (see @ref test-filtering) and disable
parallel tests. The test suite automatically disables parallel make when run The test suite runner has a make-like job control enabled by the `-j` or
in gdb. `--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
failure it is recommended to employ test filtures (see @ref test-filtering)
and disable parallel tests. The test suite automatically disables parallel
make when run in gdb.
@section test-config X.Org config to avoid interference @section test-config X.Org config to avoid interference
@ -28,35 +31,67 @@ with your desktop.
Most tests require the creation of uinput devices and access to the Most tests require the creation of uinput devices and access to the
resulting `/dev/input/eventX` nodes. Some tests require temporary udev rules. resulting `/dev/input/eventX` nodes. Some tests require temporary udev rules.
<b>This usually requires the tests to be run as root</b>. <b>This usually requires the tests to be run as root</b>. If not run as
root, the test suite runner will exit with status 77, interpreted as
"skipped" by ninja.
@section test-filtering Selective running of tests @section test-filtering Selective running of tests
litest's tests are grouped by test groups and devices. A test group is e.g. litest's tests are grouped into test groups, test names and devices. A test
"touchpad:tap" and incorporates all tapping-related tests for touchpads. group is e.g. "touchpad:tap" and incorporates all tapping-related tests for
Each test function is (usually) run with one or more specific devices. touchpads. Each test function is (usually) run with one or more specific
The `--list` commandline argument shows the list of suites and tests. devices. The `--list` commandline argument shows the list of suites and
tests. This is useful when trying to figure out if a specific test is
run for a device.
@code @code
$ ./test/libinput-test-suite-runner --list $ ./test/libinput-test-suite-runner --list
device:wheel: ...
wheel only pointer:left-handed:
blackwidow pointer_left_handed_during_click_multiple_buttons:
device:invalid devices: trackpoint
no device ms-surface-cover
device:group: mouse-wheelclickcount
no device mouse-wheelclickangle
logitech trackball low-dpi-mouse
MS surface cover mouse-roccat
mouse_roccat mouse-wheel-tilt
wheel only mouse
blackwidow logitech-trackball
cyborg-rat
magicmouse
pointer_left_handed_during_click:
trackpoint
ms-surface-cover
mouse-wheelclickcount
mouse-wheelclickangle
low-dpi-mouse
mouse-roccat
mouse-wheel-tilt
mouse
logitech-trackball
cyborg-rat
litest-magicmouse-device
pointer_left_handed:
trackpoint
ms-surface-cover
mouse-wheelclickcount
mouse-wheelclickangle
low-dpi-mouse
mouse-roccat
mouse-wheel-tilt
mouse
... ...
@endcode @endcode
In the above example, the "device:wheel" suite is run for the "wheel only" and In the above example, the "pointer:left-handed" suite contains multiple
the "blackwidow" device. Both devices are automatically instantiated through tests, e.g. "pointer_left_handed_during_click" (this is also the function
uinput by litest. The "no device" entry signals that litest does not name of the test, making it easy to grep for). This particular test is run
instantiate a uinput device for a specific test (though the test itself may for various devices including the trackpoint device and the magic mouse
device.
The "no device" entry signals that litest does not instantiate a uinput
device for a specific test (though the test itself may
instantiate one). instantiate one).
The `--filter-test` argument enables selective running of tests through The `--filter-test` argument enables selective running of tests through
@ -93,7 +128,7 @@ environment variable, if set, also enables verbose mode.
@code @code
$ ./test/libinput-test-suite-runner --verbose $ ./test/libinput-test-suite-runner --verbose
$ LITEST_VERBOSE=1 make check $ LITEST_VERBOSE=1 ninja test
@endcode @endcode
*/ */

View file

@ -1,5 +1,5 @@
project('libinput', 'c', 'cpp', project('libinput', 'c', 'cpp',
version : '1.9.1', version : '1.9.2',
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.40.0') meson_version : '>= 0.40.0')

View file

@ -1588,6 +1588,8 @@ tp_interface_process(struct evdev_dispatch *dispatch,
static void static void
tp_remove_sendevents(struct tp_dispatch *tp) tp_remove_sendevents(struct tp_dispatch *tp)
{ {
struct paired_keyboard *kbd;
libinput_timer_cancel(&tp->palm.trackpoint_timer); libinput_timer_cancel(&tp->palm.trackpoint_timer);
libinput_timer_cancel(&tp->dwt.keyboard_timer); libinput_timer_cancel(&tp->dwt.keyboard_timer);
@ -1596,9 +1598,10 @@ tp_remove_sendevents(struct tp_dispatch *tp)
libinput_device_remove_event_listener( libinput_device_remove_event_listener(
&tp->palm.trackpoint_listener); &tp->palm.trackpoint_listener);
if (tp->dwt.keyboard) ARRAY_FOR_EACH(tp->dwt.paired_keyboard, kbd) {
libinput_device_remove_event_listener( if (kbd->device)
&tp->dwt.keyboard_listener); libinput_device_remove_event_listener(&kbd->listener);
}
if (tp->lid_switch.lid_switch) if (tp->lid_switch.lid_switch)
libinput_device_remove_event_listener( libinput_device_remove_event_listener(
@ -1964,9 +1967,8 @@ tp_dwt_pair_keyboard(struct evdev_device *touchpad,
struct evdev_device *keyboard) struct evdev_device *keyboard)
{ {
struct tp_dispatch *tp = (struct tp_dispatch*)touchpad->dispatch; struct tp_dispatch *tp = (struct tp_dispatch*)touchpad->dispatch;
struct paired_keyboard *kbd;
if (tp->dwt.keyboard) bool found = false;
return;
if ((keyboard->tags & EVDEV_TAG_KEYBOARD) == 0) if ((keyboard->tags & EVDEV_TAG_KEYBOARD) == 0)
return; return;
@ -1974,16 +1976,25 @@ tp_dwt_pair_keyboard(struct evdev_device *touchpad,
if (!tp_want_dwt(touchpad, keyboard)) if (!tp_want_dwt(touchpad, keyboard))
return; return;
libinput_device_add_event_listener(&keyboard->base, ARRAY_FOR_EACH(tp->dwt.paired_keyboard, kbd) {
&tp->dwt.keyboard_listener, if (kbd->device)
tp_keyboard_event, tp); continue;
tp->dwt.keyboard = keyboard;
tp->dwt.keyboard_active = false;
evdev_log_debug(touchpad, found = true;
"palm: dwt activated with %s<->%s\n", libinput_device_add_event_listener(&keyboard->base,
touchpad->devname, &kbd->listener,
keyboard->devname); tp_keyboard_event, tp);
kbd->device = keyboard;
evdev_log_debug(touchpad,
"palm: dwt activated with %s<->%s\n",
touchpad->devname,
keyboard->devname);
break;
}
if (!found)
evdev_log_bug_libinput(touchpad,
"too many internal keyboards for dwt\n");
} }
static void static void
@ -2121,6 +2132,7 @@ tp_interface_device_removed(struct evdev_device *device,
struct evdev_device *removed_device) struct evdev_device *removed_device)
{ {
struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch; struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
struct paired_keyboard *kbd;
if (removed_device == tp->buttons.trackpoint) { if (removed_device == tp->buttons.trackpoint) {
/* Clear any pending releases for the trackpoint */ /* Clear any pending releases for the trackpoint */
@ -2134,11 +2146,12 @@ tp_interface_device_removed(struct evdev_device *device,
tp->buttons.trackpoint = NULL; tp->buttons.trackpoint = NULL;
} }
if (removed_device == tp->dwt.keyboard) { ARRAY_FOR_EACH(tp->dwt.paired_keyboard, kbd) {
libinput_device_remove_event_listener( if (kbd->device == removed_device) {
&tp->dwt.keyboard_listener); libinput_device_remove_event_listener(&kbd->listener);
tp->dwt.keyboard = NULL; kbd->device = NULL;
tp->dwt.keyboard_active = false; tp->dwt.keyboard_active = false;
}
} }
if (removed_device == tp->lid_switch.lid_switch) { if (removed_device == tp->lid_switch.lid_switch) {

View file

@ -383,13 +383,20 @@ struct tp_dispatch {
struct libinput_device_config_dwt config; struct libinput_device_config_dwt config;
bool dwt_enabled; bool dwt_enabled;
bool keyboard_active; /* We have to allow for more than one device node to be the
struct libinput_event_listener keyboard_listener; * internal dwt keyboard (Razer Blade). But they're the same
struct libinput_timer keyboard_timer; * physical device, so we don't care about per-keyboard
struct evdev_device *keyboard; * key/modifier masks.
*/
struct paired_keyboard {
struct evdev_device *device;
struct libinput_event_listener listener;
} paired_keyboard[3];
unsigned long key_mask[NLONGS(KEY_CNT)]; unsigned long key_mask[NLONGS(KEY_CNT)];
unsigned long mod_mask[NLONGS(KEY_CNT)]; unsigned long mod_mask[NLONGS(KEY_CNT)];
bool keyboard_active;
struct libinput_timer keyboard_timer;
uint64_t keyboard_last_press_time; uint64_t keyboard_last_press_time;
} dwt; } dwt;

View file

@ -100,7 +100,7 @@ static const char udev_rule[] =
"\n" "\n"
"LABEL=\"mouse_end\""; "LABEL=\"mouse_end\"";
TEST_DEVICE("litest-magicmouse-device", TEST_DEVICE("magicmouse",
.type = LITEST_MAGICMOUSE, .type = LITEST_MAGICMOUSE,
.features = LITEST_RELATIVE | LITEST_BUTTON | LITEST_WHEEL, .features = LITEST_RELATIVE | LITEST_BUTTON | LITEST_WHEEL,
.interface = &interface, .interface = &interface,

View file

@ -27,6 +27,7 @@
#include <check.h> #include <check.h>
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <libgen.h>
#include <fcntl.h> #include <fcntl.h>
#include <fnmatch.h> #include <fnmatch.h>
#include <getopt.h> #include <getopt.h>
@ -1071,20 +1072,35 @@ litest_install_model_quirks(struct list *created_files_list)
list_insert(created_files_list, &file->link); list_insert(created_files_list, &file->link);
} }
static inline void
mkdir_p(const char *dir)
{
char *path, *parent;
int rc;
if (streq(dir, "/"))
return;
path = strdup(dir);
parent = dirname(path);
mkdir_p(parent);
rc = mkdir(dir, 0755);
if (rc == -1 && errno != EEXIST) {
litest_abort_msg("Failed to create directory %s (%s)\n",
dir,
strerror(errno));
}
free(path);
}
static void static void
litest_init_udev_rules(struct list *created_files) litest_init_udev_rules(struct list *created_files)
{ {
int rc; mkdir_p(UDEV_RULES_D);
mkdir_p(UDEV_HWDB_D);
rc = mkdir(UDEV_RULES_D, 0755);
if (rc == -1 && errno != EEXIST)
litest_abort_msg("Failed to create udev rules directory (%s)\n",
strerror(errno));
rc = mkdir(UDEV_HWDB_D, 0755);
if (rc == -1 && errno != EEXIST)
litest_abort_msg("Failed to create udev hwdb directory (%s)\n",
strerror(errno));
litest_install_model_quirks(created_files); litest_install_model_quirks(created_files);
litest_init_all_device_udev_rules(created_files); litest_init_all_device_udev_rules(created_files);

View file

@ -4232,6 +4232,152 @@ START_TEST(touchpad_dwt_acer_hawaii)
} }
END_TEST END_TEST
START_TEST(touchpad_dwt_multiple_keyboards)
{
struct litest_device *touchpad = litest_current_device();
struct litest_device *k1, *k2;
struct libinput *li = touchpad->libinput;
ck_assert(has_disable_while_typing(touchpad));
enable_dwt(touchpad);
k1 = litest_add_device(li, LITEST_KEYBOARD);
k2 = litest_add_device(li, LITEST_KEYBOARD);
litest_keyboard_key(k1, KEY_A, true);
litest_keyboard_key(k1, KEY_A, false);
litest_drain_events(li);
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
litest_touch_up(touchpad, 0);
litest_assert_empty_queue(li);
litest_timeout_dwt_short();
litest_keyboard_key(k2, KEY_A, true);
litest_keyboard_key(k2, KEY_A, false);
litest_drain_events(li);
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
litest_touch_up(touchpad, 0);
litest_assert_empty_queue(li);
litest_timeout_dwt_short();
litest_delete_device(k1);
litest_delete_device(k2);
}
END_TEST
START_TEST(touchpad_dwt_multiple_keyboards_bothkeys)
{
struct litest_device *touchpad = litest_current_device();
struct litest_device *k1, *k2;
struct libinput *li = touchpad->libinput;
ck_assert(has_disable_while_typing(touchpad));
enable_dwt(touchpad);
k1 = litest_add_device(li, LITEST_KEYBOARD);
k2 = litest_add_device(li, LITEST_KEYBOARD);
litest_keyboard_key(k1, KEY_A, true);
litest_keyboard_key(k1, KEY_A, false);
litest_keyboard_key(k2, KEY_B, true);
litest_keyboard_key(k2, KEY_B, false);
litest_drain_events(li);
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
litest_touch_up(touchpad, 0);
litest_assert_empty_queue(li);
litest_delete_device(k1);
litest_delete_device(k2);
}
END_TEST
START_TEST(touchpad_dwt_multiple_keyboards_bothkeys_modifier)
{
struct litest_device *touchpad = litest_current_device();
struct litest_device *k1, *k2;
struct libinput *li = touchpad->libinput;
ck_assert(has_disable_while_typing(touchpad));
enable_dwt(touchpad);
k1 = litest_add_device(li, LITEST_KEYBOARD);
k2 = litest_add_device(li, LITEST_KEYBOARD);
litest_keyboard_key(k1, KEY_RIGHTCTRL, true);
litest_keyboard_key(k1, KEY_RIGHTCTRL, false);
litest_keyboard_key(k2, KEY_B, true);
litest_keyboard_key(k2, KEY_B, false);
litest_drain_events(li);
/* If the keyboard is a single physical device, the above should
* trigger the modifier behavior for dwt. But libinput views it as
* two separate devices and this is such a niche case that it
* doesn't matter. So we test for the easy behavior:
* ctrl+B across two devices is *not* a dwt modifier combo
*/
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
litest_touch_up(touchpad, 0);
litest_assert_empty_queue(li);
litest_delete_device(k1);
litest_delete_device(k2);
}
END_TEST
START_TEST(touchpad_dwt_multiple_keyboards_remove)
{
struct litest_device *touchpad = litest_current_device();
struct litest_device *keyboards[2];
struct libinput *li = touchpad->libinput;
int which = _i; /* ranged test */
struct litest_device *removed, *remained;
ck_assert_int_le(which, 1);
ck_assert(has_disable_while_typing(touchpad));
enable_dwt(touchpad);
keyboards[0] = litest_add_device(li, LITEST_KEYBOARD);
keyboards[1] = litest_add_device(li, LITEST_KEYBOARD);
litest_keyboard_key(keyboards[0], KEY_A, true);
litest_keyboard_key(keyboards[0], KEY_A, false);
litest_keyboard_key(keyboards[1], KEY_B, true);
litest_keyboard_key(keyboards[1], KEY_B, false);
litest_drain_events(li);
litest_timeout_dwt_short();
removed = keyboards[which % 2];
remained = keyboards[(which + 1) % 2];
litest_delete_device(removed);
litest_keyboard_key(remained, KEY_C, true);
litest_keyboard_key(remained, KEY_C, false);
litest_drain_events(li);
litest_touch_down(touchpad, 0, 50, 50);
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
litest_touch_up(touchpad, 0);
litest_assert_empty_queue(li);
litest_delete_device(remained);
}
END_TEST
static int static int
has_thumb_detect(struct litest_device *dev) has_thumb_detect(struct litest_device *dev)
{ {
@ -5493,6 +5639,7 @@ void
litest_setup_tests_touchpad(void) litest_setup_tests_touchpad(void)
{ {
struct range axis_range = {ABS_X, ABS_Y + 1}; struct range axis_range = {ABS_X, ABS_Y + 1};
struct range twice = {0, 2 };
litest_add("touchpad:motion", touchpad_1fg_motion, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:motion", touchpad_1fg_motion, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:motion", touchpad_2fg_no_motion, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("touchpad:motion", touchpad_2fg_no_motion, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
@ -5620,6 +5767,10 @@ litest_setup_tests_touchpad(void)
litest_add("touchpad:dwt", touchpad_dwt_remove_kbd_while_active, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:dwt", touchpad_dwt_remove_kbd_while_active, LITEST_TOUCHPAD, LITEST_ANY);
litest_add_for_device("touchpad:dwt", touchpad_dwt_apple, LITEST_BCM5974); litest_add_for_device("touchpad:dwt", touchpad_dwt_apple, LITEST_BCM5974);
litest_add_for_device("touchpad:dwt", touchpad_dwt_acer_hawaii, LITEST_ACER_HAWAII_TOUCHPAD); litest_add_for_device("touchpad:dwt", touchpad_dwt_acer_hawaii, LITEST_ACER_HAWAII_TOUCHPAD);
litest_add_for_device("touchpad:dwt", touchpad_dwt_multiple_keyboards, LITEST_SYNAPTICS_I2C);
litest_add_for_device("touchpad:dwt", touchpad_dwt_multiple_keyboards_bothkeys, LITEST_SYNAPTICS_I2C);
litest_add_for_device("touchpad:dwt", touchpad_dwt_multiple_keyboards_bothkeys_modifier, LITEST_SYNAPTICS_I2C);
litest_add_ranged_for_device("touchpad:dwt", touchpad_dwt_multiple_keyboards_remove, LITEST_SYNAPTICS_I2C, &twice);
litest_add("touchpad:thumb", touchpad_thumb_begin_no_motion, LITEST_CLICKPAD, LITEST_ANY); litest_add("touchpad:thumb", touchpad_thumb_begin_no_motion, LITEST_CLICKPAD, LITEST_ANY);
litest_add("touchpad:thumb", touchpad_thumb_update_no_motion, LITEST_CLICKPAD, LITEST_ANY); litest_add("touchpad:thumb", touchpad_thumb_update_no_motion, LITEST_CLICKPAD, LITEST_ANY);

View file

@ -747,6 +747,9 @@ print_switch_event(struct libinput_event *ev)
case LIBINPUT_SWITCH_LID: case LIBINPUT_SWITCH_LID:
which = "lid"; which = "lid";
break; break;
case LIBINPUT_SWITCH_TABLET_MODE:
which = "tablet-mode";
break;
default: default:
abort(); abort();
} }

View file

@ -62,6 +62,9 @@ Enable or disable natural scrolling
.B \-\-enable\-left\-handed|\-\-disable\-left\-handed .B \-\-enable\-left\-handed|\-\-disable\-left\-handed
Enable or disable left handed button configuration Enable or disable left handed button configuration
.TP 8 .TP 8
.B \-\-enable\-middlebutton|\-\-disable\-middlebutton
Enable or disable middle button emulation
.TP 8
.B \-\-enable\-dwt|\-\-disable\-dwt .B \-\-enable\-dwt|\-\-disable\-dwt
Enable or disable disable-while-typing Enable or disable disable-while-typing
.TP 8 .TP 8

View file

@ -314,6 +314,12 @@ print_device_notify(struct libinput_event *ev)
if (libinput_device_has_capability(dev, if (libinput_device_has_capability(dev,
LIBINPUT_DEVICE_CAP_TABLET_PAD)) LIBINPUT_DEVICE_CAP_TABLET_PAD))
printf("tablet-pad"); printf("tablet-pad");
if (libinput_device_has_capability(dev,
LIBINPUT_DEVICE_CAP_GESTURE))
printf("gesture");
if (libinput_device_has_capability(dev,
LIBINPUT_DEVICE_CAP_SWITCH))
printf("switch");
printf("\n"); printf("\n");
printf("Tap-to-click: %s\n", tap_default(dev)); printf("Tap-to-click: %s\n", tap_default(dev));

View file

@ -26,9 +26,15 @@
import sys import sys
import argparse import argparse
import evdev try:
import evdev.ecodes import evdev
import pyudev import evdev.ecodes
import pyudev
except ModuleNotFoundError as e:
print('Error: {}'.format(str(e)), file=sys.stderr)
print('One or more python modules are missing. Please install those '
'modules and re-run this tool.')
sys.exit(1)
class Range(object): class Range(object):

View file

@ -9,7 +9,7 @@ libinput\-measure\-touch-size \- measure touch size and orientation of devices
The The
.B "libinput measure touch\-size" .B "libinput measure touch\-size"
tool measures the size and orientation of a touch as provided by the kernel. tool measures the size and orientation of a touch as provided by the kernel.
an interactive tool. When executed, the tool will prompt the user to This is an interactive tool. When executed, the tool will prompt the user to
interact with the touch device. On termination, the tool prints a summary of the interact with the touch device. On termination, the tool prints a summary of the
values seen. This data should be attached to any values seen. This data should be attached to any
touch\-size\-related bug report. touch\-size\-related bug report.

View file

@ -26,9 +26,15 @@
import sys import sys
import argparse import argparse
import evdev try:
import evdev.ecodes import evdev
import pyudev import evdev.ecodes
import pyudev
except ModuleNotFoundError as e:
print('Error: {}'.format(str(e)), file=sys.stderr)
print('One or more python modules are missing. Please install those '
'modules and re-run this tool.')
sys.exit(1)
class Range(object): class Range(object):

View file

@ -26,9 +26,15 @@
import sys import sys
import argparse import argparse
import evdev try:
import evdev.ecodes import evdev
import pyudev import evdev.ecodes
import pyudev
except ModuleNotFoundError as e:
print('Error: {}'.format(str(e)), file=sys.stderr)
print('One or more python modules are missing. Please install those '
'modules and re-run this tool.')
sys.exit(1)
MINIMUM_EVENT_COUNT = 1000 MINIMUM_EVENT_COUNT = 1000

View file

@ -510,11 +510,20 @@ tools_exec_command(const char *prefix, int real_argc, char **real_argv)
setup_path(); setup_path();
rc = execvp(executable, argv); rc = execvp(executable, argv);
if (rc) if (rc) {
fprintf(stderr, if (errno == ENOENT) {
"Failed to execute '%s' (%s)\n", fprintf(stderr,
command, "libinput: %s is not a libinput command or not installed. "
strerror(errno)); "See 'libinput --help'\n",
command);
} else {
fprintf(stderr,
"Failed to execute '%s' (%s)\n",
command,
strerror(errno));
}
}
return EXIT_FAILURE; return EXIT_FAILURE;
} }