mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-03-25 23:30:42 +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
|
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
|
||||||
|
|
|
||||||
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
|
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
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -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')
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue