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
dev
Neil Roberts 11 years ago committed by Kristian Høgsberg
parent daf7d4774b
commit be336c8918
  1. 43
      src/evdev.c
  2. 2
      src/evdev.h

@ -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,

@ -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,

Loading…
Cancel
Save