mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-02-05 01:40:29 +01:00
touchpad: sync the slot state after tp_resume()
If the touchpad is suspended and resumed (e.g. lid switch), the initial slot state may be out of sync. If a touch happened while the touchpad was suspended and the next touch down is on exactly the same x and/or y coordinate, our touch point would still have the coordinates of the most recently seen touch (i.e. before touchpad suspend). This could cause a pointer jump or test case failures. The real-world impact of this is minimal, putting the finger down in exactly the same spot is virtually impossible. It could cause a test case failure in the lid_disable_touchpad() test though, the second touch sequence was on the same y coordinate and the touch location for that whole sequence was x/0. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
9ddf8a6421
commit
6a77cae850
1 changed files with 42 additions and 33 deletions
|
|
@ -1446,6 +1446,45 @@ tp_interface_suspend(struct evdev_dispatch *dispatch,
|
|||
tp_clear_state(tp);
|
||||
}
|
||||
|
||||
static inline void
|
||||
tp_sync_touch(struct tp_dispatch *tp,
|
||||
struct evdev_device *device,
|
||||
struct tp_touch *t,
|
||||
int slot)
|
||||
{
|
||||
struct libevdev *evdev = device->evdev;
|
||||
|
||||
if (!libevdev_fetch_slot_value(evdev,
|
||||
slot,
|
||||
ABS_MT_POSITION_X,
|
||||
&t->point.x))
|
||||
t->point.x = libevdev_get_event_value(evdev, EV_ABS, ABS_X);
|
||||
if (!libevdev_fetch_slot_value(evdev,
|
||||
slot,
|
||||
ABS_MT_POSITION_Y,
|
||||
&t->point.y))
|
||||
t->point.y = libevdev_get_event_value(evdev, EV_ABS, ABS_Y);
|
||||
|
||||
if (!libevdev_fetch_slot_value(evdev,
|
||||
slot,
|
||||
ABS_MT_PRESSURE,
|
||||
&t->pressure))
|
||||
t->pressure = libevdev_get_event_value(evdev,
|
||||
EV_ABS,
|
||||
ABS_PRESSURE);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_sync_slots(struct tp_dispatch *tp,
|
||||
struct evdev_device *device)
|
||||
{
|
||||
/* Always sync the first touch so we get ABS_X/Y synced on
|
||||
* single-touch touchpads */
|
||||
tp_sync_touch(tp, device, &tp->touches[0], 0);
|
||||
for (unsigned int i = 1; i < tp->num_slots; i++)
|
||||
tp_sync_touch(tp, device, &tp->touches[i], i);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_resume(struct tp_dispatch *tp, struct evdev_device *device)
|
||||
{
|
||||
|
|
@ -1458,6 +1497,8 @@ tp_resume(struct tp_dispatch *tp, struct evdev_device *device)
|
|||
} else {
|
||||
evdev_device_resume(device);
|
||||
}
|
||||
|
||||
tp_sync_slots(tp, device);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1912,34 +1953,6 @@ tp_init_touch(struct tp_dispatch *tp,
|
|||
t->has_ended = true;
|
||||
}
|
||||
|
||||
static void
|
||||
tp_sync_touch(struct tp_dispatch *tp,
|
||||
struct evdev_device *device,
|
||||
struct tp_touch *t,
|
||||
int slot)
|
||||
{
|
||||
struct libevdev *evdev = device->evdev;
|
||||
|
||||
if (!libevdev_fetch_slot_value(evdev,
|
||||
slot,
|
||||
ABS_MT_POSITION_X,
|
||||
&t->point.x))
|
||||
t->point.x = libevdev_get_event_value(evdev, EV_ABS, ABS_X);
|
||||
if (!libevdev_fetch_slot_value(evdev,
|
||||
slot,
|
||||
ABS_MT_POSITION_Y,
|
||||
&t->point.y))
|
||||
t->point.y = libevdev_get_event_value(evdev, EV_ABS, ABS_Y);
|
||||
|
||||
if (!libevdev_fetch_slot_value(evdev,
|
||||
slot,
|
||||
ABS_MT_PRESSURE,
|
||||
&t->pressure))
|
||||
t->pressure = libevdev_get_event_value(evdev,
|
||||
EV_ABS,
|
||||
ABS_PRESSURE);
|
||||
}
|
||||
|
||||
static inline void
|
||||
tp_disable_abs_mt(struct evdev_device *device)
|
||||
{
|
||||
|
|
@ -2025,11 +2038,7 @@ tp_init_slots(struct tp_dispatch *tp,
|
|||
for (i = 0; i < tp->ntouches; i++)
|
||||
tp_init_touch(tp, &tp->touches[i]);
|
||||
|
||||
/* Always sync the first touch so we get ABS_X/Y synced on
|
||||
* single-touch touchpads */
|
||||
tp_sync_touch(tp, device, &tp->touches[0], 0);
|
||||
for (i = 1; i < tp->num_slots; i++)
|
||||
tp_sync_touch(tp, device, &tp->touches[i], i);
|
||||
tp_sync_slots(tp, device);
|
||||
|
||||
/* Some touchpads don't reset BTN_TOOL_FINGER on touch up and only
|
||||
* change to/from it when BTN_TOOL_DOUBLETAP is set. This causes us
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue