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:
Peter Hutterer 2007-10-03 11:33:10 +09:30
parent f965a5f345
commit 05106ac983

View File

@ -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);
} }