dix: Remove temporary detachment of slave devices.

Previously, an active grab on an attached slave device would send the device
floating for the duration of the grab. This breaks existing XI applications
(e.g. the GIMP) since they grab all devices automatically - resulting in the
loss of control over the VCP.

The behaviour of extended input devices during a grab in relation to the
core pointer is not specified in the XI protocol specification.
The removal of the temporary detachment restores the behaviour of extended
input devices as present in currently released servers - even if a device is
grabbed, an event from this device will result in an event from the core
pointer.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2009-07-12 21:43:06 +10:00
parent 9f1570c8f4
commit 0c0ef42292

View File

@ -1444,54 +1444,6 @@ CheckGrabForSyncs(DeviceIntPtr thisDev, Bool thisMode, Bool otherMode)
ComputeFreezes();
}
/* Only ever used if a grab is called on an attached slave device. */
static int GrabPrivateKeyIndex;
static DevPrivateKey GrabPrivateKey = &GrabPrivateKeyIndex;
/**
* Save the device's master device in the devPrivates. This needs to be done
* if a client directly grabs a slave device that is attached to a master. For
* the duration of the grab, the device is detached, ungrabbing re-attaches it
* though.
*
* We store the ID of the master device only in case the master disappears
* while the device has a grab.
*/
static void
DetachFromMaster(DeviceIntPtr dev)
{
int id;
if (!dev->u.master)
return;
id = dev->u.master->id;
dixSetPrivate(&dev->devPrivates, GrabPrivateKey, (void *)id);
AttachDevice(NULL, dev, NULL);
}
static void
ReattachToOldMaster(DeviceIntPtr dev)
{
int id;
void *p;
DeviceIntPtr master = NULL;
if (IsMaster(dev))
return;
p = dixLookupPrivate(&dev->devPrivates, GrabPrivateKey);
id = (int)p; /* silence gcc warnings */
dixLookupDevice(&master, id, serverClient, DixUseAccess);
if (master)
{
AttachDevice(serverClient, dev, master);
dixSetPrivate(&dev->devPrivates, GrabPrivateKey, NULL);
}
}
/**
* Activate a pointer grab on the given device. A pointer grab will cause all
* core pointer events of this device to be delivered to the grabbing client only.
@ -1517,10 +1469,6 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
: mouse->spriteInfo->sprite->win;
Bool isPassive = autoGrab & ~ImplicitGrabMask;
/* slave devices need to float for the duration of the grab. */
if (!(autoGrab & ImplicitGrabMask) && !IsMaster(mouse))
DetachFromMaster(mouse);
if (grab->confineTo)
{
if (grab->confineTo->drawable.pScreen
@ -1555,8 +1503,6 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
{
GrabPtr grab = mouse->deviceGrab.grab;
DeviceIntPtr dev;
Bool wasImplicit = (mouse->deviceGrab.fromPassiveGrab &&
mouse->deviceGrab.implicitGrab);
mouse->valuator->motionHintWindow = NullWindow;
mouse->deviceGrab.grab = NullGrab;
@ -1576,9 +1522,6 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
if (grab->cursor)
FreeCursor(grab->cursor, (Cursor)0);
if (!wasImplicit)
ReattachToOldMaster(mouse);
ComputeFreezes();
}
@ -1593,10 +1536,6 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool pass
GrabInfoPtr grabinfo = &keybd->deviceGrab;
WindowPtr oldWin;
/* slave devices need to float for the duration of the grab. */
if (!(passive & ImplicitGrabMask) && !IsMaster(keybd))
DetachFromMaster(keybd);
if (grabinfo->grab)
oldWin = grabinfo->grab->window;
else if (keybd->focus)
@ -1629,8 +1568,6 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd)
DeviceIntPtr dev;
WindowPtr focusWin = keybd->focus ? keybd->focus->win
: keybd->spriteInfo->sprite->win;
Bool wasImplicit = (keybd->deviceGrab.fromPassiveGrab &&
keybd->deviceGrab.implicitGrab);
if (focusWin == FollowKeyboardWin)
focusWin = inputInfo.keyboard->focus->win;
@ -1647,9 +1584,6 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd)
}
DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
if (!wasImplicit)
ReattachToOldMaster(keybd);
ComputeFreezes();
}