From be336c89182ce2acf608c889223cf7d1b8940083 Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Tue, 24 Sep 2013 20:05:07 +0100 Subject: [PATCH] evdev: Process touch up events of single-touch devices Previously only the touch up key event was used for single-touch devices and the touch down event was generated on the first motion event. This was breaking if the touch up and down events were sent without a motion in-between because the evdev driver wouldn't generate a touch down event and Weston would lose track of the number of touch points that are down. This patch changes it to track the up and down key events as pending events similar to how it does for multi-touch devices. https://bugs.freedesktop.org/show_bug.cgi?id=69759 --- src/evdev.c | 43 ++++++++++++++++++++++++++++++------------- src/evdev.h | 2 ++ 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index c1e11d38..48e5470d 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -121,21 +121,25 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) notify_touch(master, time, slot, 0, 0, WL_TOUCH_UP); goto handled; + case EVDEV_ABSOLUTE_TOUCH_DOWN: + transform_absolute(device, &cx, &cy); + weston_output_transform_coordinate(device->output, + cx, cy, &x, &y); + notify_touch(master, time, 0, x, y, WL_TOUCH_DOWN); + goto handled; case EVDEV_ABSOLUTE_MOTION: transform_absolute(device, &cx, &cy); weston_output_transform_coordinate(device->output, cx, cy, &x, &y); - if (device->caps & EVDEV_TOUCH) { - if (master->num_tp == 0) - notify_touch(master, time, 0, - x, y, WL_TOUCH_DOWN); - else - notify_touch(master, time, 0, - x, y, WL_TOUCH_MOTION); - } else + if (device->caps & EVDEV_TOUCH) + notify_touch(master, time, 0, x, y, WL_TOUCH_MOTION); + else notify_motion_absolute(master, time, x, y); goto handled; + case EVDEV_ABSOLUTE_TOUCH_UP: + notify_touch(master, time, 0, 0, 0, WL_TOUCH_UP); + goto handled; } assert(0 && "Unknown pending event type"); @@ -144,6 +148,18 @@ handled: device->pending_event = EVDEV_NONE; } +static void +evdev_process_touch_button(struct evdev_device *device, int time, int value) +{ + if (device->pending_event != EVDEV_NONE && + device->pending_event != EVDEV_ABSOLUTE_MOTION) + evdev_flush_pending_event(device, time); + + device->pending_event = (value ? + EVDEV_ABSOLUTE_TOUCH_DOWN : + EVDEV_ABSOLUTE_TOUCH_UP); +} + static inline void evdev_process_key(struct evdev_device *device, struct input_event *e, int time) { @@ -151,6 +167,12 @@ evdev_process_key(struct evdev_device *device, struct input_event *e, int time) if (e->value == 2) return; + if (e->code == BTN_TOUCH) { + if (!device->is_mt) + evdev_process_touch_button(device, time, e->value); + return; + } + evdev_flush_pending_event(device, time); switch (e->code) { @@ -168,11 +190,6 @@ evdev_process_key(struct evdev_device *device, struct input_event *e, int time) WL_POINTER_BUTTON_STATE_RELEASED); break; - case BTN_TOUCH: - if (e->value == 0 && !device->is_mt) - notify_touch(device->seat, time, 0, 0, 0, - WL_TOUCH_UP); - break; default: notify_key(device->seat, time, e->code, diff --git a/src/evdev.h b/src/evdev.h index 6d916202..5e4d11ac 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -32,7 +32,9 @@ enum evdev_event_type { EVDEV_NONE, + EVDEV_ABSOLUTE_TOUCH_DOWN, EVDEV_ABSOLUTE_MOTION, + EVDEV_ABSOLUTE_TOUCH_UP, EVDEV_ABSOLUTE_MT_DOWN, EVDEV_ABSOLUTE_MT_MOTION, EVDEV_ABSOLUTE_MT_UP,