mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-21 15:30:07 +01:00
filter: avoid division-by-zero when delta_time is zero in custom filter
delta_time can be zero when: - the fallback acceleration function is used for multiple movement types (for example, pointer motion and wheel scrolling simultaneously) - two different methods produce the same movement at the same time (for example, button-scrolling and wheel-scrolling) Reusing the last delta_time is a graceful fallback even if there are duplicate events or event-ordering bugs. Signed-off-by: Yinon Burgansky <yinonburgansky@gmail.com> Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1336>
This commit is contained in:
parent
94b7836456
commit
cc7dfccd22
1 changed files with 18 additions and 4 deletions
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
struct custom_accel_function {
|
struct custom_accel_function {
|
||||||
uint64_t last_time;
|
uint64_t last_time;
|
||||||
|
uint64_t last_delta_time;
|
||||||
double step;
|
double step;
|
||||||
size_t npoints;
|
size_t npoints;
|
||||||
double points[];
|
double points[];
|
||||||
|
|
@ -58,6 +59,7 @@ create_custom_accel_function(double step, const double *points, size_t npoints)
|
||||||
struct custom_accel_function *cf =
|
struct custom_accel_function *cf =
|
||||||
zalloc(sizeof(*cf) + npoints * sizeof(*points));
|
zalloc(sizeof(*cf) + npoints * sizeof(*points));
|
||||||
cf->last_time = 0;
|
cf->last_time = 0;
|
||||||
|
cf->last_delta_time = FIRST_MOTION_TIME_INTERVAL;
|
||||||
cf->step = step;
|
cf->step = step;
|
||||||
cf->npoints = npoints;
|
cf->npoints = npoints;
|
||||||
memcpy(cf->points, points, sizeof(*points) * npoints);
|
memcpy(cf->points, points, sizeof(*points) * npoints);
|
||||||
|
|
@ -110,13 +112,25 @@ custom_accel_function_calculate_speed(struct custom_accel_function *cf,
|
||||||
|
|
||||||
/* calculate speed based on time passed since last event */
|
/* calculate speed based on time passed since last event */
|
||||||
double distance = hypot(unaccelerated->x, unaccelerated->y);
|
double distance = hypot(unaccelerated->x, unaccelerated->y);
|
||||||
|
/* delta_time can be zero when:
|
||||||
|
* - the fallback acceleration function is used for multiple movement types
|
||||||
|
* (for example, pointer motion and wheel scrolling simultaneously)
|
||||||
|
* - two different methods produce the same movement at the same time
|
||||||
|
* (for example, button-scrolling and wheel-scrolling)
|
||||||
|
*
|
||||||
|
* Reusing the last delta_time is a graceful fallback even if there are
|
||||||
|
* duplicate events or event-ordering bugs.
|
||||||
|
*/
|
||||||
|
uint64_t delta_time =
|
||||||
|
(time > cf->last_time) ? time - cf->last_time : cf->last_delta_time;
|
||||||
/* handle first event in a motion */
|
/* handle first event in a motion */
|
||||||
if (time - cf->last_time > MOTION_TIMEOUT)
|
if (delta_time > MOTION_TIMEOUT)
|
||||||
cf->last_time = time - FIRST_MOTION_TIME_INTERVAL;
|
delta_time = FIRST_MOTION_TIME_INTERVAL;
|
||||||
|
|
||||||
double dt = us2ms_f(time - cf->last_time);
|
/* speed is in device-units per ms */
|
||||||
double speed = distance / dt; /* speed is in device-units per ms */
|
double speed = distance / us2ms_f(delta_time);
|
||||||
cf->last_time = time;
|
cf->last_time = time;
|
||||||
|
cf->last_delta_time = delta_time;
|
||||||
|
|
||||||
return speed;
|
return speed;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue