Xi: Fix TouchEnd to TouchUpdate change for one accepted grab

If there is only one listener of a touch, the listener is a grab, and is
accepted before the touch has ended, the current code will not end the
touch record when the touch does end.

This change adds a listener state for when a touch is accepted but has
not yet ended. We now keep the touch record alive in this state, but end
it when the touch ends.

Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Chase Douglas 2012-03-07 16:06:26 -08:00 committed by Peter Hutterer
parent e884ff8ad4
commit 58427e08a4
2 changed files with 18 additions and 9 deletions

View File

@ -1210,6 +1210,8 @@ ProcessTouchOwnershipEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
/* Owner accepted after receiving end */
if (ti->listeners[0].state == LISTENER_HAS_END)
TouchEndTouch(dev, ti);
else
ti->listeners[0].state = LISTENER_HAS_ACCEPTED;
}
else { /* this is the very first ownership event for a grab */
DeliverTouchEvents(dev, ti, (InternalEvent *) ev, ev->resource);
@ -1730,7 +1732,11 @@ DeliverTouchBeginEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
else {
if (has_ownershipmask)
TouchSendOwnershipEvent(dev, ti, 0, listener->listener);
state = LISTENER_IS_OWNER;
if (!has_ownershipmask || listener->type == LISTENER_REGULAR)
state = LISTENER_HAS_ACCEPTED;
else
state = LISTENER_IS_OWNER;
}
listener->state = state;
@ -1759,20 +1765,22 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev,
listener->state = LISTENER_HAS_END;
}
else if (TouchResourceIsOwner(ti, listener->listener)) {
Bool normal_end = !(ev->device_event.flags & TOUCH_ACCEPT);
/* FIXME: what about early acceptance */
if (!(ev->device_event.flags & TOUCH_ACCEPT)) {
if (listener->state != LISTENER_HAS_END)
rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
listener->state = LISTENER_HAS_END;
}
if (normal_end && listener->state != LISTENER_HAS_END)
rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
if ((ti->num_listeners > 1 ||
(listener->type == LISTENER_GRAB &&
xi2mask_isset(xi2mask, dev, XI_TouchOwnership))) &&
listener->state != LISTENER_HAS_ACCEPTED) &&
(ev->device_event.flags & (TOUCH_ACCEPT | TOUCH_REJECT)) == 0) {
ev->any.type = ET_TouchUpdate;
ev->device_event.flags |= TOUCH_PENDING_END;
ti->pending_finish = TRUE;
}
if (normal_end)
listener->state = LISTENER_HAS_END;
}
out:

View File

@ -523,7 +523,8 @@ enum TouchListenerState {
LISTENER_AWAITING_OWNER, /**< Waiting for a TouchOwnership event */
LISTENER_EARLY_ACCEPT, /**< Waiting for ownership, has already
accepted */
LISTENER_IS_OWNER, /**< Is the current owner */
LISTENER_IS_OWNER, /**< Is the current owner, hasn't accepted */
LISTENER_HAS_ACCEPTED, /**< Is the current owner, has accepted */
LISTENER_HAS_END, /**< Has already received the end event */
};