summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2019-09-20 13:49:34 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2021-06-09 13:12:59 +1000
commit38e2a434c5efc51ed830952e5f0b9cdfdcaf571b (patch)
tree4041b790aedc4d662684d51a657aeb1a223cfa80 /doc
parentc96d414fdce8f28bbf3101071eedac5854caaa87 (diff)
downloadlibinput-38e2a434c5efc51ed830952e5f0b9cdfdcaf571b.tar.gz
doc: add docs for hold gestures
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'doc')
-rw-r--r--doc/user/gestures.rst229
1 files changed, 229 insertions, 0 deletions
diff --git a/doc/user/gestures.rst b/doc/user/gestures.rst
index 2dd8eb63..8338a8fe 100644
--- a/doc/user/gestures.rst
+++ b/doc/user/gestures.rst
@@ -150,3 +150,232 @@ The image above illustrates this ambiguity. The index and middle finger are
set down first, the data stream from both finger positions looks identical.
In this case, libinput assumes the fingers are in a horizontal arrangement
(the right image above) and use a swipe gesture.
+
+.. _gestures_hold:
+
+------------------------------------------------------------------------------
+Hold gestures
+------------------------------------------------------------------------------
+
+A hold gesture is one where the user places one or more fingers on the
+device without significant movement. The exact conditions when a hold gesture
+transitions to pointer motion, scrolling or other gestures
+are implementation-defined.
+
+The hold gesture is intended to allow for the implementation of two specific
+features:
+
+- where a two-finger scrolling starts kinetic scrolling in the caller, a
+ subsequent hold gesture can be used to stop that kinetic scroll motion,
+ and
+- hold-to-trigger interactions where the interaction could be a click, a
+ context menu, or some other context-specific interaction.
+
+Hold gestures have three potential logical states:
+
+- **begin**: one or more fingers are placed on the device at the same time
+- **end**: all fingers are removed and the device enters a neutral logical state
+- **end(cancelled)**: all fingers are part of a known interaction and the
+ currenthold gesture is no longer active. This may also occurs when
+ switching between hold gestures with different finger counts.
+
+.. note:: By definition, a hold gesture does not move and thus no coordinate
+ updates are available.
+
+For example, a user that puts one finger, then a second finger down and
+releases them later may trigger the following event sequence:
+
+============= ============ ============
+Action Event Finger count
+============= ============ ============
+Finger 1 down <no event>
+Finger 2 down **begin** 2
+Finger 2 up **end** 2
+Finger 1 up <no event>
+============= ============ ============
+
+A hold gesture may by be **cancelled**. This occurs
+when the hold gesture changes into some other interaction and should no
+longer be considered the current hold gesture. A **end(cancelled)** event
+applies to the whole gesture (all fingers). For example, a pointer motion on
+a touchpad may trigger this sequence:
+
++----------------+---------------------+
+| Action | Event |
++================+=====================+
+|Finger 1 down | **hold begin** |
++----------------+---------------------+
+|Finger 1 motion | | **hold cancel** |
+| | | **pointer motion**|
+| | |
++----------------+---------------------+
+|Finger 1 motion | **pointer motion** |
++----------------+---------------------+
+|Finger 1 up | *no event* |
++----------------+---------------------+
+
+.. note:: Many interactions with a touchpad will start with a hold
+ gesture that is then cancelled as that gesture turns into e.g.
+ pointer motion. A caller **must** handle hold gesture
+ cancellations correctly.
+
+A two-finger scroll motion on a touchpad may trigger this sequence:
+
++------------------+---------------------+--------------+
+| Action | Event | Finger count |
++==================+=====================+==============+
+|Finger 1 down | **hold begin** | 1 |
++------------------+---------------------+--------------+
+|Finger 2 down | **hold cancel** | 1 |
+| | **hold begin** | 2 |
++------------------+---------------------+--------------+
+|Finger 1+2 motion | | **hold cancel** | 2 |
+| | | **pointer axis** | |
+| | | |
++------------------+---------------------+--------------+
+|Finger 1+2 motion | **pointer axis** | |
++------------------+---------------------+--------------+
+| | Finger 1 up | **pointer axis** | |
+| | Finger 2 up | (scroll stop) | |
+| | | |
++------------------+---------------------+--------------+
+
+A three-finger-swipe on a touchpad may trigger this sequence:
+
++------------------+---------------------+--------------+
+| Action | Event | Finger count |
++==================+=====================+==============+
+|Finger 1 down | **hold begin** | 1 |
++------------------+---------------------+--------------+
+|Finger 2 down | **hold cancel** | 1 |
+| | **hold begin** | 2 |
++------------------+---------------------+--------------+
+|Finger 3 down | **hold cancel** | 2 |
+| | **hold begin** | 3 |
++------------------+---------------------+--------------+
+|Finger motion | | **hold cancel** | 3 |
+| | | **swipe begin** | 3 |
+| | | |
++------------------+---------------------+--------------|
+|Finger motion | **swipe update** | 3 |
++------------------+---------------------+--------------+
+| | Finger 1 up | **swipe end** | 3 |
+| | Finger 2 up | | |
+| | Finger 3 up | | |
+| | | |
++------------------+---------------------+--------------+
+
+Single-finger hold gestures
+...........................
+
+libinput uses implementation-defined timeouts based on other interactions
+to determine whether a single-finger hold gestures should start. In other
+words, a caller **must not** rely on a hold gesture always being triggered
+as soon as a single finger is placed on the touchpad. This is true for any
+hold gesture but especially so for single-finger hold gestures.
+
+Hold gestures with a single finger are prone to being extremely short-lived.
+On many devices it is impossible to hold a finger still enough for there to
+be no pointer motion events, even if those deltas are miniscule. Changing
+movement thresholds to rely on hold gestures would reduce device
+responsiveness.
+
+It is thus the responsibility of the caller to determine where hold gestures
+transition in and out of other interactions. For example, a two-finger hold
+may produce a cancelled single-finger hold gesture first:
+
++----------------+---------------------+--------------+--------------+
+| Action | Event | Finger count | Notes |
++================+=====================+==============+==============+
+|Finger 1 down | **hold begin** | 1 | |
++----------------+---------------------+--------------+--------------+
+|Finger 1 motion | | **hold cancel** | 1 | tiny deltas |
+| | | **pointer motion**| | |
+| | | | |
++----------------+---------------------+--------------+--------------+
+|Finger 2 down | **hold begin** | 2 | |
++----------------+---------------------+--------------+--------------+
+| | Finger 1 up | **hold end** | | |
+| | Finger 2 up | | | |
+| | | | |
++----------------+---------------------+--------------+--------------+
+
+Note how the second hold gesture started with a finger count of 2 - without
+the user ever lifting the first finger. Cancellation of hold gesture does
+not imply the user has lifted a finger.
+
+A hold gesture may start after a previous gesture completed. For example, a
+single finger move-and-hold may trigger different sequences for the same
+user interaction:
+
++----------------+---------------------+----------------+--------------+
+| Action | Device 1 | Device 2 | Notes |
++================+=====================+================+==============+
+|Finger 1 down | **hold begin** | **hold begin** | |
++----------------+---------------------+----------------+--------------+
+|Finger 1 motion | | **hold cancel** | | tiny deltas |
+| | | **pointer motion**| | |
+| | | | |
++----------------+---------------------+----------------+--------------+
+| | **hold begin** | | |
++----------------+---------------------+----------------+--------------+
+| Finger 1 up | **hold end** | **hold end** | |
++----------------+---------------------+----------------+--------------+
+
+A caller that wants to use hold gestures must thus be able to infer the same
+interaction based on a stream of pointer motion events with small deltas.
+
+libinput may start a new hold begin gesture once the pointer stops moving.
+The time between the last pointer motion event and the hold begin event is
+implementation-defined.
+
+
+Hold gestures and thumb/palm detection
+......................................
+
+Thumb and palm detection effectively remove touches from being counted
+towards an interaction, see :ref:`thumb_detection` and
+:ref:`palm_detection` for details.
+
+In the context of hold gestures, thumbs and palms are treated by libinput as
+if the finger was removed from the device. Where other non-thumb/non-palm
+fingers remain on the device, an **hold update** event is sent. Otherwise,
+the hold gesture terminates with a **hold cancel** event.
+
+Notably, libinput's thumb and palm detection is not a simple boolean per
+touch but specific to the state of that touch in the overall context. For
+example, a touch may be a thumb for tapping but not for clickfinger
+interactions. A caller must not infer the number of physical fingers from
+the hold gesture.
+
+Likewise, libinput may classify a finger as thumb in the same hardware event
+as a new finger is placed on the touchpad. In that case, the hold gesture
+**may** continue as one-finger gesture despite there being two physical
+touch points.
+
+Information to determine whether a touch is a thumb or a palm may not be
+available until some time into an interaction. Thus very short brushes
+of the touchpad by a palm may trigger a **hold begin** followed by an
+immediate **hold end** as libinput lacks sufficient information to identify
+the touch as thumb/palm and send the corresponding **hold cancel**
+event. A caller must not assume that a hold gesture always represents a
+valid finger down.
+
+Hold gestures and tap-to-click
+..............................
+
+:ref:`tapping` is the feature that enables short-lived touches to trigger
+button presses.
+
+.. warning:: Summary: do not use hold gestures to do your own tap-to-click
+ implementation
+
+In the context of hold gestures, tap-to-click cancels current hold gestures
+and a finger dragging (see :ref:`tapndrag`) does not begin a hold
+gesture. Where tap-to-click is disabled a tap-like gesture may create
+**hold begin** followed by a **hold end** event. Callers **must not** use
+hold gestures for their own tap-to-click implementation as the data is not
+reliable enough. libinput may change internal timeouts and thresholds
+depending on whether tap-to-click is enabled and the hold gesture event may
+not match touch sequences that a user would expect to be a tap-to-click
+interaction.