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>
This commit is contained in:
parent
a2d6932ad4
commit
8eeaa74bc2
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
11
dix/events.c
11
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue