dix: Use DeliverGrabbedEvent for implicit passive grabs (#25400)

A client requesting a GrabModeSync button grab, owner-events true, with only
the ButtonRelease mask set would never receive the press event even if the
grab window had the ButtonPress mask set.

The protocol requires that if owner-events is true, then the delivery mask
is the combination of the grab mask + the window event mask.

DeliverGrabbedEvents does this already for us, checking first the delivery
based on owner_events and then based on the grab mask. AFAICT, the device
cannot enter the states FREEZE_BOTH_NEXT_EVENT or FREEZE_NEXT_EVENT that
would be handled by DGE in any possible path here.

Bonus point - CheckPassiveGrabsOnWindows suddenly becomes a lot lesss
complicated.

X.Org Bug 25400 <http://bugs.freedesktop.org/show_bug.cgi?id=25400>

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
Peter Hutterer 2010-02-25 12:49:21 +10:00 committed by Keith Packard
parent de86a3a344
commit cf72b5437d

View File

@ -3462,7 +3462,6 @@ CheckPassiveGrabsOnWindow(
{ {
DeviceIntPtr gdev; DeviceIntPtr gdev;
XkbSrvInfoPtr xkbi = NULL; XkbSrvInfoPtr xkbi = NULL;
Mask mask = 0;
gdev= grab->modifierDevice; gdev= grab->modifierDevice;
if (grab->grabtype == GRABTYPE_CORE) if (grab->grabtype == GRABTYPE_CORE)
@ -3515,10 +3514,6 @@ CheckPassiveGrabsOnWindow(
(grab->confineTo->realized && (grab->confineTo->realized &&
BorderSizeNotEmpty(device, grab->confineTo)))) BorderSizeNotEmpty(device, grab->confineTo))))
{ {
int rc, count = 0;
xEvent *xE = NULL;
xEvent core;
event->corestate &= 0x1f00; event->corestate &= 0x1f00;
event->corestate |= tempGrab.modifiersDetail.exact & (~0x1f00); event->corestate |= tempGrab.modifiersDetail.exact & (~0x1f00);
grabinfo = &device->deviceGrab; grabinfo = &device->deviceGrab;
@ -3565,62 +3560,8 @@ CheckPassiveGrabsOnWindow(
} }
if (match & CORE_MATCH)
{
rc = EventToCore((InternalEvent*)event, &core);
if (rc != Success)
{
if (rc != BadMatch)
ErrorF("[dix] %s: core conversion failed in CPGFW "
"(%d, %d).\n", device->name, event->type, rc);
continue;
}
xE = &core;
count = 1;
mask = grab->eventMask;
} else if (match & XI2_MATCH)
{
rc = EventToXI2((InternalEvent*)event, &xE);
if (rc != Success)
{
if (rc != BadMatch)
ErrorF("[dix] %s: XI2 conversion failed in CPGFW "
"(%d, %d).\n", device->name, event->type, rc);
continue;
}
count = 1;
/* FIXME: EventToXI2 returns NULL for enter events, so
* dereferencing the event is bad. Internal event types are
* aligned with core events, so the else clause is valid.
* long-term we should use internal events for enter/focus
* as well */
if (xE)
mask = grab->xi2mask[device->id][((xGenericEvent*)xE)->evtype/8];
else if (event->type == XI_Enter || event->type == XI_FocusIn)
mask = grab->xi2mask[device->id][event->type/8];
} else
{
rc = EventToXI((InternalEvent*)event, &xE, &count);
if (rc != Success)
{
if (rc != BadMatch)
ErrorF("[dix] %s: XI conversion failed in CPGFW "
"(%d, %d).\n", device->name, event->type, rc);
continue;
}
mask = grab->eventMask;
}
(*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE); (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE);
DeliverGrabbedEvent((InternalEvent*)event, device, FALSE);
if (xE)
{
FixUpEventFromWindow(device, xE, grab->window, None, TRUE);
TryClientEvents(rClient(grab), device, xE, count, mask,
GetEventFilter(device, xE), grab);
}
if (grabinfo->sync.state == FROZEN_NO_EVENT) if (grabinfo->sync.state == FROZEN_NO_EVENT)
{ {
@ -3630,8 +3571,6 @@ CheckPassiveGrabsOnWindow(
grabinfo->sync.state = FROZEN_WITH_EVENT; grabinfo->sync.state = FROZEN_WITH_EVENT;
} }
if (match & (XI_MATCH | XI2_MATCH))
xfree(xE); /* on core match xE == &core */
return TRUE; return TRUE;
} }
} }