dix: change the filters to be per-device.
If we have one global filter, one pointer may change the filter value and affect another pointer. Reproduceable effect: blackbox and xterm, start dragging xterm then click anywhere with the other pointer (attached to different masterd device!). The button release resets the filter[Motion_Filter(button)] value, thus stopping dragging and no event is sent to the client anymore. Having the filters set per device gets around this.
This commit is contained in:
parent
0931f40bf1
commit
f44d7dcb5f
|
@ -550,7 +550,7 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
|
||||||
return DONT_PROCESS;
|
return DONT_PROCESS;
|
||||||
if (b->map[key] <= 5)
|
if (b->map[key] <= 5)
|
||||||
b->state |= (Button1Mask >> 1) << b->map[key];
|
b->state |= (Button1Mask >> 1) << b->map[key];
|
||||||
SetMaskForEvent(Motion_Filter(b), DeviceMotionNotify);
|
SetMaskForEvent(device->id, Motion_Filter(b), DeviceMotionNotify);
|
||||||
} else if (xE->u.u.type == DeviceButtonRelease) {
|
} else if (xE->u.u.type == DeviceButtonRelease) {
|
||||||
if (!b)
|
if (!b)
|
||||||
return DONT_PROCESS;
|
return DONT_PROCESS;
|
||||||
|
@ -567,7 +567,7 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
|
||||||
return DONT_PROCESS;
|
return DONT_PROCESS;
|
||||||
if (b->map[key] <= 5)
|
if (b->map[key] <= 5)
|
||||||
b->state &= ~((Button1Mask >> 1) << b->map[key]);
|
b->state &= ~((Button1Mask >> 1) << b->map[key]);
|
||||||
SetMaskForEvent(Motion_Filter(b), DeviceMotionNotify);
|
SetMaskForEvent(device->id, Motion_Filter(b), DeviceMotionNotify);
|
||||||
} else if (xE->u.u.type == ProximityIn)
|
} else if (xE->u.u.type == ProximityIn)
|
||||||
device->valuator->mode &= ~OutOfProximity;
|
device->valuator->mode &= ~OutOfProximity;
|
||||||
else if (xE->u.u.type == ProximityOut)
|
else if (xE->u.u.type == ProximityOut)
|
||||||
|
|
12
Xi/extinit.c
12
Xi/extinit.c
|
@ -827,13 +827,16 @@ SetExclusiveAccess(Mask mask)
|
||||||
static void
|
static void
|
||||||
SetMaskForExtEvent(Mask mask, int event)
|
SetMaskForExtEvent(Mask mask, int event)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
EventInfo[ExtEventIndex].mask = mask;
|
EventInfo[ExtEventIndex].mask = mask;
|
||||||
EventInfo[ExtEventIndex++].type = event;
|
EventInfo[ExtEventIndex++].type = event;
|
||||||
|
|
||||||
if ((event < LASTEvent) || (event >= 128))
|
if ((event < LASTEvent) || (event >= 128))
|
||||||
FatalError("MaskForExtensionEvent: bogus event number");
|
FatalError("MaskForExtensionEvent: bogus event number");
|
||||||
SetMaskForEvent(mask, event);
|
|
||||||
|
for (i = 0; i < MAX_DEVICES; i++)
|
||||||
|
SetMaskForEvent(i, mask, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
@ -974,13 +977,16 @@ FixExtensionEvents(ExtensionEntry * extEntry)
|
||||||
static void
|
static void
|
||||||
RestoreExtensionEvents(void)
|
RestoreExtensionEvents(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i, j;
|
||||||
|
|
||||||
IReqCode = 0;
|
IReqCode = 0;
|
||||||
|
|
||||||
for (i = 0; i < ExtEventIndex - 1; i++) {
|
for (i = 0; i < ExtEventIndex - 1; i++) {
|
||||||
if ((EventInfo[i].type >= LASTEvent) && (EventInfo[i].type < 128))
|
if ((EventInfo[i].type >= LASTEvent) && (EventInfo[i].type < 128))
|
||||||
SetMaskForEvent(0, EventInfo[i].type);
|
{
|
||||||
|
for (j = 0; j < MAX_DEVICES; j++)
|
||||||
|
SetMaskForEvent(j, 0, EventInfo[i].type);
|
||||||
|
}
|
||||||
EventInfo[i].mask = 0;
|
EventInfo[i].mask = 0;
|
||||||
EventInfo[i].type = 0;
|
EventInfo[i].type = 0;
|
||||||
}
|
}
|
||||||
|
|
64
dix/events.c
64
dix/events.c
|
@ -367,8 +367,12 @@ static Mask lastEventMask;
|
||||||
|
|
||||||
extern int DeviceMotionNotify;
|
extern int DeviceMotionNotify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event filters. One set of filters for each device, but only the first layer
|
||||||
|
* is initialized. The rest is memcpy'd in InitEvents.
|
||||||
|
*/
|
||||||
#define CantBeFiltered NoEventMask
|
#define CantBeFiltered NoEventMask
|
||||||
static Mask filters[128] =
|
static Mask filters[MAX_DEVICES][128] = {
|
||||||
{
|
{
|
||||||
NoSuchEvent, /* 0 */
|
NoSuchEvent, /* 0 */
|
||||||
NoSuchEvent, /* 1 */
|
NoSuchEvent, /* 1 */
|
||||||
|
@ -405,7 +409,7 @@ static Mask filters[128] =
|
||||||
ColormapChangeMask, /* ColormapNotify */
|
ColormapChangeMask, /* ColormapNotify */
|
||||||
CantBeFiltered, /* ClientMessage */
|
CantBeFiltered, /* ClientMessage */
|
||||||
CantBeFiltered /* MappingNotify */
|
CantBeFiltered /* MappingNotify */
|
||||||
};
|
}};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -787,17 +791,19 @@ XineramaChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor)
|
||||||
#endif /* PANORAMIX */
|
#endif /* PANORAMIX */
|
||||||
|
|
||||||
void
|
void
|
||||||
SetMaskForEvent(Mask mask, int event)
|
SetMaskForEvent(int deviceid, Mask mask, int event)
|
||||||
{
|
{
|
||||||
int coretype;
|
int coretype;
|
||||||
|
if (deviceid < 0 || deviceid > MAX_DEVICES)
|
||||||
|
FatalError("SetMaskForEvent: bogus device id");
|
||||||
if ((event < LASTEvent) || (event >= 128))
|
if ((event < LASTEvent) || (event >= 128))
|
||||||
FatalError("SetMaskForEvent: bogus event number");
|
FatalError("SetMaskForEvent: bogus event number");
|
||||||
filters[event] = mask;
|
filters[deviceid][event] = mask;
|
||||||
|
|
||||||
/* Need to change the mask for the core events too */
|
/* Need to change the mask for the core events too */
|
||||||
coretype = XItoCoreType(event);
|
coretype = XItoCoreType(event);
|
||||||
if (coretype)
|
if (coretype)
|
||||||
filters[coretype] = mask;
|
filters[deviceid][coretype] = mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
_X_EXPORT void
|
_X_EXPORT void
|
||||||
|
@ -2440,7 +2446,7 @@ DeliverDeviceEvents(WindowPtr pWin, xEvent *xE, GrabPtr grab,
|
||||||
{
|
{
|
||||||
Window child = None;
|
Window child = None;
|
||||||
int type = xE->u.u.type;
|
int type = xE->u.u.type;
|
||||||
Mask filter = filters[type];
|
Mask filter = filters[dev->id][type];
|
||||||
int deliveries = 0;
|
int deliveries = 0;
|
||||||
|
|
||||||
if (type & EXTENSION_EVENT_BASE)
|
if (type & EXTENSION_EVENT_BASE)
|
||||||
|
@ -2555,7 +2561,9 @@ DeliverEvents(WindowPtr pWin, xEvent *xE, int count,
|
||||||
|
|
||||||
if (!count)
|
if (!count)
|
||||||
return 0;
|
return 0;
|
||||||
filter = filters[xE->u.u.type];
|
/* We don't know a device here. However, this should only ever be called
|
||||||
|
for a non-device event so we are safe to use 0*/
|
||||||
|
filter = filters[0][xE->u.u.type];
|
||||||
if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
|
if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
|
||||||
xE->u.destroyNotify.event = pWin->drawable.id;
|
xE->u.destroyNotify.event = pWin->drawable.id;
|
||||||
if (filter != StructureAndSubMask)
|
if (filter != StructureAndSubMask)
|
||||||
|
@ -3466,8 +3474,8 @@ CheckPassiveGrabsOnWindow(
|
||||||
FixUpEventFromWindow(device, xE, grab->window, None, TRUE);
|
FixUpEventFromWindow(device, xE, grab->window, None, TRUE);
|
||||||
|
|
||||||
(void) TryClientEvents(rClient(grab), xE, count,
|
(void) TryClientEvents(rClient(grab), xE, count,
|
||||||
filters[xE->u.u.type],
|
filters[device->id][xE->u.u.type],
|
||||||
filters[xE->u.u.type], grab);
|
filters[device->id][xE->u.u.type], grab);
|
||||||
|
|
||||||
if (grabinfo->sync.state == FROZEN_NO_EVENT)
|
if (grabinfo->sync.state == FROZEN_NO_EVENT)
|
||||||
{
|
{
|
||||||
|
@ -3590,7 +3598,8 @@ DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
|
||||||
FixUpEventFromWindow(pointer, xE, focus, None, FALSE);
|
FixUpEventFromWindow(pointer, xE, focus, None, FALSE);
|
||||||
if (xE->u.u.type & EXTENSION_EVENT_BASE)
|
if (xE->u.u.type & EXTENSION_EVENT_BASE)
|
||||||
mskidx = keybd->id;
|
mskidx = keybd->id;
|
||||||
(void)DeliverEventsToWindow(keybd, focus, xE, count, filters[xE->u.u.type],
|
(void)DeliverEventsToWindow(keybd, focus, xE, count,
|
||||||
|
filters[keybd->id][xE->u.u.type],
|
||||||
NullGrab, mskidx);
|
NullGrab, mskidx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3671,7 +3680,7 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
|
||||||
IsInterferingGrab(rClient(grab), thisDev, xE)))
|
IsInterferingGrab(rClient(grab), thisDev, xE)))
|
||||||
{
|
{
|
||||||
deliveries = TryClientEvents(rClient(grab), xE, count,
|
deliveries = TryClientEvents(rClient(grab), xE, count,
|
||||||
mask, filters[xE->u.u.type], grab);
|
mask, filters[thisDev->id][xE->u.u.type], grab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (deliveries && (xE->u.u.type == MotionNotify
|
if (deliveries && (xE->u.u.type == MotionNotify
|
||||||
|
@ -3989,7 +3998,7 @@ ProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count)
|
||||||
*/
|
*/
|
||||||
if (xE->u.u.detail == 0)
|
if (xE->u.u.detail == 0)
|
||||||
return;
|
return;
|
||||||
filters[MotionNotify] = Motion_Filter(butc);
|
filters[mouse->id][Motion_Filter(butc)] = MotionNotify;
|
||||||
if (!grab)
|
if (!grab)
|
||||||
if (CheckDeviceGrabs(mouse, xE, 0, count))
|
if (CheckDeviceGrabs(mouse, xE, 0, count))
|
||||||
return;
|
return;
|
||||||
|
@ -3997,7 +4006,7 @@ ProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count)
|
||||||
case ButtonRelease:
|
case ButtonRelease:
|
||||||
if (xE->u.u.detail == 0)
|
if (xE->u.u.detail == 0)
|
||||||
return;
|
return;
|
||||||
filters[MotionNotify] = Motion_Filter(butc);
|
filters[mouse->id][Motion_Filter(butc)] = MotionNotify;
|
||||||
if (!butc->state && mouse->deviceGrab.fromPassiveGrab)
|
if (!butc->state && mouse->deviceGrab.fromPassiveGrab)
|
||||||
deactivateGrab = TRUE;
|
deactivateGrab = TRUE;
|
||||||
break;
|
break;
|
||||||
|
@ -4350,14 +4359,14 @@ EnterLeaveEvent(
|
||||||
sendevent = TRUE;
|
sendevent = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mask & filters[type]) && sendevent)
|
if ((mask & filters[mouse->id][type]) && sendevent)
|
||||||
{
|
{
|
||||||
if (grab)
|
if (grab)
|
||||||
(void)TryClientEvents(rClient(grab), &event, 1, mask,
|
(void)TryClientEvents(rClient(grab), &event, 1, mask,
|
||||||
filters[type], grab);
|
filters[mouse->id][type], grab);
|
||||||
else
|
else
|
||||||
(void)DeliverEventsToWindow(mouse, pWin, &event, 1, filters[type],
|
(void)DeliverEventsToWindow(mouse, pWin, &event, 1,
|
||||||
NullGrab, 0);
|
filters[mouse->id][type], NullGrab, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we don't have enough bytes, so we squash flags and mode into
|
/* we don't have enough bytes, so we squash flags and mode into
|
||||||
|
@ -4372,15 +4381,17 @@ EnterLeaveEvent(
|
||||||
mskidx = mouse->id;
|
mskidx = mouse->id;
|
||||||
inputMasks = wOtherInputMasks(pWin);
|
inputMasks = wOtherInputMasks(pWin);
|
||||||
if (inputMasks &&
|
if (inputMasks &&
|
||||||
(filters[devEnterLeave->type] & inputMasks->deliverableEvents[mskidx]))
|
(filters[mouse->id][devEnterLeave->type] &
|
||||||
|
inputMasks->deliverableEvents[mskidx]))
|
||||||
{
|
{
|
||||||
if (devgrab)
|
if (devgrab)
|
||||||
(void)TryClientEvents(rClient(devgrab), (xEvent*)devEnterLeave, 1,
|
(void)TryClientEvents(rClient(devgrab), (xEvent*)devEnterLeave, 1,
|
||||||
mask, filters[devEnterLeave->type], devgrab);
|
mask, filters[mouse->id][devEnterLeave->type],
|
||||||
|
devgrab);
|
||||||
else
|
else
|
||||||
(void)DeliverEventsToWindow(mouse, pWin, (xEvent*)devEnterLeave,
|
(void)DeliverEventsToWindow(mouse, pWin, (xEvent*)devEnterLeave,
|
||||||
1, filters[devEnterLeave->type],
|
1, filters[mouse->id][devEnterLeave->type],
|
||||||
NullGrab, mouse->id);
|
NullGrab, mouse->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((type == EnterNotify) && (mask & KeymapStateMask))
|
if ((type == EnterNotify) && (mask & KeymapStateMask))
|
||||||
|
@ -4579,8 +4590,8 @@ FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin)
|
||||||
event.u.u.type = type;
|
event.u.u.type = type;
|
||||||
event.u.u.detail = detail;
|
event.u.u.detail = detail;
|
||||||
event.u.focus.window = pWin->drawable.id;
|
event.u.focus.window = pWin->drawable.id;
|
||||||
(void)DeliverEventsToWindow(dev, pWin, &event, 1, filters[type], NullGrab,
|
(void)DeliverEventsToWindow(dev, pWin, &event, 1,
|
||||||
0);
|
filters[dev->id][type], NullGrab, 0);
|
||||||
if ((type == FocusIn) &&
|
if ((type == FocusIn) &&
|
||||||
((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
|
((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
|
||||||
{
|
{
|
||||||
|
@ -5528,7 +5539,12 @@ InitEvents(void)
|
||||||
inputInfo.keyboard = (DeviceIntPtr)NULL;
|
inputInfo.keyboard = (DeviceIntPtr)NULL;
|
||||||
inputInfo.pointer = (DeviceIntPtr)NULL;
|
inputInfo.pointer = (DeviceIntPtr)NULL;
|
||||||
lastEventMask = OwnerGrabButtonMask;
|
lastEventMask = OwnerGrabButtonMask;
|
||||||
filters[MotionNotify] = PointerMotionMask;
|
filters[0][PointerMotionMask] = MotionNotify;
|
||||||
|
for (i = 1; i < MAX_DEVICES; i++)
|
||||||
|
{
|
||||||
|
memcpy(&filters[i], filters[0], sizeof(filters[0]));
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef XEVIE
|
#ifdef XEVIE
|
||||||
xeviewin = NULL;
|
xeviewin = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -345,6 +345,7 @@ extern void SetVendorString(char *string);
|
||||||
/* events.c */
|
/* events.c */
|
||||||
|
|
||||||
extern void SetMaskForEvent(
|
extern void SetMaskForEvent(
|
||||||
|
int /* deviceid */,
|
||||||
Mask /* mask */,
|
Mask /* mask */,
|
||||||
int /* event */);
|
int /* event */);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue