Merge branch 'wip/touchpad-hysteresis-issues-v2'

This commit is contained in:
Peter Hutterer 2017-11-03 11:00:03 +10:00
commit aaded3d01d
5 changed files with 55 additions and 5 deletions

View file

@ -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

View file

@ -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;

View file

@ -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)

View file

@ -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)
{

View file

@ -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);