0e1e01a399
- Update touch patch to upstream version (from fdo #66720) - re-add xephyr resizable patch, got lost in rebase (#976995)
106 lines
4.6 KiB
Diff
106 lines
4.6 KiB
Diff
From 8eeaa74bc241acb41f1d3ed64971e0b01e794776 Mon Sep 17 00:00:00 2001
|
|
From: Peter Hutterer <peter.hutterer@who-t.net>
|
|
Date: Tue, 9 Jul 2013 13:27:19 +1000
|
|
Subject: [PATCH] dix: when ungrabbing an active grab, accept pointer grabs
|
|
(#66720)
|
|
|
|
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@who-t.net>
|
|
Reviewed-by: Jasper St. Pierre <jstpierre@mecheye.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
|
|
|