--- ../exevents.c~ 2013-04-16 16:13:09.917826088 +0200 +++ Xi/exevents.c 2013-04-16 19:09:58.108367152 +0200 @@ -1626,22 +1626,21 @@ (type != ET_TouchEnd && ti->sprite.spriteTraceGood == 0)) return; - /* TouchOwnership events are handled separately from the rest, as they - * have more complex semantics. */ - if (ev->any.type == ET_TouchOwnership) - ProcessTouchOwnershipEvent(dev, ti, &ev->touch_ownership_event); - else { - TouchCopyValuatorData(&ev->device_event, ti); - /* WARNING: the event type may change to TouchUpdate in - * DeliverTouchEvents if a TouchEnd was delivered to a grabbing - * owner */ - DeliverTouchEvents(dev, ti, (InternalEvent *) ev, 0); - if (ev->any.type == ET_TouchEnd) - TouchEndTouch(dev, ti); - } - - if (emulate_pointer) + TouchCopyValuatorData(&ev->device_event, ti); + /* WARNING: the event type may change to TouchUpdate in + * DeliverTouchEvents if a TouchEnd was delivered to a grabbing + * owner */ + DeliverTouchEvents(dev, ti, (InternalEvent *) ev, 0); + if (ev->any.type == ET_TouchEnd) + TouchEndTouch(dev, ti); + + if (emulate_pointer) { + /* The event type might have been changed above. However, for pointer + * emulation purposes, we want to restore the original event type for + * correct processing of TouchEnd events. */ + ev->any.type = type; UpdateDeviceState(dev, &ev->device_event); + } } /** @@ -1789,10 +1788,14 @@ break; case ET_TouchBegin: case ET_TouchUpdate: - case ET_TouchOwnership: case ET_TouchEnd: ProcessTouchEvent(ev, device); break; + case ET_TouchOwnership: + /* TouchOwnership events are handled separately from the rest, as they + * have more complex semantics. */ + ProcessTouchOwnershipEvent(&ev->touch_ownership_event, device); + break; default: ProcessDeviceEvent(ev, device); break;