From a25f248fc3bd0375d91ca8a44320200d445ecfbb Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 27 May 2009 15:47:12 +1000 Subject: [PATCH] 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 --- Xi/exevents.c | 10 +++++----- dix/enterleave.c | 3 ++- dix/events.c | 35 +++++++++++++++++++++++++---------- include/dix.h | 1 + 4 files changed, 33 insertions(+), 16 deletions(-) diff --git a/Xi/exevents.c b/Xi/exevents.c index 91a3461384..781f4b8580 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -1872,7 +1872,7 @@ DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev) switch (dev->focus->revert) { case RevertToNone: - if (!ActivateFocusInGrab(dev, NoneWin)) + if (!ActivateFocusInGrab(dev, pWin, NoneWin)) DoFocusEvents(dev, pWin, NoneWin, focusEventMode); dev->focus->win = NoneWin; dev->focus->traceGood = 0; @@ -1884,13 +1884,13 @@ DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev) dev->focus->traceGood--; } while (!parent->realized); - if (!ActivateFocusInGrab(dev, parent)) + if (!ActivateFocusInGrab(dev, pWin, parent)) DoFocusEvents(dev, pWin, parent, focusEventMode); dev->focus->win = parent; dev->focus->revert = RevertToNone; break; case RevertToPointerRoot: - if (!ActivateFocusInGrab(dev, PointerRootWin)) + if (!ActivateFocusInGrab(dev, pWin, PointerRootWin)) DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode); dev->focus->win = PointerRootWin; dev->focus->traceGood = 0; @@ -1901,12 +1901,12 @@ DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev) if (!kbd || (kbd == dev && kbd != inputInfo.keyboard)) kbd = inputInfo.keyboard; if (kbd->focus->win) { - if (!ActivateFocusInGrab(dev, kbd->focus->win)) + if (!ActivateFocusInGrab(dev, pWin, kbd->focus->win)) DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode); dev->focus->win = FollowKeyboardWin; dev->focus->traceGood = 0; } else { - if (!ActivateFocusInGrab(dev, NoneWin)) + if (!ActivateFocusInGrab(dev, pWin, NoneWin)) DoFocusEvents(dev, pWin, NoneWin, focusEventMode); dev->focus->win = NoneWin; dev->focus->traceGood = 0; diff --git a/dix/enterleave.c b/dix/enterleave.c index eadcc4558e..d7f5f58bce 100644 --- a/dix/enterleave.c +++ b/dix/enterleave.c @@ -609,7 +609,8 @@ DoEnterLeaveEvents(DeviceIntPtr pDev, if (fromWin == toWin) return; - CoreEnterLeaveEvents(pDev, fromWin, toWin, mode); + if (mode != XINotifyPassiveGrab && mode != XINotifyPassiveUngrab) + CoreEnterLeaveEvents(pDev, fromWin, toWin, mode); DeviceEnterLeaveEvents(pDev, fromWin, toWin, mode); } diff --git a/dix/events.c b/dix/events.c index 5d22016f72..503a58d761 100644 --- a/dix/events.c +++ b/dix/events.c @@ -2635,8 +2635,9 @@ XYToWindow(DeviceIntPtr pDev, int x, int y) * @returns TRUE if the device has been grabbed, or FALSE otherwise. */ BOOL -ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr win) +ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win) { + BOOL rc = FALSE; DeviceEvent event; if (dev->deviceGrab.grab && @@ -2646,6 +2647,7 @@ ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr win) if (dev->deviceGrab.grab->window == win || IsParent(dev->deviceGrab.grab->window, win)) return FALSE; + DoEnterLeaveEvents(dev, old, win, XINotifyPassiveUngrab); (*dev->deviceGrab.DeactivateGrab)(dev); } @@ -2660,18 +2662,22 @@ ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr win) event.deviceid = dev->id; event.sourceid = dev->id; 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. * * @returns TRUE if the device has been grabbed, or FALSE otherwise. */ static BOOL -ActivateEnterGrab(DeviceIntPtr dev, WindowPtr win) +ActivateEnterGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win) { + BOOL rc = FALSE; DeviceEvent event; if (dev->deviceGrab.grab && @@ -2681,6 +2687,7 @@ ActivateEnterGrab(DeviceIntPtr dev, WindowPtr win) if (dev->deviceGrab.grab->window == win || IsParent(dev->deviceGrab.grab->window, win)) return FALSE; + DoEnterLeaveEvents(dev, old, win, XINotifyPassiveUngrab); (*dev->deviceGrab.DeactivateGrab)(dev); } @@ -2692,7 +2699,11 @@ ActivateEnterGrab(DeviceIntPtr dev, WindowPtr win) event.deviceid = dev->id; event.sourceid = dev->id; 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(); if (prevSpriteWin != NullWindow) { - if (!ActivateEnterGrab(pDev, newSpriteWin)) + if (!ActivateEnterGrab(pDev, prevSpriteWin, newSpriteWin)) DoEnterLeaveEvents(pDev, prevSpriteWin, newSpriteWin, NotifyNormal); } @@ -4267,6 +4278,10 @@ DeviceEnterLeaveEvent( int btlen, len, i; DeviceIntPtr kbd; + if ((mode == XINotifyPassiveGrab && type == XI_Leave) || + (mode == XINotifyPassiveUngrab && type == XI_Enter)) + return; + btlen = (mouse->button) ? (mouse->button->numButtons + 7)/8 : 0; btlen = (btlen + 3)/4; len = sizeof(xXIEnterEvent) + btlen * 4; @@ -4426,11 +4441,11 @@ SetInputFocus( mode = (dev->deviceGrab.grab) ? NotifyWhileGrabbed : NotifyNormal; if (focus->win == FollowKeyboardWin) { - if (!ActivateFocusInGrab(dev, focusWin)) + if (!ActivateFocusInGrab(dev, keybd->focus->win, focusWin)) DoFocusEvents(dev, keybd->focus->win, focusWin, mode); } else { - if (!ActivateFocusInGrab(dev, focusWin)) + if (!ActivateFocusInGrab(dev, focus->win, focusWin)) DoFocusEvents(dev, focus->win, focusWin, mode); } focus->time = time; @@ -5413,13 +5428,13 @@ DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources) || clients[CLIENT_ID(parent->drawable.id)]->clientGone #endif ); - if (!ActivateFocusInGrab(keybd, parent)) + if (!ActivateFocusInGrab(keybd, pWin, parent)) DoFocusEvents(keybd, pWin, parent, focusEventMode); focus->win = parent; focus->revert = RevertToNone; break; case RevertToPointerRoot: - if (!ActivateFocusInGrab(keybd, PointerRootWin)) + if (!ActivateFocusInGrab(keybd, pWin, PointerRootWin)) DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode); focus->win = PointerRootWin; focus->traceGood = 0; diff --git a/include/dix.h b/include/dix.h index bfb0369337..df73519c8e 100644 --- a/include/dix.h +++ b/include/dix.h @@ -352,6 +352,7 @@ extern void DeactivateKeyboardGrab( extern BOOL ActivateFocusInGrab( DeviceIntPtr /* dev */, + WindowPtr /* old */, WindowPtr /* win */); extern void AllowSome(