dix: restore commit b3b2a6a0d4 that for some

reason got wiped.
        fix ProcGrabKeyboard to use PickKeyboard
        fix PickKeyboard to actually work.
This commit is contained in:
Peter Hutterer 2007-03-09 17:13:05 +10:30
parent 07806f4081
commit 577464af43
2 changed files with 67 additions and 5 deletions

View File

@ -1706,6 +1706,11 @@ DeliverEventsToWindow(DeviceIntPtr pDev, register WindowPtr pWin, xEvent
if (filter != CantBeFiltered && if (filter != CantBeFiltered &&
!((wOtherEventMasks(pWin)|pWin->eventMask) & filter)) !((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
return 0; return 0;
if (!(type & EXTENSION_EVENT_BASE) &&
IsInterferingGrab(wClient(pWin), pDev, pEvents))
return 0;
if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count, if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count,
pWin->eventMask, filter, grab)) ) pWin->eventMask, filter, grab)) )
{ {
@ -1734,6 +1739,11 @@ DeliverEventsToWindow(DeviceIntPtr pDev, register WindowPtr pWin, xEvent
other = (InputClients *)wOtherClients(pWin); other = (InputClients *)wOtherClients(pWin);
for (; other; other = other->next) 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, if ( (attempt = TryClientEvents(rClient(other), pEvents, count,
other->mask[mskidx], filter, grab)) ) other->mask[mskidx], filter, grab)) )
{ {
@ -4144,11 +4154,12 @@ ProcGrabKeyboard(ClientPtr client)
xGrabKeyboardReply rep; xGrabKeyboardReply rep;
REQUEST(xGrabKeyboardReq); REQUEST(xGrabKeyboardReq);
int result; int result;
DeviceIntPtr keyboard = PickKeyboard(client);
REQUEST_SIZE_MATCH(xGrabKeyboardReq); REQUEST_SIZE_MATCH(xGrabKeyboardReq);
if (XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE)) if (XaceHook(XACE_DEVICE_ACCESS, client, keyboard, TRUE))
result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode, result = GrabDevice(client, keyboard, stuff->keyboardMode,
stuff->pointerMode, stuff->grabWindow, stuff->pointerMode, stuff->grabWindow,
stuff->ownerEvents, stuff->time, stuff->ownerEvents, stuff->time,
KeyPressMask | KeyReleaseMask, &rep.status); KeyPressMask | KeyReleaseMask, &rep.status);
@ -4169,7 +4180,7 @@ ProcGrabKeyboard(ClientPtr client)
int int
ProcUngrabKeyboard(ClientPtr client) ProcUngrabKeyboard(ClientPtr client)
{ {
DeviceIntPtr device = inputInfo.keyboard; DeviceIntPtr device = PickKeyboard(client);
GrabPtr grab; GrabPtr grab;
TimeStamp time; TimeStamp time;
REQUEST(xResourceReq); REQUEST(xResourceReq);
@ -4902,8 +4913,8 @@ PickPointer(ClientPtr client)
_X_EXPORT DeviceIntPtr _X_EXPORT DeviceIntPtr
PickKeyboard(ClientPtr client) PickKeyboard(ClientPtr client)
{ {
DeviceIntPtr dev; DeviceIntPtr ptr;
DeviceIntPtr ptr = inputInfo.devices; DeviceIntPtr dev = inputInfo.devices;
ptr = PickPointer(client); ptr = PickPointer(client);
while(dev) while(dev)
@ -4916,3 +4927,49 @@ PickKeyboard(ClientPtr client)
return inputInfo.keyboard; 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;
}

View File

@ -614,6 +614,11 @@ extern DeviceIntPtr PickPointer(
extern DeviceIntPtr PickKeyboard( extern DeviceIntPtr PickKeyboard(
ClientPtr /* client */); ClientPtr /* client */);
extern Bool IsInterferingGrab(
ClientPtr /* client */,
DeviceIntPtr /* dev */,
xEvent* /* events */);
#ifdef PANORAMIX #ifdef PANORAMIX
extern void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff); extern void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff);
#endif #endif