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:
parent
0b48506782
commit
1eebb03a31
29
dix/events.c
29
dix/events.c
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue