xserver: Branch 'mpx'

Peter Hutterer whot at kemper.freedesktop.org
Tue Apr 17 04:52:14 EEST 2007


 dix/events.c |   59 +++++++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 45 insertions(+), 14 deletions(-)

New commits:
diff-tree 451d5464b4e8a2516b8a4598b3c4eb14656be90e (from ea27b09d3a973d9a4943f205b24940b8624cf405)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Tue Apr 17 11:17:04 2007 +0930

    Change enter/leave semantics for events with detail Notify{Nonlinear}Virtual.
    
    Core enter/leave events with detail Notify{Ancestor|Inferior|Nonlinear} are
    only sent for the first/last pointer to enter/leave. Events with detail
    Notify{Nonlinear}Virtual are sent at all times, but not to those windows that
    currently have one or more pointers inside their boundaries.

diff --git a/dix/events.c b/dix/events.c
index e515f10..def209e 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -281,7 +281,7 @@ static void DoEnterLeaveEvents(
     WindowPtr fromWin,
     WindowPtr toWin,
     int mode
-);
+); 
 
 static WindowPtr XYToWindow(
     int x,
@@ -3453,6 +3453,7 @@ EnterLeaveEvent(
     GrabPtr	        devgrab = mouse->deviceGrab.grab;
     Mask		mask;
     long*               inWindow; /* no of sprites inside pWin */
+    Bool                sendevent = FALSE;        
 
     deviceEnterNotify   *devEnterLeave;
     int                 mskidx;
@@ -3503,21 +3504,51 @@ EnterLeaveEvent(
 
     inWindow = &pWin->devPrivates[EnterLeavePrivatesIndex].val;
 
-    (type == EnterNotify) ? (*inWindow)++ : (*inWindow)--;
+    /*
+     * Sending multiple core enter/leave events to the same window confuse the
+     * client.  
+     * We can send multiple events that have detail NotifyVirtual or
+     * NotifyNonlinearVirtual however.
+     *
+     * For standard events (NotifyAncestor, NotifyInferior, NotifyNonlinear)
+     * we only send an enter event for the first pointer to enter. A leave
+     * event is sent for the last pointer to leave. 
+     *
+     * For events with Virtual detail, we send them only to a window that does
+     * not have a pointer inside.
+     *
+     * For a window tree in the form of 
+     *
+     * A -> Bp -> C -> D 
+     *  \               (where B and E have pointers)
+     *    -> Ep         
+     *    
+     * If the pointer moves from E into D, a LeaveNotify is sent to E, an
+     * EnterNotify is sent to D, an EnterNotify with detail
+     * NotifyNonlinearVirtual to C and nothing to B.
+     */
 
-    if (mask & filters[type])
+    if (event.u.u.detail != NotifyVirtual && 
+            event.u.u.detail != NotifyNonlinearVirtual)
     {
-        /* only send core events for the first device to enter and the last
-           one to leave */
-        if ((*inWindow) == (LeaveNotify - type))
-        {
-            if (grab)
-                (void)TryClientEvents(rClient(grab), &event, 1, mask,
-                                      filters[type], grab);
-            else
-                (void)DeliverEventsToWindow(mouse, pWin, &event, 1, filters[type],
-                                            NullGrab, 0);
-        }
+        (type == EnterNotify) ? (*inWindow)++ : (*inWindow)--;
+
+        if (((*inWindow) == (LeaveNotify - type)))
+            sendevent = TRUE;
+    } else
+    {
+        if (!(*inWindow))
+            sendevent = TRUE;
+    }
+
+    if ((mask & filters[type]) && sendevent)
+    {
+        if (grab)
+            (void)TryClientEvents(rClient(grab), &event, 1, mask,
+                                  filters[type], grab);
+        else
+            (void)DeliverEventsToWindow(mouse, pWin, &event, 1, filters[type],
+                                        NullGrab, 0);
     }
 
     devEnterLeave = (deviceEnterNotify*)&event;



More information about the xorg-commit mailing list