Commit graph

95 commits

Author SHA1 Message Date
José Expósito
b5b6f835af gestures: use events to change between states
Refactor the gesture state machine to emit events to change between states.

Signed-off-by: José Expósito <jose.exposito89@gmail.com>
2021-06-09 01:18:58 +00:00
José Expósito
d5636eb934 gestures: handle pointer motion as an extra state
Refactor the gesture state machine to integrate pointer motion as an extra state
of the state machine.

Signed-off-by: José Expósito <jose.exposito89@gmail.com>
2021-06-09 01:18:58 +00:00
José Expósito
ba3e79c9f4 gestures: refactor gesture enabled
Move the condition to check if gestures are enabled to its own function.

Signed-off-by: José Expósito <jose.exposito89@gmail.com>
2021-06-09 01:18:58 +00:00
José Expósito
bbc5aee5e5 gestures: add a function to know if there is pending pointer motion
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
2021-06-09 01:18:58 +00:00
novenary
c4ea48eda6 Increase pinch grace period to 300ms
Windows allows "about a third of a second" to trigger a two-finger
pinch.

https://gitlab.freedesktop.org/libinput/libinput/-/issues/550#implementation-in-other-systems

Signed-off-by: novenary <streetwalkermc@gmail.com>
2021-05-19 05:12:58 +00:00
novenary
ca3df8a076 Allow reviving a thumb that moves sufficiently
When pinching, the thumb tends to move slower than the finger, so we may
suppress it too early.

Add a grace period during which it may be revived.

Signed-off-by: novenary <streetwalkermc@gmail.com>
2021-05-19 05:12:58 +00:00
novenary
939a022cbc Improve disambiguation between two-finger pinch and scroll
A pinch is defined as two fingers moving in different directions, and a
scroll as two fingers moving in the same direction.

Often enough when the user is trying to pinch, we may initially see both
fingers moving in the same direction and decide that they want to
scroll.

Add a grace period during which we may transition to a pinch in those
situations.

Test fix: touchpad_trackpoint_buttons_2fg_scroll emits movements that
change the distance between fingers, which triggers this new transition
and makes the test fail; correct this.

Signed-off-by: novenary <streetwalkermc@gmail.com>
2021-05-19 05:12:58 +00:00
JoseExposito
3565dafdf1 gestures: move the logic to detect gestures to its own function
Move the code in used to detect motion based gestures (scroll, swipe and pinch)
to tp_gesture_detect_motion_gestures.

Signed-off-by: José Expósito <jose.exposito89@gmail.com>
2021-04-13 14:01:11 +10:00
JoseExposito
73ef2d70c2 gestures: move up some functions to use them later
Move tp_gesture_same_directions, tp_gesture_mm_moved and tp_gesture_init_pinch
to be able to use them in future commits.

Signed-off-by: José Expósito <jose.exposito89@gmail.com>
2021-04-13 14:01:11 +10:00
JoseExposito
020f13e10d gestures: move the code to get raw pointer motion to its own function
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
2021-04-13 14:01:11 +10:00
Alexander Mikhaylenko
60d5172e15 gestures: Filter unaccelerated deltas for gestures
Make sure the unaccelerated deltas are comparable to scroll deltas.

edit by whot:
The original intention of the unaccelerated motion data here was to provide
both accelerated and unaccelerated motion for gestures so it was possible to
have 1:1 mapping from gesture motion to screen activity.

Normalizing to 1000dpi this way would've worked for mice but touchpad
acceleration also includes the TP_MAGIC_SLOWDOWN (amongst other tricks) which
slows down motion to around 27% *before* applying the acceleration function.
On a 1000dpi touchpad (~40 units/mm) simply normalizing touchpad motion to
1000dpi results in pointer motion that is way too fast, it's lacking that
slowdown to 27% of original speed.

This results in the accelerated and unaccelerated gesture data being in
effectively two different coordinate systems with the caller having no ability
to relate the two.

Switching to the special constant acceleration applies that slowdown and
matches the data to the part of the acceleration curve where no (additional)
acceleration is applied.

It makes the gesture unaccelerated data comparable to the accelerated data
and to scroll data which uses the same process.

Fixes #582

Signed-off-by: Alexander Mikhaylenko <alexm@gnome.org>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-03-16 21:29:56 +00:00
Rosen Penev
467752047e
[clang-tidy] do not use else after return
Found with readability-else-after-return

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-08-27 01:17:24 -07:00
Matt Mayfield
73870d938e touchpad: restore thumb detection while keeping fixes from !292
!292 improved libinput's ability to detect multiple-finger clicks when
the fingers were not aligned close to horizontally. However that caused
thumb detection to fail in several use cases.

This patch restores thumb detection for
- 2+ finger physical clickpad presses
- resting thumb while two-finger scrolling
- touches in the thumb exclusion area during multi-finger taps
and improves pinch detection when thumb is centered below fingers.

It also further enhances the flexibility of finger position for 2-, 3-,
or 4-finger taps: if all tapping fingers land on the touchpad within a
short time (currently 100ms), they will all count regardless of
position (unless below the lower_thumb_line).

Signed-off-by: Matt Mayfield <mdmayfield@yahoo.com>
2020-05-22 02:16:05 +00:00
Peter Hutterer
cb1be90439 gestures: where we have more fingers than slots, default to swipe
Fixes #360

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2019-09-25 04:10:02 +00:00
Peter Hutterer
129a1dffa4 gestures: rename the inner/outer thresholds to min/max_move
inner/outer refer more to static thresholds when really what we have here is a
minimum movement before we look at the touch, and a maximum one after which
it's largely ignored.

Straight-up rename, no functional changes.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2019-09-25 04:10:02 +00:00
Konstantin Kharlamov
c29fabb2cf evdev-mt-touchpad-gestures.c: remove unused include
Signed-off-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
2019-09-12 09:36:40 +10:00
Matt Mayfield
73d55cc6c5 touchpad: don't allow gestures with a clickpad button down by a finger
Allowing gestures when holding a physical click enables tasks like
switching workspaces while dragging an icon, but this should only be
possible with a *thumb* holding down the clickpad, not fingers. This
commit restores the ability to hold down the clickpad with two or three
fingers to right- or middle-drag.

Fixes #339, #340

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2019-08-16 14:48:52 +10:00
Matt Mayfield
4536b5b38f touchpad: revamp thumb detection
Instead of a simple yes/no/maybe for thumbs, have a more extensive state
machine that keeps track of the thumb. Since we only support one thumb anyway,
the tracking moves to the tp_dispatch struct.

Test case changes:
touchpad_clickfinger_3fg_tool_position:
  with better thumb detection we can now handle this properly and expect a
  right button (2fg) press for the test case
touchpad_thumb_no_doublethumb_with_timeout:
  two thumbs are now always two fingers, so let's switch to axis events here

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2019-07-17 09:33:14 +10:00
Peter Hutterer
282979558e touchpad: add a helper function for supressing a thumb
Only sets the state to YES at the moment, will do more in the future.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2019-07-15 13:08:47 +10:00
Matt Mayfield
15c8613a65 gestures: Improve thumb detection, allow one finger scroll
Check if there's a thumb if we have two touches. If one finger moves but
the thumb remains still, we assume that one is really a thumb. But if the
thumb moves while the finger is still, let's assume this is a 2-finger scroll.

Extracted from Matt Mayfield's thumb detection patchset
2019-07-15 13:08:47 +10:00
Peter Hutterer
1dae79c833 gestures: fast-track scroll/swipe detection when gestures are off
We can't detect pinch when gestures are off anyway, so we don't need to check
the finger distances.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2019-07-15 13:08:47 +10:00
Matt Mayfield
93ab2f964a gestures: improvements to pinch detection
Only bias towards scrolling if the fingers are in the position past the
timeout.
2019-07-15 13:08:47 +10:00
Matt Mayfield
e97f054917 gestures: improve scroll responsiveness for vertically aligned touches
Put some basic location checks in, if the fingers are next to each other and
vertically close, assume scroll over swipe.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>:
2019-07-15 13:08:47 +10:00
Matt Mayfield
7b9a6a94a3 touchpad: basic thumb detection within gestures
When a touchpad has thumb detection enabled, avoid false-positive gestures
involving a resting thumb by using two thresholds: inner and outer.

While both touches remain inside their inner thresholds, remain in UNKNOWN
state to allow for accurate gesture detection even with no timeout.

If both touches move outside their inner thresholds, start a pinch or
swipe/scroll gesture according to direction, as usual.

If one touch moves outside its outer threshold while the other has not yet
exceeded its inner threshold, and thumb detection is enabled, then if one
touch is >20mm lower, mark it as a thumb and cancel the gesture.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2019-07-15 13:08:47 +10:00
Peter Hutterer
7c9ed03c42 touchpad: add a helper function for counting touches for gestures
Currently the same as tp_touch_active() but this will change.

No functional changes.

Extracted from Matt Mayfield's thumb detection patches.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2019-07-15 13:08:47 +10:00
Peter Hutterer
7e89e43c74 touchpad: rename the scroll timeout define, drop the pinch one
The previously 'scroll'-named timeout is also used for swipe, so let's rename
it. And the pinch one isn't used at all.

Extracted from Matt Mayfield's thumb detection patches.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2019-07-15 13:08:47 +10:00
Peter Hutterer
43b910b1df touchpad: reduce state debugging output by only logging changed states
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2019-07-15 13:08:47 +10:00
Peter Hutterer
24da4ecd85 touchpad: change the min vector for the scroll lock to 0.15
This makes the difference between noticable delay and unnoticable while having
virtually no false positives (for me).

https://gitlab.freedesktop.org/libinput/libinput/issues/101

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-08-13 14:04:24 +10:00
Matt Mayfield
bb87a3d9e9 touchpad: 90-degree scroll helper
This makes two-finger scrolling in straight lines easier, while still
allowing free/diagonal movement. It works in three stages:

1) Initial movement
   - For the first few millimeters, scroll movements within 30 degrees
     of horizontal or vertical are straightened to 90-degree angles.
   - Scroll movements close to 45 degree diagonals are unchanged.
   - If movement continues very close to straight horizontal or
     vertical, stage 2 begins and the axis lock engages.
   - If movement continues along a diagonal, stage 2 is skipped and
     free scrolling is immediately enabled.
2) Axis lock
   - If the user scrolls fairly closely to straight vertical, no
     horizontal movement will happen at all, and vice versa.
   - It is possible to switch between straight vertical and straight
     horizontal, and the axis lock will automatically change.
   - If deliberate diagonal movement is detected at any point, stage
     3 begins and the axis lock disengages.
3) Free scrolling
   - Scrolling is unconstrained until the fingers are lifted.
2018-08-08 11:36:39 -05:00
Peter Hutterer
66687902d0 gestures: if two fingers are in definitive pinch position, pinch
Two fingers on the touchpad, they're 40x40mm apart, that's a pinch. But only
after a timeout because we don't want to start a 2fg gesture if the user puts
down the third/fourth finger within the next few ms.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-04-26 13:59:03 +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
6d435cda06 gestures: don't try to pinch for nfingers > slots
We don't know the position of the third finger on 2-slot touchpads, differing
between swipe and pinch is reliable. Simply disable 3-finger pinch and always
use swipe; 3fg pinch is uncommon anyway and it's better to have one of the
gestures working reliably than both unreliably.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2017-08-01 16:42:03 +01: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
Marcos Paulo de Souza
8584c044da touchpad: make use of use tp_for_each_touch
Instead of reimplementing a for loop every time.

Signed-off-by: Marcos Paulo de Souza <marcos.souza.org@gmail.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-03 12:38:15 +10:00
Peter Hutterer
6181adbdcd evdev: standardize log messsages
Prefix device log messages with the device's sysname so it's more obvious
where the messages are coming from. This makes it much easier to grep for a
specific device's messages but also adds some identifier to messages that
were previously without any identifier (e.g. all the state machine debugging)

All info and error messages also automatically prefix the device name, so
those messages are standardised too, e.g

an info message now:
  event4  - SynPS/2 Synaptics TouchPad: is tagged by udev as: Touchpad
a debug message now:
  event4  - using pressure-based touch detection

And since this required changing a lot of the strings in messages anyway,
polish a few minor things too.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Hans de Goede <hdegoede@redhat.com>
2017-02-24 16:04:44 +10:00
Peter Hutterer
a64f9df5ce Drop normalized_get_direction, use physical distances instead
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2017-01-23 10:43:04 +10:00
Peter Hutterer
33d708e2de touchpad: convert normalized_length to physical coordinates
Now that the acceleration code doesn't use dpi-normalized coordinates anymore,
we don't need to use them in the touchpad code. Switch to physical distances
instead, it makes debugging a lot saner.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2017-01-23 10:37:08 +10:00
Peter Hutterer
af1e6c08ac gestures: if fingers don't move, force a gesture by finger position
If the fingers rest on the touchpad without moving for a timeout, switch to
pinch or swipe based on the finger position. We already switched to two-finger
scrolling based on the timeout, now we also do so for 3 and 4 finger gestures.
This gives us better reaction to small movements.

This also fixes previously unreachable code: the test for the finger position
required at least 3 fingers down but was within a condition that ensured only
2 fingers were down. This was introduced in 11917061fe.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2016-12-22 07:26:29 +10:00
Peter Hutterer
0bd94a17ff touchpad: change direction flags from int to uint32_t
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-12-21 08:08:59 +10:00
Peter Hutterer
ab42022253 Change the directions bitmask to a uin32_t
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-12-15 19:43:41 +10:00
Peter Hutterer
340474857e Whitespace fixes
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-12-05 15:17:28 +10:00
Peter Hutterer
a5450e99de gestures: reduce the 2fg scroll timeout to 150ms
This timeout is there to switch to scrolling when the fingers rest on the
touchpad unmoving and thus avoids the initial scroll threshold for slow
scrolls.

Since the only other gestures we support are swipe (usually a fast movement)
and pinch-and-rotate (also a fast movement) we can drop the timeout down
significantly and thus make the scroll feel more reactive.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2016-08-05 07:35:30 +10:00
Peter Hutterer
2f0d0b9f63 Change a few functions that only ever returned 0 to voids
These are internal functions, if we need them to return an error code we can
change that at any time. Meanwhile, if we only ever return 0 anyway we might
as well just make them voids to save on error paths.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Yong Bakos <ybakos@humanoriented.com>
Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com>
2016-07-20 11:43:40 +10:00
Peter Hutterer
4923c404e8 gestures: make the gesture movement threshold depending on finger count
Increase the mm move threshold for 3 and 4 finger gestures to 2 and 3 mm,
respectively. In multi-finger gestures it's common to have minor movement
while all fingers are being put down or before the conscious movement starts.
This can trigger invalid gesture detection (e.g. a pinch instead of a swipe).
Increase the movement threshold to make sure we have sufficient input data.

No changes to 2-finger movements.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2016-07-04 07:42:54 +10:00
Peter Hutterer
11917061fe touchpad: only check for vertical finger distribution on 2fg gestures
A natural hand position for a 4-finger swipe will have one finger well below
the other triggering the pinch detection. This is obviously wrong, only do the
finger position analysis when we have 2 fingers.

This is only a partial fix, for 3-4 finger gestures chances are high that the
third/fourth finger come in a different event frame. Before that we likely
detect 2 fingers in a possible pinch position and still trigger the code path.
This issue has to be fixed separately.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2016-06-29 08:32:04 +10:00
Peter Hutterer
48d82ed3ea touchpad: use the tp_libinput_context() helper
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-06-10 06:57:41 +10:00
Peter Hutterer
98ee1791ca gestures: don't send swipe gestures when gestures are disabled
Introduced in 6ad303b as part of an code flow optimization, causing any 3+
finger gesture to be posted as swipe gesture, even when gestures are disabled.
However, the event is filtered in the higher levels with a bug message printed
to the log.

Don't post swipe gestures for devices where gestures are disabled.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2016-05-16 08:18:59 +10:00
Peter Hutterer
bc17185f42 touchpad: only post motion events if we have motion
Because our delta calculation factors in previous events on touchpads (to
reduce jitter) we may get a nonzero delta if we have an event that doesn't
actually change x or y.

Drop the t->dirty workaround introduced in a608d9d, an event that virtually
disappears can mess up our state machines.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2016-03-29 15:48:17 +10:00
Peter Hutterer
dbb85f6739 touchpad: only trigger immediate pinch detection for three fingers
If the fingers are vertically apart by more than 20mm we used to assume a
pinch gesture immediately. This is too close together for some users during
two-finger scrolling. Since we should always bias towards scrolling, only
trigger this detection for three fingers, the rest has to go through the
movement detection.

The reason for the pinch detection here was to differentiate from 3fg swipe
gestures (83f3dbd1), hence we're still in spirit of that patch.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Tested-by: Jan Alexander Steffens (heftig) <jan.steffens@gmail.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2016-02-28 20:35:59 +10:00
Peter Hutterer
f8bcbc2dbb gestures: average motion by active touches, not moved touches
When two fingers move slowly, an event frame may only have one finger motion,
followed by a frame with the other finger's motion. If we only divide by the
number of dirty touches, the speed of the gesture increases whenever that
happens.

Reported-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2016-01-27 09:51:05 +10:00