Xi: Send Enter or Leave events with XIPassive(Un)grabNotify

If a passive enter or focus in grab activates, send additional enter or
focus events with mode XIPassiveGrabNotify to the grabbing client.
Likewise, if the grab deactivates, send additional leave or focus out
events.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2009-05-27 15:47:12 +10:00
parent a7e23a79c1
commit a25f248fc3
4 changed files with 33 additions and 16 deletions

View File

@ -1872,7 +1872,7 @@ DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev)
switch (dev->focus->revert) { switch (dev->focus->revert) {
case RevertToNone: case RevertToNone:
if (!ActivateFocusInGrab(dev, NoneWin)) if (!ActivateFocusInGrab(dev, pWin, NoneWin))
DoFocusEvents(dev, pWin, NoneWin, focusEventMode); DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
dev->focus->win = NoneWin; dev->focus->win = NoneWin;
dev->focus->traceGood = 0; dev->focus->traceGood = 0;
@ -1884,13 +1884,13 @@ DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev)
dev->focus->traceGood--; dev->focus->traceGood--;
} }
while (!parent->realized); while (!parent->realized);
if (!ActivateFocusInGrab(dev, parent)) if (!ActivateFocusInGrab(dev, pWin, parent))
DoFocusEvents(dev, pWin, parent, focusEventMode); DoFocusEvents(dev, pWin, parent, focusEventMode);
dev->focus->win = parent; dev->focus->win = parent;
dev->focus->revert = RevertToNone; dev->focus->revert = RevertToNone;
break; break;
case RevertToPointerRoot: case RevertToPointerRoot:
if (!ActivateFocusInGrab(dev, PointerRootWin)) if (!ActivateFocusInGrab(dev, pWin, PointerRootWin))
DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode); DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode);
dev->focus->win = PointerRootWin; dev->focus->win = PointerRootWin;
dev->focus->traceGood = 0; dev->focus->traceGood = 0;
@ -1901,12 +1901,12 @@ DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev)
if (!kbd || (kbd == dev && kbd != inputInfo.keyboard)) if (!kbd || (kbd == dev && kbd != inputInfo.keyboard))
kbd = inputInfo.keyboard; kbd = inputInfo.keyboard;
if (kbd->focus->win) { if (kbd->focus->win) {
if (!ActivateFocusInGrab(dev, kbd->focus->win)) if (!ActivateFocusInGrab(dev, pWin, kbd->focus->win))
DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode); DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode);
dev->focus->win = FollowKeyboardWin; dev->focus->win = FollowKeyboardWin;
dev->focus->traceGood = 0; dev->focus->traceGood = 0;
} else { } else {
if (!ActivateFocusInGrab(dev, NoneWin)) if (!ActivateFocusInGrab(dev, pWin, NoneWin))
DoFocusEvents(dev, pWin, NoneWin, focusEventMode); DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
dev->focus->win = NoneWin; dev->focus->win = NoneWin;
dev->focus->traceGood = 0; dev->focus->traceGood = 0;

View File

@ -609,7 +609,8 @@ DoEnterLeaveEvents(DeviceIntPtr pDev,
if (fromWin == toWin) if (fromWin == toWin)
return; return;
CoreEnterLeaveEvents(pDev, fromWin, toWin, mode); if (mode != XINotifyPassiveGrab && mode != XINotifyPassiveUngrab)
CoreEnterLeaveEvents(pDev, fromWin, toWin, mode);
DeviceEnterLeaveEvents(pDev, fromWin, toWin, mode); DeviceEnterLeaveEvents(pDev, fromWin, toWin, mode);
} }

View File

@ -2635,8 +2635,9 @@ XYToWindow(DeviceIntPtr pDev, int x, int y)
* @returns TRUE if the device has been grabbed, or FALSE otherwise. * @returns TRUE if the device has been grabbed, or FALSE otherwise.
*/ */
BOOL BOOL
ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr win) ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
{ {
BOOL rc = FALSE;
DeviceEvent event; DeviceEvent event;
if (dev->deviceGrab.grab && if (dev->deviceGrab.grab &&
@ -2646,6 +2647,7 @@ ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr win)
if (dev->deviceGrab.grab->window == win || if (dev->deviceGrab.grab->window == win ||
IsParent(dev->deviceGrab.grab->window, win)) IsParent(dev->deviceGrab.grab->window, win))
return FALSE; return FALSE;
DoEnterLeaveEvents(dev, old, win, XINotifyPassiveUngrab);
(*dev->deviceGrab.DeactivateGrab)(dev); (*dev->deviceGrab.DeactivateGrab)(dev);
} }
@ -2660,18 +2662,22 @@ ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr win)
event.deviceid = dev->id; event.deviceid = dev->id;
event.sourceid = dev->id; event.sourceid = dev->id;
event.detail.button = 0; event.detail.button = 0;
return CheckPassiveGrabsOnWindow(win, dev, &event, FALSE); rc = CheckPassiveGrabsOnWindow(win, dev, &event, FALSE);
if (rc)
DoEnterLeaveEvents(dev, old, win, XINotifyPassiveUngrab);
return rc;
} }
/** /**
* Ungrab a currently Enter grabbed device and grab the deice for the given * Ungrab a currently Enter grabbed device and grab the device for the given
* window. * window.
* *
* @returns TRUE if the device has been grabbed, or FALSE otherwise. * @returns TRUE if the device has been grabbed, or FALSE otherwise.
*/ */
static BOOL static BOOL
ActivateEnterGrab(DeviceIntPtr dev, WindowPtr win) ActivateEnterGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
{ {
BOOL rc = FALSE;
DeviceEvent event; DeviceEvent event;
if (dev->deviceGrab.grab && if (dev->deviceGrab.grab &&
@ -2681,6 +2687,7 @@ ActivateEnterGrab(DeviceIntPtr dev, WindowPtr win)
if (dev->deviceGrab.grab->window == win || if (dev->deviceGrab.grab->window == win ||
IsParent(dev->deviceGrab.grab->window, win)) IsParent(dev->deviceGrab.grab->window, win))
return FALSE; return FALSE;
DoEnterLeaveEvents(dev, old, win, XINotifyPassiveUngrab);
(*dev->deviceGrab.DeactivateGrab)(dev); (*dev->deviceGrab.DeactivateGrab)(dev);
} }
@ -2692,7 +2699,11 @@ ActivateEnterGrab(DeviceIntPtr dev, WindowPtr win)
event.deviceid = dev->id; event.deviceid = dev->id;
event.sourceid = dev->id; event.sourceid = dev->id;
event.detail.button = 0; event.detail.button = 0;
return CheckPassiveGrabsOnWindow(win, dev, &event, FALSE); rc = CheckPassiveGrabsOnWindow(win, dev, &event, FALSE);
if (rc)
DoEnterLeaveEvents(dev, old, win, XINotifyPassiveGrab);
return rc;
} }
/** /**
@ -2795,7 +2806,7 @@ CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev)
UpdateCurrentTimeIf(); UpdateCurrentTimeIf();
if (prevSpriteWin != NullWindow) { if (prevSpriteWin != NullWindow) {
if (!ActivateEnterGrab(pDev, newSpriteWin)) if (!ActivateEnterGrab(pDev, prevSpriteWin, newSpriteWin))
DoEnterLeaveEvents(pDev, prevSpriteWin, DoEnterLeaveEvents(pDev, prevSpriteWin,
newSpriteWin, NotifyNormal); newSpriteWin, NotifyNormal);
} }
@ -4267,6 +4278,10 @@ DeviceEnterLeaveEvent(
int btlen, len, i; int btlen, len, i;
DeviceIntPtr kbd; DeviceIntPtr kbd;
if ((mode == XINotifyPassiveGrab && type == XI_Leave) ||
(mode == XINotifyPassiveUngrab && type == XI_Enter))
return;
btlen = (mouse->button) ? (mouse->button->numButtons + 7)/8 : 0; btlen = (mouse->button) ? (mouse->button->numButtons + 7)/8 : 0;
btlen = (btlen + 3)/4; btlen = (btlen + 3)/4;
len = sizeof(xXIEnterEvent) + btlen * 4; len = sizeof(xXIEnterEvent) + btlen * 4;
@ -4426,11 +4441,11 @@ SetInputFocus(
mode = (dev->deviceGrab.grab) ? NotifyWhileGrabbed : NotifyNormal; mode = (dev->deviceGrab.grab) ? NotifyWhileGrabbed : NotifyNormal;
if (focus->win == FollowKeyboardWin) if (focus->win == FollowKeyboardWin)
{ {
if (!ActivateFocusInGrab(dev, focusWin)) if (!ActivateFocusInGrab(dev, keybd->focus->win, focusWin))
DoFocusEvents(dev, keybd->focus->win, focusWin, mode); DoFocusEvents(dev, keybd->focus->win, focusWin, mode);
} else } else
{ {
if (!ActivateFocusInGrab(dev, focusWin)) if (!ActivateFocusInGrab(dev, focus->win, focusWin))
DoFocusEvents(dev, focus->win, focusWin, mode); DoFocusEvents(dev, focus->win, focusWin, mode);
} }
focus->time = time; focus->time = time;
@ -5413,13 +5428,13 @@ DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
|| clients[CLIENT_ID(parent->drawable.id)]->clientGone || clients[CLIENT_ID(parent->drawable.id)]->clientGone
#endif #endif
); );
if (!ActivateFocusInGrab(keybd, parent)) if (!ActivateFocusInGrab(keybd, pWin, parent))
DoFocusEvents(keybd, pWin, parent, focusEventMode); DoFocusEvents(keybd, pWin, parent, focusEventMode);
focus->win = parent; focus->win = parent;
focus->revert = RevertToNone; focus->revert = RevertToNone;
break; break;
case RevertToPointerRoot: case RevertToPointerRoot:
if (!ActivateFocusInGrab(keybd, PointerRootWin)) if (!ActivateFocusInGrab(keybd, pWin, PointerRootWin))
DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode); DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
focus->win = PointerRootWin; focus->win = PointerRootWin;
focus->traceGood = 0; focus->traceGood = 0;

View File

@ -352,6 +352,7 @@ extern void DeactivateKeyboardGrab(
extern BOOL ActivateFocusInGrab( extern BOOL ActivateFocusInGrab(
DeviceIntPtr /* dev */, DeviceIntPtr /* dev */,
WindowPtr /* old */,
WindowPtr /* win */); WindowPtr /* win */);
extern void AllowSome( extern void AllowSome(