mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-25 04:40:05 +01:00
Merge branch 'wip/touchpad-hysteresis-issues-v2'
This commit is contained in:
commit
aaded3d01d
5 changed files with 55 additions and 5 deletions
|
|
@ -131,6 +131,21 @@ tp_motion_history_push(struct tp_touch *t)
|
|||
t->history.index = motion_index;
|
||||
}
|
||||
|
||||
static inline void
|
||||
tp_maybe_disable_hysteresis(struct tp_dispatch *tp, uint64_t time)
|
||||
{
|
||||
/* If the finger is down for 80ms without seeing motion events,
|
||||
the firmware filters and we don't need a software hysteresis */
|
||||
if (time - tp->hysteresis.last_motion_time > ms2us(80)) {
|
||||
tp->hysteresis.enabled = false;
|
||||
evdev_log_debug(tp->device, "hysteresis disabled\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (tp->queued & TOUCHPAD_EVENT_MOTION)
|
||||
tp->hysteresis.last_motion_time = time;
|
||||
}
|
||||
|
||||
static inline void
|
||||
tp_motion_hysteresis(struct tp_dispatch *tp,
|
||||
struct tp_touch *t)
|
||||
|
|
@ -138,15 +153,18 @@ tp_motion_hysteresis(struct tp_dispatch *tp,
|
|||
int x = t->point.x,
|
||||
y = t->point.y;
|
||||
|
||||
if (!tp->hysteresis.enabled)
|
||||
return;
|
||||
|
||||
if (t->history.count == 0) {
|
||||
t->hysteresis_center = t->point;
|
||||
} else {
|
||||
x = evdev_hysteresis(x,
|
||||
t->hysteresis_center.x,
|
||||
tp->hysteresis_margin.x);
|
||||
tp->hysteresis.margin.x);
|
||||
y = evdev_hysteresis(y,
|
||||
t->hysteresis_center.y,
|
||||
tp->hysteresis_margin.y);
|
||||
tp->hysteresis.margin.y);
|
||||
t->hysteresis_center.x = x;
|
||||
t->hysteresis_center.y = y;
|
||||
t->point.x = x;
|
||||
|
|
@ -273,6 +291,7 @@ tp_begin_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
|||
t->thumb.first_touch_time = time;
|
||||
t->tap.is_thumb = false;
|
||||
assert(tp->nfingers_down >= 1);
|
||||
tp->hysteresis.last_motion_time = time;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1526,6 +1545,9 @@ static void
|
|||
tp_handle_state(struct tp_dispatch *tp,
|
||||
uint64_t time)
|
||||
{
|
||||
if (tp->hysteresis.enabled)
|
||||
tp_maybe_disable_hysteresis(tp, time);
|
||||
|
||||
tp_process_state(tp, time);
|
||||
tp_post_events(tp, time);
|
||||
tp_post_process_state(tp, time);
|
||||
|
|
@ -2912,8 +2934,9 @@ tp_init_hysteresis(struct tp_dispatch *tp)
|
|||
|
||||
res_x = tp->device->abs.absinfo_x->resolution;
|
||||
res_y = tp->device->abs.absinfo_y->resolution;
|
||||
tp->hysteresis_margin.x = res_x/2;
|
||||
tp->hysteresis_margin.y = res_y/2;
|
||||
tp->hysteresis.margin.x = res_x/2;
|
||||
tp->hysteresis.margin.y = res_y/2;
|
||||
tp->hysteresis.enabled = true;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -269,7 +269,12 @@ struct tp_dispatch {
|
|||
double orientation_to_angle;
|
||||
} touch_size;
|
||||
|
||||
struct device_coords hysteresis_margin;
|
||||
struct {
|
||||
bool enabled;
|
||||
struct device_coords margin;
|
||||
unsigned int other_event_count;
|
||||
uint64_t last_motion_time;
|
||||
} hysteresis;
|
||||
|
||||
struct {
|
||||
double x_scale_coeff;
|
||||
|
|
|
|||
13
src/evdev.h
13
src/evdev.h
|
|
@ -610,6 +610,19 @@ evdev_to_left_handed(struct evdev_device *device,
|
|||
* calculation to do circular hysteresis are nontrivial, especially since
|
||||
* many touchpads have uneven x/y resolutions.
|
||||
*
|
||||
* Given coordinates, 0, 1, 2, ... this is what we return for a margin of 3
|
||||
* and a center of 0:
|
||||
*
|
||||
* Input: 1 2 3 4 5 6 5 4 3 2 1 0 -1
|
||||
* Coord: 0 0 0 1 2 3 3 3 3 3 3 3 2
|
||||
* Center: 0 0 0 1 2 3 3 3 3 3 3 3 2
|
||||
*
|
||||
* Problem: viewed from a stationary finger that starts moving, the
|
||||
* hysteresis margin is M in both directions. Once we start moving
|
||||
* continuously though, the margin is 0 in the movement direction and 2*M to
|
||||
* change direction. That makes the finger less responsive to directional
|
||||
* changes than to the original movement.
|
||||
*
|
||||
* @param in The input coordinate
|
||||
* @param center Current center of the hysteresis
|
||||
* @param margin Hysteresis width (on each side)
|
||||
|
|
|
|||
|
|
@ -3239,6 +3239,12 @@ litest_timeout_tablet_proxout(void)
|
|||
msleep(70);
|
||||
}
|
||||
|
||||
void
|
||||
litest_timeout_hysteresis(void)
|
||||
{
|
||||
msleep(90);
|
||||
}
|
||||
|
||||
void
|
||||
litest_push_event_frame(struct litest_device *dev)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -766,6 +766,9 @@ litest_timeout_trackpoint(void);
|
|||
void
|
||||
litest_timeout_tablet_proxout(void);
|
||||
|
||||
void
|
||||
litest_timeout_hysteresis(void);
|
||||
|
||||
void
|
||||
litest_push_event_frame(struct litest_device *dev);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue