summaryrefslogtreecommitdiff
path: root/doc/user/pointer-acceleration.rst
blob: 1d60702a27c6911da2ce77a13cec91ed2d8310e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
.. _pointer-acceleration:

==============================================================================
 Pointer acceleration
==============================================================================

libinput uses device-specific pointer acceleration methods, with the default
being the :ref:`ptraccel-linear`. The methods share common properties, such as
:ref:`ptraccel-velocity`.

This page explains the high-level concepts used in the code. It aims to
provide an overview for developers and is not necessarily useful for
users.

.. _ptraccel-profiles:

------------------------------------------------------------------------------
Pointer acceleration profiles
------------------------------------------------------------------------------

The profile decides the general method of pointer acceleration.
libinput currently supports three profiles: **"adaptive"**, **"flat"** and
**custom**.

- The **adaptive** profile is the default profile for all devices and takes the
  current speed of the device into account when deciding on acceleration.
- The **flat** profile is simply a constant factor applied to all device deltas,
  regardless of the speed of motion (see :ref:`ptraccel-profile-flat`).
- The **custom** profile allows the user to define a custom acceleration
  function, giving full control over accelerations behavior at different speed
  (see :ref:`ptraccel-profile-custom`).

Most of this document describes the adaptive pointer acceleration.

.. _ptraccel-velocity:

------------------------------------------------------------------------------
Velocity calculation
------------------------------------------------------------------------------

The device's speed of movement is measured across multiple input events
through so-called "trackers". Each event prepends a the tracker item, each
subsequent tracker contains the delta of that item to the current position,
the timestamp of the event that created it and the cardinal direction of the
movement at the time. If a device moves into the same direction, the
velocity is calculated across multiple trackers. For example, if a device
moves steadily for 10 events to the left, the velocity is calculated across
all 10 events.

Whenever the movement changes direction or significantly changes speed, the
velocity is calculated from the direction/speed change only. For example, if
a device moves steadily for 8 events to the left and then 2 events to the
right, the velocity is only that of the last 2 events.

An extra time limit prevents events that are too old to factor into the
velocity calculation. For example, if a device moves steadily for 5 events
to the left, then pauses, then moves again for 5 events to the left, only
the last 5 events are used for velocity calculation.

The velocity is then used to calculate the acceleration factor

.. _ptraccel-factor:

------------------------------------------------------------------------------
Acceleration factor
------------------------------------------------------------------------------

The acceleration factor is the final outcome of the pointer acceleration
calculations. It is a unitless factor that is applied to the current delta,
a factor of 2 doubles the delta (i.e. speeds up the movement), a factor of
less than 1 reduces the delta (i.e. slows the movement).

Any factor less than 1 requires the user to move the device further to move
the visible pointer. This is called deceleration and enables high precision
target selection through subpixel movements. libinput's current maximum
deceleration factor is 0.3 (i.e. slow down to 30% of the pointer speed).

A factor higher than 1 moves the pointer further than the physical device
moves. This is acceleration and allows a user to cross the screen quickly
but effectively skips pixels. libinput's current maximum acceleration factor
is 3.5.

.. _ptraccel-linear:

------------------------------------------------------------------------------
Linear pointer acceleration
------------------------------------------------------------------------------

The linear pointer acceleration method is the default for most pointer
devices. It provides deceleration at very slow movements, a 1:1 mapping for
regular movements and a linear increase to the maximum acceleration factor
for fast movements.

Linear pointer acceleration applies to devices with above 1000dpi resolution
and after :ref:`motion_normalization` is applied.

.. figure:: ptraccel-linear.svg
    :align: center

    Linear pointer acceleration

The image above shows the linear pointer acceleration settings at various
speeds. The line for 0.0 is the default acceleration curve, speed settings
above 0.0 accelerate sooner, faster and to a higher maximum acceleration.
Speed settings below 0 delay when acceleration kicks in, how soon the
maximum acceleration is reached and the maximum acceleration factor.

Extremely low speed settings provide no acceleration and additionally
decelerate all movement by a constant factor.

.. _ptraccel-low-dpi:

------------------------------------------------------------------------------
Pointer acceleration for low-dpi devices
------------------------------------------------------------------------------

Low-dpi devices are those with a physical resolution of less than 1000 dots
per inch (dpi). The pointer acceleration is adjusted to provide roughly the
same feel for all devices at normal to high speeds. At slow speeds, the
pointer acceleration works on device-units rather than normalized
coordinates (see :ref:`motion_normalization`).

.. figure:: ptraccel-low-dpi.svg
    :align: center

    Pointer acceleration for low-dpi devices

The image above shows the default pointer acceleration curve for a speed of
0.0 at different DPI settings. A device with low DPI has the acceleration
applied sooner and with a stronger acceleration factor.

.. _ptraccel-touchpad:

------------------------------------------------------------------------------
Pointer acceleration on touchpads
------------------------------------------------------------------------------

Touchpad pointer acceleration uses the same approach as the
:ref:`ptraccel-linear` profile, with a constant deceleration factor applied. The
user expectation of how much a pointer should move in response to finger
movement is different to that of a mouse device, hence the constant
deceleration factor.

.. figure:: ptraccel-touchpad.svg
    :align: center

    Pointer acceleration curve for touchpads

The image above shows the touchpad acceleration profile in comparison to the
:ref:`ptraccel-linear`. The shape of the curve is identical but vertically squashed.

.. _ptraccel-trackpoint:

------------------------------------------------------------------------------
Pointer acceleration on trackpoints
------------------------------------------------------------------------------

The main difference between trackpoint hardware and mice or touchpads is
that trackpoint speed is a function of pressure rather than moving speed.
But trackpoint hardware is quite varied in how it reacts to user pressure
and unlike other devices it cannot easily be normalized for physical
properties. Measuring pressure objectively across a variety of hardware is
nontrivial. See :ref:`trackpoints` for more details.

The deltas for trackpoints are converted units/ms but there is no common
physical reference point for a unit. Thus, the same pressure on different
trackpoints will generate different speeds and thus different acceleration
behaviors. Additionally, some trackpoints provide the ability to adjust the
sensitivity in hardware by modifying a sysfs file on the serio node. A
higher sensitivity results in higher deltas, thus changing the definition of
what is a unit again.

libinput attempts to normalize unit data to the best of its abilities, see
:ref:`trackpoint_multiplier`. Beyond this, it is not possible to have
consistent behavior across different touchpad devices.

.. figure:: ptraccel-trackpoint.svg
    :align: center

    Pointer acceleration curves for trackpoints

The image above shows the trackpoint acceleration profile for the speed in
units/ms.

.. _ptraccel-profile-flat:

------------------------------------------------------------------------------
The flat pointer acceleration profile
------------------------------------------------------------------------------

In a flat profile, the acceleration factor is constant regardless of the
velocity of the pointer and each delta (dx, dy) results in an accelerated delta
(dx * factor, dy * factor). This provides 1:1 movement between the device
and the pointer on-screen.

.. _ptraccel-tablet:

------------------------------------------------------------------------------
Pointer acceleration on tablets
------------------------------------------------------------------------------

Pointer acceleration for relative motion on tablet devices is a flat
acceleration, with the speed setting slowing down or speeding up the pointer
motion by a constant factor. Tablets do not allow for switchable profiles.

.. _ptraccel-profile-custom:

------------------------------------------------------------------------------
The custom acceleration profile
------------------------------------------------------------------------------

libinput supports a user-defined custom acceleration profile, which can be
adjusted for different movement types supported by a device. Movement types
include pointer movement, scrolling, etc. but the set of supported
movement types depends on the device.

The custom pointer acceleration profile gives users full control over the
acceleration behavior at different speeds. libinput exposes
an acceleration function ``f(x)`` where the x axis is the device speed in
device units per millisecond and the y axis is the pointer speed. By
supplying the y axis values for this function, users can control the
behavior of the device.

The user should take into account the native device dpi and screen dpi in
order to achieve the desired behavior/feel.

The custom acceleration function is defined using ``n`` points which are spaced
uniformly along the x axis, starting from 0 and continuing in constant steps.
At least two points must be defined and there is an implementation-defined
limit on how many points may be added.

Thus the points defining the custom function are:
``(0 * step, f[0]), (1 * step, f[1]), ..., ((n-1) * step, f[n-1])``
where ``f`` is a list of ``n`` unitless values defining the acceleration
factor for each velocity.
When a velocity value does not lie exactly on those points, a linear
interpolation of the two closest points will be calculated.
When a velocity value is greater than the max point defined, a linear
extrapolation of the two biggest points will be calculated.

An example is the curve of ``0.0, 1.0`` with a step of ``1.0``. This curve
is the equivalent of the flat acceleration profile with any input speed `N`
mapped to the same pointer speed `N`. The curve `1.0, 1.0` neutralizes
any input speed differences and results in a fixed pointer speed.

Supported Movement types:

+---------------+---------------------------------+----------------------+
| Movement type | Uses                            | supported by         |
+===============+=================================+======================+
| Fallback      | Catch-all default movement type | All devices          |
+---------------+---------------------------------+----------------------+
| Motion        | Used for pointer motion         | All devices          |
+---------------+---------------------------------+----------------------+

If a user does not provide the fallback custom acceleration function, a
flat acceleration function is used, i.e. no acceleration.

The fallback acceleration may be used for different types of movements, it is
strongly recommended that this acceleration function is a constant function.

For example, a physical mouse usually has two movement types: pointer
movement and scroll (wheel) movement. As there is no separate movement
type for scroll yet, scroll movement is be accelerated using the Fallback
acceleration function. Pointer movements is accelerated using the Motion
acceleration function. If no Motion acceleration function is set, the
Fallback acceleration function is used.

When using custom acceleration profile, any calls to set the speed have no
effect on the behavior of the custom acceleration function, but any future calls to
get the speed will reflect the requested speed setting.