Commit 0e2b4f99 authored by Alexandre Julliard's avatar Alexandre Julliard

winex11: Warp the pointer when clipping, but ignore the resulting events.

parent 9556b4f7
...@@ -318,26 +318,27 @@ static enum event_merge_action merge_events( XEvent *prev, XEvent *next ) ...@@ -318,26 +318,27 @@ static enum event_merge_action merge_events( XEvent *prev, XEvent *next )
break; break;
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
case GenericEvent: case GenericEvent:
{
struct x11drv_thread_data *thread_data = x11drv_thread_data();
if (prev->xcookie.extension != xinput2_opcode) break; if (prev->xcookie.extension != xinput2_opcode) break;
if (prev->xcookie.evtype != XI_RawMotion) break; if (prev->xcookie.evtype != XI_RawMotion) break;
if (thread_data->warp_serial) break;
switch (next->type) switch (next->type)
{ {
case MotionNotify: case MotionNotify:
{
struct x11drv_thread_data *thread_data = x11drv_thread_data();
if (next->xany.window == thread_data->clip_window && if (next->xany.window == thread_data->clip_window &&
next->xmotion.time - thread_data->last_motion_notify < 1000) next->xmotion.time - thread_data->last_motion_notify < 1000)
{ {
TRACE( "ignoring MotionNotify for clip window\n" ); TRACE( "ignoring MotionNotify for clip window\n" );
return MERGE_IGNORE; return MERGE_IGNORE;
} }
}
break; break;
case GenericEvent: case GenericEvent:
if (next->xcookie.extension != xinput2_opcode) break; if (next->xcookie.extension != xinput2_opcode) break;
if (next->xcookie.evtype != XI_RawMotion) break; if (next->xcookie.evtype != XI_RawMotion) break;
return merge_raw_motion_events( prev->xcookie.data, next->xcookie.data ); return merge_raw_motion_events( prev->xcookie.data, next->xcookie.data );
} }
}
break; break;
#endif #endif
} }
......
...@@ -1213,15 +1213,13 @@ BOOL CDECL X11DRV_SetCursorPos( INT x, INT y ) ...@@ -1213,15 +1213,13 @@ BOOL CDECL X11DRV_SetCursorPos( INT x, INT y )
{ {
struct x11drv_thread_data *data = x11drv_init_thread_data(); struct x11drv_thread_data *data = x11drv_init_thread_data();
if (data->xi2_state == xi_enabled) return TRUE;
TRACE( "warping to (%d,%d)\n", x, y );
wine_tsx11_lock(); wine_tsx11_lock();
data->warp_serial = NextRequest( data->display );
XWarpPointer( data->display, root_window, root_window, 0, 0, 0, 0, XWarpPointer( data->display, root_window, root_window, 0, 0, 0, 0,
x - virtual_screen_rect.left, y - virtual_screen_rect.top ); x - virtual_screen_rect.left, y - virtual_screen_rect.top );
XFlush( data->display ); /* avoids bad mouse lag in games that do their own mouse warping */ XFlush( data->display ); /* avoids bad mouse lag in games that do their own mouse warping */
wine_tsx11_unlock(); wine_tsx11_unlock();
TRACE( "warped to %d,%d serial %lu\n", x, y, data->warp_serial );
return TRUE; return TRUE;
} }
...@@ -1240,9 +1238,10 @@ BOOL CDECL X11DRV_GetCursorPos(LPPOINT pos) ...@@ -1240,9 +1238,10 @@ BOOL CDECL X11DRV_GetCursorPos(LPPOINT pos)
ret = XQueryPointer( display, root_window, &root, &child, &rootX, &rootY, &winX, &winY, &xstate ); ret = XQueryPointer( display, root_window, &root, &child, &rootX, &rootY, &winX, &winY, &xstate );
if (ret) if (ret)
{ {
POINT old = *pos;
pos->x = winX + virtual_screen_rect.left; pos->x = winX + virtual_screen_rect.left;
pos->y = winY + virtual_screen_rect.top; pos->y = winY + virtual_screen_rect.top;
TRACE("pointer at (%d,%d)\n", pos->x, pos->y ); TRACE( "pointer at (%d,%d) server pos %d,%d\n", pos->x, pos->y, old.x, old.y );
} }
wine_tsx11_unlock(); wine_tsx11_unlock();
return ret; return ret;
...@@ -1353,7 +1352,8 @@ void X11DRV_MotionNotify( HWND hwnd, XEvent *xev ) ...@@ -1353,7 +1352,8 @@ void X11DRV_MotionNotify( HWND hwnd, XEvent *xev )
XMotionEvent *event = &xev->xmotion; XMotionEvent *event = &xev->xmotion;
INPUT input; INPUT input;
TRACE( "hwnd %p/%lx pos %d,%d is_hint %d\n", hwnd, event->window, event->x, event->y, event->is_hint ); TRACE( "hwnd %p/%lx pos %d,%d is_hint %d serial %lu\n",
hwnd, event->window, event->x, event->y, event->is_hint, event->serial );
input.u.mi.dx = event->x; input.u.mi.dx = event->x;
input.u.mi.dy = event->y; input.u.mi.dy = event->y;
...@@ -1366,6 +1366,7 @@ void X11DRV_MotionNotify( HWND hwnd, XEvent *xev ) ...@@ -1366,6 +1366,7 @@ void X11DRV_MotionNotify( HWND hwnd, XEvent *xev )
{ {
struct x11drv_thread_data *thread_data = x11drv_thread_data(); struct x11drv_thread_data *thread_data = x11drv_thread_data();
if (event->time - thread_data->last_motion_notify < 1000) return; if (event->time - thread_data->last_motion_notify < 1000) return;
if (thread_data->warp_serial && (long)(event->serial - thread_data->warp_serial) < 0) return;
thread_data->last_motion_notify = event->time; thread_data->last_motion_notify = event->time;
} }
...@@ -1402,12 +1403,15 @@ void X11DRV_EnterNotify( HWND hwnd, XEvent *xev ) ...@@ -1402,12 +1403,15 @@ void X11DRV_EnterNotify( HWND hwnd, XEvent *xev )
/*********************************************************************** /***********************************************************************
* X11DRV_RawMotion * X11DRV_RawMotion
*/ */
static void X11DRV_RawMotion( XIRawEvent *event ) static void X11DRV_RawMotion( XGenericEventCookie *xev )
{ {
XIRawEvent *event = xev->data;
const double *values = event->valuators.values; const double *values = event->valuators.values;
INPUT input; INPUT input;
struct x11drv_thread_data *thread_data = x11drv_thread_data();
if (!event->valuators.mask_len) return; if (!event->valuators.mask_len) return;
if (thread_data->xi2_state != xi_enabled) return;
input.u.mi.dx = 0; input.u.mi.dx = 0;
input.u.mi.dy = 0; input.u.mi.dy = 0;
...@@ -1419,6 +1423,18 @@ static void X11DRV_RawMotion( XIRawEvent *event ) ...@@ -1419,6 +1423,18 @@ static void X11DRV_RawMotion( XIRawEvent *event )
if (XIMaskIsSet( event->valuators.mask, 0 )) input.u.mi.dx = *values++; if (XIMaskIsSet( event->valuators.mask, 0 )) input.u.mi.dx = *values++;
if (XIMaskIsSet( event->valuators.mask, 1 )) input.u.mi.dy = *values++; if (XIMaskIsSet( event->valuators.mask, 1 )) input.u.mi.dy = *values++;
if (thread_data->warp_serial)
{
long diff = xev->serial - thread_data->warp_serial;
if (diff >= 0) thread_data->warp_serial = 0; /* we caught up now */
if (diff <= 0) /* <= 0 because we also want to ignore the first event after the warp request */
{
TRACE( "pos %d,%d old serial %lu, ignoring\n", input.u.mi.dx, input.u.mi.dy, xev->serial );
return;
}
}
TRACE( "pos %d,%d\n", input.u.mi.dx, input.u.mi.dy ); TRACE( "pos %d,%d\n", input.u.mi.dx, input.u.mi.dy );
input.type = INPUT_MOUSE; input.type = INPUT_MOUSE;
...@@ -1478,7 +1494,7 @@ void X11DRV_GenericEvent( HWND hwnd, XEvent *xev ) ...@@ -1478,7 +1494,7 @@ void X11DRV_GenericEvent( HWND hwnd, XEvent *xev )
switch (event->evtype) switch (event->evtype)
{ {
case XI_RawMotion: case XI_RawMotion:
X11DRV_RawMotion( event->data ); X11DRV_RawMotion( event );
break; break;
default: default:
......
...@@ -551,6 +551,7 @@ struct x11drv_thread_data ...@@ -551,6 +551,7 @@ struct x11drv_thread_data
Time last_motion_notify; /* time of last mouse motion */ Time last_motion_notify; /* time of last mouse motion */
XFontSet font_set; /* international text drawing font set */ XFontSet font_set; /* international text drawing font set */
Window selection_wnd; /* window used for selection interactions */ Window selection_wnd; /* window used for selection interactions */
unsigned long warp_serial; /* serial number of last pointer warp request */
Window clip_window; /* window used for cursor clipping */ Window clip_window; /* window used for cursor clipping */
HWND clip_hwnd; /* message window stored in desktop while clipping is active */ HWND clip_hwnd; /* message window stored in desktop while clipping is active */
DWORD clip_reset; /* time when clipping was last reset */ DWORD clip_reset; /* time when clipping was last reset */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment