dix: rework temporary slave detachment.
Rework addresses two issues: - storing the master device's pointer is a bad idea, we need to store the ID of the device in case it disappears during the grab. - restoring the old master did not actually reattach the device. Fixed now.
This commit is contained in:
parent
b3e4810a28
commit
f56ad22e8f
55
dix/events.c
55
dix/events.c
|
@ -1435,44 +1435,47 @@ CheckGrabForSyncs(DeviceIntPtr thisDev, Bool thisMode, Bool otherMode)
|
||||||
/* Only ever used if a grab is called on an attached slave device. */
|
/* Only ever used if a grab is called on an attached slave device. */
|
||||||
static int GrabPrivateKeyIndex;
|
static int GrabPrivateKeyIndex;
|
||||||
static DevPrivateKey GrabPrivateKey = &GrabPrivateKeyIndex;
|
static DevPrivateKey GrabPrivateKey = &GrabPrivateKeyIndex;
|
||||||
typedef struct _GrabMemoryRec {
|
|
||||||
DeviceIntPtr oldmaster;
|
|
||||||
} GrabMemoryRec, *GrabMemoryPtr;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the device's master device in the devPrivates. This needs to be done
|
* 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
|
* 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
|
* the duration of the grab, the device is detached, ungrabbing re-attaches it
|
||||||
* though.
|
* though.
|
||||||
|
*
|
||||||
|
* We store the ID of the master device only in case the master disappears
|
||||||
|
* while the device has a grab.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
SaveOldMaster(DeviceIntPtr dev)
|
DetachFromMaster(DeviceIntPtr dev)
|
||||||
{
|
{
|
||||||
GrabMemoryPtr gm;
|
int id;
|
||||||
|
if (!dev->u.master)
|
||||||
if (!(gm = xalloc(sizeof(GrabMemoryRec))))
|
|
||||||
{
|
|
||||||
ErrorF("[dix] Cannot allocate grab private. Grab not "
|
|
||||||
"possible on device.\n");
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
gm->oldmaster = dev->u.master;
|
id = dev->u.master->id;
|
||||||
dixSetPrivate(&dev->devPrivates, GrabPrivateKey, gm);
|
|
||||||
|
dixSetPrivate(&dev->devPrivates, GrabPrivateKey, (void *)id);
|
||||||
|
AttachDevice(NULL, dev, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
RestoreOldMaster(DeviceIntPtr dev)
|
ReattachToOldMaster(DeviceIntPtr dev)
|
||||||
{
|
{
|
||||||
GrabMemoryPtr gm;
|
int id;
|
||||||
|
void *p;
|
||||||
|
DeviceIntPtr master = NULL;
|
||||||
|
|
||||||
if (IsMaster(dev))
|
if (IsMaster(dev))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gm = (GrabMemoryPtr)dixLookupPrivate(&dev->devPrivates, GrabPrivateKey);
|
|
||||||
if (gm)
|
p = dixLookupPrivate(&dev->devPrivates, GrabPrivateKey);
|
||||||
|
id = (int)p; /* silence gcc warnings */
|
||||||
|
dixLookupDevice(&master, id, serverClient, DixUseAccess);
|
||||||
|
|
||||||
|
if (master)
|
||||||
{
|
{
|
||||||
dev->u.master = gm->oldmaster;
|
AttachDevice(serverClient, dev, master);
|
||||||
xfree(gm);
|
|
||||||
dixSetPrivate(&dev->devPrivates, GrabPrivateKey, NULL);
|
dixSetPrivate(&dev->devPrivates, GrabPrivateKey, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1504,10 +1507,7 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
|
||||||
|
|
||||||
/* slave devices need to float for the duration of the grab. */
|
/* slave devices need to float for the duration of the grab. */
|
||||||
if (!isPassive && !IsMaster(mouse))
|
if (!isPassive && !IsMaster(mouse))
|
||||||
{
|
DetachFromMaster(mouse);
|
||||||
SaveOldMaster(mouse);
|
|
||||||
AttachDevice(NULL, mouse, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (grab->confineTo)
|
if (grab->confineTo)
|
||||||
{
|
{
|
||||||
|
@ -1564,7 +1564,7 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
|
||||||
FreeCursor(grab->cursor, (Cursor)0);
|
FreeCursor(grab->cursor, (Cursor)0);
|
||||||
|
|
||||||
if (!wasPassive)
|
if (!wasPassive)
|
||||||
RestoreOldMaster(mouse);
|
ReattachToOldMaster(mouse);
|
||||||
|
|
||||||
ComputeFreezes();
|
ComputeFreezes();
|
||||||
}
|
}
|
||||||
|
@ -1582,10 +1582,7 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool pass
|
||||||
|
|
||||||
/* slave devices need to float for the duration of the grab. */
|
/* slave devices need to float for the duration of the grab. */
|
||||||
if (!passive && !IsMaster(keybd))
|
if (!passive && !IsMaster(keybd))
|
||||||
{
|
DetachFromMaster(keybd);
|
||||||
SaveOldMaster(keybd);
|
|
||||||
AttachDevice(NULL, keybd, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (grabinfo->grab)
|
if (grabinfo->grab)
|
||||||
oldWin = grabinfo->grab->window;
|
oldWin = grabinfo->grab->window;
|
||||||
|
@ -1637,7 +1634,7 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd)
|
||||||
DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
|
DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
|
||||||
|
|
||||||
if (!wasPassive)
|
if (!wasPassive)
|
||||||
RestoreOldMaster(keybd);
|
ReattachToOldMaster(keybd);
|
||||||
|
|
||||||
ComputeFreezes();
|
ComputeFreezes();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user