server: Sync cursor position on window position change.

This commit is contained in:
Paul Gofman 2024-10-21 16:11:43 -06:00 committed by Alexandre Julliard
parent 3a736901cd
commit db9a4bc66a
Notes: Alexandre Julliard 2024-10-30 14:01:07 -05:00
Approved-by: Rémi Bernon (@rbernon)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/wine/merge_requests/6708
4 changed files with 63 additions and 2 deletions

View file

@ -73,6 +73,8 @@
#define ARCH "none" #define ARCH "none"
#endif #endif
static void pump_msg_loop(HWND hwnd, HACCEL hAccel);
/* encoded DRAWITEMSTRUCT into an LPARAM */ /* encoded DRAWITEMSTRUCT into an LPARAM */
typedef struct typedef struct
{ {
@ -108,6 +110,7 @@ typedef struct
static BOOL test_DestroyWindow_flag; static BOOL test_DestroyWindow_flag;
static BOOL test_context_menu; static BOOL test_context_menu;
static BOOL ignore_mouse_messages = TRUE;
static HWINEVENTHOOK hEvent_hook; static HWINEVENTHOOK hEvent_hook;
static HHOOK hKBD_hook; static HHOOK hKBD_hook;
static HHOOK hCBT_hook; static HHOOK hCBT_hook;
@ -6160,6 +6163,30 @@ static const struct message WmFrameChanged_move[] = {
{ 0 } { 0 }
}; };
static const struct message WmMove_mouse[] = {
{ WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOACTIVATE|SWP_NOSIZE },
{ WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOACTIVATE|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOCLIENTSIZE },
{ WM_MOVE, sent|defwinproc, 0 },
{ WM_GETTEXT, sent|optional },
{ EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
{ EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* Win7 seems to send this twice. */
{ WM_SETCURSOR, sent|lparam, 0, HTCLIENT | (WM_MOUSEMOVE << 16) },
{ WM_MOUSEMOVE, sent },
/* WM_MOUSEMOVE with accompanying WM_SETCURSOR may sometimes appear a few extra times on Windows 7 with the
* same parameters. */
{ WM_SETCURSOR, sent|lparam|optional, 0, HTCLIENT | (WM_MOUSEMOVE << 16) },
{ WM_MOUSEMOVE, sent|optional },
{ WM_SETCURSOR, sent|lparam|optional, 0, HTCLIENT | (WM_MOUSEMOVE << 16) },
{ WM_MOUSEMOVE, sent|optional },
{ WM_SETCURSOR, sent|lparam|optional, 0, HTCLIENT | (WM_MOUSEMOVE << 16) },
{ WM_MOUSEMOVE, sent|optional },
{ WM_SETCURSOR, sent|lparam|optional, 0, HTCLIENT | (WM_MOUSEMOVE << 16) },
{ WM_MOUSEMOVE, sent|optional },
{ WM_SETCURSOR, sent|lparam|optional, 0, HTCLIENT | (WM_MOUSEMOVE << 16) },
{ WM_MOUSEMOVE, sent|optional },
{ 0 }
};
static void test_setwindowpos(void) static void test_setwindowpos(void)
{ {
HWND hwnd; HWND hwnd;
@ -6198,6 +6225,7 @@ static void test_setwindowpos(void)
expect(sysX + X, rc.right); expect(sysX + X, rc.right);
expect(winY + Y, rc.bottom); expect(winY + Y, rc.bottom);
GetWindowRect(hwnd, &rc);
res = SetWindowPos( hwnd, 0, 0, 0, 0, 0, res = SetWindowPos( hwnd, 0, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
ok_sequence(WmFrameChanged_move, "FrameChanged", FALSE); ok_sequence(WmFrameChanged_move, "FrameChanged", FALSE);
@ -6207,6 +6235,26 @@ static void test_setwindowpos(void)
expect(sysX, rc.right); expect(sysX, rc.right);
expect(winY, rc.bottom); expect(winY, rc.bottom);
/* get away from possible menu bar to avoid spurious position changed induced by WM. */
res = SetWindowPos( hwnd, HWND_TOPMOST, 200, 200, 200, 200, SWP_SHOWWINDOW );
ok(res == TRUE, "SetWindowPos expected TRUE, got %Id.\n", res);
SetForegroundWindow( hwnd );
SetActiveWindow( hwnd );
flush_events();
pump_msg_loop( hwnd, 0 );
flush_sequence();
GetWindowRect( hwnd, &rc );
SetCursorPos( rc.left + 100, rc.top + 100 );
flush_events();
pump_msg_loop( hwnd, 0 );
flush_sequence();
ignore_mouse_messages = FALSE;
res = SetWindowPos( hwnd, 0, 205, 205, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
ok(res == TRUE, "SetWindowPos expected TRUE, got %Id.\n", res);
flush_events();
ok_sequence(WmMove_mouse, "MouseMove", FALSE);
ignore_mouse_messages = TRUE;
DestroyWindow(hwnd); DestroyWindow(hwnd);
} }
@ -10853,7 +10901,8 @@ static LRESULT MsgCheckProc (BOOL unicode, HWND hwnd, UINT message,
case WM_NCMOUSEMOVE: case WM_NCMOUSEMOVE:
case WM_SETCURSOR: case WM_SETCURSOR:
case WM_IME_SELECT: case WM_IME_SELECT:
return 0; if (ignore_mouse_messages) return 0;
break;
} }
msg.hwnd = hwnd; msg.hwnd = hwnd;

View file

@ -584,6 +584,15 @@ static void set_cursor_pos( struct desktop *desktop, int x, int y )
queue_hardware_message( desktop, msg, 1 ); queue_hardware_message( desktop, msg, 1 );
} }
/* sync cursor position after window change */
void update_cursor_pos( struct desktop *desktop )
{
const desktop_shm_t *desktop_shm;
desktop_shm = desktop->shared;
set_cursor_pos( desktop, desktop_shm->cursor.x, desktop_shm->cursor.y );
}
/* retrieve default position and time for synthesized messages */ /* retrieve default position and time for synthesized messages */
static void get_message_defaults( struct msg_queue *queue, int *x, int *y, unsigned int *time ) static void get_message_defaults( struct msg_queue *queue, int *x, int *y, unsigned int *time )
{ {

View file

@ -127,6 +127,7 @@ extern int attach_thread_input( struct thread *thread_from, struct thread *threa
extern void detach_thread_input( struct thread *thread_from ); extern void detach_thread_input( struct thread *thread_from );
extern void set_clip_rectangle( struct desktop *desktop, const rectangle_t *rect, extern void set_clip_rectangle( struct desktop *desktop, const rectangle_t *rect,
unsigned int flags, int reset ); unsigned int flags, int reset );
extern void update_cursor_pos( struct desktop *desktop );
extern void post_message( user_handle_t win, unsigned int message, extern void post_message( user_handle_t win, unsigned int message,
lparam_t wparam, lparam_t lparam ); lparam_t wparam, lparam_t lparam );
extern void send_notify_message( user_handle_t win, unsigned int message, extern void send_notify_message( user_handle_t win, unsigned int message,

View file

@ -2405,7 +2405,7 @@ DECL_HANDLER(set_window_pos)
const rectangle_t *extra_rects = get_req_data(); const rectangle_t *extra_rects = get_req_data();
struct window *previous = NULL; struct window *previous = NULL;
struct window *top, *win = get_window( req->handle ); struct window *top, *win = get_window( req->handle );
unsigned int flags = req->swp_flags; unsigned int flags = req->swp_flags, old_style;
if (!win) return; if (!win) return;
if (!win->parent) flags |= SWP_NOZORDER; /* no Z order for the desktop */ if (!win->parent) flags |= SWP_NOZORDER; /* no Z order for the desktop */
@ -2470,8 +2470,10 @@ DECL_HANDLER(set_window_pos)
if (win->paint_flags & PAINT_HAS_PIXEL_FORMAT) update_pixel_format_flags( win ); if (win->paint_flags & PAINT_HAS_PIXEL_FORMAT) update_pixel_format_flags( win );
win->monitor_dpi = req->monitor_dpi; win->monitor_dpi = req->monitor_dpi;
old_style = win->style;
set_window_pos( win, previous, flags, &window_rect, &client_rect, set_window_pos( win, previous, flags, &window_rect, &client_rect,
&visible_rect, &surface_rect, &valid_rect ); &visible_rect, &surface_rect, &valid_rect );
if (win->style & old_style & WS_VISIBLE) update_cursor_pos( win->desktop );
if (win->paint_flags & SET_WINPOS_LAYERED_WINDOW) validate_whole_window( win ); if (win->paint_flags & SET_WINPOS_LAYERED_WINDOW) validate_whole_window( win );