summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter@cs.unisa.edu.au>2007-03-09 17:13:05 +1030
committerPeter Hutterer <peter@cs.unisa.edu.au>2007-03-09 17:13:05 +1030
commit577464af4362e5a32cf7165b5128655dd86c6200 (patch)
treed10b8123dc2987061ee14289c6b52aca68676566
parent07806f4081f8dcd3b5733b590eb6e5b4cae734ad (diff)
dix: restore commit b3b2a6a0d43d1724e04d69588f8a55c3270e5523 that for some
reason got wiped. fix ProcGrabKeyboard to use PickKeyboard fix PickKeyboard to actually work.
-rw-r--r--dix/events.c67
-rw-r--r--include/dix.h5
2 files changed, 67 insertions, 5 deletions
diff --git a/dix/events.c b/dix/events.c
index 4e77577a8..b4b929f6c 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1706,6 +1706,11 @@ DeliverEventsToWindow(DeviceIntPtr pDev, register WindowPtr pWin, xEvent
if (filter != CantBeFiltered &&
!((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
return 0;
+
+ if (!(type & EXTENSION_EVENT_BASE) &&
+ IsInterferingGrab(wClient(pWin), pDev, pEvents))
+ return 0;
+
if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count,
pWin->eventMask, filter, grab)) )
{
@@ -1734,6 +1739,11 @@ DeliverEventsToWindow(DeviceIntPtr pDev, register WindowPtr pWin, xEvent
other = (InputClients *)wOtherClients(pWin);
for (; other; other = other->next)
{
+ /* core event? check for grab interference */
+ if (!(type & EXTENSION_EVENT_BASE) &&
+ IsInterferingGrab(rClient(other), pDev, pEvents))
+ continue;
+
if ( (attempt = TryClientEvents(rClient(other), pEvents, count,
other->mask[mskidx], filter, grab)) )
{
@@ -4144,11 +4154,12 @@ ProcGrabKeyboard(ClientPtr client)
xGrabKeyboardReply rep;
REQUEST(xGrabKeyboardReq);
int result;
+ DeviceIntPtr keyboard = PickKeyboard(client);
REQUEST_SIZE_MATCH(xGrabKeyboardReq);
- if (XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE))
- result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode,
+ if (XaceHook(XACE_DEVICE_ACCESS, client, keyboard, TRUE))
+ result = GrabDevice(client, keyboard, stuff->keyboardMode,
stuff->pointerMode, stuff->grabWindow,
stuff->ownerEvents, stuff->time,
KeyPressMask | KeyReleaseMask, &rep.status);
@@ -4169,7 +4180,7 @@ ProcGrabKeyboard(ClientPtr client)
int
ProcUngrabKeyboard(ClientPtr client)
{
- DeviceIntPtr device = inputInfo.keyboard;
+ DeviceIntPtr device = PickKeyboard(client);
GrabPtr grab;
TimeStamp time;
REQUEST(xResourceReq);
@@ -4902,8 +4913,8 @@ PickPointer(ClientPtr client)
_X_EXPORT DeviceIntPtr
PickKeyboard(ClientPtr client)
{
- DeviceIntPtr dev;
- DeviceIntPtr ptr = inputInfo.devices;
+ DeviceIntPtr ptr;
+ DeviceIntPtr dev = inputInfo.devices;
ptr = PickPointer(client);
while(dev)
@@ -4916,3 +4927,49 @@ PickKeyboard(ClientPtr client)
return inputInfo.keyboard;
}
+/* 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.
+ * 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)
+{
+ DeviceIntPtr it = inputInfo.devices;
+
+ if (dev->coreGrab.grab && SameClient(dev->coreGrab.grab, client))
+ return FALSE;
+
+ switch(event->u.u.type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ case EnterNotify:
+ case LeaveNotify:
+ break;
+ default:
+ return FALSE;
+ }
+
+ while(it)
+ {
+ if (it != dev)
+ {
+ if (it->coreGrab.grab && SameClient(it->coreGrab.grab, client))
+ {
+ return TRUE;
+
+ }
+ }
+ it = it->next;
+ }
+
+ return FALSE;
+}
+
diff --git a/include/dix.h b/include/dix.h
index 06dafbb70..57cdce33d 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -614,6 +614,11 @@ extern DeviceIntPtr PickPointer(
extern DeviceIntPtr PickKeyboard(
ClientPtr /* client */);
+extern Bool IsInterferingGrab(
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ xEvent* /* events */);
+
#ifdef PANORAMIX
extern void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff);
#endif