Cursor (both the cursor itself and its visibility) are per thread on Windows and Wine's implementation outside of winex11.drv seem to agree with that. Using global cursor variable in winex11.drv leads to wrong cursor being set or set visible for a window when the app sets a cursor from the other thread.
-- v2: winex11.drv: Set correct cursor when setting cursor from another thread.
From: Paul Gofman pgofman@codeweavers.com
--- dlls/winex11.drv/mouse.c | 3 ++- dlls/winex11.drv/window.c | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 9e005881170..d0cc185d96c 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -1503,7 +1503,8 @@ void X11DRV_SetCursor( HCURSOR handle ) NtGetTickCount() - last_cursor_change > 100) { last_cursor_change = NtGetTickCount(); - if (cursor_window) send_notify_message( cursor_window, WM_X11DRV_SET_CURSOR, 0, (LPARAM)handle ); + if (cursor_window) send_notify_message( cursor_window, WM_X11DRV_SET_CURSOR, + GetCurrentThreadId(), (LPARAM)handle ); } }
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 3ebbee0856e..118604b0ae0 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2996,15 +2996,26 @@ LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) X11DRV_resize_desktop( (BOOL)lp ); return 0; case WM_X11DRV_SET_CURSOR: + { + Window win = 0; + if ((data = get_win_data( hwnd ))) { - Window win = data->whole_window; + win = data->whole_window; release_win_data( data ); - if (win) set_window_cursor( win, (HCURSOR)lp ); } else if (hwnd == x11drv_thread_data()->clip_hwnd) - set_window_cursor( x11drv_thread_data()->clip_window, (HCURSOR)lp ); + win = x11drv_thread_data()->clip_window; + + if (win) + { + if (wp == GetCurrentThreadId()) + set_window_cursor( win, (HCURSOR)lp ); + else + sync_window_cursor( win ); + } return 0; + } case WM_X11DRV_CLIP_CURSOR_NOTIFY: return clip_cursor_notify( hwnd, (HWND)wp, (HWND)lp ); case WM_X11DRV_CLIP_CURSOR_REQUEST:
v2: - Use sync_window_cursor() when processing WM_X11DRV_SET_CURSOR message from another thread. This way it should still avoid an extra server call in a typical case of setting the cursor within the same thread but get correct cursor if thread is different.