dix: ignore passive grab if the client already has a grab on the device.

In some cases a button press may activate a passive core grab. If the client
owning the passive grab already has a core grab on another device, don't
actually activate it. Otherwise the client gets two simultaneous passive
core grabs, and may never ungrab the device again (only if the other grab uses
GrabModeSync).

Reproducable: fire up gnome-session, open up gnome-terminal. Click with the
ClientPointer onto the window decoration, then click with another pointer onto
an application icon in the panel. Drag the icon out, release the button and
voila - you just lost your second mouse.
This commit is contained in:
Peter Hutterer 2007-10-03 15:18:17 +09:30
parent 0b48506782
commit 1eebb03a31

View File

@ -3297,6 +3297,35 @@ CheckPassiveGrabsOnWindow(
grab->modifierDevice = GetPairedKeyboard(device);
}
/* In some cases a passive core grab may exist, but the client
* already has a core grab on some other device. In this case we
* must not get the grab, otherwise we may never ungrab the
* device.
*/
if (grab->coreGrab)
{
DeviceIntPtr other;
BOOL interfering = FALSE;
for (other = inputInfo.devices; other; other = other->next)
{
GrabPtr othergrab = other->deviceGrab.grab;
if (othergrab && othergrab->coreGrab &&
SameClient(grab, rClient(othergrab)) &&
((IsPointerDevice(grab->device) &&
IsPointerDevice(othergrab->device)) ||
(IsKeyboardDevice(grab->device) &&
IsKeyboardDevice(othergrab->device))))
{
interfering = TRUE;
break;
}
}
if (interfering)
continue;
}
(*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE);
FixUpEventFromWindow(device, xE, grab->window, None, TRUE);