xserver: Branch 'mpx'

Peter Hutterer whot at kemper.freedesktop.org
Fri Apr 27 08:10:22 EEST 2007


 dix/events.c  |   27 +++++++++++++++++++++------
 include/dix.h |    1 +
 2 files changed, 22 insertions(+), 6 deletions(-)

New commits:
diff-tree 339b73e710a0920608a3fbcb20b406f0f6c4e0f6 (from cfc01115af4136b2dad8218ba6b389513a356a2e)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Fri Apr 27 13:24:27 2007 +0930

    Allow events to grabWindows event if the device is not grabbed.
    
    This kinda makes popup windows useable if the WM doesn't set the
    ClientPointer. Kinda.

diff --git a/dix/events.c b/dix/events.c
index a751e3c..da3f6aa 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1729,7 +1729,7 @@ DeliverEventsToWindow(DeviceIntPtr pDev,
 	    return 0;
         
         if (!(type & EXTENSION_EVENT_BASE) && 
-            IsInterferingGrab(wClient(pWin), pDev, pEvents))
+            IsInterferingGrab(wClient(pWin), pWin, pDev, pEvents))
                 return 0;
 
 	if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count,
@@ -1762,7 +1762,7 @@ DeliverEventsToWindow(DeviceIntPtr pDev,
 	{
             /* core event? check for grab interference */
             if (!(type & EXTENSION_EVENT_BASE) &&
-                    IsInterferingGrab(rClient(other), pDev, pEvents))
+                    IsInterferingGrab(rClient(other), pWin, pDev, pEvents))
                 continue;
 
 	    if ( (attempt = TryClientEvents(rClient(other), pEvents, count,
@@ -5097,15 +5097,19 @@ PickKeyboard(ClientPtr client)
 /* A client that has one or more core grabs does not get core events from
  * devices it does not have a grab on. Legacy applications behave bad
  * otherwise because they are not used to it and the events interfere.
+ * The one exception is: if we're about to send an event to a window that is
+ * specified as grab window, we still do it. This makes popup menus
+ * half-useable for WMs that don't set the ClientPointer.
  * Only applies for core events.
  *
  * Return true if a core event from the device would interfere and should not
  * be delivered.
  */
 Bool 
-IsInterferingGrab(ClientPtr client, DeviceIntPtr dev, xEvent* event)
+IsInterferingGrab(ClientPtr client, WindowPtr win, DeviceIntPtr dev, xEvent* event)
 {
-    DeviceIntPtr it = inputInfo.devices;
+    DeviceIntPtr it;
+    Bool mayInterfere = FALSE;
 
     if (dev->coreGrab.grab && SameClient(dev->coreGrab.grab, client))
         return FALSE;
@@ -5124,19 +5128,30 @@ IsInterferingGrab(ClientPtr client, Devi
             return FALSE;
     }
 
+    it = inputInfo.devices;
     while(it)
     {
         if (it != dev)
         {
             if (it->coreGrab.grab && SameClient(it->coreGrab.grab, client))
             {
-                return TRUE;
+                /* there's a client with a grab on some device. 
+                 * if we're delivering to the very same window that is
+                 * grabbed (or a child), we're good */
+                WindowPtr parent = win;
+                while(parent)
+                {
+                    if (it->coreGrab.grab->window == parent)
+                        return FALSE;
+                    parent = parent->parent;
+                }
 
+                mayInterfere = TRUE;
             }
         }
         it = it->next;
     }
 
-    return FALSE;
+    return mayInterfere;
 }
 
diff --git a/include/dix.h b/include/dix.h
index 9da265d..93472e8 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -550,6 +550,7 @@ extern DeviceIntPtr PickKeyboard(
 
 extern Bool IsInterferingGrab(
         ClientPtr /* client */,
+        WindowPtr /* win */,
         DeviceIntPtr /* dev */,
         xEvent* /* events */);
 



More information about the xorg-commit mailing list