xserver: Branch 'master'

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Feb 15 04:37:43 UTC 2021


 dix/events.c |   19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

New commits:
commit f682e0563f736ed2c2c612ed575e05b6e3db945e
Author: Povilas Kanapickas <povilas at radix.lt>
Date:   Mon Feb 8 05:21:29 2021 +0200

    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.

diff --git a/dix/events.c b/dix/events.c
index 1441cff25..b05c95c43 100644
--- a/dix/events.c
+++ b/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);


More information about the xorg-commit mailing list