dix: Send touch end to clients that do async grab without touch events
If a XI2 client started listening to touches due to a selection and then creates an active async grab that does not include touch events, then it currently won't get the touch end event which will produce inconsistent view of the pending touches. Note that we only need to consider touch listeners and can ignore pointer emulation. Under XI2 if a active grab replaces a passive implicit grab and the active grab does not include the button release event, the client won't get it either.
This commit is contained in:
parent
c7730cfe55
commit
f682e0563f
19
dix/events.c
19
dix/events.c
|
@ -1482,14 +1482,27 @@ UpdateTouchesForGrab(DeviceIntPtr mouse)
|
|||
CLIENT_BITS(listener->listener) == grab->resource) {
|
||||
listener->listener = grab->resource;
|
||||
listener->level = grab->grabtype;
|
||||
listener->state = TOUCH_LISTENER_IS_OWNER;
|
||||
listener->window = grab->window;
|
||||
|
||||
if (grab->grabtype == CORE || grab->grabtype == XI ||
|
||||
!xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin))
|
||||
!xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin)) {
|
||||
|
||||
if (listener->type == TOUCH_LISTENER_REGULAR &&
|
||||
listener->state != TOUCH_LISTENER_AWAITING_BEGIN &&
|
||||
listener->state != TOUCH_LISTENER_HAS_END) {
|
||||
/* if the listener already got any events relating to the touch, we must send
|
||||
a touch end because the grab overrides the previous listener and won't
|
||||
itself send any touch events.
|
||||
*/
|
||||
TouchEmitTouchEnd(mouse, ti, 0, listener->listener);
|
||||
}
|
||||
listener->type = TOUCH_LISTENER_POINTER_GRAB;
|
||||
else
|
||||
} else {
|
||||
listener->type = TOUCH_LISTENER_GRAB;
|
||||
}
|
||||
|
||||
listener->state = TOUCH_LISTENER_IS_OWNER;
|
||||
|
||||
if (listener->grab)
|
||||
FreeGrab(listener->grab);
|
||||
listener->grab = AllocGrab(grab);
|
||||
|
|
Loading…
Reference in New Issue