Change CheckMotion to ignore non-pointer events but acknowledge XI events.

Call CheckMotion from ProcessOtherEvents() to make sure absolute XI events
update the sprite before an event is sent.
This commit is contained in:
Peter Hutterer 2007-07-09 10:42:03 +09:30
parent 62efc3951a
commit 9809715afa
2 changed files with 52 additions and 22 deletions

View File

@ -129,6 +129,8 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
if (grab && grab->coreGrab && !device->deviceGrab.fromPassiveGrab) if (grab && grab->coreGrab && !device->deviceGrab.fromPassiveGrab)
return; return;
CheckMotion(xE, device);
if (xE->u.u.type != DeviceValuator && xE->u.u.type != GenericEvent) { if (xE->u.u.type != DeviceValuator && xE->u.u.type != GenericEvent) {
DeviceIntPtr mouse = NULL, kbd = NULL; DeviceIntPtr mouse = NULL, kbd = NULL;
GetSpritePosition(device, &rootX, &rootY); GetSpritePosition(device, &rootX, &rootY);

View File

@ -2449,10 +2449,16 @@ XYToWindow(DeviceIntPtr pDev, int x, int y)
* position, then update the event with the new coordinates that may have been * position, then update the event with the new coordinates that may have been
* changed. If the window underneath the sprite has changed, change to new * changed. If the window underneath the sprite has changed, change to new
* cursor and send enter/leave events. * cursor and send enter/leave events.
*
* CheckMotion() will not do anything and return FALSE if the event is not a
* pointer event.
*
* @return TRUE if the sprite has moved or FALSE otherwise.
*/ */
Bool Bool
CheckMotion(xEvent *xE, DeviceIntPtr pDev) CheckMotion(xEvent *xE, DeviceIntPtr pDev)
{ {
INT16 *rootX, *rootY;
WindowPtr prevSpriteWin; WindowPtr prevSpriteWin;
SpritePtr pSprite = pDev->spriteInfo->sprite; SpritePtr pSprite = pDev->spriteInfo->sprite;
@ -2465,21 +2471,44 @@ CheckMotion(xEvent *xE, DeviceIntPtr pDev)
if (xE && !syncEvents.playingEvents) if (xE && !syncEvents.playingEvents)
{ {
if (pSprite->hot.pScreen != pSprite->hotPhys.pScreen) /* GetPointerEvents() guarantees that pointer events have the correct
{ rootX/Y set already. */
pSprite->hot.pScreen = pSprite->hotPhys.pScreen; switch(xE->u.u.type)
RootWindow(pDev) = WindowTable[pSprite->hot.pScreen->myNum]; {
} case ButtonPress:
pSprite->hot.x = XE_KBPTR.rootX; case ButtonRelease:
pSprite->hot.y = XE_KBPTR.rootY; case MotionNotify:
if (pSprite->hot.x < pSprite->physLimits.x1) rootX = &XE_KBPTR.rootX;
pSprite->hot.x = pSprite->physLimits.x1; rootY = &XE_KBPTR.rootY;
else if (pSprite->hot.x >= pSprite->physLimits.x2) break;
pSprite->hot.x = pSprite->physLimits.x2 - 1; default:
if (pSprite->hot.y < pSprite->physLimits.y1) if (xE->u.u.type == DeviceButtonPress ||
pSprite->hot.y = pSprite->physLimits.y1; xE->u.u.type == DeviceButtonRelease ||
else if (pSprite->hot.y >= pSprite->physLimits.y2) xE->u.u.type == DeviceMotionNotify)
pSprite->hot.y = pSprite->physLimits.y2 - 1; {
rootX = &((deviceKeyButtonPointer*)xE)->root_x;
rootY = &((deviceKeyButtonPointer*)xE)->root_y;
break;
}
/* all other events return FALSE */
return FALSE;
}
if (pSprite->hot.pScreen != pSprite->hotPhys.pScreen)
{
pSprite->hot.pScreen = pSprite->hotPhys.pScreen;
RootWindow(pDev) = WindowTable[pSprite->hot.pScreen->myNum];
}
pSprite->hot.x = *rootX;
pSprite->hot.y = *rootY;
if (pSprite->hot.x < pSprite->physLimits.x1)
pSprite->hot.x = pSprite->physLimits.x1;
else if (pSprite->hot.x >= pSprite->physLimits.x2)
pSprite->hot.x = pSprite->physLimits.x2 - 1;
if (pSprite->hot.y < pSprite->physLimits.y1)
pSprite->hot.y = pSprite->physLimits.y1;
else if (pSprite->hot.y >= pSprite->physLimits.y2)
pSprite->hot.y = pSprite->physLimits.y2 - 1;
#ifdef SHAPE #ifdef SHAPE
if (pSprite->hotShape) if (pSprite->hotShape)
ConfineToShape(pDev, pSprite->hotShape, &pSprite->hot.x, &pSprite->hot.y); ConfineToShape(pDev, pSprite->hotShape, &pSprite->hot.x, &pSprite->hot.y);
@ -2490,16 +2519,16 @@ CheckMotion(xEvent *xE, DeviceIntPtr pDev)
#endif #endif
pSprite->hotPhys = pSprite->hot; pSprite->hotPhys = pSprite->hot;
if ((pSprite->hotPhys.x != XE_KBPTR.rootX) || if ((pSprite->hotPhys.x != *rootX) ||
(pSprite->hotPhys.y != XE_KBPTR.rootY)) (pSprite->hotPhys.y != *rootY))
{ {
(*pSprite->hotPhys.pScreen->SetCursorPosition)( (*pSprite->hotPhys.pScreen->SetCursorPosition)(
pDev, pSprite->hotPhys.pScreen, pDev, pSprite->hotPhys.pScreen,
pSprite->hotPhys.x, pSprite->hotPhys.y, FALSE); pSprite->hotPhys.x, pSprite->hotPhys.y, FALSE);
} }
XE_KBPTR.rootX = pSprite->hot.x; *rootX = pSprite->hot.x;
XE_KBPTR.rootY = pSprite->hot.y; *rootY = pSprite->hot.y;
} }
#ifdef XEVIE #ifdef XEVIE
@ -3635,9 +3664,8 @@ ProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count)
} }
} }
/* We need to call CheckMotion for each event. It doesn't really give us /* We need to call CheckMotion for each event. It doesn't really give us
any benefit for relative devices, but absolute devices won't send any benefit for relative devices, but absolute devices may not send
button events to the right position. button events to the right position otherwise. */
*/
if (!CheckMotion(xE, mouse) && xE->u.u.type == MotionNotify) if (!CheckMotion(xE, mouse) && xE->u.u.type == MotionNotify)
return; return;
if (xE->u.u.type != MotionNotify) if (xE->u.u.type != MotionNotify)