From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55047 --- dlls/win32u/input.c | 6 +++--- dlls/win32u/message.c | 4 +++- dlls/win32u/sysparams.c | 2 +- dlls/win32u/win32u_private.h | 2 +- server/queue.c | 12 ++++++------ server/user.h | 3 ++- server/window.c | 2 +- 7 files changed, 17 insertions(+), 14 deletions(-)
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 2311fb359af..8010183d97c 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2544,13 +2544,13 @@ BOOL get_clip_cursor( RECT *rect ) return ret; }
-BOOL process_wine_clipcursor( HWND hwnd, BOOL empty, BOOL reset ) +BOOL process_wine_clipcursor( HWND hwnd, UINT flags, BOOL reset ) { struct user_thread_info *thread_info = get_user_thread_info(); RECT rect, virtual_rect = NtUserGetVirtualScreenRect(); - BOOL was_clipping; + BOOL was_clipping, empty = !!(flags & SET_CURSOR_NOCLIP);
- TRACE( "hwnd %p, empty %u, reset %u\n", hwnd, empty, reset ); + TRACE( "hwnd %p, flags %#x, reset %u\n", hwnd, flags, reset );
if ((was_clipping = thread_info->clipping_cursor)) InterlockedDecrement( &clipping_cursor ); thread_info->clipping_cursor = FALSE; diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index cb44e0037d9..687caef9bfc 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -1272,7 +1272,9 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR return call_current_hook( h_extra->handle, HC_ACTION, wparam, h_extra->lparam ); } case WM_WINE_CLIPCURSOR: - if (wparam && lparam) return clip_fullscreen_window( hwnd, FALSE ); + /* non-hardware message, posted on display mode change to trigger fullscreen + clipping or to the desktop window to forcefully release the cursor grabs */ + if (!wparam) return clip_fullscreen_window( hwnd, FALSE ); return process_wine_clipcursor( hwnd, wparam, lparam ); case WM_WINE_SETCURSOR: FIXME( "Unexpected non-hardware WM_WINE_SETCURSOR message\n" ); diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 4f69cac7040..59f624214b7 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2929,7 +2929,7 @@ static LONG apply_display_settings( const WCHAR *devname, const DEVMODEW *devmod MAKELPARAM( current_mode.dmPelsWidth, current_mode.dmPelsHeight ), SMTO_ABORTIFHUNG, 2000, FALSE ); /* post clip_fullscreen_window request to the foreground window */ - NtUserPostMessage( NtUserGetForegroundWindow(), WM_WINE_CLIPCURSOR, TRUE, TRUE ); + NtUserPostMessage( NtUserGetForegroundWindow(), WM_WINE_CLIPCURSOR, 0, 0 ); }
return ret; diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 3bd41a4ffa8..ee117ed2637 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -104,7 +104,7 @@ extern BOOL set_foreground_window( HWND hwnd, BOOL mouse ) DECLSPEC_HIDDEN; extern void toggle_caret( HWND hwnd ) DECLSPEC_HIDDEN; extern void update_mouse_tracking_info( HWND hwnd ) DECLSPEC_HIDDEN; extern BOOL get_clip_cursor( RECT *rect ) DECLSPEC_HIDDEN; -extern BOOL process_wine_clipcursor( HWND hwnd, BOOL empty, BOOL reset ) DECLSPEC_HIDDEN; +extern BOOL process_wine_clipcursor( HWND hwnd, UINT flags, BOOL reset ) DECLSPEC_HIDDEN; extern BOOL clip_fullscreen_window( HWND hwnd, BOOL reset ) DECLSPEC_HIDDEN;
/* menu.c */ diff --git a/server/queue.c b/server/queue.c index ec8ddcbee5c..fcc946ff0cb 100644 --- a/server/queue.c +++ b/server/queue.c @@ -508,7 +508,7 @@ static void get_message_defaults( struct msg_queue *queue, int *x, int *y, unsig }
/* set the cursor clip rectangle */ -void set_clip_rectangle( struct desktop *desktop, const rectangle_t *rect, int reset ) +void set_clip_rectangle( struct desktop *desktop, const rectangle_t *rect, unsigned int flags, int reset ) { rectangle_t top_rect; int x, y; @@ -532,17 +532,17 @@ void set_clip_rectangle( struct desktop *desktop, const rectangle_t *rect, int r if (x != desktop->cursor.x || y != desktop->cursor.y) set_cursor_pos( desktop, x, y );
/* request clip cursor rectangle reset to the desktop thread */ - if (reset) post_desktop_message( desktop, WM_WINE_CLIPCURSOR, TRUE, FALSE ); + if (reset) post_desktop_message( desktop, WM_WINE_CLIPCURSOR, flags, FALSE );
/* notify foreground thread, of reset, or to apply new cursor clipping rect */ - queue_cursor_message( desktop, 0, WM_WINE_CLIPCURSOR, rect == NULL, reset ); + queue_cursor_message( desktop, 0, WM_WINE_CLIPCURSOR, flags, reset ); }
/* change the foreground input and reset the cursor clip rect */ static void set_foreground_input( struct desktop *desktop, struct thread_input *input ) { if (desktop->foreground_input == input) return; - set_clip_rectangle( desktop, NULL, 1 ); + set_clip_rectangle( desktop, NULL, SET_CURSOR_NOCLIP, 1 ); desktop->foreground_input = input; }
@@ -3383,8 +3383,8 @@ DECL_HANDLER(set_cursor) input->cursor_count += req->show_count; } if (req->flags & SET_CURSOR_POS) set_cursor_pos( desktop, req->x, req->y ); - if (req->flags & SET_CURSOR_CLIP) set_clip_rectangle( desktop, &req->clip, 0 ); - if (req->flags & SET_CURSOR_NOCLIP) set_clip_rectangle( desktop, NULL, 0 ); + if (req->flags & SET_CURSOR_CLIP) set_clip_rectangle( desktop, &req->clip, req->flags, 0 ); + if (req->flags & SET_CURSOR_NOCLIP) set_clip_rectangle( desktop, NULL, SET_CURSOR_NOCLIP, 0 );
if (req->flags & (SET_CURSOR_HANDLE | SET_CURSOR_COUNT)) { diff --git a/server/user.h b/server/user.h index f67e710938f..b6f47bcac1c 100644 --- a/server/user.h +++ b/server/user.h @@ -110,7 +110,8 @@ extern void queue_cleanup_window( struct thread *thread, user_handle_t win ); extern int init_thread_queue( struct thread *thread ); extern int attach_thread_input( struct thread *thread_from, struct thread *thread_to ); extern void detach_thread_input( struct thread *thread_from ); -extern void set_clip_rectangle( struct desktop *desktop, const rectangle_t *rect, int reset ); +extern void set_clip_rectangle( struct desktop *desktop, const rectangle_t *rect, + unsigned int flags, int reset ); extern void post_message( user_handle_t win, unsigned int message, lparam_t wparam, lparam_t lparam ); extern void send_notify_message( user_handle_t win, unsigned int message, diff --git a/server/window.c b/server/window.c index 9db8ccbe27e..328e3dfc64c 100644 --- a/server/window.c +++ b/server/window.c @@ -1829,7 +1829,7 @@ static void set_window_pos( struct window *win, struct window *previous, }
/* reset cursor clip rectangle when the desktop changes size */ - if (win == win->desktop->top_window) set_clip_rectangle( win->desktop, NULL, 1 ); + if (win == win->desktop->top_window) set_clip_rectangle( win->desktop, NULL, SET_CURSOR_NOCLIP, 1 );
/* if the window is not visible, everything is easy */ if (!visible) return;