mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-25 08:10:05 +01:00
touchpad: sync the initial touch state
Unlikely, but there's the odd chance of the first touch coming in with the same X or Y coordinate the kernel already has internally. This would generate a bogus delta on the second event when the touch coordinate jumps from 0/y or x/0 to the real coordinates. For touchpads with distance support this is a real issue since the default value for a touch distance is > 0. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Tested-by: Benjamin Tissoires <benjamin.tissoires@gmail.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
180564c780
commit
af4ff07f6b
2 changed files with 90 additions and 0 deletions
|
|
@ -1087,6 +1087,28 @@ 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);
|
||||
|
||||
libevdev_fetch_slot_value(evdev, slot, ABS_MT_DISTANCE, &t->distance);
|
||||
}
|
||||
|
||||
static int
|
||||
tp_init_slots(struct tp_dispatch *tp,
|
||||
struct evdev_device *device)
|
||||
|
|
@ -1134,6 +1156,12 @@ 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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4531,9 +4531,69 @@ START_TEST(touchpad_trackpoint_no_trackpoint)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_initial_state)
|
||||
{
|
||||
struct litest_device *dev;
|
||||
struct libinput *libinput1, *libinput2;
|
||||
struct libinput_event *ev1, *ev2;
|
||||
struct libinput_event_pointer *p1, *p2;
|
||||
int axis = _i; /* looped test */
|
||||
int x = 40, y = 60;
|
||||
|
||||
dev = litest_current_device();
|
||||
libinput1 = dev->libinput;
|
||||
|
||||
libinput_device_config_tap_set_enabled(dev->libinput_device,
|
||||
LIBINPUT_CONFIG_TAP_DISABLED);
|
||||
|
||||
litest_touch_down(dev, 0, x, y);
|
||||
litest_touch_up(dev, 0);
|
||||
|
||||
/* device is now on some x/y value */
|
||||
litest_drain_events(libinput1);
|
||||
|
||||
libinput2 = litest_create_context();
|
||||
libinput_path_add_device(libinput2,
|
||||
libevdev_uinput_get_devnode(dev->uinput));
|
||||
litest_drain_events(libinput2);
|
||||
|
||||
if (axis == ABS_X)
|
||||
x = 30;
|
||||
else
|
||||
y = 30;
|
||||
litest_touch_down(dev, 0, x, y);
|
||||
litest_touch_move_to(dev, 0, x, y, 80, 80, 10, 1);
|
||||
litest_touch_up(dev, 0);
|
||||
|
||||
litest_wait_for_event(libinput1);
|
||||
litest_wait_for_event(libinput2);
|
||||
|
||||
while (libinput_next_event_type(libinput1)) {
|
||||
ev1 = libinput_get_event(libinput1);
|
||||
ev2 = libinput_get_event(libinput2);
|
||||
|
||||
p1 = litest_is_motion_event(ev1);
|
||||
p2 = litest_is_motion_event(ev2);
|
||||
|
||||
ck_assert_int_eq(libinput_event_get_type(ev1),
|
||||
libinput_event_get_type(ev2));
|
||||
|
||||
ck_assert_int_eq(libinput_event_pointer_get_dx(p1),
|
||||
libinput_event_pointer_get_dx(p2));
|
||||
ck_assert_int_eq(libinput_event_pointer_get_dy(p1),
|
||||
libinput_event_pointer_get_dy(p2));
|
||||
libinput_event_destroy(ev1);
|
||||
libinput_event_destroy(ev2);
|
||||
}
|
||||
|
||||
libinput_unref(libinput2);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct range multitap_range = {3, 8};
|
||||
struct range axis_range = {ABS_X, ABS_Y + 1};
|
||||
|
||||
litest_add("touchpad:motion", touchpad_1fg_motion, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add("touchpad:motion", touchpad_2fg_no_motion, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
|
||||
|
|
@ -4676,5 +4736,7 @@ int main(int argc, char **argv)
|
|||
litest_add_for_device("touchpad:trackpoint", touchpad_trackpoint_buttons_2fg_scroll, LITEST_SYNAPTICS_TRACKPOINT_BUTTONS);
|
||||
litest_add_for_device("touchpad:trackpoint", touchpad_trackpoint_no_trackpoint, LITEST_SYNAPTICS_TRACKPOINT_BUTTONS);
|
||||
|
||||
litest_add_ranged("touchpad:state", touchpad_initial_state, LITEST_TOUCHPAD, LITEST_ANY, &axis_range);
|
||||
|
||||
return litest_run(argc, argv);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue