Compare commits

...

42 commits
main ... 1.10.5

Author SHA1 Message Date
Peter Hutterer
7c95300758 libinput 1.10.5
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-04-19 11:41:08 +10:00
Peter Hutterer
d16cbccee6 udev: add T450s trackpoint range
From https://bugs.freedesktop.org/show_bug.cgi?id=103947

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 93dfd0fa54)
2018-04-18 15:10:47 +10:00
Peter Hutterer
0ef5e3f167 udev: add trackpoint range for the T440s
Measured at 200 sensitivity because that's what systemd sets for us

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit cf445f99dc)
2018-04-18 15:10:41 +10:00
Peter Hutterer
a391e89041 evdev: point users to the trackpoint documentation for missing ranges
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit f2b1eed976)
2018-04-18 15:09:45 +10:00
Peter Hutterer
1ea91b212b udev: add trackpoint range for Lenovo X280
https://bugs.freedesktop.org/show_bug.cgi?id=105485

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 9d7f48b66a)
2018-04-18 15:09:41 +10:00
Sean Lanigan
6c7adee8b0 Add Dell XPS13 L322X touchpad quirks
Signed-off-by: Sean Lanigan <sean@lano.id.au>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 5aec854ac3)
2018-04-18 14:10:28 +10:00
Peter Hutterer
8b338f0b5f debounce: disable debouncing on the Logitech K400
This is an external keyboard+touchpad but not recognised as touchpad by the
kernel so it's in mouse emulation mode. Double-taps are sent with impossibly
close timestamps and filtered out by the debouncing code. Since this isn't a
real button that can wear out anyway, let's just disable debouncing on this
device.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 23614f7551)
2018-04-13 10:50:56 +10:00
Peter Hutterer
e4f0ee9677 libinput 1.10.4
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-04-09 14:06:15 +10:00
Peter Hutterer
201eaf3a8b touchpad: don't process state for a touch in TOUCH_NONE
If a touch is in TOUCH_NONE, there is nothing to see here, please move along.

In the case of bug 105696, we were accessing the speed.exceeded_count of a
touch that was released previously, erroneously detecting a speed-based thumb.
The sequence was:
- touch down in slot 0, speed.exceeded_count is reset to 0
- move touch until exceeded_count is greater than our threshold
- touch up in slot 0
- touch down in slot 1 [1]
- touch down in slot 2 (more than 25mm away)
- we counted the slot 0 speed.exceeded_count, labeling the slot 2 touch as
  speed-based thumb

[1] peculiar behavior only observed on this device, usually slots get re-used
at the first opportunity so having an inactive slot followed by higher slots
being used is unusual.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 928bad9104)
2018-04-09 13:57:14 +10:00
Peter Hutterer
9585fe86ee Fix a doxygen link for the get_default_matrix call
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 24963d4e45)
2018-04-09 13:57:05 +10:00
Peter Hutterer
bab4ca0274 touchpad: use the fuzz value (if any) for the hysteresis margin
We currently used 0.5mm on touchpads as hysteresis value. This causes pointer
movement delays, it is likely too high. Reduce it to a kernel-set fuzz value
(if any) and see how we go with that. On many touchpads, the fuzz is 8 which
would be closer to 0.2mm on e.g. a T440.

Note that the does some defuzzing anyway, but the response of that function is
nonlinear, e.g. for a fuzz of 8, the physical deltas map to:

phys 0..3  → delta 0
phys 4..7  → delta 1
phys 8..15 → delta 4, 5, 6, 7
phys 16..N → delta 16..N

In other words, we never see some logical deltas 2 and 3. While this shouldn't
matter given the average touchpad resolution, reducing the hysteresis margin
is likely to provide some better response. We never see values 8-15 either
which could be the cause of some pointer jumps we've been seeing.

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

Devices with a fuzz of 0 have the hysteresis margin reduced to 0.25mm (from
0.5mm).

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit ea7498ef97)
2018-04-09 11:38:08 +10:00
Peter Hutterer
579428cdf4 tools: touchpad-pressure: init the lo/hi values correctly
From https://bugs.freedesktop.org/show_bug.cgi?id=105535

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 4ff5f02d9c)
2018-04-09 11:23:57 +10:00
Peter Hutterer
f36bb869ee touchpad: don't enable top palm detection on touchpads <= 55mm high
Tiny enough as it is, let's not take usable space away.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit d786b55daa)
2018-04-09 11:23:38 +10:00
Peter Hutterer
75215aaf5e tools: fix man page for debug-events
click method is 'buttonareas', not just 'buttons'

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit a59ce1c0c4)
2018-04-09 11:23:24 +10:00
Nandor Han
71191a88c2 udev: validate input devices during cold-plug
During libinput initialization a list of existing input devices is
retrieved from udev. This can lead to a situation where libinput can
end up processing un-configured devices because of the race generated
by udev events and libinput startup.
Sequence example:
weston - start
udev - device 1 added
weston - get a list of input devices
weston - process device 1 -- undefined behavior
udev - device 1 added - finalized

The problem was found because of incorrect touchscreen association
when in a dual monitor system the secondary touchscreen was
incorrectly associated with output one since udev didn't finish the
device initialization and WL_OUTPUT was missing.

To avoid this situation we skip un-configured devices during libinput
initialization, relying on udev to send events when devices are
fully configured.

Note: due to the peculiarities of udev_device_get_is_initialized(), the
input device is still processed if the call fails. If there are no udev
rules defined for the device, it will never be reported as initialized,
but this is not a problem, because all input devices handled by libinput
must have some udev properties set, therefore they always have rules.

Signed-off-by: Nandor Han <nandor.han@ge.com>
[Pekka: change log to debug, unref device]
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 23d543b711)
2018-04-09 11:14:03 +10:00
Peter Hutterer
f2cfd8a693 touchpad: only keep low-pressure fingers alive for 2+-slot touchpads
Regression introduced by 3979b9e16a, bug 105258.
With that commit, we only ended real touches when we had less than nslots fake
fingers down. i.e. tripletap on a 2 slot touchpad would not end the
first/second touch even if the pressure goes below the threshold. e.g. Lenovo
x270 needs this, see https://bugs.freedesktop.org/attachment.cgi?id=137672, it
dips below the pressure threshold for the first slot and ends the second slot
in the same frame as the third finger is detected. Fun times.

Anyway, this breaks semi-mt touchpads, another fine category of devices,
because some of those can detect hovering fingers at low pressure, see bug
105535. Because semi-mt devices are generally garbage, we treat them as
single-touch devices instead. So whenever two fingers are down, we treat both
as above the pressure threshold, even when they're physicall hovering.

Fix this by making the x270 fix conditional on at least 2 slots.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 3f5ff113a8)
2018-04-03 16:08:02 +10:00
Peter Hutterer
decfb09027 libinput 1.10.3
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-03-14 15:18:06 +10:00
Peter Hutterer
204820e4de touchpad: make sure we compare only the last 3 events for wobble
We're left-shifting the bits but weren't comparing against the l_r_l mask
itself. So if we get a sequence of [1, 1, 0, 1] we didn't detect a wobble
because 0b1101 != 0b101 (what we're looking for).

Fix this by turning it into a right shift, that way the bits fall off
the mask automatic
                  al
                    ly
                      y
                      y
                      y
                      y
                     .  .
                   _._v.___

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 5883ac7d98)
2018-03-14 10:17:32 +10:00
Peter Hutterer
42e8813a63 touchpad: end hovering touches in maybe_end_touch
Otherwise a hovering touch stays around forever even after the finger has
discontinued. This doesn't matter on slots, but for fake fingers the finger
may suddenly end up being forced down/up as a result of the pressure changes
on the real fingers.

So when in maybe_end_touch, switch them back to NONE immediately - hovering
touches do not need to trigger a TOUCH_END event.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit d8db6b5927)
2018-03-12 12:03:28 +10:00
Peter Hutterer
eeb967b650 libinput 1.10.2
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-03-07 15:01:49 +10:00
Daniel van Vugt
b437b2f196 Introduce omnidirectional (elliptical) hysteresis
This changes the hysteresis region to an ellipse (usually a circle), where
previously it was a rectangle (usually square).

Using an ellipse means the algorithm is no longer more sensitive in some
directions than others. It is now omnidirectional, which solves a few
problems:
  * Moving a finger in small circles now creates circles, not squares.
  * Moving a finger in a curve no longer snaps the cursor to vertical
    or horizontal lines. The cursor now follows a similar curve to the
    finger.

https://bugs.freedesktop.org/page.cgi?id=splinter.html&bug=105306

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 6936a15558)
2018-03-07 10:42:27 +10:00
Peter Hutterer
1c15e162b8 touchpad: add a TOUCH_MAYBE_END state
This state is used by the pre-processing of the touch states to indicate that
the touch point has ended and is changed to TOUCH_END as soon as that
pre-processing is finished.

Sometimes we have to resurrect a touch point that has physically or logically
ended but needs to be kept around to keep the BTN_TOOL_* fake finger count
happy. Particularly on Synaptics touchpads, where a BTN_TOOL_TRIPLETAP can
cause a touch point to end (i.e. 1 touch down + TRIPLETAP) but that touch
restarts in the next sequence. We had a quirk for this in place already, but
if we end the touch and then re-instate it with tp_begin_touch(), we may lose
some information about thumb/palm/etc. states that touch already had. As a
result, the state machines can get confused and a touch that was previously
ignored as thumb suddenly isn't one anymore and triggers assertions.

The specific sequence in bug 10528 is:
* touch T1 down
* touch T2 down, detected as speed-based thumb, tap state machine ignores
  it
* frame F: TRIPLETAP down, touch T2 up
* frame F+1: touch T2 down in next frame, but without the thumb bit
* frame F+n: touch T2 ends, tap state machine gets confused because
  that touch should not trigger a release

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 6ccd8e934f)
2018-03-07 10:42:15 +10:00
Peter Hutterer
40750c26f8 touchpad: don't end below-threshold pressure touches if nfake_fingers > nslots
If we have more BTN_TOOL_*TAP fingers down than we have slots, ignore any
below-threshold pressure changes on the slots. When a touchpad only detects
two touches, guessing whether the third touch has sufficient pressure is
unreliable. Instead, always assume that all touches have sufficient pressure
when we exceed the slot number.

Exception: if all real fingers are below the pressure threshold, the fake
fingers are ignored too.

Related to https://bugs.freedesktop.org/show_bug.cgi?id=105258

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 3979b9e16a)
2018-03-07 10:39:54 +10:00
Peter Hutterer
dd85749e61 touchpad: add the pressure thresholds to the debugging output
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 85e5d80cd4)
2018-03-07 10:39:53 +10:00
Peter Hutterer
2496923585 test: don't run the 2fg pressure test on single-touch touchpads
Only the appletouch has pressure and thus executed that code path

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 21b83dfd0b)
2018-03-07 10:39:52 +10:00
Peter Hutterer
0fec9c65e9 test: don't run the MT pressure test on devices without MT pressure
This test worked because on devices that don't use pressure the touches were
reset when BTN_TOUCH when to 0, triggering the 'ignore fake fingers when no
real fingers are down' behavior. But this is a different code path than the
pressure handling, so let's separate those tests.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 990da54aa6)
2018-03-07 10:39:51 +10:00
Mario Di Raimondo
c4fc98731d Fix Apple Magic Trackpad sensitivity
https://bugs.freedesktop.org/show_bug.cgi?id=103572

Signed-off-by: Mario Di Raimondo <mario.diraimondo@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit f47eb2d796)
2018-03-07 10:39:48 +10:00
Konstantin Kharlamov
3efd7c82aa touchpad: add wobbling detection
The details are explained in comment in the code. That aside, I shall
mention the check is so light, that it shouldn't influence CPU
performance even a bit, and can blindly be kept always enabled.

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

Signed-off-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
(cherry picked from commit 400aadd53a)
2018-03-02 14:04:08 +10:00
Konstantin Kharlamov
5f4d975861 touchpad: remove the code for disabling hysteresis
Signed-off-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
(cherry picked from commit e8dffbd73a)
2018-03-02 14:04:07 +10:00
Peter Hutterer
298b28d7f1 touchpad: move the hysteresis into its own substruct
Prep work for the wobbling detection patch

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
(cherry picked from commit e43bd4ae3a)
2018-03-02 14:04:06 +10:00
Peter Hutterer
68949fc5c5 touchpad: don't do speed-based thumb detection on single-touch or semi-mts
Because life is too short for this

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 39b806089c)
2018-03-02 14:03:57 +10:00
Peter Hutterer
25d1fbbf00 meson: add the 221 version to the libsystemd dependency
The sd-bus interface we're using wasn't public until 221.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 8353eeb5a8)
2018-03-02 14:03:40 +10:00
Peter Hutterer
5c86ba7580 libinput 1.10.1
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-02-28 10:03:22 +10:00
Peter Hutterer
c5c6cc13be tools: fix inverse up/down threshold handling in measure touch-size
https://bugs.freedesktop.org/show_bug.cgi?id=105264

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 5b29be3998)
2018-02-28 08:48:08 +10:00
Peter Hutterer
70258657b0 tools: fix option parsing in libinput measure
Missing '+' in the optstring caused it to evaluate all options. If any
argument was passed to a subcommand, libinput-measure would throw an error and
exit.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 59550ed21c)
2018-02-28 08:48:03 +10:00
Peter Hutterer
596a03a0fa touchpad: only begin fake touches when we have at least one finger down
If a single-touch touchpad drops below the pressure threshold in the same
frame where a fake finger is added, we begin a fake touch here. The subsequent
loop ends this fake touch because real_fingers_down is 0.

This causes the tapping code to have a mismatch of how many fingers are down
because it never sees the touch begin event for that finger.

https://bugs.freedesktop.org/show_bug.cgi?id=105160
(cherry picked from commit 01a633b6eb)
2018-02-28 08:47:44 +10:00
Maxin B. John
71fe2b6ef4 libinput-measure-touchpad-tap: use /usr/bin/env to invoke python3
Tweak this python scripts to use '/usr/bin/env python3'

Signed-off-by: Maxin B. John <maxin.john@intel.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 920debffd7)
2018-02-28 08:47:35 +10:00
Peter Hutterer
fc78cdc4bb udev: fix segfault when resuming before assigning a seat
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 63880d6e1b)
2018-02-28 08:47:32 +10:00
Quentin Glidic
0fcbb58d97 meson: Fix absolute libdir case in install script
If libdir is an absolute path (which means it’s outside of prefix) we
would wrongly add the prefix to it in the install script. Just pass the
correct libdir from Meson directly thanks to join_paths() magic.

Signed-off-by: Quentin Glidic <sardemff7+git@sardemff7.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit b2b5cdaf61)
2018-02-28 08:47:29 +10:00
Quentin Glidic
c726f37ebd meson: Fix bindir usage in install script
Since the install script cannot know the correct bindir, just pass it
from Meson directly.

Signed-off-by: Quentin Glidic <sardemff7+git@sardemff7.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 0843fa8e5e)
2018-02-28 08:47:27 +10:00
Peter Hutterer
3d4712d10a evdev: add a quirk to disable debouncing on the MS Nano Transcievers
A set of wireless devices that can scramble the timestamps, so we get
press/release within 8ms even though I doubt the user is capable of doing
this. Since they're generally good quality anyway, let's just disable
debouncing on those until someone complains and we need something more
sophisticated.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 3a3fd645c4)
2018-02-28 08:47:07 +10:00
Peter Hutterer
076c7b6c00 evdev: fail before open_restricted if the devnode doesn't exist
https://bugzilla.redhat.com/show_bug.cgi?id=1536633
https://bugzilla.redhat.com/show_bug.cgi?id=1539046
https://bugzilla.redhat.com/show_bug.cgi?id=1539783
https://bugzilla.redhat.com/show_bug.cgi?id=1540662
https://bugs.freedesktop.org/show_bug.cgi?id=104278

Debugged-by: Jeff Smith <whydoubt@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit cb186abc17)
2018-02-28 08:46:53 +10:00
28 changed files with 777 additions and 861 deletions

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 78 KiB

View file

@ -1,5 +1,5 @@
project('libinput', 'c', 'cpp',
version : '1.10.0',
version : '1.10.5',
license : 'MIT/Expat',
default_options : [ 'c_std=gnu99', 'warning_level=2' ],
meson_version : '>= 0.40.0')
@ -234,7 +234,7 @@ pkgconfig.generate(
# Restore the SELinux context for the libinput.so.a.b.c on install
# meson bug https://github.com/mesonbuild/meson/issues/1967
meson.add_install_script('src/libinput-restore-selinux-context.sh',
get_option('libdir'),
join_paths(get_option('prefix'), get_option('libdir')),
lib_libinput.full_path())
############ documentation ############
@ -496,7 +496,8 @@ configure_file(input : 'tools/libinput.man',
install_dir : join_paths(get_option('mandir'), 'man1')
)
meson.add_install_script('tools/install-compat-scripts.sh')
meson.add_install_script('tools/install-compat-scripts.sh',
join_paths(get_option('prefix'), get_option('bindir')))
ptraccel_debug_sources = [ 'tools/ptraccel-debug.c' ]
executable('ptraccel-debug',
@ -522,7 +523,7 @@ if get_option('tests')
config_h.set10('HAVE_LIBUNWIND', dep_libunwind.found())
# for inhibit support during test run
dep_libsystemd = dependency('libsystemd', required : false)
dep_libsystemd = dependency('libsystemd', version : '>= 221', required : false)
config_h.set10('HAVE_LIBSYSTEMD', dep_libsystemd.found())
lib_litest_sources = [
@ -563,6 +564,7 @@ if get_option('tests')
'test/litest-device-mouse-low-dpi.c',
'test/litest-device-mouse-wheel-click-angle.c',
'test/litest-device-mouse-wheel-click-count.c',
'test/litest-device-ms-nano-transceiver-mouse.c',
'test/litest-device-ms-surface-cover.c',
'test/litest-device-protocol-a-touch-screen.c',
'test/litest-device-qemu-usb-tablet.c',

View file

@ -83,6 +83,7 @@ debounce_state_to_str(enum debounce_state state)
CASE_RETURN_STRING(DEBOUNCE_STATE_MAYBE_SPURIOUS);
CASE_RETURN_STRING(DEBOUNCE_STATE_RELEASED);
CASE_RETURN_STRING(DEBOUNCE_STATE_PRESS_PENDING);
CASE_RETURN_STRING(DEBOUNCE_STATE_DISABLED);
}
return NULL;
@ -394,6 +395,31 @@ debounce_press_pending_event(struct fallback_dispatch *fallback, enum debounce_e
}
}
static void
debounce_disabled_event(struct fallback_dispatch *fallback,
enum debounce_event event,
uint64_t time)
{
switch (event) {
case DEBOUNCE_EVENT_PRESS:
fallback->debounce.button_time = time;
debounce_notify_button(fallback,
LIBINPUT_BUTTON_STATE_PRESSED);
break;
case DEBOUNCE_EVENT_RELEASE:
fallback->debounce.button_time = time;
debounce_notify_button(fallback,
LIBINPUT_BUTTON_STATE_RELEASED);
break;
case DEBOUNCE_EVENT_TIMEOUT_SHORT:
case DEBOUNCE_EVENT_TIMEOUT:
log_debounce_bug(fallback, event);
break;
case DEBOUNCE_EVENT_OTHERBUTTON:
break;
}
}
static void
debounce_handle_event(struct fallback_dispatch *fallback,
enum debounce_event event,
@ -434,6 +460,9 @@ debounce_handle_event(struct fallback_dispatch *fallback,
case DEBOUNCE_STATE_PRESS_PENDING:
debounce_press_pending_event(fallback, event, time);
break;
case DEBOUNCE_STATE_DISABLED:
debounce_disabled_event(fallback, event, time);
break;
}
evdev_log_debug(fallback->device,
@ -484,7 +513,8 @@ fallback_debounce_handle_state(struct fallback_dispatch *dispatch,
for (size_t i = 0; i < nchanged; i++) {
bool is_down = hw_is_key_down(dispatch, changed[i]);
if (flushed) {
if (flushed &&
dispatch->debounce.state != DEBOUNCE_STATE_DISABLED) {
debounce_set_state(dispatch,
!is_down ?
DEBOUNCE_STATE_IS_DOWN :
@ -538,6 +568,13 @@ fallback_init_debounce(struct fallback_dispatch *dispatch)
struct evdev_device *device = dispatch->device;
char timer_name[64];
if (device->model_flags &
(EVDEV_MODEL_MS_NANO_TRANSCEIVER|EVDEV_MODEL_LOGITECH_K400)) {
dispatch->debounce.state = DEBOUNCE_STATE_DISABLED;
return;
}
dispatch->debounce.state = DEBOUNCE_STATE_IS_UP;
snprintf(timer_name,

View file

@ -127,12 +127,9 @@ fallback_filter_defuzz_touch(struct fallback_dispatch *dispatch,
if (!dispatch->mt.want_hysteresis)
return false;
point.x = evdev_hysteresis(slot->point.x,
slot->hysteresis_center.x,
dispatch->mt.hysteresis_margin.x);
point.y = evdev_hysteresis(slot->point.y,
slot->hysteresis_center.y,
dispatch->mt.hysteresis_margin.y);
point = evdev_hysteresis(&slot->point,
&slot->hysteresis_center,
&dispatch->mt.hysteresis_margin);
slot->hysteresis_center = slot->point;
if (point.x == slot->point.x && point.y == slot->point.y)

View file

@ -41,6 +41,8 @@ enum debounce_state {
DEBOUNCE_STATE_MAYBE_SPURIOUS,
DEBOUNCE_STATE_RELEASED,
DEBOUNCE_STATE_PRESS_PENDING,
DEBOUNCE_STATE_DISABLED = 999,
};
struct fallback_dispatch {

View file

@ -362,6 +362,13 @@ tp_edge_scroll_handle_state(struct tp_dispatch *tp, uint64_t time)
case TOUCH_UPDATE:
tp_edge_scroll_handle_event(tp, t, SCROLL_EVENT_MOTION);
break;
case TOUCH_MAYBE_END:
/* This shouldn't happen we transfer to TOUCH_END
* before processing state */
evdev_log_debug(tp->device,
"touch unexpected state %d\n",
t->state);
/* fallthrough */
case TOUCH_END:
tp_edge_scroll_handle_event(tp, t, SCROLL_EVENT_RELEASE);
break;

View file

@ -1025,6 +1025,7 @@ tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time)
} else if (t->state == TOUCH_END) {
if (t->was_down) {
assert(tp->tap.nfingers_down >= 1);
tp->tap.nfingers_down--;
tp_tap_handle_event(tp, t, TAP_EVENT_RELEASE, time);
}

View file

@ -92,6 +92,10 @@ tp_calculate_motion_speed(struct tp_dispatch *tp, struct tp_touch *t)
double distance;
double speed;
/* Don't do this on single-touch or semi-mt devices */
if (!tp->has_mt || tp->semi_mt)
return;
/* This doesn't kick in until we have at least 4 events in the
* motion history. As a side-effect, this automatically handles the
* 2fg scroll where a finger is down and moving fast before the
@ -131,46 +135,75 @@ tp_motion_history_push(struct tp_touch *t)
t->history.index = motion_index;
}
/* Idea: if we got a tuple of *very* quick moves like {Left, Right,
* Left}, or {Right, Left, Right}, it means touchpad jitters since no
* human can move like that within thresholds.
*
* We encode left moves as zeroes, and right as ones. We also drop
* the array to all zeroes when contraints are not satisfied. Then we
* search for the pattern {1,0,1}. It can't match {Left, Right, Left},
* but it does match {Left, Right, Left, Right}, so it's okay.
*
* This only looks at x changes, y changes are ignored.
*/
static inline void
tp_maybe_disable_hysteresis(struct tp_dispatch *tp, uint64_t time)
tp_detect_wobbling(struct tp_dispatch *tp,
struct tp_touch *t,
uint64_t time)
{
/* If the finger is down for 80ms without seeing motion events,
the firmware filters and we don't need a software hysteresis */
if (tp->nfingers_down >= 1 &&
time - tp->hysteresis.last_motion_time > ms2us(80)) {
tp->hysteresis.enabled = false;
evdev_log_debug(tp->device, "hysteresis disabled\n");
int dx, dy;
uint64_t dtime;
if (!(tp->queued & TOUCHPAD_EVENT_MOTION) || tp->hysteresis.enabled)
return;
if (t->last_point.x == 0) { /* first invocation */
dx = 0;
dy = 0;
} else {
dx = t->last_point.x - t->point.x;
dy = t->last_point.y - t->point.y;
}
dtime = time - tp->hysteresis.last_motion_time;
tp->hysteresis.last_motion_time = time;
t->last_point = t->point;
if (dx == 0 && dy != 0) /* ignore y-only changes */
return;
if (dtime > ms2us(40)) {
t->hysteresis.x_motion_history = 0;
return;
}
if (tp->queued & TOUCHPAD_EVENT_MOTION)
tp->hysteresis.last_motion_time = time;
t->hysteresis.x_motion_history >>= 1;
if (dx > 0) { /* right move */
static const char r_l_r = 0x5; /* {Right, Left, Right} */
t->hysteresis.x_motion_history |= (1 << 2);
if (t->hysteresis.x_motion_history == r_l_r) {
tp->hysteresis.enabled = true;
evdev_log_debug(tp->device, "hysteresis enabled\n");
}
}
}
static inline void
tp_motion_hysteresis(struct tp_dispatch *tp,
struct tp_touch *t)
{
int x = t->point.x,
y = t->point.y;
if (!tp->hysteresis.enabled)
return;
if (t->history.count == 0) {
t->hysteresis_center = t->point;
} else {
x = evdev_hysteresis(x,
t->hysteresis_center.x,
tp->hysteresis.margin.x);
y = evdev_hysteresis(y,
t->hysteresis_center.y,
tp->hysteresis.margin.y);
t->hysteresis_center.x = x;
t->hysteresis_center.y = y;
t->point.x = x;
t->point.y = y;
}
if (t->history.count > 0)
t->point = evdev_hysteresis(&t->point,
&t->hysteresis.center,
&tp->hysteresis.margin);
t->hysteresis.center = t->point;
}
static inline void
@ -276,6 +309,7 @@ tp_new_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
t->time = time;
t->speed.last_speed = 0;
t->speed.exceeded_count = 0;
t->hysteresis.x_motion_history = 0;
tp->queued |= TOUCHPAD_EVENT_MOTION;
}
@ -296,23 +330,69 @@ tp_begin_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
tp->hysteresis.last_motion_time = time;
}
/**
* Schedule a touch to be ended, based on either the events or some
* attributes of the touch (size, pressure). In some cases we need to
* resurrect a touch that has ended, so this doesn't actually end the touch
* yet. All the TOUCH_MAYBE_END touches get properly ended once the device
* state has been processed once and we know how many zombie touches we
* need.
*/
static inline void
tp_maybe_end_touch(struct tp_dispatch *tp,
struct tp_touch *t,
uint64_t time)
{
switch (t->state) {
case TOUCH_NONE:
case TOUCH_MAYBE_END:
return;
case TOUCH_END:
evdev_log_bug_libinput(tp->device,
"touch already in TOUCH_END\n");
return;
case TOUCH_HOVERING:
case TOUCH_BEGIN:
case TOUCH_UPDATE:
break;
}
if (t->state != TOUCH_HOVERING) {
assert(tp->nfingers_down >= 1);
tp->nfingers_down--;
t->state = TOUCH_MAYBE_END;
} else {
t->state = TOUCH_NONE;
}
t->dirty = true;
}
/**
* Inverse to tp_maybe_end_touch(), restores a touch back to its previous
* state.
*/
static inline void
tp_recover_ended_touch(struct tp_dispatch *tp,
struct tp_touch *t)
{
t->dirty = true;
t->state = TOUCH_UPDATE;
tp->nfingers_down++;
}
/**
* End a touch, even if the touch sequence is still active.
* Use tp_maybe_end_touch() instead.
*/
static inline void
tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
{
switch (t->state) {
case TOUCH_HOVERING:
t->state = TOUCH_NONE;
/* fallthough */
case TOUCH_NONE:
case TOUCH_END:
if (t->state != TOUCH_MAYBE_END) {
evdev_log_bug_libinput(tp->device,
"touch should be MAYBE_END, is %d\n",
t->state);
return;
case TOUCH_BEGIN:
case TOUCH_UPDATE:
break;
}
t->dirty = true;
@ -321,8 +401,6 @@ tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
t->pinned.is_pinned = false;
t->time = time;
t->palm.time = 0;
assert(tp->nfingers_down >= 1);
tp->nfingers_down--;
tp->queued |= TOUCHPAD_EVENT_MOTION;
}
@ -333,7 +411,7 @@ static inline void
tp_end_sequence(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
{
t->has_ended = true;
tp_end_touch(tp, t, time);
tp_maybe_end_touch(tp, t, time);
}
static void
@ -480,13 +558,11 @@ tp_restore_synaptics_touches(struct tp_dispatch *tp,
for (i = 0; i < tp->num_slots; i++) {
struct tp_touch *t = tp_get_touch(tp, i);
if (t->state != TOUCH_END)
if (t->state != TOUCH_MAYBE_END)
continue;
/* new touch, move it through begin to update immediately */
tp_new_touch(tp, t, time);
tp_begin_touch(tp, t, time);
t->state = TOUCH_UPDATE;
tp_recover_ended_touch(tp, t);
}
}
@ -1070,11 +1146,17 @@ tp_unhover_pressure(struct tp_dispatch *tp, uint64_t time)
tp_motion_history_reset(t);
tp_begin_touch(tp, t, time);
}
} else {
/* don't unhover for pressure if we have too many
* fake fingers down, see comment below. Except
* for single-finger touches where the real touch
* decides for the rest.
*/
} else if (nfake_touches <= tp->num_slots ||
tp->num_slots == 1) {
if (t->pressure < tp->pressure.low) {
evdev_log_debug(tp->device,
"pressure: end touch\n");
tp_end_touch(tp, t, time);
tp_maybe_end_touch(tp, t, time);
}
}
}
@ -1092,14 +1174,16 @@ tp_unhover_pressure(struct tp_dispatch *tp, uint64_t time)
* _all_ fingers have enough pressure, even if some of the slotted
* ones don't. Anything else gets insane quickly.
*/
tp_for_each_touch(tp, t) {
if (t->state == TOUCH_HOVERING) {
/* avoid jumps when landing a finger */
tp_motion_history_reset(t);
tp_begin_touch(tp, t, time);
if (real_fingers_down > 0) {
tp_for_each_touch(tp, t) {
if (t->state == TOUCH_HOVERING) {
/* avoid jumps when landing a finger */
tp_motion_history_reset(t);
tp_begin_touch(tp, t, time);
if (tp->nfingers_down >= nfake_touches)
break;
if (tp->nfingers_down >= nfake_touches)
break;
}
}
}
@ -1109,10 +1193,11 @@ tp_unhover_pressure(struct tp_dispatch *tp, uint64_t time)
t = tp_get_touch(tp, i);
if (t->state == TOUCH_HOVERING ||
t->state == TOUCH_NONE)
t->state == TOUCH_NONE ||
t->state == TOUCH_MAYBE_END)
continue;
tp_end_touch(tp, t, time);
tp_maybe_end_touch(tp, t, time);
if (real_fingers_down > 0 &&
tp->nfingers_down == nfake_touches)
@ -1154,7 +1239,7 @@ tp_unhover_size(struct tp_dispatch *tp, uint64_t time)
if (t->major < low || t->minor < low) {
evdev_log_debug(tp->device,
"touch-size: end touch\n");
tp_end_touch(tp, t, time);
tp_maybe_end_touch(tp, t, time);
}
}
}
@ -1208,7 +1293,7 @@ tp_unhover_fake_touches(struct tp_dispatch *tp, uint64_t time)
t->state == TOUCH_NONE)
continue;
tp_end_touch(tp, t, time);
tp_maybe_end_touch(tp, t, time);
if (tp_fake_finger_is_touching(tp) &&
tp->nfingers_down == nfake_touches)
@ -1375,6 +1460,21 @@ tp_detect_thumb_while_moving(struct tp_dispatch *tp)
second->thumb.state = THUMB_STATE_YES;
}
static void
tp_pre_process_state(struct tp_dispatch *tp, uint64_t time)
{
struct tp_touch *t;
tp_process_fake_touches(tp, time);
tp_unhover_touches(tp, time);
tp_for_each_touch(tp, t) {
if (t->state == TOUCH_MAYBE_END)
tp_end_touch(tp, t, time);
}
}
static void
tp_process_state(struct tp_dispatch *tp, uint64_t time)
{
@ -1384,13 +1484,14 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
bool have_new_touch = false;
unsigned int speed_exceeded_count = 0;
tp_process_fake_touches(tp, time);
tp_unhover_touches(tp, time);
tp_position_fake_touches(tp);
want_motion_reset = tp_need_motion_history_reset(tp);
tp_for_each_touch(tp, t) {
if (t->state == TOUCH_NONE)
continue;
if (want_motion_reset) {
tp_motion_history_reset(t);
t->quirks.reset_motion_history = true;
@ -1420,7 +1521,7 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
tp_thumb_detect(tp, t, time);
tp_palm_detect(tp, t, time);
tp_detect_wobbling(tp, t, time);
tp_motion_hysteresis(tp, t);
tp_motion_history_push(t);
@ -1544,9 +1645,7 @@ static void
tp_handle_state(struct tp_dispatch *tp,
uint64_t time)
{
if (tp->hysteresis.enabled)
tp_maybe_disable_hysteresis(tp, time);
tp_pre_process_state(tp, time);
tp_process_state(tp, time);
tp_post_events(tp, time);
tp_post_process_state(tp, time);
@ -2690,7 +2789,7 @@ tp_init_palmdetect_edge(struct tp_dispatch *tp,
edges = evdev_device_mm_to_units(device, &mm);
tp->palm.right_edge = edges.x;
if (!tp->buttons.has_topbuttons) {
if (!tp->buttons.has_topbuttons && height > 55) {
/* top edge is 5% of the height */
mm.y = height * 0.05;
edges = evdev_device_mm_to_units(device, &mm);
@ -2930,13 +3029,23 @@ tp_init_default_resolution(struct tp_dispatch *tp,
static inline void
tp_init_hysteresis(struct tp_dispatch *tp)
{
int res_x, res_y;
int xmargin, ymargin;
const struct input_absinfo *ax = tp->device->abs.absinfo_x,
*ay = tp->device->abs.absinfo_y;
res_x = tp->device->abs.absinfo_x->resolution;
res_y = tp->device->abs.absinfo_y->resolution;
tp->hysteresis.margin.x = res_x/2;
tp->hysteresis.margin.y = res_y/2;
tp->hysteresis.enabled = true;
if (ax->fuzz)
xmargin = ax->fuzz;
else
xmargin = ax->resolution/4;
if (ay->fuzz)
ymargin = ay->fuzz;
else
ymargin = ay->resolution/4;
tp->hysteresis.margin.x = xmargin;
tp->hysteresis.margin.y = ymargin;
tp->hysteresis.enabled = false;
}
static void
@ -2995,7 +3104,9 @@ tp_init_pressure(struct tp_dispatch *tp,
tp->pressure.low = lo;
evdev_log_debug(device,
"using pressure-based touch detection\n");
"using pressure-based touch detection (%d:%d)\n",
lo,
hi);
}
static bool

View file

@ -46,10 +46,11 @@ enum touchpad_event {
enum touch_state {
TOUCH_NONE = 0,
TOUCH_HOVERING,
TOUCH_BEGIN,
TOUCH_UPDATE,
TOUCH_END
TOUCH_HOVERING = 1,
TOUCH_BEGIN = 2,
TOUCH_UPDATE = 3,
TOUCH_MAYBE_END = 4,
TOUCH_END = 5,
};
enum touch_palm_state {
@ -147,6 +148,7 @@ struct tp_touch {
bool has_ended; /* TRACKING_ID == -1 */
bool dirty;
struct device_coords point;
struct device_coords last_point;
uint64_t time;
int pressure;
bool is_tool_palm; /* MT_TOOL_PALM */
@ -173,7 +175,10 @@ struct tp_touch {
unsigned int count;
} history;
struct device_coords hysteresis_center;
struct {
struct device_coords center;
uint8_t x_motion_history;
} hysteresis;
/* A pinned touchpoint is the one that pressed the physical button
* on a clickpad. After the release, it won't move until the center

View file

@ -1180,6 +1180,12 @@ evdev_get_trackpoint_range(struct evdev_device *device)
goto out;
}
evdev_log_info(device,
"trackpoint does not have a specified range, "
"guessing... see %strackpoints.html\n",
HTTP_DOC_LINK);
prop = udev_device_get_property_value(device->udev_device,
"POINTINGSTICK_SENSITIVITY");
if (prop) {
@ -1251,6 +1257,7 @@ evdev_read_model_flags(struct evdev_device *device)
MODEL(ALPS_TOUCHPAD),
MODEL(SYNAPTICS_SERIAL_TOUCHPAD),
MODEL(JUMPING_SEMI_MT),
MODEL(LOGITECH_K400),
MODEL(CYBORG_RAT),
MODEL(HP_STREAM11_TOUCHPAD),
MODEL(LENOVO_T450_TOUCHPAD),
@ -1264,6 +1271,7 @@ evdev_read_model_flags(struct evdev_device *device)
MODEL(APPLE_TOUCHPAD_ONEBUTTON),
MODEL(LOGITECH_MARBLE_MOUSE),
MODEL(TABLET_NO_PROXIMITY_OUT),
MODEL(MS_NANO_TRANSCEIVER),
#undef MODEL
{ "ID_INPUT_TRACKBALL", EVDEV_MODEL_TRACKBALL },
{ NULL, EVDEV_MODEL_DEFAULT },
@ -1917,6 +1925,11 @@ evdev_device_create(struct libinput_seat *seat,
const char *devnode = udev_device_get_devnode(udev_device);
const char *sysname = udev_device_get_sysname(udev_device);
if (!devnode) {
log_info(libinput, "%s: no device node associated\n", sysname);
return NULL;
}
if (udev_device_should_be_ignored(udev_device)) {
log_debug(libinput, "%s: device is ignored\n", sysname);
return NULL;
@ -2434,6 +2447,9 @@ evdev_device_resume(struct evdev_device *device)
return -ENODEV;
devnode = udev_device_get_devnode(device->udev_device);
if (!devnode)
return -ENODEV;
fd = open_restricted(libinput, devnode,
O_RDWR | O_NONBLOCK | O_CLOEXEC);

View file

@ -110,6 +110,7 @@ enum evdev_device_model {
EVDEV_MODEL_ALPS_TOUCHPAD = (1 << 8),
EVDEV_MODEL_SYNAPTICS_SERIAL_TOUCHPAD = (1 << 9),
EVDEV_MODEL_JUMPING_SEMI_MT = (1 << 10),
EVDEV_MODEL_LOGITECH_K400 = (1 << 11),
EVDEV_MODEL_LENOVO_X220_TOUCHPAD_FW81 = (1 << 12),
EVDEV_MODEL_CYBORG_RAT = (1 << 14),
EVDEV_MODEL_HP_STREAM11_TOUCHPAD = (1 << 16),
@ -124,6 +125,7 @@ enum evdev_device_model {
EVDEV_MODEL_APPLE_TOUCHPAD_ONEBUTTON = (1 << 25),
EVDEV_MODEL_LOGITECH_MARBLE_MOUSE = (1 << 26),
EVDEV_MODEL_TABLET_NO_PROXIMITY_OUT = (1 << 27),
EVDEV_MODEL_MS_NANO_TRANSCEIVER = (1 << 28),
};
enum evdev_button_scroll_state {
@ -599,11 +601,11 @@ evdev_to_left_handed(struct evdev_device *device,
* Apply a hysteresis filtering to the coordinate in, based on the current
* hysteresis center and the margin. If 'in' is within 'margin' of center,
* return the center (and thus filter the motion). If 'in' is outside,
* return a point on the edge of the new margin. So for a point x in the
* space outside c + margin we return r:
* +---+ +---+
* return a point on the edge of the new margin (which is an ellipse, usually
* a circle). So for a point x in the space outside c + margin we return r:
* ,---. ,---.
* | c | x | r x
* +---+ +---+
* `---' `---'
*
* The effect of this is that initial small motions are filtered. Once we
* move into one direction we lag the real coordinates by 'margin' but any
@ -616,41 +618,71 @@ evdev_to_left_handed(struct evdev_device *device,
* Otherwise, the center has a dead zone of size margin around it and the
* first reachable point is the margin edge.
*
* Hysteresis is handled separately per axis (and the window is thus
* rectangular, not circular). It is unkown if that's an issue, but the
* calculation to do circular hysteresis are nontrivial, especially since
* many touchpads have uneven x/y resolutions.
*
* Given coordinates, 0, 1, 2, ... this is what we return for a margin of 3
* and a center of 0:
*
* Input: 1 2 3 4 5 6 5 4 3 2 1 0 -1
* Coord: 0 0 0 1 2 3 3 3 3 3 3 3 2
* Center: 0 0 0 1 2 3 3 3 3 3 3 3 2
*
* Problem: viewed from a stationary finger that starts moving, the
* hysteresis margin is M in both directions. Once we start moving
* continuously though, the margin is 0 in the movement direction and 2*M to
* change direction. That makes the finger less responsive to directional
* changes than to the original movement.
*
* @param in The input coordinate
* @param center Current center of the hysteresis
* @param margin Hysteresis width (on each side)
*
* @return The new center of the hysteresis
*/
static inline int
evdev_hysteresis(int in, int center, int margin)
static inline struct device_coords
evdev_hysteresis(const struct device_coords *in,
const struct device_coords *center,
const struct device_coords *margin)
{
int diff = in - center;
if (abs(diff) <= margin)
return center;
int dx = in->x - center->x;
int dy = in->y - center->y;
int dx2 = dx * dx;
int dy2 = dy * dy;
int a = margin->x;
int b = margin->y;
double normalized_finger_distance, finger_distance, margin_distance;
double lag_x, lag_y;
struct device_coords result;
if (diff > 0)
return in - margin;
else
return in + margin;
if (!a || !b)
return *in;
/*
* Basic equation for an ellipse of radii a,b:
* x²/a² + y²/b² = 1
* But we start by making a scaled ellipse passing through the
* relative finger location (dx,dy). So the scale of this ellipse is
* the ratio of finger_distance to margin_distance:
* dx²/a² + dy²/b² = normalized_finger_distance²
*/
normalized_finger_distance = sqrt((double)dx2 / (a * a) +
(double)dy2 / (b * b));
/* Which means anything less than 1 is within the elliptical margin */
if (normalized_finger_distance < 1.0)
return *center;
finger_distance = sqrt(dx2 + dy2);
margin_distance = finger_distance / normalized_finger_distance;
/*
* Now calculate the x,y coordinates on the edge of the margin ellipse
* where it intersects the finger vector. Shortcut: We achieve this by
* finding the point with the same gradient as dy/dx.
*/
if (dx) {
double gradient = (double)dy / dx;
lag_x = margin_distance / sqrt(gradient * gradient + 1);
lag_y = sqrt((margin_distance + lag_x) *
(margin_distance - lag_x));
} else { /* Infinite gradient */
lag_x = 0.0;
lag_y = margin_distance;
}
/*
* 'result' is the centre of an ellipse (radii a,b) which has been
* dragged by the finger moving inside it to 'in'. The finger is now
* touching the margin ellipse at some point: (±lag_x,±lag_y)
*/
result.x = (dx >= 0) ? in->x - lag_x : in->x + lag_x;
result.y = (dy >= 0) ? in->y - lag_y : in->y + lag_y;
return result;
}
static inline struct libinput *

View file

@ -7,6 +7,6 @@ libdir="$1"
sofile=$(basename "$2")
if command -v restorecon >/dev/null; then
echo "Restoring SELinux context on $MESON_INSTALL_DESTDIR_PREFIX/$libdir/$sofile"
restorecon "$MESON_INSTALL_DESTDIR_PREFIX/$libdir/$sofile"
echo "Restoring SELinux context on ${DESTDIR}${libdir}/${sofile}"
restorecon "${DESTDIR}${libdir}/${sofile}"
fi

View file

@ -4325,7 +4325,7 @@ libinput_device_config_calibration_get_matrix(struct libinput_device *device,
*
* @see libinput_device_config_calibration_has_matrix
* @see libinput_device_config_calibration_set_matrix
* @see libinput_device_config_calibration_get_default_matrix
* @see libinput_device_config_calibration_get_matrix
*/
int
libinput_device_config_calibration_get_default_matrix(struct libinput_device *device,

View file

@ -150,6 +150,17 @@ udev_input_add_devices(struct udev_input *input, struct udev *udev)
continue;
}
/* Skip unconfigured device. udev will send an event
* when device is fully configured */
if (!udev_device_get_is_initialized(device)) {
log_debug(&input->base,
"%-7s - skip unconfigured input device '%s'\n",
sysname,
udev_device_get_devnode(device));
udev_device_unref(device);
continue;
}
if (device_added(device, input, NULL) < 0) {
udev_device_unref(device);
udev_enumerate_unref(e);
@ -229,7 +240,7 @@ udev_input_enable(struct libinput *libinput)
struct udev *udev = input->udev;
int fd;
if (input->udev_monitor)
if (input->udev_monitor || !input->seat_id)
return 0;
input->udev_monitor = udev_monitor_new_from_netlink(udev, "udev");

View file

@ -0,0 +1,59 @@
/*
* Copyright © 2018 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "config.h"
#include "litest.h"
#include "litest-int.h"
static struct input_id input_id = {
.bustype = 0x3,
.vendor = 0x045e,
.product = 0x0800,
};
static int events[] = {
EV_KEY, BTN_LEFT,
EV_KEY, BTN_RIGHT,
EV_KEY, BTN_MIDDLE,
EV_KEY, BTN_SIDE,
EV_KEY, BTN_EXTRA,
EV_REL, REL_X,
EV_REL, REL_Y,
EV_REL, REL_WHEEL,
EV_REL, REL_DIAL,
EV_REL, REL_HWHEEL,
-1 , -1,
};
TEST_DEVICE("ms-nano-mouse",
.type = LITEST_MS_NANO_TRANSCEIVER_MOUSE,
.features = LITEST_RELATIVE | LITEST_BUTTON | LITEST_WHEEL | LITEST_NO_DEBOUNCE,
.interface = NULL,
.name = "Microsoft Microsoft® Nano Transceiver v2.0",
.id = &input_id,
.absinfo = NULL,
.events = events,
)

View file

@ -270,6 +270,7 @@ enum litest_device_type {
LITEST_WACOM_BAMBOO_2FG_PEN,
LITEST_WACOM_BAMBOO_2FG_FINGER,
LITEST_HP_WMI_HOTKEYS,
LITEST_MS_NANO_TRANSCEIVER_MOUSE,
};
enum litest_device_feature {
@ -303,6 +304,7 @@ enum litest_device_feature {
LITEST_LEDS = 1 << 25,
LITEST_SWITCH = 1 << 26,
LITEST_IGNORED = 1 << 27,
LITEST_NO_DEBOUNCE = 1 << 28,
};
/* this is a semi-mt device, so we keep track of the touches that the tests

View file

@ -2602,11 +2602,11 @@ litest_setup_tests_pointer(void)
litest_add("pointer:time", pointer_time_usec, LITEST_RELATIVE, LITEST_ANY);
litest_add_ranged("pointer:debounce", debounce_bounce, LITEST_BUTTON, LITEST_TOUCHPAD, &buttons);
litest_add("pointer:debounce", debounce_bounce_check_immediate, LITEST_BUTTON, LITEST_TOUCHPAD);
litest_add_ranged("pointer:debounce", debounce_spurious, LITEST_BUTTON, LITEST_TOUCHPAD, &buttons);
litest_add("pointer:debounce", debounce_spurious_multibounce, LITEST_BUTTON, LITEST_TOUCHPAD);
litest_add("pointer:debounce_otherbutton", debounce_spurious_dont_enable_on_otherbutton, LITEST_BUTTON, LITEST_TOUCHPAD);
litest_add("pointer:debounce_otherbutton", debounce_spurious_cancel_debounce_otherbutton, LITEST_BUTTON, LITEST_TOUCHPAD);
litest_add("pointer:debounce_otherbutton", debounce_spurious_switch_to_otherbutton, LITEST_BUTTON, LITEST_TOUCHPAD);
litest_add_ranged("pointer:debounce", debounce_bounce, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE, &buttons);
litest_add("pointer:debounce", debounce_bounce_check_immediate, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
litest_add_ranged("pointer:debounce", debounce_spurious, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE, &buttons);
litest_add("pointer:debounce", debounce_spurious_multibounce, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
litest_add("pointer:debounce_otherbutton", debounce_spurious_dont_enable_on_otherbutton, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
litest_add("pointer:debounce_otherbutton", debounce_spurious_cancel_debounce_otherbutton, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
litest_add("pointer:debounce_otherbutton", debounce_spurious_switch_to_otherbutton, LITEST_BUTTON, LITEST_TOUCHPAD|LITEST_NO_DEBOUNCE);
}

View file

@ -1591,6 +1591,117 @@ START_TEST(touchpad_3fg_tap_quickrelease)
}
END_TEST
START_TEST(touchpad_3fg_tap_pressure_btntool)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
if (libevdev_get_abs_maximum(dev->evdev, ABS_MT_SLOT) >= 2)
return;
/* libinput doesn't export when it uses pressure detection, so we
* need to reconstruct this here. Specifically, semi-mt devices are
* non-mt in libinput, so if they have ABS_PRESSURE, they'll use it.
*/
if (!libevdev_has_event_code(dev->evdev, EV_ABS, ABS_MT_PRESSURE))
return;
litest_enable_tap(dev->libinput_device);
litest_enable_edge_scroll(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 50, 50);
litest_touch_down(dev, 1, 70, 50);
libinput_dispatch(li);
litest_touch_move_to(dev, 0, 50, 50, 50, 70, 10, 0);
litest_touch_move_to(dev, 1, 70, 50, 50, 70, 10, 0);
litest_drain_events(li);
/* drop below the pressure threshold in the same frame as starting a
* third touch, see
* E: 8713.954784 0001 014e 0001 # EV_KEY / BTN_TOOL_TRIPLETAP 1
* in https://bugs.freedesktop.org/attachment.cgi?id=137672
*/
litest_event(dev, EV_ABS, ABS_MT_PRESSURE, 3);
litest_event(dev, EV_ABS, ABS_PRESSURE, 3);
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
libinput_dispatch(li);
litest_push_event_frame(dev);
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 0);
litest_pop_event_frame(dev);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
libinput_dispatch(li);
litest_timeout_tap();
libinput_dispatch(li);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_3fg_tap_hover_btntool)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
if (libevdev_get_abs_maximum(dev->evdev, ABS_MT_SLOT) >= 2)
return;
/* libinput doesn't export when it uses pressure detection, so we
* need to reconstruct this here. Specifically, semi-mt devices are
* non-mt in libinput, so if they have ABS_PRESSURE, they'll use it.
*/
if (libevdev_has_event_code(dev->evdev, EV_ABS, ABS_MT_PRESSURE))
return;
if (libevdev_has_property(dev->evdev, INPUT_PROP_SEMI_MT) &&
libevdev_has_event_code(dev->evdev, EV_ABS, ABS_PRESSURE))
return;
litest_enable_tap(dev->libinput_device);
litest_enable_edge_scroll(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 50, 50);
litest_touch_down(dev, 1, 70, 50);
libinput_dispatch(li);
litest_touch_move_to(dev, 0, 50, 50, 50, 70, 10, 0);
litest_touch_move_to(dev, 1, 70, 50, 50, 70, 10, 0);
litest_drain_events(li);
/* drop below the pressure threshold in the same frame as starting a
* third touch */
litest_event(dev, EV_KEY, BTN_TOUCH, 0);
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
libinput_dispatch(li);
litest_push_event_frame(dev);
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 0);
litest_pop_event_frame(dev);
litest_assert_empty_queue(li);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
}
END_TEST
START_TEST(touchpad_3fg_tap_btntool)
{
struct litest_device *dev = litest_current_device();
@ -3273,6 +3384,8 @@ litest_setup_tests_touchpad_tap(void)
litest_add_ranged("tap-3fg:3fg", touchpad_3fg_tap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &tap_map_range);
litest_add("tap-3fg:3fg", touchpad_3fg_tap_tap_again, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("tap-3fg:3fg", touchpad_3fg_tap_quickrelease, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("tap-3fg:3fg", touchpad_3fg_tap_hover_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("tap-3fg:3fg", touchpad_3fg_tap_pressure_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add_for_device("tap-3fg:3fg", touchpad_3fg_tap_btntool_pointerjump, LITEST_SYNAPTICS_TOPBUTTONPAD);
litest_add("tap-4fg:4fg", touchpad_4fg_tap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
litest_add("tap-4fg:4fg", touchpad_4fg_tap_quickrelease, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);

View file

@ -953,7 +953,7 @@ START_TEST(touchpad_edge_scroll_into_area)
}
END_TEST
static int
static bool
touchpad_has_palm_detect_size(struct litest_device *dev)
{
double width, height;
@ -975,6 +975,20 @@ touchpad_has_palm_detect_size(struct litest_device *dev)
return rc == 0 && width >= 70;
}
static bool
touchpad_has_top_palm_detect_size(struct litest_device *dev)
{
double width, height;
int rc;
if (!touchpad_has_palm_detect_size(dev))
return false;
rc = libinput_device_get_size(dev->libinput_device, &width, &height);
return rc == 0 && height > 55;
}
START_TEST(touchpad_palm_detect_at_edge)
{
struct litest_device *dev = litest_current_device();
@ -1009,7 +1023,7 @@ START_TEST(touchpad_palm_detect_at_top)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
if (!touchpad_has_palm_detect_size(dev))
if (!touchpad_has_top_palm_detect_size(dev))
return;
litest_disable_tap(dev->libinput_device);
@ -1131,7 +1145,7 @@ START_TEST(touchpad_palm_detect_top_palm_stays_palm)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
if (!touchpad_has_palm_detect_size(dev))
if (!touchpad_has_top_palm_detect_size(dev))
return;
litest_disable_tap(dev->libinput_device);
@ -1178,7 +1192,7 @@ START_TEST(touchpad_palm_detect_top_palm_becomes_pointer)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
if (!touchpad_has_palm_detect_size(dev))
if (!touchpad_has_top_palm_detect_size(dev))
return;
litest_disable_tap(dev->libinput_device);
@ -1231,7 +1245,7 @@ START_TEST(touchpad_palm_detect_no_palm_moving_into_top)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
if (!touchpad_has_palm_detect_size(dev))
if (!touchpad_has_top_palm_detect_size(dev))
return;
litest_disable_tap(dev->libinput_device);
@ -1260,7 +1274,7 @@ START_TEST(touchpad_palm_detect_no_tap_top_edge)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
if (!touchpad_has_palm_detect_size(dev))
if (!touchpad_has_top_palm_detect_size(dev))
return;
litest_enable_tap(dev->libinput_device);
@ -4473,6 +4487,43 @@ START_TEST(touchpad_thumb_moving)
}
END_TEST
START_TEST(touchpad_thumb_moving_empty_slots)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_disable_tap(dev->libinput_device);
litest_enable_2fg_scroll(dev);
if (libevdev_get_num_slots(dev->evdev) < 3)
return;
litest_drain_events(li);
/* exceed the speed movement threshold in slot 0 */
litest_touch_down(dev, 0, 50, 20);
litest_touch_move_to(dev, 0, 50, 20, 70, 99, 15, 0);
litest_touch_up(dev, 0);
litest_drain_events(li);
/* scroll in slots 1 and 2 */
litest_touch_down(dev, 1, 50, 50);
litest_touch_down(dev, 2, 90, 50);
libinput_dispatch(li);
for (int i = 0, y = 50; i < 10; i++, y++) {
litest_touch_move_to(dev, 1, 50, y, 50, y + 1, 1, 0);
litest_touch_move_to(dev, 2, 50, y, 50, y + 1, 1, 0);
}
libinput_dispatch(li);
litest_touch_up(dev, 1);
litest_touch_up(dev, 2);
libinput_dispatch(li);
litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 2);
}
END_TEST
START_TEST(touchpad_thumb_clickfinger)
{
struct litest_device *dev = litest_current_device();
@ -5423,6 +5474,111 @@ START_TEST(touchpad_pressure_tap_2fg_1fg_light)
}
END_TEST
START_TEST(touchpad_pressure_btntool)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct axis_replacement axes[] = {
{ ABS_MT_PRESSURE, 5 },
{ ABS_PRESSURE, 5 },
{ -1, 0 }
};
/* we only have tripletap, can't test 4 slots because nothing will
* happen */
if (libevdev_get_num_slots(dev->evdev) != 2)
return;
if (!touchpad_has_pressure(dev))
return;
litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
/* Two light touches down, doesn't count */
litest_touch_down_extended(dev, 0, 40, 50, axes);
litest_touch_down_extended(dev, 1, 45, 50, axes);
libinput_dispatch(li);
litest_assert_empty_queue(li);
/* Tripletap but since no finger is logically down, it doesn't count */
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_assert_empty_queue(li);
/* back to two fingers */
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
libinput_dispatch(li);
/* make one finger real */
litest_touch_move_to(dev, 0, 40, 50, 41, 52, 10, 10);
litest_drain_events(li);
/* tripletap should now be 3 fingers tap */
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
libinput_dispatch(li);
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 0);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
libinput_dispatch(li);
litest_timeout_tap();
libinput_dispatch(li);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li,
BTN_MIDDLE,
LIBINPUT_BUTTON_STATE_RELEASED);
}
END_TEST
START_TEST(touchpad_pressure_semi_mt_2fg_goes_light)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct axis_replacement axes[] = {
{ ABS_PRESSURE, 2 },
{ -1, 0 }
};
litest_enable_2fg_scroll(dev);
litest_drain_events(li);
litest_touch_down(dev, 0, 40, 50);
litest_touch_down(dev, 1, 60, 50);
litest_touch_move_two_touches(dev, 40, 50, 60, 50, 0, -20, 10, 0);
/* This should trigger a scroll end event */
litest_push_event_frame(dev);
litest_touch_move_extended(dev, 0, 40, 31, axes);
litest_touch_move_extended(dev, 1, 60, 31, axes);
litest_pop_event_frame(dev);
libinput_dispatch(li);
litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 0);
litest_push_event_frame(dev);
litest_touch_move_extended(dev, 0, 40, 35, axes);
litest_touch_move_extended(dev, 1, 60, 35, axes);
litest_pop_event_frame(dev);
litest_push_event_frame(dev);
litest_touch_move_extended(dev, 0, 40, 40, axes);
litest_touch_move_extended(dev, 1, 60, 40, axes);
litest_pop_event_frame(dev);
libinput_dispatch(li);
litest_assert_empty_queue(li);
}
END_TEST
static inline bool
touchpad_has_touch_size(struct litest_device *dev)
{
@ -5779,6 +5935,7 @@ litest_setup_tests_touchpad(void)
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_moving, LITEST_CLICKPAD, LITEST_ANY);
litest_add("touchpad:thumb", touchpad_thumb_moving_empty_slots, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:thumb", touchpad_thumb_clickfinger, LITEST_CLICKPAD, LITEST_ANY);
litest_add("touchpad:thumb", touchpad_thumb_btnarea, LITEST_CLICKPAD, LITEST_ANY);
litest_add("touchpad:thumb", touchpad_thumb_tap_begin, LITEST_CLICKPAD, LITEST_ANY);
@ -5805,7 +5962,9 @@ litest_setup_tests_touchpad(void)
litest_add("touchpad:pressure", touchpad_pressure_2fg_st, LITEST_TOUCHPAD|LITEST_SINGLE_TOUCH, LITEST_ANY);
litest_add("touchpad:pressure", touchpad_pressure_tap, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:pressure", touchpad_pressure_tap_2fg, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:pressure", touchpad_pressure_tap_2fg_1fg_light, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:pressure", touchpad_pressure_tap_2fg_1fg_light, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:pressure", touchpad_pressure_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:pressure", touchpad_pressure_semi_mt_2fg_goes_light, LITEST_SEMI_MT, LITEST_ANY);
litest_add("touchpad:touch-size", touchpad_touch_size, LITEST_APPLE_CLICKPAD, LITEST_ANY);
litest_add("touchpad:touch-size", touchpad_touch_size_2fg, LITEST_APPLE_CLICKPAD, LITEST_ANY);

View file

@ -394,6 +394,47 @@ START_TEST(udev_suspend_resume)
}
END_TEST
START_TEST(udev_resume_before_seat)
{
struct libinput *li;
struct udev *udev;
int rc;
udev = udev_new();
ck_assert(udev != NULL);
li = libinput_udev_create_context(&simple_interface, NULL, udev);
ck_assert(li != NULL);
rc = libinput_resume(li);
ck_assert_int_eq(rc, 0);
libinput_unref(li);
udev_unref(udev);
}
END_TEST
START_TEST(udev_suspend_resume_before_seat)
{
struct libinput *li;
struct udev *udev;
int rc;
udev = udev_new();
ck_assert(udev != NULL);
li = libinput_udev_create_context(&simple_interface, NULL, udev);
ck_assert(li != NULL);
libinput_suspend(li);
rc = libinput_resume(li);
ck_assert_int_eq(rc, 0);
libinput_unref(li);
udev_unref(udev);
}
END_TEST
START_TEST(udev_device_sysname)
{
struct libinput *li;
@ -619,6 +660,8 @@ litest_setup_tests_udev(void)
litest_add_for_device("udev:suspend", udev_double_suspend, LITEST_SYNAPTICS_CLICKPAD_X220);
litest_add_for_device("udev:suspend", udev_double_resume, LITEST_SYNAPTICS_CLICKPAD_X220);
litest_add_for_device("udev:suspend", udev_suspend_resume, LITEST_SYNAPTICS_CLICKPAD_X220);
litest_add_for_device("udev:suspend", udev_resume_before_seat, LITEST_SYNAPTICS_CLICKPAD_X220);
litest_add_for_device("udev:suspend", udev_suspend_resume_before_seat, LITEST_SYNAPTICS_CLICKPAD_X220);
litest_add_for_device("udev:device events", udev_device_sysname, LITEST_SYNAPTICS_CLICKPAD_X220);
litest_add_for_device("udev:seat", udev_seat_recycle, LITEST_SYNAPTICS_CLICKPAD_X220);

View file

@ -1,9 +1,7 @@
#!/bin/sh
#
# This does not honor $bindir properly, because we cannot get to it
# here. Does anyone build to something but prefix/bin?
#
bindir="${DESTDIR}/${MESON_INSTALL_PREFIX}/bin"
mkdir -p "$bindir"
bindir="${DESTDIR}${1}"
# Do not create bindir, because if it is not there now, we have a problem
cp "${MESON_SOURCE_ROOT}/tools/libinput-list-devices.compat" "${bindir}/libinput-list-devices"
cp "${MESON_SOURCE_ROOT}/tools/libinput-debug-events.compat" "${bindir}/libinput-debug-events"

View file

@ -68,7 +68,7 @@ Enable or disable middle button emulation
.B \-\-enable\-dwt|\-\-disable\-dwt
Enable or disable disable-while-typing
.TP 8
.B \-\-set\-click\-method=[none|clickfinger|buttons]
.B \-\-set\-click\-method=[none|clickfinger|buttonareas]
Set the desired click method
.TP 8
.B \-\-set\-scroll\-method=[none|twofinger|edge|button]

View file

@ -234,7 +234,7 @@ class Device(object):
ud = pyudev.Devices.from_device_file(context, self.path)
v = ud.get('LIBINPUT_ATTR_TOUCH_SIZE_RANGE')
if v:
self.up, self.down = colon_tuple(v)
self.down, self.up = colon_tuple(v)
v = ud.get('LIBINPUT_ATTR_PALM_SIZE_THRESHOLD')
if v:

View file

@ -163,8 +163,8 @@ class Device(object):
prange = p.max - p.min
# libinput defaults
self.up = int(p.min + 0.12 * prange)
self.down = int(p.min + 0.10 * prange)
self.down = int(p.min + 0.12 * prange)
self.up = int(p.min + 0.10 * prange)
self.palm = 130 # the libinput default
self._init_thresholds_from_udev()
@ -189,7 +189,7 @@ class Device(object):
ud = pyudev.Devices.from_device_file(context, self.path)
v = ud.get('LIBINPUT_ATTR_PRESSURE_RANGE')
if v:
self.up, self.down = colon_tuple(v)
self.down, self.up = colon_tuple(v)
v = ud.get('LIBINPUT_ATTR_PALM_PRESSURE_THRESHOLD')
if v:

View file

@ -1,4 +1,4 @@
#!/usr/bin/python3
#!/usr/bin/env python3
# vim: set expandtab shiftwidth=4:
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#

View file

@ -53,7 +53,7 @@ main(int argc, char **argv)
{ 0, 0, 0, 0}
};
c = getopt_long(argc, argv, "h", opts, &option_index);
c = getopt_long(argc, argv, "+h", opts, &option_index);
if (c == -1)
break;

View file

@ -59,8 +59,10 @@ libinput:name:*Apple Inc. Apple Internal Keyboard*:dmi:*
libinput:mouse:input:b0005v05ACp030D*
LIBINPUT_MODEL_APPLE_MAGICMOUSE=1
# Magic Trackpad
libinput:touchpad:input:b0005v05ACp030E*
LIBINPUT_ATTR_SIZE_HINT=130x110
LIBINPUT_ATTR_TOUCH_SIZE_RANGE=60:40
libinput:touchpad:input:b0003v05ACp021A*
LIBINPUT_MODEL_APPLE_TOUCHPAD_ONEBUTTON=1
@ -95,6 +97,10 @@ libinput:name:* Touchpad:dmi:*svnDellInc.:*
libinput:name:*AlpsPS/2 ALPS GlidePoint:dmi:*svnDellInc.:pnLatitudeE6220:*
LIBINPUT_ATTR_PRESSURE_RANGE=100:90
libinput:name:*CyPS/2 Cypress Trackpad:dmi:*svnDell*:*XPSL322X*
LIBINPUT_ATTR_PRESSURE_RANGE=30:20
LIBINPUT_ATTR_PALM_PRESSURE_THRESHOLD=254
##########################################
# Elantech
##########################################
@ -196,6 +202,20 @@ libinput:tablet:input:b0003v256Cp*
libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*:pvrThinkPadX230*
LIBINPUT_MODEL_LENOVO_X230=1
# T440p on PS/2
libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*:pvrThinkPadT440p*
# T440p on RMI4
libinput:name:Synaptics tm2964-001:dmi:*svnLENOVO:*:pvrThinkPadT440p*
LIBINPUT_MODEL_LENOVO_T450_TOUCHPAD=1
# T440s trackpoint
libinput:name:TPPS/2 IBM TrackPoint:dmi:*svnLENOVO:*:pvrThinkPadT440s*
LIBINPUT_ATTR_TRACKPOINT_RANGE=30
# T450s trackpoint
libinput:name:TPPS/2 IBM TrackPoint:dmi:*svnLENOVO:*:pvrThinkPadT450s*
LIBINPUT_ATTR_TRACKPOINT_RANGE=50
# Lenovo T450/T460 and all other Lenovos of the *50 and *60 generation,
# including the X1 Carbon 3rd gen
libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*:pvrThinkPad??50*:
@ -208,6 +228,10 @@ libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*:pvrThinkPadX1Carbon3rd
libinput:keyboard:input:b0003v17EFp6047*
LIBINPUT_ATTR_KEYBOARD_INTEGRATION=external
# Lenovo X280
libinput:name:*ALPS TrackPoint*:svnLENOVO:*:pvrThinkPadX280:*
LIBINPUT_ATTR_TRACKPOINT_RANGE=70
##########################################
# Logitech
##########################################
@ -218,6 +242,10 @@ libinput:name:*Logitech M570*:dmi:*
libinput:mouse:input:b0003v046DpC408*
LIBINPUT_MODEL_LOGITECH_MARBLE_MOUSE=1
# Logitech K400
libinput:mouse:input:b0003v046Dp4024*
LIBINPUT_MODEL_LOGITECH_K400=1
##########################################
# Microsoft
##########################################
@ -229,6 +257,10 @@ libinput:name:*Lid Switch*:dmi:*svnMicrosoftCorporation:pnSurface3:*
libinput:name:*Microsoft Surface Type Cover Keyboard*:dmi:*svnMicrosoftCorporation:pnSurface3:*
LIBINPUT_ATTR_KEYBOARD_INTEGRATION=internal
# Microsoft Microsoft® Nano Transceiver v2.0"
libinput:mouse:input:b0003v045Ep0800*
LIBINPUT_MODEL_MS_NANO_TRANSCEIVER=1
##########################################
# Razer
##########################################

View file

@ -113,6 +113,7 @@ def property_grammar():
('LIBINPUT_ATTR_LID_SWITCH_RELIABILITY',
Or(('reliable', 'write_open'))),
('LIBINPUT_ATTR_KEYBOARD_INTEGRATION', Or(('internal', 'external'))),
('LIBINPUT_ATTR_TRACKPOINT_RANGE', INTEGER('Y')),
)
value_props = [Literal(name)('NAME') - Suppress('=') - val('VALUE') for
name, val in vprops]