diff options
author | Daniel Stone <daniel@fooishbar.org> | 2011-12-15 07:52:28 +1000 |
---|---|---|
committer | Chase Douglas <chase.douglas@canonical.com> | 2011-12-21 10:34:12 -0800 |
commit | a83bf2e4ef987f2c448338b49dbefefff2e7a8c7 (patch) | |
tree | d94defa6b7aaf364da03ddad0f02015afc43976f | |
parent | 09b10d42d8dcc3e4503ba79660a91b4b385bb1ff (diff) |
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>
-rw-r--r-- | dix/grabs.c | 3 | ||||
-rw-r--r-- | dix/touch.c | 44 | ||||
-rw-r--r-- | include/input.h | 1 |
3 files changed, 48 insertions, 0 deletions
diff --git a/dix/grabs.c b/dix/grabs.c index da014dfc3..701470c83 100644 --- a/dix/grabs.c +++ b/dix/grabs.c @@ -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); diff --git a/dix/touch.c b/dix/touch.c index 9bd07c37c..db0bf334a 100644 --- a/dix/touch.c +++ b/dix/touch.c @@ -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()); +} diff --git a/include/input.h b/include/input.h index 4ed9dce14..fb456175a 100644 --- a/include/input.h +++ b/include/input.h @@ -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); |