From: Jan Klötzke jan@kloetzke.net
At least Doom 64 calls ClipCursor() with identical parameters repeatedly, which seems to cause a considerable overhead. Together with high polling rate mouse input this causes the game to almost freeze while the mouse is being moved. So if the clipping did not change we can bail out early because it will not cause any observable difference anyway.
Care must be taken if the grab was lost. In this case we must retry until we finally got the cursor grab again.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46976 Signed-off-by: Jan Klötzke jan@kloetzke.net --- dlls/winex11.drv/mouse.c | 6 ++++++ dlls/winex11.drv/x11drv.h | 1 + dlls/winex11.drv/x11drv_main.c | 1 + 3 files changed, 8 insertions(+)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 1a09c578c26..c259d2bf38f 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -382,6 +382,10 @@ static BOOL grab_clipping_window( const RECT *clip ) return TRUE; /* don't clip in the desktop process */
if (!data) return FALSE; + + if (data->clipping && EqualRect( clip, &clip_rect ) && !grab_retry) + return TRUE; + if (!(clip_window = init_clip_window())) return TRUE;
if (!data->clip_hwnd) @@ -440,6 +444,7 @@ static BOOL grab_clipping_window( const RECT *clip ) return FALSE; } clip_rect = *clip; + grab_retry = FALSE; if (!data->clipping) sync_window_cursor( clip_window ); InterlockedExchangePointer( (void **)&cursor_window, data->clip_hwnd ); data->clipping = TRUE; @@ -491,6 +496,7 @@ void reset_clipping_window(void) */ void retry_grab_clipping_window(void) { + grab_retry = TRUE; if (clipping_cursor) NtUserClipCursor( &clip_rect ); else if (last_clip_refused && NtUserGetForegroundWindow() == last_clip_foreground_window) diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 2a5a45b1643..1d5c3b97600 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -434,6 +434,7 @@ extern BOOL use_system_cursors DECLSPEC_HIDDEN; extern BOOL show_systray DECLSPEC_HIDDEN; extern BOOL grab_pointer DECLSPEC_HIDDEN; extern BOOL grab_fullscreen DECLSPEC_HIDDEN; +extern BOOL grab_retry DECLSPEC_HIDDEN; extern BOOL usexcomposite DECLSPEC_HIDDEN; extern BOOL managed_mode DECLSPEC_HIDDEN; extern BOOL decorated_mode DECLSPEC_HIDDEN; diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 9b3af044877..efbe8699f00 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -79,6 +79,7 @@ BOOL use_system_cursors = TRUE; BOOL show_systray = TRUE; BOOL grab_pointer = TRUE; BOOL grab_fullscreen = FALSE; +BOOL grab_retry = FALSE; BOOL managed_mode = TRUE; BOOL decorated_mode = TRUE; BOOL private_color_map = FALSE;