summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2018-11-22 10:24:54 +1000
committerJosé Expósito <jose.exposito89@gmail.com>2021-08-31 08:45:01 +0200
commit6bb02aaf307a38e60ec8e6b2198d8e0c30d59a95 (patch)
tree0078abc6aa906a55afbee130e49ca5baca619604 /doc
parent427c855d21b442620bf6472c2a0585ddca9673e0 (diff)
downloadlibinput-6bb02aaf307a38e60ec8e6b2198d8e0c30d59a95.tar.gz
High-resolution scroll wheel support
Starting with kernel v5.0 two new axes are available for high-resolution wheel scrolling: REL_WHEEL_HI_RES and REL_HWHEEL_HI_RES. Both axes send data in fractions of 120 where each multiple of 120 amounts to one logical scroll event. Fractions of 120 indicate a wheel movement less than one detent. This commit adds a new API for scroll events. Three new event types that encode the axis source in the event type name and a new API to get a normalized-to-120 value that also used by Windows and the kernel (each multiple of 120 represents a logical scroll click). This addresses a main shortcoming with the existing API - it was unreliable to calculate the click angle based on the axis value+discrete events and thus any caller using the axis value alone would be left with some ambiguity. With the v120 API it's now possible to (usually) calculate the click angle, but more importantly it provides the simplest hw-independent way of scrolling by a click or a fraction of a click. A new event type is required, the only way to integrate the v120 value otherwise was to start sending events with a discrete value of 0. This would break existing xf86-input-libinput (divide by zero, fixed in 0.28.2) and weston (general confusion). mutter, kwin are unaffected. With the new API, the old POINTER_AXIS event are deprecated - callers should use the new API where available and discard any POINTER_AXIS events. Notable: REL_WHEEL/REL_HWHEEL are emulated by the kernel but there's no guarantee that they'll come every accumulated 120 values, e.g. Logitech mice often send events that don't add up to 120 per detent. We use the kernel's wheel click emulation instead of doing our own. libinput guarantees high-resolution events even on pre-5.0 kernels. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: José Expósito <jose.exposito89@gmail.com>
Diffstat (limited to 'doc')
-rw-r--r--doc/user/development.rst1
-rw-r--r--doc/user/meson.build1
-rw-r--r--doc/user/scrolling.rst3
-rw-r--r--doc/user/wheel-api.rst183
4 files changed, 188 insertions, 0 deletions
diff --git a/doc/user/development.rst b/doc/user/development.rst
index b96d3654..4b7e4a0d 100644
--- a/doc/user/development.rst
+++ b/doc/user/development.rst
@@ -36,6 +36,7 @@ Topics below explain some behaviors of libinput.
normalization-of-relative-motion.rst
seats.rst
timestamps.rst
+ wheel-api.rst
.. _hacking_on_libinput:
diff --git a/doc/user/meson.build b/doc/user/meson.build
index 8d2714b2..332f67b9 100644
--- a/doc/user/meson.build
+++ b/doc/user/meson.build
@@ -167,6 +167,7 @@ src_rst = files(
'trackpoints.rst',
'trackpoint-configuration.rst',
'what-is-libinput.rst',
+ 'wheel-api.rst',
'features.rst',
'development.rst',
'troubleshooting.rst',
diff --git a/doc/user/scrolling.rst b/doc/user/scrolling.rst
index 82b88768..e568755d 100644
--- a/doc/user/scrolling.rst
+++ b/doc/user/scrolling.rst
@@ -130,6 +130,9 @@ button is logically held down, motion events are converted to scroll events.
Scroll sources
------------------------------------------------------------------------------
+.. note:: Scroll sources are deprecated with libinput 1.19. The scroll
+ source is now encoded in the event type.
+
libinput provides a pointer axis *source* for each scroll event. The
source can be obtained with the **libinput_event_pointer_get_axis_source()**
function and is one of **wheel**, **finger**, or **continuous**. The source
diff --git a/doc/user/wheel-api.rst b/doc/user/wheel-api.rst
new file mode 100644
index 00000000..e488a65a
--- /dev/null
+++ b/doc/user/wheel-api.rst
@@ -0,0 +1,183 @@
+.. _wheel_scrolling:
+
+==============================================================================
+Wheel scrolling
+==============================================================================
+
+libinput provides two events to handle wheel scrolling:
+
+- ``LIBINPUT_EVENT_POINTER_AXIS`` events are sent for regular wheel clicks,
+ usually those representing one detent on the device. These wheel clicks
+ usually require a rotation of 15 or 20 degrees.
+ **This event is deprecated as of libinput 1.19.**
+
+- ``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL`` events are sent for regular and/or
+ high resolution wheel movements. High-resolution events are often 4 or 8
+ times more frequent than wheel clicks and require the device to be switched
+ into high-resolution mode (Linux kernel 5.0 and later). Where
+ high-resolution wheels are not provided by the kernel, libinput emulates
+ these events for regular wheel clicks.
+ **This event is available since libinput 1.19.**
+
+The events are separate for historical reasons. Both events are
+generated for the same device but are independent event streams. Callers
+must not assume any relation between the two, i.e. there is no guarantee
+that an axis event is sent before or after any specific high-resolution
+event and vice versa. Callers should not handle both events.
+
+.. warning:: do not handle both ``LIBINPUT_EVENT_POINTER_AXIS`` and
+ ``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL``. Always use the latter where
+ possible, otherwise only use the former.
+
+Both events have their own set of APIs to access the data within:
+
+- ``LIBINPUT_EVENT_POINTER_AXIS``: Deprecated as of libinput 1.19, where
+ possible it is recommended to handle **only**
+ ``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL``.
+
+ * ``libinput_event_pointer_get_axis_value()`` returns the angle of movement
+ in degrees.
+ * ``libinput_event_pointer_get_axis_source()`` returns the source of the
+ event: wheel, finger or continuous.
+ * ``libinput_event_pointer_get_axis_value_discrete()`` returns the number of
+ logical wheel clicks.
+
+- ``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL`` available since libinput 1.19.
+
+ * ``libinput_event_pointer_get_scroll_value_v120()`` returns a value
+ normalized into the 0..120 range, see below. Any multiple of 120 should
+ be treated as one full wheel click.
+
+.. note:: Where possible, the ``libinput_event_pointer_get_axis_value()``,
+ ``libinput_event_pointer_get_axis_source()`` and
+ ``libinput_event_pointer_get_axis_value_discrete()`` API should be
+ avoided.
+
+------------------------------------------------------------------------------
+The v120 Wheel API
+------------------------------------------------------------------------------
+
+The ``v120`` value matches the Windows API for wheel scrolling. Wheel
+movements are normalized into multiples (or fractions) of 120 with each
+multiple of 120 representing one detent of movement. The ``v120`` API is the
+recommended API for callers that do not care about the exact physical
+motion and is the simplest API to handle high-resolution scrolling.
+
+Most wheels provide 24 detents per 360 degree rotation (click angle of 15),
+others provide 18 detents per 360 degree rotation (click angle 20). Mice
+falling outside these two are rare but do exist. Below is a table showing
+the various values for a single event, depending on the click angle of the
+wheel:
+
++-------------+------------+---------------+------+
+| Click angle | Axis value | Discrete value| v120 |
++=============+============+===============+======+
+| 15 | 15 | 1 | 120 |
++-------------+------------+---------------+------+
+| 20 | 20 | 1 | 120 |
++-------------+------------+---------------+------+
+
+Fast scrolling may trigger cover than one detent per event and thus each
+event may contain multiples of the value, discrete or v120 value:
+
++-------------+------------+---------------+------+
+| Click angle | Axis value | Discrete value| v120 |
++=============+============+===============+======+
+| 15 | 30 | 2 | 240 |
++-------------+------------+---------------+------+
+| 20 | 60 | 3 | 360 |
++-------------+------------+---------------+------+
+
+Scrolling on high-resolution wheels will produce fractions of 120, depending
+on the resolution of the wheel. The example below shows a mouse with click
+angle 15 and a resolution of 3 events per wheel click and a mouse with click
+angle 20 and a resolution of 2 events per wheel click.
+
++-------------+------------+---------------+------+
+| Click angle | Axis value | Discrete value| v120 |
++=============+============+===============+======+
+| 15 | 5 | 0 | 40 |
++-------------+------------+---------------+------+
+| 20 | 10 | 0 | 60 |
++-------------+------------+---------------+------+
+
+------------------------------------------------------------------------------
+Event sequences for high-resolution wheel mice
+------------------------------------------------------------------------------
+
+High-resolution scroll wheels provide multiple events for each detent is
+hit. For those mice, an event sequence covering two detents may look like
+this:
+
++--------------+---------+------------+---------------+------+
+| Event number | Type | Axis value | Discrete value| v120 |
++==============+=========+============+===============+======+
+| 1 | WHEEL | 5 | n/a | 40 |
++--------------+---------+------------+---------------+------+
+| 2 | WHEEL | 5 | n/a | 40 |
++--------------+---------+------------+---------------+------+
+| 3 | WHEEL | 5 | n/a | 40 |
++--------------+---------+------------+---------------+------+
+| 4 | AXIS | 15 | 1 | 120 |
++--------------+---------+------------+---------------+------+
+| 5 | WHEEL | 5 | n/a | 40 |
++--------------+---------+------------+---------------+------+
+| 6 | WHEEL | 5 | n/a | 40 |
++--------------+---------+------------+---------------+------+
+| 7 | AXIS | 15 | 1 | 120 |
++--------------+---------+------------+---------------+------+
+
+The above assumes a click angle of 15 for the physical detents. Note how the
+second set of high-resolution events do **not** add up to a multiple of
+120 before the low-resolution event. A caller must not assume any relation
+between ``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL`` and
+``LIBINPUT_EVENT_POINTER_AXIS``.
+
+Fast-scrolling on a high-resolution mouse may trigger multiple fractions per
+hardware scanout cycle and result in an event sequence like this:
+
++---------------+---------+------------+---------------+------+
+| Event number | Type | Axis value | Discrete value| v120 |
++===============+=========+============+===============+======+
+| 1 | WHEEL | 5 | n/a | 40 |
++---------------+---------+------------+---------------+------+
+| 2 | WHEEL | 10 | n/a | 80 |
++---------------+---------+------------+---------------+------+
+| 3 | AXIS | 15 | 1 | 120 |
++---------------+---------+------------+---------------+------+
+| 4 | WHEEL | 10 | n/a | 80 |
++---------------+---------+------------+---------------+------+
+| 5 | WHEEL | 10 | n/a | 80 |
++---------------+---------+------------+---------------+------+
+| 6 | AXIS | 15 | 1 | 120 |
++---------------+---------+------------+---------------+------+
+| 7 | WHEEL | 5 | n/a | 40 |
++---------------+---------+------------+---------------+------+
+
+Note how the first low-resolution event is sent at an accumulated 15
+degrees, the second at an accumulated 20 degrees. The libinput API does not
+specify the smallest fraction a wheel supports.
+
+------------------------------------------------------------------------------
+Event sequences for regular wheel mice
+------------------------------------------------------------------------------
+
+``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL`` for low-resolution mice are virtually
+identical to ``LIBINPUT_EVENT_POINTER_AXIS`` events. Note that the discrete
+value is always 0 for ``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL``.
+
++--------------+---------+------------+---------------+------+
+| Event number | Type | Axis value | Discrete value| v120 |
++==============+=========+============+===============+======+
+| 1 | AXIS | 15 | 1 | 120 |
++--------------+---------+------------+---------------+------+
+| 2 | WHEEL | 15 | n/a | 120 |
++--------------+---------+------------+---------------+------+
+| 3 | WHEEL | 15 | n/a | 120 |
++--------------+---------+------------+---------------+------+
+| 4 | AXIS | 15 | 1 | 120 |
++--------------+---------+------------+---------------+------+
+
+Note that the order of ``LIBINPUT_EVENT_POINTER_AXIS`` vs
+``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL`` events is not guaranteed, as shown in
+the example above.