mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-03-22 17:20:39 +01:00
Replace pointer acceleration with a much simpler linear one
We ran a userstudy, evaluating three different accel methods. Detailed results are available at: http://www.who-t.net/publications/hutterer2014_libinput_ptraccel_study.pdf We found that there was little difference between the method we had in libinput 0.6 and this three-line function. Users didn't really notice a difference, but measured data suggests that it has slight advantages in some use-cases. The method proposed here is the one labeled "linear" in the paper, its profile looks roughly like this: _____________ / ____/ / / where the x axis is the speed, y is the acceleration factor. The first plateau is at the acceleration factor 1 (i.e. unaccelerated movement), the second plateau is at the max acceleration factor. The threshold in the code defines where and how long the plateau is. Differences to the previous accel function: - both inclines are linear rather than curved - the second incline is less steep than the current method From a maintainer's point-of-view, this function is significantly easier to understand and manipulate than the previous one. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
fa363ed0e8
commit
4913fd7a48
4 changed files with 15 additions and 45 deletions
|
|
@ -845,7 +845,7 @@ tp_init_accel(struct tp_dispatch *tp, double diagonal)
|
|||
}
|
||||
|
||||
accel = create_pointer_accelator_filter(
|
||||
pointer_accel_profile_smooth_simple);
|
||||
pointer_accel_profile_linear);
|
||||
if (accel == NULL)
|
||||
return -1;
|
||||
|
||||
|
|
|
|||
|
|
@ -865,7 +865,7 @@ configure_pointer_acceleration(struct evdev_device *device)
|
|||
{
|
||||
device->pointer.filter =
|
||||
create_pointer_accelator_filter(
|
||||
pointer_accel_profile_smooth_simple);
|
||||
pointer_accel_profile_linear);
|
||||
if (!device->pointer.filter)
|
||||
return -1;
|
||||
|
||||
|
|
|
|||
43
src/filter.c
43
src/filter.c
|
|
@ -270,41 +270,16 @@ calc_penumbral_gradient(double x)
|
|||
}
|
||||
|
||||
double
|
||||
pointer_accel_profile_smooth_simple(struct motion_filter *filter,
|
||||
void *data,
|
||||
double velocity, /* units/ms */
|
||||
uint64_t time)
|
||||
pointer_accel_profile_linear(struct motion_filter *filter,
|
||||
void *data,
|
||||
double speed_in,
|
||||
uint64_t time)
|
||||
{
|
||||
double threshold = DEFAULT_THRESHOLD; /* units/ms */
|
||||
double accel = DEFAULT_ACCELERATION; /* unitless factor */
|
||||
double smooth_accel_coefficient; /* unitless factor */
|
||||
double factor; /* unitless factor */
|
||||
double s1, s2;
|
||||
const int max_accel = DEFAULT_ACCELERATION;
|
||||
|
||||
if (threshold < 0.1)
|
||||
threshold = 0.1;
|
||||
if (accel < 1.0)
|
||||
accel = 1.0;
|
||||
s1 = min(1, speed_in * 5);
|
||||
s2 = 1 + (speed_in - DEFAULT_THRESHOLD) * 1.1;
|
||||
|
||||
/* We use units/ms as velocity but it has no real meaning unless all
|
||||
devices have the same resolution. For touchpads, we normalize to
|
||||
400dpi (15.75 units/mm), but the resolution on USB mice is all
|
||||
over the place. Though most mice these days have either 400
|
||||
dpi (15.75 units/mm), 800 dpi or 1000dpi, excluding gaming mice
|
||||
that can usually adjust it on the fly anyway and currently go up
|
||||
to 8200dpi.
|
||||
*/
|
||||
if (velocity < (threshold / 2.0))
|
||||
return calc_penumbral_gradient(0.5 + velocity / threshold) * 2.0 - 1.0;
|
||||
|
||||
if (velocity <= threshold)
|
||||
return 1.0;
|
||||
|
||||
factor = velocity/threshold;
|
||||
if (factor >= accel)
|
||||
return accel;
|
||||
|
||||
/* factor is between 1.0 and accel, scale this to 0.0 - 1.0 */
|
||||
factor = (factor - 1.0) / (accel - 1.0);
|
||||
smooth_accel_coefficient = calc_penumbral_gradient(factor);
|
||||
return 1.0 + (smooth_accel_coefficient * (accel - 1.0));
|
||||
return min(max_accel, s2 > 1 ? s2 : s1);
|
||||
}
|
||||
|
|
|
|||
13
src/filter.h
13
src/filter.h
|
|
@ -65,14 +65,9 @@ create_pointer_accelator_filter(accel_profile_func_t filter);
|
|||
* Pointer acceleration profiles.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Profile similar which is similar to nonaccelerated but with a smooth
|
||||
* transition between accelerated and non-accelerated.
|
||||
*/
|
||||
double
|
||||
pointer_accel_profile_smooth_simple(struct motion_filter *filter,
|
||||
void *data,
|
||||
double velocity,
|
||||
uint64_t time);
|
||||
|
||||
pointer_accel_profile_linear(struct motion_filter *filter,
|
||||
void *data,
|
||||
double speed_in,
|
||||
uint64_t time);
|
||||
#endif /* FILTER_H */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue