mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-31 21:40:09 +01:00
touchpad: reset the motion history during/after a slots->nfake crossover
Whenever we cross from N slots to at least one fake finger, reset the motion history and skip the next event too. Especially on serial Synaptics touchpads, the first touch update after a two-slot → TRIPLETAP is garbage, as is the one from TRIPLETAP → two slots. Example sequence reproduce on a T440s: E: 4.488757 0003 003a 0084 # EV_ABS / ABS_MT_PRESSURE 84 E: 4.488757 0003 002f 0001 # EV_ABS / ABS_MT_SLOT 1 E: 4.488757 0003 0039 0433 # EV_ABS / ABS_MT_TRACKING_ID 433 E: 4.488757 0003 0035 2500 # EV_ABS / ABS_MT_POSITION_X 2500 E: 4.488757 0003 0036 3064 # EV_ABS / ABS_MT_POSITION_Y 3064 E: 4.488757 0003 003a 0060 # EV_ABS / ABS_MT_PRESSURE 60 E: 4.488757 0003 0018 0084 # EV_ABS / ABS_PRESSURE 84 E: 4.488757 0001 0145 0000 # EV_KEY / BTN_TOOL_FINGER 0 E: 4.488757 0001 014e 0001 # EV_KEY / BTN_TOOL_TRIPLETAP 1 E: 4.488757 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- E: 4.508506 0003 002f 0000 # EV_ABS / ABS_MT_SLOT 0 E: 4.508506 0003 0036 2982 # EV_ABS / ABS_MT_POSITION_Y 2982 E: 4.508506 0003 003a 0086 # EV_ABS / ABS_MT_PRESSURE 86 E: 4.508506 0003 002f 0001 # EV_ABS / ABS_MT_SLOT 1 E: 4.508506 0003 0035 3464 # EV_ABS / ABS_MT_POSITION_X 3464 E: 4.508506 0003 0036 2716 # EV_ABS / ABS_MT_POSITION_Y 2716 E: 4.508506 0003 0001 2982 # EV_ABS / ABS_Y 2982 E: 4.508506 0003 0018 0086 # EV_ABS / ABS_PRESSURE 86 E: 4.508506 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- subsequent events then hover around the 3464 mark, but that initial jump is enough to cause a massive cursor jump. https://bugs.freedesktop.org/show_bug.cgi?id=91352 Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Hallelujah-expressed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
d4ceb671b9
commit
a87d51f9d7
2 changed files with 36 additions and 2 deletions
|
|
@ -760,6 +760,24 @@ tp_unhover_touches(struct tp_dispatch *tp, uint64_t time)
|
|||
|
||||
}
|
||||
|
||||
static inline bool
|
||||
tp_need_motion_history_reset(struct tp_dispatch *tp)
|
||||
{
|
||||
/* semi-mt finger postions may "jump" when nfingers changes */
|
||||
if (tp->semi_mt && tp->nfingers_down != tp->old_nfingers_down)
|
||||
return true;
|
||||
|
||||
/* if we're transitioning between slots and fake touches in either
|
||||
* direction, we may get a coordinate jump
|
||||
*/
|
||||
if (tp->nfingers_down != tp->old_nfingers_down &&
|
||||
(tp->nfingers_down > tp->num_slots ||
|
||||
tp->old_nfingers_down > tp->num_slots))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
tp_process_state(struct tp_dispatch *tp, uint64_t time)
|
||||
{
|
||||
|
|
@ -767,16 +785,23 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
|
|||
struct tp_touch *first = tp_get_touch(tp, 0);
|
||||
unsigned int i;
|
||||
bool restart_filter = false;
|
||||
bool want_motion_reset;
|
||||
|
||||
tp_process_fake_touches(tp, time);
|
||||
tp_unhover_touches(tp, time);
|
||||
|
||||
want_motion_reset = tp_need_motion_history_reset(tp);
|
||||
|
||||
for (i = 0; i < tp->ntouches; i++) {
|
||||
t = tp_get_touch(tp, i);
|
||||
|
||||
/* semi-mt finger postions may "jump" when nfingers changes */
|
||||
if (tp->semi_mt && tp->nfingers_down != tp->old_nfingers_down)
|
||||
if (want_motion_reset) {
|
||||
tp_motion_history_reset(t);
|
||||
t->quirks.reset_motion_history = true;
|
||||
} else if (t->quirks.reset_motion_history) {
|
||||
tp_motion_history_reset(t);
|
||||
t->quirks.reset_motion_history = false;
|
||||
}
|
||||
|
||||
if (i >= tp->num_slots && t->state != TOUCH_NONE) {
|
||||
t->point = first->point;
|
||||
|
|
|
|||
|
|
@ -147,6 +147,15 @@ struct tp_touch {
|
|||
int distance; /* distance == 0 means touch */
|
||||
int pressure;
|
||||
|
||||
struct {
|
||||
/* A quirk mostly used on Synaptics touchpads. In a
|
||||
transition to/from fake touches > num_slots, the current
|
||||
event data is likely garbage and the subsequent event
|
||||
is likely too. This marker tells us to reset the motion
|
||||
history again -> this effectively swallows any motion */
|
||||
bool reset_motion_history;
|
||||
} quirks;
|
||||
|
||||
struct {
|
||||
struct device_coords samples[TOUCHPAD_HISTORY_LENGTH];
|
||||
unsigned int index;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue