From ead21f9426122536adfb4787ac181008ae83cd4b Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 19 Nov 2012 16:16:10 +1000 Subject: [PATCH 1/6] =?UTF-8?q?Xi:=20fix=20typo=20"mechansims"=20=E2=86=92?= =?UTF-8?q?=20"mechanisms"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Peter Hutterer --- Xi/exevents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index 2caf98c25..ae126dfd7 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -1409,7 +1409,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, ptrev->device_event.corestate = event_get_corestate(dev, kbd); if (grab) { - /* this side-steps the usual activation mechansims, but... */ + /* this side-steps the usual activation mechanisms, but... */ if (ev->any.type == ET_TouchBegin && !dev->deviceGrab.grab) ActivatePassiveGrab(dev, grab, ptrev, ev); /* also delivers the event */ else { From 146f48c2934fc85ec095496da5c8f0102bc7f5b5 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 22 Nov 2012 13:49:34 +1000 Subject: [PATCH 2/6] dix: don't call ProcessInputEvents() when accepting/rejecting touches TouchListenerAcceptReject may be called during normal event processing, but ProcessInputEvents is not reentrant and calling it here smashes the event queue. Signed-off-by: Peter Hutterer --- dix/touch.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/dix/touch.c b/dix/touch.c index 29ba17194..f4a93c684 100644 --- a/dix/touch.c +++ b/dix/touch.c @@ -987,8 +987,6 @@ TouchListenerAcceptReject(DeviceIntPtr dev, TouchPointInfoPtr ti, int listener, for (i = 0; i < nev; i++) mieqProcessDeviceEvent(dev, events + i, NULL); - ProcessInputEvents(); - FreeEventList(events, GetMaximumEventsNum()); return nev ? Success : BadMatch; From bc1f90a615018c05994fae3e678dd2341256cd82 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 26 Nov 2012 12:23:54 +1000 Subject: [PATCH 3/6] dix: only reject active grabs on ungrab and do it before actually ungrabbing An active grab ungrabbing is the same as rejecting the grab, since the client is no longer interested in those events. So reject any touch grab, but do so before actually deactivating since we're interested in the TouchEnd for the current grabbing client. A passive grab otoh is _not_ like rejecting a grab, since it deactivates automatically when the touch ends. Signed-off-by: Peter Hutterer --- dix/events.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dix/events.c b/dix/events.c index 3282ef818..03ed106ed 100644 --- a/dix/events.c +++ b/dix/events.c @@ -1503,11 +1503,20 @@ DeactivatePointerGrab(DeviceIntPtr mouse) { GrabPtr grab = mouse->deviceGrab.grab; DeviceIntPtr dev; + Bool wasPassive = mouse->deviceGrab.fromPassiveGrab; Bool wasImplicit = (mouse->deviceGrab.fromPassiveGrab && mouse->deviceGrab.implicitGrab); XID grab_resource = grab->resource; int i; + /* If an explicit grab was deactivated, we must remove it from the head of + * all the touches' listener lists. */ + for (i = 0; !wasPassive && mouse->touch && i < mouse->touch->num_touches; i++) { + TouchPointInfoPtr ti = mouse->touch->touches + i; + if (ti->active && TouchResourceIsOwner(ti, grab_resource)) + TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch); + } + TouchRemovePointerGrab(mouse); mouse->valuator->motionHintWindow = NullWindow; From ece8157a59751b3ed492fb2e1eb8d5f20221e195 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 26 Nov 2012 15:14:19 +1000 Subject: [PATCH 4/6] dix: when deactivating pointer-only grabs, don't emulate TouchEnd events A client with a pointer grab on a touch device must reject the touch when detactivating the grab while the touch is active. However, such a rejecting must not trigger a ButtonRelease event to be emulated and sent to the client. Set the grabbing listener's state to HAS_END, so we simply skip delivery to that client. Signed-off-by: Peter Hutterer --- dix/events.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/dix/events.c b/dix/events.c index 03ed106ed..31f8d8700 100644 --- a/dix/events.c +++ b/dix/events.c @@ -1513,8 +1513,15 @@ DeactivatePointerGrab(DeviceIntPtr mouse) * all the touches' listener lists. */ for (i = 0; !wasPassive && mouse->touch && i < mouse->touch->num_touches; i++) { TouchPointInfoPtr ti = mouse->touch->touches + i; - if (ti->active && TouchResourceIsOwner(ti, grab_resource)) + if (ti->active && TouchResourceIsOwner(ti, grab_resource)) { + /* Rejecting will generate a TouchEnd, but we must not + emulate a ButtonRelease here. So pretend the listener + already has the end event */ + if (grab->grabtype == CORE || grab->grabtype == XI || + !xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin)) + ti->listeners[0].state = LISTENER_HAS_END; TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch); + } } TouchRemovePointerGrab(mouse); From 00def5144557cfe8bf535f926212a8e084dc7cf6 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 26 Nov 2012 14:55:13 +1000 Subject: [PATCH 5/6] Xi: if a TouchEnd appears on a actively grabbing client, always accept Once the TouchEnd appears on the device, the touch is done. If the client still has a pointer grab, accept it to avoid clients with TouchOwnership selections to wait indefinitely for the actual touch event. Signed-off-by: Peter Hutterer --- Xi/exevents.c | 55 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index ae126dfd7..4c1aeb4da 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -1566,32 +1566,41 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev) else ti = TouchFindByClientID(dev, touchid); - /* Under the following circumstances we create a new touch record for an - * existing touch: - * - * - The touch may be pointer emulated - * - An explicit grab is active on the device - * - The grab is a pointer grab - * - * This allows for an explicit grab to receive pointer events for an already - * active touch. - */ - if (!ti && type != ET_TouchBegin && emulate_pointer && - dev->deviceGrab.grab && !dev->deviceGrab.fromPassiveGrab && + /* Active pointer grab */ + if (emulate_pointer && dev->deviceGrab.grab && !dev->deviceGrab.fromPassiveGrab && (dev->deviceGrab.grab->grabtype == CORE || dev->deviceGrab.grab->grabtype == XI || - !xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin))) { - ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid, - emulate_pointer); - if (!ti) { - DebugF("[Xi] %s: Failed to create new dix record for explicitly " - "grabbed touchpoint %d\n", - dev->name, touchid); - return; - } + !xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin))) + { + /* Active pointer grab on touch point and we get a TouchEnd - claim this + * touchpoint accepted, otherwise clients waiting for ownership will + * wait on this touchpoint until this client ungrabs, or the cows come + * home, whichever is earlier */ + if (ti && type == ET_TouchEnd) + TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch); + else if (!ti && type != ET_TouchBegin) { + /* Under the following circumstances we create a new touch record for an + * existing touch: + * + * - The touch may be pointer emulated + * - An explicit grab is active on the device + * - The grab is a pointer grab + * + * This allows for an explicit grab to receive pointer events for an already + * active touch. + */ + ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid, + emulate_pointer); + if (!ti) { + DebugF("[Xi] %s: Failed to create new dix record for explicitly " + "grabbed touchpoint %d\n", + dev->name, touchid); + return; + } - TouchBuildSprite(dev, ti, ev); - TouchSetupListeners(dev, ti, ev); + TouchBuildSprite(dev, ti, ev); + TouchSetupListeners(dev, ti, ev); + } } if (!ti) { From 08da994a08bb74afae81176c56fb525d0439274b Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 26 Nov 2012 12:33:29 +1000 Subject: [PATCH 6/6] dix: add FIXME, TouchRemovePointerGrab does nothing Signed-off-by: Peter Hutterer --- dix/touch.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dix/touch.c b/dix/touch.c index f4a93c684..d890b6227 100644 --- a/dix/touch.c +++ b/dix/touch.c @@ -915,6 +915,8 @@ TouchRemovePointerGrab(DeviceIntPtr dev) ti = TouchFindByClientID(dev, ev->touchid); if (!ti) return; + + /* FIXME: missing a bit of code here... */ } /* As touch grabs don't turn into active grabs with their own resources, we