barriers: Send an XI_BarrierLeave event when a barrier is destroyed

This ensures that we always complete an event sequence.

Signed-off-by: Jasper St. Pierre <jstpierre@mecheye.net>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Jasper St. Pierre 2012-12-09 19:45:48 -05:00 committed by Peter Hutterer
parent 207e8dee00
commit 6401317bdc

View File

@ -539,8 +539,52 @@ static int
BarrierFreeBarrier(void *data, XID id)
{
struct PointerBarrierClient *c;
Time ms = GetTimeInMillis();
c = container_of(data, struct PointerBarrierClient, barrier);
/* FIXME: this is really broken for multidevice */
if (c->hit) {
DeviceIntPtr dev = NULL;
ScreenPtr screen = c->screen;
BarrierEvent ev = {
.header = ET_Internal,
.type = ET_BarrierLeave,
.length = sizeof (BarrierEvent),
.time = ms,
/* .deviceid */
.sourceid = 0,
.barrierid = c->id,
.window = c->window->drawable.id,
.root = screen->root->drawable.id,
.dx = 0,
.dy = 0,
/* .root_x */
/* .root_y */
.dt = ms - c->last_timestamp,
.event_id = c->barrier_event_id,
.flags = XIBarrierPointerReleased,
};
for (dev = inputInfo.devices; dev; dev = dev->next) {
int root_x, root_y;
if (dev->type != MASTER_POINTER)
continue;
if (!barrier_blocks_device(c, dev))
continue;
ev.deviceid = dev->id;
GetSpritePosition(dev, &root_x, &root_y);
ev.root_x = root_x;
ev.root_y = root_y;
mieqEnqueue(dev, (InternalEvent *) &ev);
}
}
xorg_list_del(&c->entry);
free(c);