From: Tim Clem tclem@codeweavers.com
Until the user moves the mouse, the server's idea of the cursor position is likely incorrect. Very early in the lifespan of a user driver (after desktop creation), sync the server with the result of the driver's GetCursorPos. --- dlls/win32u/input.c | 29 +++++++++++++++++++++++++++++ dlls/win32u/win32u_private.h | 1 + dlls/win32u/winstation.c | 1 + 3 files changed, 31 insertions(+)
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 5ba7d151f57..8ab33619dd1 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -30,6 +30,7 @@ #pragma makedep unix #endif
+#include <pthread.h> #include "ntstatus.h" #define WIN32_NO_STATUS #include "win32u_private.h" @@ -39,6 +40,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(win); WINE_DECLARE_DEBUG_CHANNEL(keyboard); +WINE_DECLARE_DEBUG_CHANNEL(cursor);
static const WCHAR keyboard_layouts_keyW[] = { @@ -2149,3 +2151,30 @@ void toggle_caret( HWND hwnd )
if (ret && !hidden) display_caret( hwnd, &r ); } + +static void sync_cursor_pos(void) +{ + POINT pt = { 0 }; + if (user_driver->pGetCursorPos( &pt )) + { + TRACE_(cursor)( "syncing initial cursor position at (%d, %d)\n", pt.x, pt.y ); + NtUserSetCursorPos( pt.x, pt.y ); + } + else + { + WARN_(cursor)( "initial GetCursorPos failed; cursor may be out of sync with the server\n" ); + } +} + +/*********************************************************************** + * init_server_cursor_pos + * + * Update the server's cursor location with the actual value from the + * user driver. Until the user moves the mouse, the server's location + * is likely incorrect. + */ +void init_server_cursor_pos(void) +{ + static pthread_once_t init_once = PTHREAD_ONCE_INIT; + pthread_once( &init_once, sync_cursor_pos ); +} diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 4be068b968d..5800804f6cc 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -272,6 +272,7 @@ extern HWND get_capture(void) DECLSPEC_HIDDEN; extern BOOL get_cursor_pos( POINT *pt ) DECLSPEC_HIDDEN; extern HWND get_focus(void) DECLSPEC_HIDDEN; extern DWORD get_input_state(void) DECLSPEC_HIDDEN; +extern void init_server_cursor_pos(void) DECLSPEC_HIDDEN; extern BOOL WINAPI release_capture(void) DECLSPEC_HIDDEN; extern BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret ) DECLSPEC_HIDDEN; extern BOOL set_caret_blink_time( unsigned int time ) DECLSPEC_HIDDEN; diff --git a/dlls/win32u/winstation.c b/dlls/win32u/winstation.c index e606047a79c..33a3b7f65c8 100644 --- a/dlls/win32u/winstation.c +++ b/dlls/win32u/winstation.c @@ -501,6 +501,7 @@ HWND get_desktop_window(void) ERR_(win)( "failed to create desktop window\n" );
register_builtin_classes(); + init_server_cursor_pos(); return UlongToHandle( thread_info->top_window ); }