diff --git a/dix/events.c b/dix/events.c index 1441cff25..b05c95c43 100644 --- a/dix/events.c +++ b/dix/events.c @@ -1482,14 +1482,27 @@ UpdateTouchesForGrab(DeviceIntPtr mouse) CLIENT_BITS(listener->listener) == grab->resource) { listener->listener = grab->resource; listener->level = grab->grabtype; - listener->state = TOUCH_LISTENER_IS_OWNER; listener->window = grab->window; if (grab->grabtype == CORE || grab->grabtype == XI || - !xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin)) + !xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin)) { + + if (listener->type == TOUCH_LISTENER_REGULAR && + listener->state != TOUCH_LISTENER_AWAITING_BEGIN && + listener->state != TOUCH_LISTENER_HAS_END) { + /* if the listener already got any events relating to the touch, we must send + a touch end because the grab overrides the previous listener and won't + itself send any touch events. + */ + TouchEmitTouchEnd(mouse, ti, 0, listener->listener); + } listener->type = TOUCH_LISTENER_POINTER_GRAB; - else + } else { listener->type = TOUCH_LISTENER_GRAB; + } + + listener->state = TOUCH_LISTENER_IS_OWNER; + if (listener->grab) FreeGrab(listener->grab); listener->grab = AllocGrab(grab);