diff options
author | Peter Hutterer <peter@cs.unisa.edu.au> | 2007-04-27 13:24:27 +0930 |
---|---|---|
committer | Peter Hutterer <peter@cs.unisa.edu.au> | 2007-04-27 13:24:27 +0930 |
commit | 339b73e710a0920608a3fbcb20b406f0f6c4e0f6 (patch) | |
tree | 4f130a3b2368f315706de8086d2e7afd6229737b | |
parent | cfc01115af4136b2dad8218ba6b389513a356a2e (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.c | 27 | ||||
-rw-r--r-- | include/dix.h | 1 |
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 */); |