mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-03-24 16:00:40 +01:00
Co-Authored-by: Claude Code <noreply@anthropic.com> Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1452>
183 lines
9.1 KiB
ReStructuredText
183 lines
9.1 KiB
ReStructuredText
.. _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 more 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.
|