Change FocusIn/Out semantics to match Enter/Leave semantics.
This commit is contained in:
parent
451d5464b4
commit
b6aec7f6f9
58
dix/events.c
58
dix/events.c
|
@ -2272,7 +2272,7 @@ DefineInitialRootWindow(WindowPtr win)
|
|||
if (DevHasCursor(pDev))
|
||||
{
|
||||
InitializeSprite(pDev, win);
|
||||
win->devPrivates[EnterLeavePrivatesIndex].val++;
|
||||
win->devPrivates[FocusPrivatesIndex].val++;
|
||||
}
|
||||
pDev = pDev->next;
|
||||
}
|
||||
|
@ -3452,7 +3452,7 @@ EnterLeaveEvent(
|
|||
GrabPtr grab = mouse->coreGrab.grab;
|
||||
GrabPtr devgrab = mouse->deviceGrab.grab;
|
||||
Mask mask;
|
||||
long* inWindow; /* no of sprites inside pWin */
|
||||
int* inWindow; /* no of sprites inside pWin */
|
||||
Bool sendevent = FALSE;
|
||||
|
||||
deviceEnterNotify *devEnterLeave;
|
||||
|
@ -3502,7 +3502,7 @@ EnterLeaveEvent(
|
|||
IsParent(focus, pWin)))
|
||||
event.u.enterLeave.flags |= ELFlagFocus;
|
||||
|
||||
inWindow = &pWin->devPrivates[EnterLeavePrivatesIndex].val;
|
||||
inWindow = &((FocusSemaphoresPtr)pWin->devPrivates[FocusPrivatesIndex].ptr)->enterleave;
|
||||
|
||||
/*
|
||||
* Sending multiple core enter/leave events to the same window confuse the
|
||||
|
@ -3665,9 +3665,60 @@ static void
|
|||
FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin)
|
||||
{
|
||||
xEvent event;
|
||||
int* numFoci; /* no of foci the window has already */
|
||||
Bool sendevent = FALSE;
|
||||
FocusSemaphoresPtr focus;
|
||||
|
||||
if (dev != inputInfo.keyboard)
|
||||
DeviceFocusEvent(dev, type, mode, detail, pWin);
|
||||
|
||||
/*
|
||||
* Same procedure as for Enter/Leave events.
|
||||
*
|
||||
* Sending multiple core FocusIn/Out events to the same window may confuse
|
||||
* the client.
|
||||
* We can send multiple events that have detail NotifyVirtual,
|
||||
* NotifyNonlinearVirtual, NotifyPointerRoot, NotifyDetailNone or
|
||||
* NotifyPointer however.
|
||||
*
|
||||
* For standard events (NotifyAncestor, NotifyInferior, NotifyNonlinear)
|
||||
* we only send an FocusIn event for the first kbd to set the focus. A
|
||||
* FocusOut event is sent for the last kbd to set the focus away from the
|
||||
* window..
|
||||
*
|
||||
* For events with Virtual detail, we send them only to a window that does
|
||||
* not have a focus from another keyboard.
|
||||
*
|
||||
* For a window tree in the form of
|
||||
*
|
||||
* A -> Bf -> C -> D
|
||||
* \ (where B and E have focus)
|
||||
* -> Ef
|
||||
*
|
||||
* If the focus changes from E into D, a FocusOut is sent to E, a
|
||||
* FocusIn is sent to D, a FocusIn with detail
|
||||
* NotifyNonlinearVirtual to C and nothing to B.
|
||||
*/
|
||||
|
||||
numFoci =
|
||||
&((FocusSemaphoresPtr)pWin->devPrivates[FocusPrivatesIndex].ptr)->focusinout;
|
||||
if (detail != NotifyVirtual &&
|
||||
detail != NotifyNonlinearVirtual &&
|
||||
detail != NotifyPointer &&
|
||||
detail != NotifyPointerRoot &&
|
||||
detail != NotifyDetailNone)
|
||||
{
|
||||
(type == FocusIn) ? (*numFoci)++ : (*numFoci)--;
|
||||
if (((*numFoci) == (FocusOut - type)))
|
||||
sendevent = TRUE;
|
||||
} else
|
||||
{
|
||||
if (!(*numFoci))
|
||||
sendevent = TRUE;
|
||||
}
|
||||
|
||||
if (sendevent)
|
||||
{
|
||||
event.u.focus.mode = mode;
|
||||
event.u.u.type = type;
|
||||
event.u.u.detail = detail;
|
||||
|
@ -3689,6 +3740,7 @@ FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin)
|
|||
KeymapStateMask, NullGrab, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* recursive because it is easier
|
||||
|
|
15
dix/window.c
15
dix/window.c
|
@ -155,7 +155,7 @@ _X_EXPORT int screenIsSaved = SCREEN_SAVER_OFF;
|
|||
|
||||
_X_EXPORT ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
|
||||
|
||||
_X_EXPORT int EnterLeavePrivatesIndex = -1;
|
||||
_X_EXPORT int FocusPrivatesIndex = -1;
|
||||
|
||||
#if 0
|
||||
extern void DeleteWindowFromAnyEvents();
|
||||
|
@ -312,6 +312,12 @@ SetWindowToDefaults(WindowPtr pWin)
|
|||
#ifdef COMPOSITE
|
||||
pWin->redirectDraw = 0;
|
||||
#endif
|
||||
|
||||
((FocusSemaphoresPtr)
|
||||
pWin->devPrivates[FocusPrivatesIndex].ptr)->enterleave = 0;
|
||||
((FocusSemaphoresPtr)
|
||||
pWin->devPrivates[FocusPrivatesIndex].ptr)->focusinout = 0;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -3981,10 +3987,11 @@ WindowParentHasDeviceCursor(WindowPtr pWin,
|
|||
_X_EXPORT Bool
|
||||
InitWindowPrivates(ScreenPtr screen)
|
||||
{
|
||||
if (EnterLeavePrivatesIndex == -1)
|
||||
EnterLeavePrivatesIndex = AllocateWindowPrivateIndex();
|
||||
if (FocusPrivatesIndex == -1)
|
||||
FocusPrivatesIndex = AllocateWindowPrivateIndex();
|
||||
|
||||
return AllocateWindowPrivate(screen, EnterLeavePrivatesIndex, 0);
|
||||
return AllocateWindowPrivate(screen, FocusPrivatesIndex,
|
||||
sizeof(FocusSemaphoresRec));
|
||||
}
|
||||
|
||||
#ifndef NOLOGOHACK
|
||||
|
|
|
@ -391,5 +391,4 @@ typedef struct _QdEvent {
|
|||
int evcount;
|
||||
} QdEventRec;
|
||||
|
||||
#define MPXDBG(...) ErrorF("MPX: " __VA_ARGS__ )
|
||||
#endif /* INPUTSTRUCT_H */
|
||||
|
|
|
@ -216,7 +216,15 @@ typedef struct _ScreenSaverStuff {
|
|||
|
||||
extern int screenIsSaved;
|
||||
extern ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
|
||||
extern int EnterLeavePrivatesIndex;
|
||||
extern int FocusPrivatesIndex;
|
||||
|
||||
/* Used to maintain semantics of core protocol for Enter/LeaveNotifies and
|
||||
* FocusIn/Out events for multiple pointers/keyboards.
|
||||
*/
|
||||
typedef struct _FocusSemaphores {
|
||||
int enterleave;
|
||||
int focusinout;
|
||||
} FocusSemaphoresRec, *FocusSemaphoresPtr;
|
||||
|
||||
/*
|
||||
* this is the configuration parameter "NO_BACK_SAVE"
|
||||
|
|
Loading…
Reference in New Issue