[PATCH libinput 4/6] evdev: release current touches when the device is suspended
Peter Hutterer
peter.hutterer at who-t.net
Mon Aug 22 06:14:56 UTC 2016
Previously suspending a touch device with at least one touch down would never
release the touch point.
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
src/evdev.c | 39 +++++++++++++++++++++++-----
test/device.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 116 insertions(+), 6 deletions(-)
diff --git a/src/evdev.c b/src/evdev.c
index 4bd4aab..0e506bc 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -1082,16 +1082,37 @@ fallback_process(struct evdev_dispatch *evdev_dispatch,
}
static void
+release_touches(struct fallback_dispatch *dispatch,
+ struct evdev_device *device,
+ uint64_t time)
+{
+ unsigned int idx;
+ bool need_frame = false;
+
+ need_frame = fallback_flush_st_up(dispatch, device, time);
+
+ for (idx = 0; idx < dispatch->mt.slots_len; idx++) {
+ struct mt_slot *slot = &dispatch->mt.slots[idx];
+
+ if (slot->seat_slot == -1)
+ continue;
+
+ if (fallback_flush_mt_up(dispatch, device, idx, time))
+ need_frame = true;
+ }
+
+ if (need_frame)
+ touch_notify_frame(&device->base, time);
+}
+
+static void
release_pressed_keys(struct fallback_dispatch *dispatch,
- struct evdev_device *device)
+ struct evdev_device *device,
+ uint64_t time)
{
struct libinput *libinput = evdev_libinput_context(device);
- uint64_t time;
int code;
- if ((time = libinput_now(libinput)) == 0)
- return;
-
for (code = 0; code < KEY_CNT; code++) {
int count = get_key_down_count(device, code);
@@ -1140,8 +1161,14 @@ fallback_suspend(struct evdev_dispatch *evdev_dispatch,
struct evdev_device *device)
{
struct fallback_dispatch *dispatch = (struct fallback_dispatch*)evdev_dispatch;
+ struct libinput *libinput = evdev_libinput_context(device);
+ uint64_t time;
- release_pressed_keys(dispatch, device);
+ if ((time = libinput_now(libinput)) == 0)
+ return;
+
+ release_touches(dispatch, device, time);
+ release_pressed_keys(dispatch, device, time);
memset(dispatch->hw_key_mask, 0, sizeof(dispatch->hw_key_mask));
}
diff --git a/test/device.c b/test/device.c
index 82ef03b..68f9b8b 100644
--- a/test/device.c
+++ b/test/device.c
@@ -211,6 +211,85 @@ START_TEST(device_disable_touchpad)
}
END_TEST
+START_TEST(device_disable_touch)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput *li = dev->libinput;
+ struct libinput_device *device;
+ enum libinput_config_status status;
+
+ device = dev->libinput_device;
+
+ litest_drain_events(li);
+
+ status = libinput_device_config_send_events_set_mode(device,
+ LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+
+ /* no event from disabling */
+ litest_assert_empty_queue(li);
+
+ litest_touch_down(dev, 0, 50, 50);
+ litest_touch_move_to(dev, 0, 50, 50, 90, 90, 10, 0);
+ litest_touch_up(dev, 0);
+
+ litest_assert_empty_queue(li);
+
+ /* no event from resuming */
+ status = libinput_device_config_send_events_set_mode(device,
+ LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+ litest_assert_empty_queue(li);
+}
+END_TEST
+
+START_TEST(device_disable_touch_during_touch)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput *li = dev->libinput;
+ struct libinput_device *device;
+ enum libinput_config_status status;
+ struct libinput_event *event;
+
+ device = dev->libinput_device;
+
+ litest_touch_down(dev, 0, 50, 50);
+ litest_touch_move_to(dev, 0, 50, 50, 90, 90, 10, 0);
+ litest_drain_events(li);
+
+ status = libinput_device_config_send_events_set_mode(device,
+ LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+
+ /* after disabling sendevents we require a touch up */
+ libinput_dispatch(li);
+ event = libinput_get_event(li);
+ litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_UP);
+ libinput_event_destroy(event);
+
+ event = libinput_get_event(li);
+ litest_is_touch_event(event, LIBINPUT_EVENT_TOUCH_FRAME);
+ libinput_event_destroy(event);
+
+ litest_assert_empty_queue(li);
+
+ litest_touch_move_to(dev, 0, 90, 90, 50, 50, 10, 0);
+ litest_touch_up(dev, 0);
+
+ litest_touch_down(dev, 0, 50, 50);
+ litest_touch_move_to(dev, 0, 50, 50, 90, 90, 10, 0);
+ litest_touch_up(dev, 0);
+
+ litest_assert_empty_queue(li);
+
+ /* no event from resuming */
+ status = libinput_device_config_send_events_set_mode(device,
+ LIBINPUT_CONFIG_SEND_EVENTS_ENABLED);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+ litest_assert_empty_queue(li);
+}
+END_TEST
+
START_TEST(device_disable_events_pending)
{
struct litest_device *dev = litest_current_device();
@@ -1353,6 +1432,10 @@ litest_setup_tests_device(void)
litest_add("device:sendevents", device_sendevents_config_default, LITEST_ANY, LITEST_TABLET);
litest_add("device:sendevents", device_disable, LITEST_RELATIVE, LITEST_TABLET);
litest_add("device:sendevents", device_disable_touchpad, LITEST_TOUCHPAD, LITEST_TABLET);
+ litest_add("device:sendevents", device_disable_touch, LITEST_TOUCH, LITEST_ANY);
+ litest_add("device:sendevents", device_disable_touch_during_touch, LITEST_TOUCH, LITEST_ANY);
+ litest_add("device:sendevents", device_disable_touch, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
+ litest_add("device:sendevents", device_disable_touch_during_touch, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
litest_add("device:sendevents", device_disable_events_pending, LITEST_RELATIVE, LITEST_TOUCHPAD|LITEST_TABLET);
litest_add("device:sendevents", device_double_disable, LITEST_ANY, LITEST_TABLET);
litest_add("device:sendevents", device_double_enable, LITEST_ANY, LITEST_TABLET);
--
2.7.4
More information about the wayland-devel
mailing list