summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter@cs.unisa.edu.au>2007-04-27 13:24:27 +0930
committerPeter Hutterer <peter@cs.unisa.edu.au>2007-04-27 13:24:27 +0930
commit339b73e710a0920608a3fbcb20b406f0f6c4e0f6 (patch)
tree4f130a3b2368f315706de8086d2e7afd6229737b
parentcfc01115af4136b2dad8218ba6b389513a356a2e (diff)
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.
-rw-r--r--dix/events.c27
-rw-r--r--include/dix.h1
2 files changed, 22 insertions, 6 deletions
diff --git a/dix/events.c b/dix/events.c
index a751e3c6a..da3f6aa7e 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1729,7 +1729,7 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
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, WindowPtr pWin, xEvent
{
/* 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, DeviceIntPtr dev, xEvent* event)
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 9da265deb..93472e832 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 */);