dix: change Enter/Leave semaphore handling to accommodate for NotifyGrab.
This is a half-assed attempt at getting rid of some enter-leave problems. When a grab is activated, the events didn't get sent before, leading to interesting results. This commit papers over it but doesn't actually fix it properly. The whole enter/leave (focusin/out) structure needs to be ripped out and changed for multiple devices.
This commit is contained in:
parent
f965a5f345
commit
05106ac983
26
dix/events.c
26
dix/events.c
|
@ -4160,7 +4160,7 @@ EnterLeaveEvent(
|
||||||
* Sending multiple core enter/leave events to the same window confuse the
|
* Sending multiple core enter/leave events to the same window confuse the
|
||||||
* client.
|
* client.
|
||||||
* We can send multiple events that have detail NotifyVirtual or
|
* We can send multiple events that have detail NotifyVirtual or
|
||||||
* NotifyNonlinearVirtual however.
|
* NotifyNonlinearVirtual however. For most clients anyway.
|
||||||
*
|
*
|
||||||
* For standard events (NotifyAncestor, NotifyInferior, NotifyNonlinear)
|
* For standard events (NotifyAncestor, NotifyInferior, NotifyNonlinear)
|
||||||
* we only send an enter event for the first pointer to enter. A leave
|
* we only send an enter event for the first pointer to enter. A leave
|
||||||
|
@ -4183,8 +4183,6 @@ EnterLeaveEvent(
|
||||||
if (event.u.u.detail != NotifyVirtual &&
|
if (event.u.u.detail != NotifyVirtual &&
|
||||||
event.u.u.detail != NotifyNonlinearVirtual)
|
event.u.u.detail != NotifyNonlinearVirtual)
|
||||||
{
|
{
|
||||||
(type == EnterNotify) ? (*inWindow)++ : (*inWindow)--;
|
|
||||||
|
|
||||||
if (((*inWindow) == (LeaveNotify - type)))
|
if (((*inWindow) == (LeaveNotify - type)))
|
||||||
sendevent = TRUE;
|
sendevent = TRUE;
|
||||||
} else
|
} else
|
||||||
|
@ -4289,6 +4287,22 @@ LeaveNotifies(DeviceIntPtr pDev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define FOCUS_SEMAPHORE_MODIFY(win, field, mode, val) \
|
||||||
|
{ \
|
||||||
|
if (mode != NotifyGrab && mode != NotifyUngrab) \
|
||||||
|
{ \
|
||||||
|
FocusSemaphoresPtr sem;\
|
||||||
|
sem = (FocusSemaphoresPtr)win->devPrivates[FocusPrivatesIndex].ptr; \
|
||||||
|
sem->field += val; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
#define ENTER_LEAVE_SEMAPHORE_UP(win, mode) \
|
||||||
|
FOCUS_SEMAPHORE_MODIFY(win, enterleave, mode, 1);
|
||||||
|
|
||||||
|
#define ENTER_LEAVE_SEMAPHORE_DOWN(win, mode) \
|
||||||
|
FOCUS_SEMAPHORE_MODIFY(win, enterleave, mode, -1);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Figure out if enter/leave events are necessary and send them to the
|
* Figure out if enter/leave events are necessary and send them to the
|
||||||
* appropriate windows.
|
* appropriate windows.
|
||||||
|
@ -4306,27 +4320,33 @@ DoEnterLeaveEvents(DeviceIntPtr pDev,
|
||||||
return;
|
return;
|
||||||
if (IsParent(fromWin, toWin))
|
if (IsParent(fromWin, toWin))
|
||||||
{
|
{
|
||||||
|
ENTER_LEAVE_SEMAPHORE_DOWN(fromWin, mode);
|
||||||
EnterLeaveEvent(pDev, LeaveNotify, mode, NotifyInferior, fromWin,
|
EnterLeaveEvent(pDev, LeaveNotify, mode, NotifyInferior, fromWin,
|
||||||
None);
|
None);
|
||||||
EnterNotifies(pDev, fromWin, toWin, mode,
|
EnterNotifies(pDev, fromWin, toWin, mode,
|
||||||
NotifyVirtual);
|
NotifyVirtual);
|
||||||
|
ENTER_LEAVE_SEMAPHORE_UP(toWin, mode);
|
||||||
EnterLeaveEvent(pDev, EnterNotify, mode, NotifyAncestor, toWin, None);
|
EnterLeaveEvent(pDev, EnterNotify, mode, NotifyAncestor, toWin, None);
|
||||||
}
|
}
|
||||||
else if (IsParent(toWin, fromWin))
|
else if (IsParent(toWin, fromWin))
|
||||||
{
|
{
|
||||||
|
ENTER_LEAVE_SEMAPHORE_DOWN(fromWin, mode);
|
||||||
EnterLeaveEvent(pDev, LeaveNotify, mode, NotifyAncestor, fromWin,
|
EnterLeaveEvent(pDev, LeaveNotify, mode, NotifyAncestor, fromWin,
|
||||||
None);
|
None);
|
||||||
LeaveNotifies(pDev, fromWin, toWin, mode, NotifyVirtual);
|
LeaveNotifies(pDev, fromWin, toWin, mode, NotifyVirtual);
|
||||||
|
ENTER_LEAVE_SEMAPHORE_UP(toWin, mode);
|
||||||
EnterLeaveEvent(pDev, EnterNotify, mode, NotifyInferior, toWin, None);
|
EnterLeaveEvent(pDev, EnterNotify, mode, NotifyInferior, toWin, None);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /* neither fromWin nor toWin is descendent of the other */
|
{ /* neither fromWin nor toWin is descendent of the other */
|
||||||
WindowPtr common = CommonAncestor(toWin, fromWin);
|
WindowPtr common = CommonAncestor(toWin, fromWin);
|
||||||
/* common == NullWindow ==> different screens */
|
/* common == NullWindow ==> different screens */
|
||||||
|
ENTER_LEAVE_SEMAPHORE_DOWN(fromWin, mode);
|
||||||
EnterLeaveEvent(pDev, LeaveNotify, mode, NotifyNonlinear, fromWin,
|
EnterLeaveEvent(pDev, LeaveNotify, mode, NotifyNonlinear, fromWin,
|
||||||
None);
|
None);
|
||||||
LeaveNotifies(pDev, fromWin, common, mode, NotifyNonlinearVirtual);
|
LeaveNotifies(pDev, fromWin, common, mode, NotifyNonlinearVirtual);
|
||||||
EnterNotifies(pDev, common, toWin, mode, NotifyNonlinearVirtual);
|
EnterNotifies(pDev, common, toWin, mode, NotifyNonlinearVirtual);
|
||||||
|
ENTER_LEAVE_SEMAPHORE_UP(toWin, mode);
|
||||||
EnterLeaveEvent(pDev, EnterNotify, mode, NotifyNonlinear, toWin,
|
EnterLeaveEvent(pDev, EnterNotify, mode, NotifyNonlinear, toWin,
|
||||||
None);
|
None);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue