Change core enter/leave semantics for multiple pointers.

Send EnterNotify when first device enters the window, LeaveNotify when the
last device leaves the window. Additional devices will not cause additional
Enter/LeaveNotifies.
This commit is contained in:
Peter Hutterer 2007-04-12 16:24:42 +09:30
parent 547d720938
commit e7b47b1758
5 changed files with 42 additions and 6 deletions

View File

@ -2270,7 +2270,10 @@ DefineInitialRootWindow(WindowPtr win)
while (pDev)
{
if (DevHasCursor(pDev))
{
InitializeSprite(pDev, win);
win->devPrivates[EnterLeavePrivatesIndex].val++;
}
pDev = pDev->next;
}
}
@ -3447,6 +3450,7 @@ EnterLeaveEvent(
GrabPtr grab = mouse->coreGrab.grab;
GrabPtr devgrab = mouse->deviceGrab.grab;
Mask mask;
long* inWindow; /* no of sprites inside pWin */
deviceEnterNotify *devEnterLeave;
int mskidx;
@ -3492,14 +3496,23 @@ EnterLeaveEvent(
IsParent(focus, pWin)))
event.u.enterLeave.flags |= ELFlagFocus;
inWindow = &pWin->devPrivates[EnterLeavePrivatesIndex].val;
(type == EnterNotify) ? (*inWindow)++ : (*inWindow)--;
if (mask & filters[type])
{
if (grab)
(void)TryClientEvents(rClient(grab), &event, 1, mask,
filters[type], grab);
else
(void)DeliverEventsToWindow(pDev, pWin, &event, 1, filters[type],
NullGrab, 0);
/* only send core events for the first device to enter and the last
one to leave */
if ((*inWindow) == (LeaveNotify - type))
{
if (grab)
(void)TryClientEvents(rClient(grab), &event, 1, mask,
filters[type], grab);
else
(void)DeliverEventsToWindow(pDev, pWin, &event, 1, filters[type],
NullGrab, 0);
}
}
devEnterLeave = (deviceEnterNotify*)&event;

View File

@ -391,6 +391,8 @@ main(int argc, char *argv[], char *envp[])
FatalError("failed to create scratch GCs");
if (!CreateDefaultStipple(i))
FatalError("failed to create default stipple");
if (!InitWindowPrivates(pScreen))
FatalError("Failed to init window privates.");
if (!CreateRootWindow(pScreen))
FatalError("failed to create root window");
}

View File

@ -155,6 +155,8 @@ _X_EXPORT int screenIsSaved = SCREEN_SAVER_OFF;
_X_EXPORT ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
_X_EXPORT int EnterLeavePrivatesIndex = -1;
#if 0
extern void DeleteWindowFromAnyEvents();
extern Mask EventMaskForClient();
@ -3969,6 +3971,22 @@ WindowParentHasDeviceCursor(WindowPtr pWin,
return FALSE;
}
/**
* Initialize some mandatory devPrivates for windows.
*
* At the moment, this includes only the enter/leave semaphore.
*
* Returns TRUE on success.
*/
_X_EXPORT Bool
InitWindowPrivates(ScreenPtr screen)
{
if (EnterLeavePrivatesIndex == -1)
EnterLeavePrivatesIndex = AllocateWindowPrivateIndex();
return AllocateWindowPrivate(screen, EnterLeavePrivatesIndex, 0);
}
#ifndef NOLOGOHACK
static void
DrawLogo(WindowPtr pWin)

View File

@ -268,4 +268,6 @@ extern void DisableMapUnmapEvents(
extern void EnableMapUnmapEvents(
WindowPtr /* pWin */ );
Bool InitWindowPrivates(
ScreenPtr /* screen */);
#endif /* WINDOW_H */

View File

@ -216,6 +216,7 @@ typedef struct _ScreenSaverStuff {
extern int screenIsSaved;
extern ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
extern int EnterLeavePrivatesIndex;
/*
* this is the configuration parameter "NO_BACK_SAVE"