dix: Remove touch grabs if the grab disappears

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
This commit is contained in:
Daniel Stone 2011-12-15 07:52:28 +10:00 committed by Peter Hutterer
parent cd3de8324e
commit 3b1e2035cc
3 changed files with 48 additions and 0 deletions

View File

@ -266,6 +266,9 @@ CreateGrab(
void
FreeGrab(GrabPtr pGrab)
{
if (pGrab->grabtype == XI2 && pGrab->type == XI_TouchBegin)
TouchListenerGone(pGrab->resource);
free(pGrab->modifiersDetail.pMask);
free(pGrab->detail.pMask);

View File

@ -37,6 +37,7 @@
#include "inpututils.h"
#include "eventconvert.h"
#include "windowstr.h"
#include "mi.h"
#define TOUCH_HISTORY_SIZE 100
@ -936,3 +937,46 @@ TouchRemovePointerGrab(DeviceIntPtr dev)
if (!ti)
return;
}
/* As touch grabs don't turn into active grabs with their own resources, we
* need to walk all the touches and remove this grab from any delivery
* lists. */
void
TouchListenerGone(XID resource)
{
TouchPointInfoPtr ti;
DeviceIntPtr dev;
InternalEvent *events = InitEventList(GetMaximumEventsNum());
int i, j, k, nev;
if (!events)
FatalError("TouchListenerGone: couldn't allocate events\n");
for (dev = inputInfo.devices; dev; dev = dev->next)
{
if (!dev->touch)
continue;
for (i = 0; i < dev->touch->num_touches; i++)
{
ti = &dev->touch->touches[i];
if (!ti->active)
continue;
for (j = 0; j < ti->num_listeners; j++)
{
if (ti->listeners[j].listener != resource)
continue;
nev = GetTouchOwnershipEvents(events, dev, ti, XIRejectTouch,
resource, 0);
for (k = 0; k < nev; k++)
mieqProcessDeviceEvent(dev, events + k, NULL);
break;
}
}
}
FreeEventList(events, GetMaximumEventsNum());
}

View File

@ -623,6 +623,7 @@ extern int TouchConvertToPointerEvent(const InternalEvent *ev,
InternalEvent *motion, InternalEvent *button);
extern int TouchGetPointerEventType(const InternalEvent *ev);
extern void TouchRemovePointerGrab(DeviceIntPtr dev);
extern void TouchListenerGone(XID resource);
/* misc event helpers */
extern Mask GetEventMask(DeviceIntPtr dev, xEvent* ev, InputClientsPtr clients);