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))
|
if (DevHasCursor(pDev))
|
||||||
{
|
{
|
||||||
InitializeSprite(pDev, win);
|
InitializeSprite(pDev, win);
|
||||||
win->devPrivates[EnterLeavePrivatesIndex].val++;
|
win->devPrivates[FocusPrivatesIndex].val++;
|
||||||
}
|
}
|
||||||
pDev = pDev->next;
|
pDev = pDev->next;
|
||||||
}
|
}
|
||||||
|
@ -3452,7 +3452,7 @@ EnterLeaveEvent(
|
||||||
GrabPtr grab = mouse->coreGrab.grab;
|
GrabPtr grab = mouse->coreGrab.grab;
|
||||||
GrabPtr devgrab = mouse->deviceGrab.grab;
|
GrabPtr devgrab = mouse->deviceGrab.grab;
|
||||||
Mask mask;
|
Mask mask;
|
||||||
long* inWindow; /* no of sprites inside pWin */
|
int* inWindow; /* no of sprites inside pWin */
|
||||||
Bool sendevent = FALSE;
|
Bool sendevent = FALSE;
|
||||||
|
|
||||||
deviceEnterNotify *devEnterLeave;
|
deviceEnterNotify *devEnterLeave;
|
||||||
|
@ -3502,7 +3502,7 @@ EnterLeaveEvent(
|
||||||
IsParent(focus, pWin)))
|
IsParent(focus, pWin)))
|
||||||
event.u.enterLeave.flags |= ELFlagFocus;
|
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
|
* 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)
|
FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin)
|
||||||
{
|
{
|
||||||
xEvent event;
|
xEvent event;
|
||||||
|
int* numFoci; /* no of foci the window has already */
|
||||||
|
Bool sendevent = FALSE;
|
||||||
|
FocusSemaphoresPtr focus;
|
||||||
|
|
||||||
if (dev != inputInfo.keyboard)
|
if (dev != inputInfo.keyboard)
|
||||||
DeviceFocusEvent(dev, type, mode, detail, pWin);
|
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.focus.mode = mode;
|
||||||
event.u.u.type = type;
|
event.u.u.type = type;
|
||||||
event.u.u.detail = detail;
|
event.u.u.detail = detail;
|
||||||
|
@ -3689,6 +3740,7 @@ FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin)
|
||||||
KeymapStateMask, NullGrab, 0);
|
KeymapStateMask, NullGrab, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* recursive because it is easier
|
* 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 ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
|
||||||
|
|
||||||
_X_EXPORT int EnterLeavePrivatesIndex = -1;
|
_X_EXPORT int FocusPrivatesIndex = -1;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
extern void DeleteWindowFromAnyEvents();
|
extern void DeleteWindowFromAnyEvents();
|
||||||
|
@ -312,6 +312,12 @@ SetWindowToDefaults(WindowPtr pWin)
|
||||||
#ifdef COMPOSITE
|
#ifdef COMPOSITE
|
||||||
pWin->redirectDraw = 0;
|
pWin->redirectDraw = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
((FocusSemaphoresPtr)
|
||||||
|
pWin->devPrivates[FocusPrivatesIndex].ptr)->enterleave = 0;
|
||||||
|
((FocusSemaphoresPtr)
|
||||||
|
pWin->devPrivates[FocusPrivatesIndex].ptr)->focusinout = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -3981,10 +3987,11 @@ WindowParentHasDeviceCursor(WindowPtr pWin,
|
||||||
_X_EXPORT Bool
|
_X_EXPORT Bool
|
||||||
InitWindowPrivates(ScreenPtr screen)
|
InitWindowPrivates(ScreenPtr screen)
|
||||||
{
|
{
|
||||||
if (EnterLeavePrivatesIndex == -1)
|
if (FocusPrivatesIndex == -1)
|
||||||
EnterLeavePrivatesIndex = AllocateWindowPrivateIndex();
|
FocusPrivatesIndex = AllocateWindowPrivateIndex();
|
||||||
|
|
||||||
return AllocateWindowPrivate(screen, EnterLeavePrivatesIndex, 0);
|
return AllocateWindowPrivate(screen, FocusPrivatesIndex,
|
||||||
|
sizeof(FocusSemaphoresRec));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NOLOGOHACK
|
#ifndef NOLOGOHACK
|
||||||
|
|
|
@ -391,5 +391,4 @@ typedef struct _QdEvent {
|
||||||
int evcount;
|
int evcount;
|
||||||
} QdEventRec;
|
} QdEventRec;
|
||||||
|
|
||||||
#define MPXDBG(...) ErrorF("MPX: " __VA_ARGS__ )
|
|
||||||
#endif /* INPUTSTRUCT_H */
|
#endif /* INPUTSTRUCT_H */
|
||||||
|
|
|
@ -216,7 +216,15 @@ typedef struct _ScreenSaverStuff {
|
||||||
|
|
||||||
extern int screenIsSaved;
|
extern int screenIsSaved;
|
||||||
extern ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
|
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"
|
* this is the configuration parameter "NO_BACK_SAVE"
|
||||||
|
|
Loading…
Reference in New Issue