2015-07-29 15:05:52 +10:00
|
|
|
/**
|
|
|
|
|
@page 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.
|
|
|
|
|
|
2015-08-27 13:13:47 +10:00
|
|
|
@section ptraccel-profiles Pointer acceleration profiles
|
|
|
|
|
|
|
|
|
|
The profile decides the general method of pointer acceleration.
|
|
|
|
|
libinput currently supports two profiles: "adaptive" and "flat". The aptive
|
|
|
|
|
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). Most of this document
|
|
|
|
|
describes the adaptive pointer acceleration.
|
|
|
|
|
|
2015-07-29 15:05:52 +10:00
|
|
|
@section 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
|
|
|
|
|
|
|
|
|
|
@section 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.
|
|
|
|
|
|
|
|
|
|
@section 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.
|
|
|
|
|
|
|
|
|
|
@image html ptraccel-linear.svg "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.
|
|
|
|
|
|
|
|
|
|
@section 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).
|
|
|
|
|
|
|
|
|
|
@image html ptraccel-low-dpi.svg "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.
|
|
|
|
|
|
|
|
|
|
@section ptraccel-touchpad Pointer acceleration on touchpads
|
|
|
|
|
|
2016-12-19 12:18:42 +10:00
|
|
|
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.
|
2015-07-29 15:05:52 +10:00
|
|
|
|
|
|
|
|
@image html ptraccel-touchpad.svg "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.
|
|
|
|
|
|
|
|
|
|
@section ptraccel-trackpoint Pointer acceleration on trackpoints
|
|
|
|
|
|
2017-05-12 14:39:24 +10:00
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
libinput's pointer acceleration is a function of the total available
|
2017-11-29 12:47:25 +10:00
|
|
|
pressure range on a device. See @ref trackpoint_range for details.
|
2017-05-12 14:39:24 +10:00
|
|
|
|
2017-11-29 12:47:25 +10:00
|
|
|
libinput relies on some system-wide configured properties, specifically the
|
|
|
|
|
@ref udev_config. The property that influences trackpoint acceleration is
|
|
|
|
|
`LIBINPUT_ATTR_TRACKPOINT_RANGE` which specifies the total delta range for
|
|
|
|
|
the trackpoint. See @ref trackpoint_range for details.
|
2016-11-03 14:01:17 +10:00
|
|
|
|
|
|
|
|
Additionally, some trackpoints provide the ability to adjust the sensitivity in
|
|
|
|
|
hardware by modifying a sysfs file on the serio node. The udev property
|
2017-11-29 12:47:25 +10:00
|
|
|
`POINTINGSTICK_SENSITIVITY` indicates the desired value, a udev
|
2016-11-03 14:01:17 +10:00
|
|
|
builtin is expected to apply this to the device, i.e. libinput does not
|
|
|
|
|
handle this property. Once applied, the sensitivity adjusts the deltas
|
2017-11-29 12:47:25 +10:00
|
|
|
coming out of the hardware. When the sensitivity changes, the trackpoint
|
|
|
|
|
range changes and thus the `LIBINPUT_ATTR_TRACKPOINT_RANGE` property
|
|
|
|
|
becomes invalid.
|
|
|
|
|
|
|
|
|
|
As of version 1.9, libinput does not parse the `POINTINGSTICK_CONST_ACCEL` property anymore.
|
2016-11-03 14:01:17 +10:00
|
|
|
|
2015-07-29 15:05:52 +10:00
|
|
|
@image html ptraccel-trackpoint.svg "Pointer acceleration curves for trackpoints"
|
|
|
|
|
|
2018-05-11 11:48:56 +10:00
|
|
|
The image above shows the trackpoint acceleration profile for each input
|
|
|
|
|
delta.
|
2015-07-29 15:05:52 +10:00
|
|
|
|
2015-08-27 13:13:47 +10:00
|
|
|
@section 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.
|
|
|
|
|
|
2016-01-06 15:26:49 +10:00
|
|
|
@section ptraccel-tablet Pointer acceleration on tablets
|
|
|
|
|
|
|
|
|
|
Pointer acceleration for relative motion on tablet devices is a flat
|
2018-05-11 15:14:27 +10:00
|
|
|
acceleration, with the speed setting slowing down or speeding up the pointer
|
2016-01-06 15:26:49 +10:00
|
|
|
motion by a constant factor. Tablets do not allow for switchable profiles.
|
|
|
|
|
|
2017-06-14 12:10:51 +10:00
|
|
|
@section ptraccel-device-speed Speed-dependent acceleration curve
|
|
|
|
|
|
|
|
|
|
When the @ref LIBINPUT_CONFIG_ACCEL_PROFILE_DEVICE_SPEED_CURVE profile is
|
|
|
|
|
selected, it is the caller's responsibility to load an acceleration profile
|
|
|
|
|
into the device that maps the device's movement into an accelerated
|
|
|
|
|
movement.
|
|
|
|
|
|
|
|
|
|
This profile maps input speed in **device units** to an acceleration
|
|
|
|
|
factor. libinput calculates the device's speed based on the deltas and their
|
|
|
|
|
timestamps and applies the factor provided by the acceleration profile to
|
|
|
|
|
the current delta.
|
|
|
|
|
|
|
|
|
|
@note This profile uses data in device units, an acceleration curve loaded
|
|
|
|
|
by the caller only applies to that device and will not behave the same way
|
|
|
|
|
for other devices.
|
|
|
|
|
|
|
|
|
|
@dot
|
|
|
|
|
digraph
|
|
|
|
|
{
|
|
|
|
|
rankdir="LR";
|
|
|
|
|
node [shape="box";]
|
|
|
|
|
subgraph cluster0 {
|
|
|
|
|
history[shape=record,label="<f0> delta(t-1)|<f1> delta(t-2)|<f2> delta(t-3)| <f3> ..."];
|
|
|
|
|
label = "motion history";
|
|
|
|
|
}
|
|
|
|
|
delta[label="delta"];
|
|
|
|
|
velocity[shape="ellipse"];
|
|
|
|
|
factor[shape="ellipse"];
|
|
|
|
|
accel[label="accelerated delta"];
|
|
|
|
|
curve[label="acceleration curve"];
|
|
|
|
|
|
|
|
|
|
delta->velocity;
|
|
|
|
|
delta->factor;
|
|
|
|
|
factor->accel;
|
|
|
|
|
history->velocity;
|
|
|
|
|
|
|
|
|
|
velocity->curve;
|
|
|
|
|
curve->factor;
|
|
|
|
|
}
|
|
|
|
|
@enddot
|
|
|
|
|
|
|
|
|
|
For example, assume the current delta is (2, 4) which maps to a current
|
|
|
|
|
movement velocity of 10 units per microsecond. libinput looks up the custom
|
|
|
|
|
acceleration function for 10 which may return 3. The accelerated delta thus
|
|
|
|
|
becomes (6, 12).
|
|
|
|
|
|
|
|
|
|
The profile itself is a curve defined by a number of points on the curve
|
|
|
|
|
mapping speed to an acceleration factor. Between each two curve points,
|
|
|
|
|
libinput provides linear interpolation, most acceleration profiles will thus
|
|
|
|
|
only need to provide a handful of curve points. The following illustration
|
|
|
|
|
shows the acceleration curve defined for the points (10, 0.25), (20, 0.4)
|
|
|
|
|
and (35, 3.0).
|
|
|
|
|
|
|
|
|
|
@image html ptraccel-curve-example.svg "Interpolation of the acceleration curve for three defined points"
|
|
|
|
|
|
|
|
|
|
As seen in the picture above: given an acceleration factor f(x) and a curve
|
|
|
|
|
defined by the caller for the points
|
|
|
|
|
a, b, and c where a < b < c:
|
|
|
|
|
- if x <= a, f(x) == f(a)
|
|
|
|
|
- if x >= c, f(x) == f(c)
|
|
|
|
|
- if a < x < b: f(x) == the the linear interpolation value between f(a) and f(b)
|
|
|
|
|
- if b < x < c: f(x) == the the linear interpolation value between f(b) and f(c)
|
|
|
|
|
|
|
|
|
|
The behavior of a a curve is implementation-defined until the caller sets
|
|
|
|
|
curve points.
|
|
|
|
|
|
2015-07-29 15:05:52 +10:00
|
|
|
*/
|