Commit graph

412 commits

Author SHA1 Message Date
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
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
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
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
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
Peter Hutterer
937e60319b touchpad: drop the double normalization
Previously, touchpad deltas were converted to 1000-dpi normalized coordinates
and handled from there. This changed in bdd4264d61 (1.6)
when the filter functions started taking device coordinates instead. Since
then, we used to convert the device delta to normalized coordinates, then
(often immediately) convert back to device coordinates, albeit for equal x/y
resolution. This isn't necessary, we can just convert the device coordinates
to x/y-equal resolution device coordinates and pass those on.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-01-10 12:21:01 +10:00
Peter Hutterer
f5a9e38c90 touchpad: don't disable the hysteresis unless a finger is down
On the very first event, the last_motion_time set by tp_begin_touch is not yet
set because we are called before the pressure-based touch detection takes
effect. And any event timestamp is more than 80ms after a zero timestamp,
causing the hysteresis to always be disabled.

https://bugs.freedesktop.org/show_bug.cgi?id=98839#c74

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-01-09 13:47:42 +10:00
Peter Hutterer
4da9d51b67 touchpad: remove duplicate if condition
This was never true, we for the first part 3 lines above and return early. So
if we get here, it's always false.

commit aa87d2b25b added the new condition above, so since then this code
was inactive and can be removed.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-12-18 14:16:26 +10:00
Peter Hutterer
46eab97538 touchpad: work palm detection into the tap state machine
Unlike the already-existing thumb detection, a touch may be labelled palm at
any time, not just during the initial touch down. This requires full
integration into the tap state machine to unwind properly. For most states, a
palm detection simply ignores the finger and reverts to the most recent state.

One exception is the case of two fingers down, one finger up followed by the
remaining finger detected as a palm finger. This triggers a single-finger tap
but with timestamps that may be from the wrong finger. Since we're within a
short tap timeout anyway this should not matter too much.

The special state PALM_UP is only handled in one condition (DEAD). Once a
touch is a palm we basically skip over it from then on. If we end up in the
DEAD state after a button press we still need to handle the palm up events
accordingly to be able to return to IDLE. That transition also requires us to
have an accurate count of the real fingers down (palms don't count) so we need
a separate nfingers_down counter for tapping.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-11-20 11:31:56 +10:00
Peter Hutterer
875ae4de1e touchpad: change a log message for consistency
The other tablet mode notices say "suspending ..."

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-11-14 15:59:55 +10:00
Peter Hutterer
dc7fb65db5 touchpad: post a SYN_REPORT after a faked trackpoint button
This has no real effect at the moment because the fallback interface doesn't
care much about SYN_REPORT, it processes events as they come in. But it's a
bug nonetheless, the process() callback expects correct event frames.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-11-14 12:04:27 +10:00
Peter Hutterer
aaded3d01d Merge branch 'wip/touchpad-hysteresis-issues-v2' 2017-11-03 11:00:03 +10:00
Peter Hutterer
4d7592066a touchpad: allow for multiple paired keyboards
needed for the razer blade keybard which provides multiple event nodes for
one physical device but it's hard/impossible to identify which one is the real
event node we care about.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-10-31 15:40:19 +10:00
Peter Hutterer
50daa7b30f touchpad: automatically disable the hysteresis where not required
Touchpads that require the hysteresis do not have filtering in the firmware
and holding a finger still causes continuous cursor movements. This implies
that we get a continuous stream of events with motion data.

If the finger is on the touchpad but we don't see any motion, the finger is
stationary and the touchpad firmware does filtering. In that case, we don't
need to add a hysteresis on top.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-10-31 09:08:44 +10:00
Peter Hutterer
8b923d371e touchpad: add an enabled toggle to the hysteresis
Hardcoded to 'enabled' right now

No functional changes

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-10-31 09:07:11 +10:00
Peter Hutterer
c498c8c60b touchpad: move hysteresis margin into its own struct
No functional changes

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-10-31 09:07:04 +10:00
Peter Hutterer
ed52002c8d touchpad: cap the edge palm detection zones at 8mm
The main purpose of the edge zone is to detect palms in the area where we
cannot assume a full finger size and thus cannot use any other palm detection
mechanism. 8mm should be large enough that a finger should be detected based
on other properties (size, pressure, ...).

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-10-25 14:21:44 +10:00
Peter Hutterer
d27c464a49 Revert "touchpad: cap the edge palm detection zones at 8mm"
This patch only adjusted the left edge, not the right edge which was still on
8%

This reverts commit 3e9e0e2eb1.
2017-10-25 14:21:24 +10:00
Peter Hutterer
3e9e0e2eb1 touchpad: cap the edge palm detection zones at 8mm
The main purpose of the edge zone is to detect palms in the area where we
cannot assume a full finger size and thus cannot use any other palm detection
mechanism. 8mm should be large enough that a finger should be detected based
on other properties (size, pressure, ...).

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Daniel Martin <consume.noise@gmail.com>
2017-10-24 08:28:32 +10:00
Peter Hutterer
f061027dbb touchpad: cut down on excessive logging for palm size
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-10-19 13:28:42 +10:00
Peter Hutterer
fb787e7a7e touchpad: invert an if condition to allow for early return
if (foo) {
	    everything
	}

changed to :

	if (!foo)
	    return
	everything

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-09-25 15:33:41 +10:00
Peter Hutterer
27eff1ac03 evdev: abstract the get_switch_state method
Shove it into the generic dispatch interface so we don't entangle evdev and
fallback.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-09-25 15:13:37 +10:00
Peter Hutterer
6c7dd36398 Use named initializers for the various dispatch interfaces
Better for self-documentation than comments and makes it more obvious if we
initialize something wrongly.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-09-25 15:13:37 +10:00
Peter Hutterer
53d53dd18e touchpad: don't resume a disabled touchpad
A touchpad that was disabled by toggling the sendevents option would come back
normally after a lid resume, despite still being nominally disabled.

https://bugzilla.redhat.com/show_bug.cgi?id=1448962

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-09-18 17:01:24 +10:00
Peter Hutterer
4ed0f7ee0e Merge branch 'wip/ignore-moved-touches' 2017-09-11 09:43:24 +10:00
Peter Hutterer
986604fd9d touchpad: if a device has a tablet mode switch, disable the touchpad
On some devices with a tablet mode switch, the touchpad is inacessible when
in tablet mode and we don't really need this except to avoid possible ghost
touches (none have been mentioned so far). On other devices like the Lenovo
Yoga, the touchpad points to the back of the device and it's hard to use the
device without accidentally using the touchpad. For those, disabling the
touchpad is the best solution.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-09-06 09:26:00 +10:00
Peter Hutterer
a598d55e37 touchpad: rename the lid_switch_listener to just listener
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-09-04 12:42:46 +10:00
Peter Hutterer
de5246dae0 touchpad: use motion speed to ignore accidental 2fg touches
Calculate the speed of the touch and compare it against a fixed speed limit.
If a touch exceeds the speed when a second touch is set down, that second
touch is marked as a thumb and ignored (unless it's right next to the other
finger, then it's likely a 2fg scroll).

The speed calculation is simple but has to lag behind by one sample - we reset
the motion history whenever a new finger is set down (to avoid pointer jumps)
so we need to know if the finger was moving fast *before* this happens. Plus,
with the pointer jumps we're more likely to get false positives if we
calculate the speed on actual finger down.

This is the simplest version for now, the speed varies greatly between
movements and should probably be averaged across the last 3-or-so samples.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-09-01 16:06:40 +10:00
Peter Hutterer
10569680d9 touchpad: store the time in the motion history
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-09-01 16:06:40 +10:00
Hans de Goede
c4857f01d8 touchpad: Enable timestamp smoothing support for bluetooth touchpads
Bluetooth wreaks havoc with the timestamp of the input events coming
from the touchpad, enable timestamp smoothing support to counter this.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-08-01 16:42:19 +01:00
Peter Hutterer
688142c8a2 Merge branch 'wip/touchpad-apple-touch-major-v2' 2017-07-14 13:47:29 +10:00
Peter Hutterer
e71ade2755 Replace calloc calls with zalloc
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-07-12 10:18:08 +10:00
Peter Hutterer
d5d6d4cd53 Abort if zalloc ever fails
There's no guarantee that libinput does the right thing if memory allocation
fails and it's such a niche case on the systems we're targeting that it just
doesn't matter. Simply abort if zalloc ever fails.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-07-12 10:18:07 +10:00
Peter Hutterer
ca4285de66 touchpad: add touch-size-based palm detection
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-07-11 12:28:28 +10:00
Peter Hutterer
432fbc33cd touchpad: add touch-size based touch handling
Apple touchpads don't use ABS_MT_PRESSURE but they are multitouch touchpads,
so the current pressure-based handling code doesn't apply because it expects
slot-based pressure for mt touchpads.

Apple does however send useful data for ABS_MT_WIDTH_MAJOR/MINOR, so let's use
that instead. The data provided in those is more-or-less random, so we need a
hwdb entry to track the acceptable thresholds.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-07-11 12:27:54 +10:00
Peter Hutterer
e08a76674a util: rename the pressure range parser to a more generic range_parser
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-07-11 12:26:17 +10:00
Peter Hutterer
9e5d1df4bb touchpad: set keyboard to non-active when the keyboard is removed
If the keyboard is removed while dwt thinks it is in active state, that state
is never reset and subsequent touches are ignored.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-07-11 11:42:27 +10:00
Peter Hutterer
756c7e3dac timer: add a timer name to each timer
So we have something useful to print when we trigger an error in the timer
code.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-07-10 12:00:50 +10:00
Ming-Yang Lu
5dc330bdea touchpad: add upper edge into exclusion zone
This reduces unexpected cursor moves when placing the thumb near the border
of trackpoint buttons and upper edge of touchpad.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-07-10 09:33:24 +10:00
Peter Hutterer
6a77cae850 touchpad: sync the slot state after tp_resume()
If the touchpad is suspended and resumed (e.g. lid switch), the initial slot
state may be out of sync. If a touch happened while the touchpad was suspended
and the next touch down is on exactly the same x and/or y coordinate, our
touch point would still have the coordinates of the most recently seen touch
(i.e. before touchpad suspend). This could cause a pointer jump or test case
failures.

The real-world impact of this is minimal, putting the finger down in exactly
the same spot is virtually impossible. It could cause a test case failure in the
lid_disable_touchpad() test though, the second touch sequence was on the same
y coordinate and the touch location for that whole sequence was x/0.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-07-10 09:33:24 +10:00
Peter Hutterer
25d54b90db touchpad: add pressure-base palm detection
If a touch goes past the fixed pressure threshold it is labelled as a palm and
stays a palm. Default value is one that works well here on a T440 and is
virtually impossible to trigger by a normal finger or thumb. A udev property
is exposed so we can handle this in the udev hwdb and the new tool introduce a
few commits ago can help finding the palm detection threshold.

Unlike the other palm detection features, once a palm goes past the threshold
it remains a palm until the touch is released. This means palm overrides any
other palm detection features. For code simplicity, we don't combine the
states but merely check for pressure before and after the other palm detection
functions. If the pressure triggers, it will trigger before anything else. And
if something else is already active (e.g. edge where the pressure doesn't work
well) it will trigger as soon as the palm is released.

The palm threshold should thus be chosen with some room to spare between the
highest finger pressure.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-07-03 15:58:13 +10:00
Peter Hutterer
381cce8ddd touchpad: increase palm edge zones to 8%
Most modern touchpads are around 100mm wide, so this provides a ca 8mm edge
zone on each side. The extra 3mm should provide for more reliable palm
detection, a few touches happen to be just on the edge of the 5mm mark.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-07-03 15:58:13 +10:00
Peter Hutterer
f10c0c590c touchpad: update the timestamp even when we only get other axes
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-06-21 19:07:11 +10:00