summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2013-02-13 15:12:32 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2013-02-13 16:59:31 +1000
commit4a28adf35a5e90ad4b9e74a23a9ef885823cb1ba (patch)
tree11e2d004c8e5dee73f5740f207fcdc31b8d73471
parentd3a8d8f40d7e337829b2bc31d5b163129a448a65 (diff)
Xi: if the last listener left is an async grab, finish the touch.touch-grab-race-condition-56578
Async grabs cannot replay events, so we don't need to keep them around. And non-touch grabbing clients will not accept/reject, so we need to finish the touch right now. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--Xi/exevents.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/Xi/exevents.c b/Xi/exevents.c
index 02b73360a..1dc688280 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1145,11 +1145,17 @@ TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti,
}
/* If we've just removed the last grab and the touch has physically
- * ended, send a TouchEnd event too and finalise the touch. */
- if (ti->num_listeners == 1 && ti->num_grabs == 0 && ti->pending_finish) {
- EmitTouchEnd(dev, ti, 0, 0, TRUE);
- TouchEndTouch(dev, ti);
- return;
+ * ended, send a TouchEnd event too and finalise the touch.
+ * If we only have an async grab left, do the same.
+ */
+ if (ti->num_listeners == 1 && ti->pending_finish) {
+ if (ti->num_grabs == 0 ||
+ ti->listeners[0].grab->grabtype != XI2 ||
+ !xi2mask_isset(ti->listeners[0].grab->xi2mask, dev, XI_TouchBegin)) {
+ EmitTouchEnd(dev, ti, 0, 0, TRUE);
+ TouchEndTouch(dev, ti);
+ return;
+ }
}
if (ti->listeners[0].state == LISTENER_EARLY_ACCEPT)