[PATCH libinput] Add pointer axis sequences and ability to cancel scrolls

Peter Hutterer peter.hutterer at who-t.net
Thu Jan 19 05:14:55 UTC 2017

[This is an RFC to add axis sequence support to the pointer axis events.
The specific use-case in bug 99415 is to be able to stop kinetic scrolling
when two fingers are put down on the touchpad again (even without moving).]

Pointer axis events (aka scroll events) can have information about when the
interaction terminated (by sending 0/0 axis events). This is insufficient for
detecting the start of a scroll sequence.

This patch introduces a new LIBINPUT_EVENT_POINTER_AXIS_START event type to
send notification that a scroll sequence has started. For symmetry, it also
adds a LIBINPUT_EVENT_POINTER_AXIS_STOP event even though the actual
information is already provided by libinput (at least for current axes and
current scroll sources. New axes/sources introduced in the future may behave
differently, oh how exciting).

Adding proper scroll sequences lends itself to also introducing a cancel event
so we can start scroll sequences and subsequently cancel them. This should
make things more reactive when we have to decide between gesture vs scroll,
though the implementation may be tricky.

Another thing here:
- we have event types down/motion/up and cancel
- gestures only have begin/update/end, the cancel is a property of the
  "end" event

I can't quite remember *why* we did it differently. It's probably in the
archives but I couldn't find it. Either way, Carlos, which one is
more useful for a caller?

Ok, now that I'm re-reading the above it should not be "start" and "stop"
but rather "begin" and "end". But now I'm too lazy to run sed over the lot :)

 doc/scrolling.dox | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/libinput.h    |  3 +++
 2 files changed, 62 insertions(+)

diff --git a/doc/scrolling.dox b/doc/scrolling.dox
index 0c03c98..87b7742 100644
--- a/doc/scrolling.dox
+++ b/doc/scrolling.dox
@@ -103,4 +103,63 @@ See the libinput_event_pointer_get_axis_source() for details on the
 behavior of each scroll source.
 See also http://who-t.blogspot.com.au/2015/03/libinput-scroll-sources.html
+ at section scroll_sequences Scroll sequences
+On some devices, libinput is able to detect pointer axis events as sequences
+with a distinct start and stop interaction. For example, finger-based
+scrolling on a touchpad has a clear start/stop action when the fingers are
+put down or released.
+For pointer axis sequences, libinput provides three types of events:
+- @ref LIBINPUT_EVENT_POINTER_AXIS_START (the "start" event), 
+- @ref LIBINPUT_EVENT_POINTER_AXIS_STOP (the "stop" event), and
+- @ref LIBINPUT_EVENT_POINTER_AXIS_CANCEL  (the "cancel" event, see @ref
+  scroll_sequences_cancel).
+In addition, the @ref LIBINPUT_EVENT_POINTER_AXIS (the "axis" event)
+contains the actual motion.
+The "start" event is sent at the start of the scroll intention is detected
+and before the first "axis" event. Any such sequence is terminated either by a
+"stop" event or a "cancel" event. One example for the use of such a sequence
+is to start a kinetic scroll motion based on the finger speed before the
+"stop" event. On the next "start" event, the caller may use this information
+to cancel any ongoing kinetic scroll motions.
+libinput does not guarantee that a "start" event is sent for a specific
+scroll interaction. For example, scroll wheels would not usually trigger a
+"start" event. If a "start" event is sent, libinput guarantees
+that the event sequence is terminated by a a "stop" or a "cancel" event.
+A "start" event does not guarantee that "axis" events follow.
+In some cases, the "start" event may be followed by a "stop" or a "cancel"
+event. Scroll sequences reflect user interaction, thus the time between any
+of the "start", "axis", "stop" and "cancel" events is arbitrary.
+Note that the "stop" event may be superfluous. The information that "this is
+a scroll stop" is also available in the last "axis" event as described in
+libinput_event_pointer_get_axis_source(). This is required for backwards
+compatiblility, callers should use the "stop" event instead. In the future,
+new pointer sources or new axes may only provide the "stop" event only.
+For an explanation on how to handle the "cancel" event, see @ref
+ at subsection scroll_sequences_cancel Cancelled scroll sequences
+In some cases, an interaction that appears like a scroll interaction at
+first may change and turn into a gesture instead. For example, a finger
+placement may look like a two-finger scroll motion at first but turn into a
+two-finger pinch instead.
+The @ref LIBINPUT_EVENT_POINTER_AXIS_CANCEL event signals the termination of
+a scroll sequence as described in @ref scroll_sequences but signals to the
+caller that the action performed during the scroll should be reverted.
+libinput does not guarantee when a "cancel" arrives in a sequence. A
+"cancel" event may only be sent during an ongoing scroll sequence (i.e.
+after a "start" event but before a "stop" event). If a "cancel" event is
+sent, no "stop" event is sent for this sequence.
diff --git a/src/libinput.h b/src/libinput.h
index 86bfeaf..5df9bc2 100644
--- a/src/libinput.h
+++ b/src/libinput.h
@@ -626,6 +626,9 @@ enum libinput_event_type {

More information about the wayland-devel mailing list