mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-03-25 14:10:34 +01:00
Compare commits
14 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56bcb2999e | ||
|
|
4ec04fa960 | ||
|
|
e35c202df7 | ||
|
|
1593d7da32 | ||
|
|
73c9ed2cd9 | ||
|
|
ed17f8b637 | ||
|
|
15e40a42e7 | ||
|
|
5c989940b6 | ||
|
|
edd83fe99e | ||
|
|
e7be909838 | ||
|
|
03cd377e00 | ||
|
|
89660005a8 | ||
|
|
5b862de70d | ||
|
|
a83085e4f9 |
18 changed files with 378 additions and 95 deletions
|
|
@ -41,6 +41,12 @@ libinput_jobs:
|
|||
name: Build - No docs
|
||||
environment:
|
||||
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
|
||||
run:
|
||||
<<: *build_and_test_default
|
||||
|
|
@ -88,6 +94,7 @@ fedora_build_all: &fedora_build_all
|
|||
- *build_no_debug_gui
|
||||
- *build_no_tests
|
||||
- *build_no_docs
|
||||
- *build_dist
|
||||
|
||||
ubuntu_install: &ubuntu_install
|
||||
run:
|
||||
|
|
@ -112,6 +119,7 @@ ubuntu_build_all: &ubuntu_build_all
|
|||
- *build_no_debug_gui
|
||||
- *build_no_tests
|
||||
- *build_no_docs
|
||||
- *build_dist
|
||||
|
||||
scan_build_run: &scan_build_run
|
||||
<<: *default_settings
|
||||
|
|
|
|||
14
doc/faqs.dox
14
doc/faqs.dox
|
|
@ -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
|
||||
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?
|
||||
|
||||
Synclient and syndaemon rely on X input device properties that are specific
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ EXTRACT_STATIC = YES
|
|||
MAX_INITIALIZER_LINES = 0
|
||||
QUIET = YES
|
||||
INPUT = @INPUT@
|
||||
IMAGE_PATH = @top_srcdir@/doc/svg \
|
||||
@top_srcdir@/doc/dot
|
||||
IMAGE_PATH = "@top_srcdir@/doc/svg" \
|
||||
"@top_srcdir@/doc/dot"
|
||||
GENERATE_HTML = YES
|
||||
SEARCHENGINE = NO
|
||||
USE_MATHJAX = YES
|
||||
|
|
@ -20,11 +20,11 @@ MACRO_EXPANSION = YES
|
|||
EXPAND_ONLY_PREDEF = YES
|
||||
PREDEFINED = LIBINPUT_ATTRIBUTE_PRINTF(f, a)= \
|
||||
LIBINPUT_ATTRIBUTE_DEPRECATED
|
||||
DOTFILE_DIRS = @top_srcdir@/doc/dot
|
||||
DOTFILE_DIRS = "@top_srcdir@/doc/dot"
|
||||
|
||||
HTML_HEADER = @top_srcdir@/doc/style/header.html
|
||||
HTML_FOOTER = @top_srcdir@/doc/style/footer.html
|
||||
HTML_EXTRA_STYLESHEET = @top_srcdir@/doc/style/bootstrap.css \
|
||||
@top_srcdir@/doc/style/customdoxygen.css \
|
||||
@top_srcdir@/doc/style/libinputdoxygen.css
|
||||
USE_MDFILE_AS_MAINPAGE = @top_srcdir@/README.md
|
||||
HTML_HEADER = "@top_srcdir@/doc/style/header.html"
|
||||
HTML_FOOTER = "@top_srcdir@/doc/style/footer.html"
|
||||
HTML_EXTRA_STYLESHEET = "@top_srcdir@/doc/style/bootstrap.css" \
|
||||
"@top_srcdir@/doc/style/customdoxygen.css" \
|
||||
"@top_srcdir@/doc/style/libinputdoxygen.css"
|
||||
USE_MDFILE_AS_MAINPAGE = "@top_srcdir@/README.md"
|
||||
|
|
|
|||
|
|
@ -1,18 +1,21 @@
|
|||
/**
|
||||
@page test-suite libinput test suite
|
||||
|
||||
The libinput test suite is based on
|
||||
[Check](http://check.sourceforge.net/doc/check_html/) and runs automatically
|
||||
during `make check`. Check itself is wrapped into a libinput-specific test
|
||||
suite called *litest*. Tests are found in `$srcdir/test/`, the main test
|
||||
suite is `libinput-test-suite-runner`.
|
||||
libinput ships with a number of tests all run automatically on `ninja test`.
|
||||
The primary test suite is the `libinput-test-suite-runner`. When testing,
|
||||
the `libinput-test-suite-runner` should always be invoked to check for
|
||||
behavior changes.
|
||||
|
||||
The test suite 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 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.
|
||||
The test suite runner uses
|
||||
[Check](http://check.sourceforge.net/doc/check_html/) underneath the hood
|
||||
but most of the functionality is abstracted into *litest* wrappers.
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
|
|
@ -28,35 +31,67 @@ with your desktop.
|
|||
|
||||
Most tests require the creation of uinput devices and access to the
|
||||
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
|
||||
|
||||
litest's tests are grouped by test groups and devices. A test group is e.g.
|
||||
"touchpad:tap" and incorporates all tapping-related tests for touchpads.
|
||||
Each test function is (usually) run with one or more specific devices.
|
||||
The `--list` commandline argument shows the list of suites and tests.
|
||||
litest's tests are grouped into test groups, test names and devices. A test
|
||||
group is e.g. "touchpad:tap" and incorporates all tapping-related tests for
|
||||
touchpads. Each test function is (usually) run with one or more specific
|
||||
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
|
||||
$ ./test/libinput-test-suite-runner --list
|
||||
device:wheel:
|
||||
wheel only
|
||||
blackwidow
|
||||
device:invalid devices:
|
||||
no device
|
||||
device:group:
|
||||
no device
|
||||
logitech trackball
|
||||
MS surface cover
|
||||
mouse_roccat
|
||||
wheel only
|
||||
blackwidow
|
||||
...
|
||||
pointer:left-handed:
|
||||
pointer_left_handed_during_click_multiple_buttons:
|
||||
trackpoint
|
||||
ms-surface-cover
|
||||
mouse-wheelclickcount
|
||||
mouse-wheelclickangle
|
||||
low-dpi-mouse
|
||||
mouse-roccat
|
||||
mouse-wheel-tilt
|
||||
mouse
|
||||
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
|
||||
|
||||
In the above example, the "device:wheel" suite is run for the "wheel only" and
|
||||
the "blackwidow" device. Both devices are automatically instantiated through
|
||||
uinput by litest. The "no device" entry signals that litest does not
|
||||
instantiate a uinput device for a specific test (though the test itself may
|
||||
In the above example, the "pointer:left-handed" suite contains multiple
|
||||
tests, e.g. "pointer_left_handed_during_click" (this is also the function
|
||||
name of the test, making it easy to grep for). This particular test is run
|
||||
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).
|
||||
|
||||
The `--filter-test` argument enables selective running of tests through
|
||||
|
|
@ -93,7 +128,7 @@ environment variable, if set, also enables verbose mode.
|
|||
|
||||
@code
|
||||
$ ./test/libinput-test-suite-runner --verbose
|
||||
$ LITEST_VERBOSE=1 make check
|
||||
$ LITEST_VERBOSE=1 ninja test
|
||||
@endcode
|
||||
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
project('libinput', 'c', 'cpp',
|
||||
version : '1.9.1',
|
||||
version : '1.9.2',
|
||||
license : 'MIT/Expat',
|
||||
default_options : [ 'c_std=gnu99', 'warning_level=2' ],
|
||||
meson_version : '>= 0.40.0')
|
||||
|
|
|
|||
|
|
@ -1588,6 +1588,8 @@ tp_interface_process(struct evdev_dispatch *dispatch,
|
|||
static void
|
||||
tp_remove_sendevents(struct tp_dispatch *tp)
|
||||
{
|
||||
struct paired_keyboard *kbd;
|
||||
|
||||
libinput_timer_cancel(&tp->palm.trackpoint_timer);
|
||||
libinput_timer_cancel(&tp->dwt.keyboard_timer);
|
||||
|
||||
|
|
@ -1596,9 +1598,10 @@ tp_remove_sendevents(struct tp_dispatch *tp)
|
|||
libinput_device_remove_event_listener(
|
||||
&tp->palm.trackpoint_listener);
|
||||
|
||||
if (tp->dwt.keyboard)
|
||||
libinput_device_remove_event_listener(
|
||||
&tp->dwt.keyboard_listener);
|
||||
ARRAY_FOR_EACH(tp->dwt.paired_keyboard, kbd) {
|
||||
if (kbd->device)
|
||||
libinput_device_remove_event_listener(&kbd->listener);
|
||||
}
|
||||
|
||||
if (tp->lid_switch.lid_switch)
|
||||
libinput_device_remove_event_listener(
|
||||
|
|
@ -1964,9 +1967,8 @@ tp_dwt_pair_keyboard(struct evdev_device *touchpad,
|
|||
struct evdev_device *keyboard)
|
||||
{
|
||||
struct tp_dispatch *tp = (struct tp_dispatch*)touchpad->dispatch;
|
||||
|
||||
if (tp->dwt.keyboard)
|
||||
return;
|
||||
struct paired_keyboard *kbd;
|
||||
bool found = false;
|
||||
|
||||
if ((keyboard->tags & EVDEV_TAG_KEYBOARD) == 0)
|
||||
return;
|
||||
|
|
@ -1974,16 +1976,25 @@ tp_dwt_pair_keyboard(struct evdev_device *touchpad,
|
|||
if (!tp_want_dwt(touchpad, keyboard))
|
||||
return;
|
||||
|
||||
libinput_device_add_event_listener(&keyboard->base,
|
||||
&tp->dwt.keyboard_listener,
|
||||
tp_keyboard_event, tp);
|
||||
tp->dwt.keyboard = keyboard;
|
||||
tp->dwt.keyboard_active = false;
|
||||
ARRAY_FOR_EACH(tp->dwt.paired_keyboard, kbd) {
|
||||
if (kbd->device)
|
||||
continue;
|
||||
|
||||
evdev_log_debug(touchpad,
|
||||
"palm: dwt activated with %s<->%s\n",
|
||||
touchpad->devname,
|
||||
keyboard->devname);
|
||||
found = true;
|
||||
libinput_device_add_event_listener(&keyboard->base,
|
||||
&kbd->listener,
|
||||
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
|
||||
|
|
@ -2121,6 +2132,7 @@ tp_interface_device_removed(struct evdev_device *device,
|
|||
struct evdev_device *removed_device)
|
||||
{
|
||||
struct tp_dispatch *tp = (struct tp_dispatch*)device->dispatch;
|
||||
struct paired_keyboard *kbd;
|
||||
|
||||
if (removed_device == tp->buttons.trackpoint) {
|
||||
/* Clear any pending releases for the trackpoint */
|
||||
|
|
@ -2134,11 +2146,12 @@ tp_interface_device_removed(struct evdev_device *device,
|
|||
tp->buttons.trackpoint = NULL;
|
||||
}
|
||||
|
||||
if (removed_device == tp->dwt.keyboard) {
|
||||
libinput_device_remove_event_listener(
|
||||
&tp->dwt.keyboard_listener);
|
||||
tp->dwt.keyboard = NULL;
|
||||
tp->dwt.keyboard_active = false;
|
||||
ARRAY_FOR_EACH(tp->dwt.paired_keyboard, kbd) {
|
||||
if (kbd->device == removed_device) {
|
||||
libinput_device_remove_event_listener(&kbd->listener);
|
||||
kbd->device = NULL;
|
||||
tp->dwt.keyboard_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (removed_device == tp->lid_switch.lid_switch) {
|
||||
|
|
|
|||
|
|
@ -383,13 +383,20 @@ struct tp_dispatch {
|
|||
struct libinput_device_config_dwt config;
|
||||
bool dwt_enabled;
|
||||
|
||||
bool keyboard_active;
|
||||
struct libinput_event_listener keyboard_listener;
|
||||
struct libinput_timer keyboard_timer;
|
||||
struct evdev_device *keyboard;
|
||||
/* We have to allow for more than one device node to be the
|
||||
* internal dwt keyboard (Razer Blade). But they're the same
|
||||
* physical device, so we don't care about per-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 mod_mask[NLONGS(KEY_CNT)];
|
||||
|
||||
bool keyboard_active;
|
||||
struct libinput_timer keyboard_timer;
|
||||
uint64_t keyboard_last_press_time;
|
||||
} dwt;
|
||||
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ static const char udev_rule[] =
|
|||
"\n"
|
||||
"LABEL=\"mouse_end\"";
|
||||
|
||||
TEST_DEVICE("litest-magicmouse-device",
|
||||
TEST_DEVICE("magicmouse",
|
||||
.type = LITEST_MAGICMOUSE,
|
||||
.features = LITEST_RELATIVE | LITEST_BUTTON | LITEST_WHEEL,
|
||||
.interface = &interface,
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <check.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <libgen.h>
|
||||
#include <fcntl.h>
|
||||
#include <fnmatch.h>
|
||||
#include <getopt.h>
|
||||
|
|
@ -1071,20 +1072,35 @@ litest_install_model_quirks(struct list *created_files_list)
|
|||
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
|
||||
litest_init_udev_rules(struct list *created_files)
|
||||
{
|
||||
int rc;
|
||||
|
||||
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));
|
||||
mkdir_p(UDEV_RULES_D);
|
||||
mkdir_p(UDEV_HWDB_D);
|
||||
|
||||
litest_install_model_quirks(created_files);
|
||||
litest_init_all_device_udev_rules(created_files);
|
||||
|
|
|
|||
|
|
@ -4232,6 +4232,152 @@ START_TEST(touchpad_dwt_acer_hawaii)
|
|||
}
|
||||
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
|
||||
has_thumb_detect(struct litest_device *dev)
|
||||
{
|
||||
|
|
@ -5493,6 +5639,7 @@ void
|
|||
litest_setup_tests_touchpad(void)
|
||||
{
|
||||
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_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_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_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_update_no_motion, LITEST_CLICKPAD, LITEST_ANY);
|
||||
|
|
|
|||
|
|
@ -747,6 +747,9 @@ print_switch_event(struct libinput_event *ev)
|
|||
case LIBINPUT_SWITCH_LID:
|
||||
which = "lid";
|
||||
break;
|
||||
case LIBINPUT_SWITCH_TABLET_MODE:
|
||||
which = "tablet-mode";
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,9 @@ Enable or disable natural scrolling
|
|||
.B \-\-enable\-left\-handed|\-\-disable\-left\-handed
|
||||
Enable or disable left handed button configuration
|
||||
.TP 8
|
||||
.B \-\-enable\-middlebutton|\-\-disable\-middlebutton
|
||||
Enable or disable middle button emulation
|
||||
.TP 8
|
||||
.B \-\-enable\-dwt|\-\-disable\-dwt
|
||||
Enable or disable disable-while-typing
|
||||
.TP 8
|
||||
|
|
|
|||
|
|
@ -314,6 +314,12 @@ print_device_notify(struct libinput_event *ev)
|
|||
if (libinput_device_has_capability(dev,
|
||||
LIBINPUT_DEVICE_CAP_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("Tap-to-click: %s\n", tap_default(dev));
|
||||
|
|
|
|||
|
|
@ -26,9 +26,15 @@
|
|||
|
||||
import sys
|
||||
import argparse
|
||||
import evdev
|
||||
import evdev.ecodes
|
||||
import pyudev
|
||||
try:
|
||||
import evdev
|
||||
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):
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ libinput\-measure\-touch-size \- measure touch size and orientation of devices
|
|||
The
|
||||
.B "libinput measure touch\-size"
|
||||
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
|
||||
values seen. This data should be attached to any
|
||||
touch\-size\-related bug report.
|
||||
|
|
|
|||
|
|
@ -26,9 +26,15 @@
|
|||
|
||||
import sys
|
||||
import argparse
|
||||
import evdev
|
||||
import evdev.ecodes
|
||||
import pyudev
|
||||
try:
|
||||
import evdev
|
||||
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):
|
||||
|
|
|
|||
|
|
@ -26,9 +26,15 @@
|
|||
|
||||
import sys
|
||||
import argparse
|
||||
import evdev
|
||||
import evdev.ecodes
|
||||
import pyudev
|
||||
try:
|
||||
import evdev
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -510,11 +510,20 @@ tools_exec_command(const char *prefix, int real_argc, char **real_argv)
|
|||
setup_path();
|
||||
|
||||
rc = execvp(executable, argv);
|
||||
if (rc)
|
||||
fprintf(stderr,
|
||||
"Failed to execute '%s' (%s)\n",
|
||||
command,
|
||||
strerror(errno));
|
||||
if (rc) {
|
||||
if (errno == ENOENT) {
|
||||
fprintf(stderr,
|
||||
"libinput: %s is not a libinput command or not installed. "
|
||||
"See 'libinput --help'\n",
|
||||
command);
|
||||
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"Failed to execute '%s' (%s)\n",
|
||||
command,
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue