[PATCH] dix: when ungrabbing an active grab, accept pointer grabs (#66720)
Jasper St. Pierre
jstpierre at mecheye.net
Wed Jul 10 14:27:55 PDT 2013
This fixes the crash and makes pointer-emulated touch work properly on my
Chromebook.
Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>
On Tue, Jul 9, 2013 at 7:01 PM, Peter Hutterer <peter.hutterer at who-t.net>wrote:
> Ungrabbing a device during an active touch grab rejects the grab.
> Ungrabbing
> a device during an active pointer grab accepts the grab.
>
> Rejection is not really an option for a pointer-emulated grab, if a client
> has a button mask on the window it would get a ButtonPress emulated after
> UngrabDevice. That is against the core grab behaviour.
>
> X.Org Bug 66720 <http://bugs.freedesktop.org/show_bug.cgi?id=66720>
>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---
> Xi/exevents.c | 33 ++++++++++++++++++++++-----------
> dix/events.c | 11 +++++++++--
> 2 files changed, 31 insertions(+), 13 deletions(-)
>
> diff --git a/Xi/exevents.c b/Xi/exevents.c
> index 2bbc6f0..fd4b80c 100644
> --- a/Xi/exevents.c
> +++ b/Xi/exevents.c
> @@ -1223,9 +1223,13 @@ ProcessTouchOwnershipEvent(TouchOwnershipEvent *ev,
> else if (ev->reason == XIAcceptTouch) {
> int i;
>
> - /* Go through the motions of ending the touch if the listener has
> +
> + /* For pointer-emulated listeners that ungrabbed the active grab,
> + * the state was forced to LISTENER_HAS_END. Still go
> + * through the motions of ending the touch if the listener has
> * already seen the end. This ensures that the touch record is
> ended in
> - * the server. */
> + * the server.
> + */
> if (ti->listeners[0].state == LISTENER_HAS_END)
> TouchEmitTouchEnd(dev, ti, TOUCH_ACCEPT,
> ti->listeners[0].listener);
>
> @@ -1883,16 +1887,23 @@ DeliverTouchEndEvent(DeviceIntPtr dev,
> TouchPointInfoPtr ti, InternalEvent *ev,
>
> if (listener->type == LISTENER_POINTER_REGULAR ||
> listener->type == LISTENER_POINTER_GRAB) {
> - rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
> - grab, xi2mask);
> + /* Note: If the active grab was ungrabbed, we already changed the
> + * state to LISTENER_HAS_END but still get here. So we mustn't
> + * actually send the event.
> + * This is part two of the hack in DeactivatePointerGrab
> + */
> + if (listener->state != LISTENER_HAS_END) {
> + rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client,
> win,
> + grab, xi2mask);
>
> - /* Once we send a TouchEnd to a legacy listener, we're already
> well
> - * past the accepting/rejecting stage (can only happen on
> - * GrabModeSync + replay. This listener now gets the end event,
> - * and we can continue.
> - */
> - if (rc == Success)
> - listener->state = LISTENER_HAS_END;
> + /* Once we send a TouchEnd to a legacy listener, we're
> already well
> + * past the accepting/rejecting stage (can only happen on
> + * GrabModeSync + replay. This listener now gets the end
> event,
> + * and we can continue.
> + */
> + if (rc == Success)
> + listener->state = LISTENER_HAS_END;
> + }
> goto out;
> }
>
> diff --git a/dix/events.c b/dix/events.c
> index e5db348..03b2d2e 100644
> --- a/dix/events.c
> +++ b/dix/events.c
> @@ -1522,13 +1522,20 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
> 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)) {
> + int mode = XIRejectTouch;
> /* 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(mouse->deviceGrab.grab->xi2mask,
> mouse, XI_TouchBegin))
> + !xi2mask_isset(mouse->deviceGrab.grab->xi2mask,
> mouse, XI_TouchBegin)) {
> + mode = XIAcceptTouch;
> + /* NOTE: we set the state here, but
> + * ProcessTouchOwnershipEvent() will still call
> + * TouchEmitTouchEnd for this listener. The other half of
> + * this hack is in DeliverTouchEndEvent */
> ti->listeners[0].state = LISTENER_HAS_END;
> - TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch);
> + }
> + TouchListenerAcceptReject(mouse, ti, 0, mode);
> }
> }
>
> --
> 1.8.2.1
>
> _______________________________________________
> xorg-devel at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: http://lists.x.org/mailman/listinfo/xorg-devel
>
--
Jasper
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.x.org/archives/xorg-devel/attachments/20130710/2059d7fc/attachment.html>
More information about the xorg-devel
mailing list