From 577464af4362e5a32cf7165b5128655dd86c6200 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 9 Mar 2007 17:13:05 +1030 Subject: [PATCH] dix: restore commit b3b2a6a0d43d1724e04d69588f8a55c3270e5523 that for some reason got wiped. fix ProcGrabKeyboard to use PickKeyboard fix PickKeyboard to actually work. --- dix/events.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++---- include/dix.h | 5 ++++ 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