From: Piotr Caban Subject: [PATCH 2/2 v3] server: Generate mouse move message when window position is changed Message-Id: Date: Wed, 8 Jun 2016 17:25:33 +0200 Signed-off-by: Piotr Caban --- dlls/user32/tests/msg.c | 55 ++++++++++++++++++++++++++++++++++++++++++------- server/queue.c | 2 +- server/user.h | 1 + server/window.c | 9 ++++++++ 4 files changed, 59 insertions(+), 8 deletions(-) diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index 603e4a3..07fa758 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -15837,7 +15837,7 @@ static void test_mouse_on_resize(char *argv0) SetWindowPos(hwnd, 0, 0, 0, 201, 201, SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE); ret = PeekMessageA(&msg, hwnd, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE); - todo_wine ok(ret, "no WM_MOUSEMOVE message\n"); + ok(ret, "no WM_MOUSEMOVE message\n"); flush_events(); start_event = CreateEventA(NULL, 0, 0, "test_mouse_on_resize_start"); @@ -15854,15 +15854,15 @@ static void test_mouse_on_resize(char *argv0) ret = WaitForSingleObject(start_event, 1000); ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", ret); ret = PeekMessageA(&msg, hwnd, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE); - todo_wine ok(ret, "no WM_MOUSEMOVE message\n"); + ok(ret, "no WM_MOUSEMOVE message\n"); flush_events(); SetEvent(end_event); - /* SetWindowPos(SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE) */ + /* SetWindowPos(SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW) */ ret = WaitForSingleObject(start_event, 1000); ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", ret); ret = PeekMessageA(&msg, hwnd, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE); - todo_wine ok(ret, "no WM_MOUSEMOVE message\n"); + ok(ret, "no WM_MOUSEMOVE message\n"); flush_events(); SetEvent(end_event); @@ -15870,7 +15870,7 @@ static void test_mouse_on_resize(char *argv0) ret = WaitForSingleObject(start_event, 1000); ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", ret); ret = PeekMessageA(&msg, hwnd, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE); - todo_wine ok(ret, "no WM_MOUSEMOVE message\n"); + ok(ret, "no WM_MOUSEMOVE message\n"); flush_events(); SetEvent(end_event); @@ -15882,10 +15882,36 @@ static void test_mouse_on_resize(char *argv0) flush_events(); SetEvent(end_event); + /* SetWindowPos(SWP_NOSIZE|SWP_NOZORDER) */ + ret = WaitForSingleObject(start_event, 1000); + ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", ret); + ret = PeekMessageA(&msg, hwnd, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE); + ok(ret, "no WM_MOUSEMOVE message\n"); + flush_events(); + SetEvent(end_event); + + /* SetWindowPos(SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE) */ + ret = WaitForSingleObject(start_event, 1000); + ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", ret); + ret = PeekMessageA(&msg, hwnd, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE); + ok(ret, "no WM_MOUSEMOVE message\n"); + flush_events(); + SetEvent(end_event); + + /* SetWindowPos(SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE) with captured mouse */ + SetCapture(hwnd); + ret = WaitForSingleObject(start_event, 1000); + ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", ret); + ret = PeekMessageA(&msg, hwnd, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE); + ok(ret, "no WM_MOUSEMOVE message\n"); + flush_events(); + SetEvent(end_event); + ReleaseCapture(); + /* window destruction */ winetest_wait_child_process(pi.hProcess); ret = PeekMessageA(&msg, hwnd, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_NOREMOVE); - todo_wine ok(ret, "no WM_MOUSEMOVE message\n"); + ok(ret, "no WM_MOUSEMOVE message\n"); flush_events(); flush_sequence(); @@ -15914,7 +15940,7 @@ static void test_mouse_on_resize_child(void) ret = WaitForSingleObject(end_event, 1000); ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", ret); - SetWindowPos(hwnd, 0, 0, 0, 201, 201, SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE); + SetWindowPos(hwnd, 0, 0, 0, 201, 201, SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW); SetEvent(start_event); ret = WaitForSingleObject(end_event, 1000); ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", ret); @@ -15929,6 +15955,21 @@ static void test_mouse_on_resize_child(void) ret = WaitForSingleObject(end_event, 1000); ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", ret); + SetWindowPos(hwnd, 0, 301, 50, 0, 0, SWP_NOSIZE|SWP_NOZORDER); + SetEvent(start_event); + ret = WaitForSingleObject(end_event, 1000); + ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", ret); + + SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); + SetEvent(start_event); + ret = WaitForSingleObject(end_event, 1000); + ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", ret); + + SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); + SetEvent(start_event); + ret = WaitForSingleObject(end_event, 1000); + ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", ret); + DestroyWindow(hwnd); CloseHandle(start_event); CloseHandle(end_event); diff --git a/server/queue.c b/server/queue.c index f82060f..c06d7a9 100644 --- a/server/queue.c +++ b/server/queue.c @@ -340,7 +340,7 @@ static int assign_thread_input( struct thread *thread, struct thread_input *new_ } /* set the cursor position and queue the corresponding mouse message */ -static void set_cursor_pos( struct desktop *desktop, int x, int y ) +void set_cursor_pos( struct desktop *desktop, int x, int y ) { struct hardware_msg_data *msg_data; struct message *msg; diff --git a/server/user.h b/server/user.h index 89646f1..4b989ae 100644 --- a/server/user.h +++ b/server/user.h @@ -117,6 +117,7 @@ extern void post_win_event( struct thread *thread, unsigned int event, const WCHAR *module, data_size_t module_size, user_handle_t handle ); extern void free_hotkeys( struct desktop *desktop, user_handle_t window ); +extern void set_cursor_pos( struct desktop *desktop, int x, int y ); /* region functions */ diff --git a/server/window.c b/server/window.c index 143b60c..47f0a82 100644 --- a/server/window.c +++ b/server/window.c @@ -1644,6 +1644,7 @@ static void set_window_pos( struct window *win, struct window *previous, rectangle_t rect; int client_changed, frame_changed; int visible = (win->style & WS_VISIBLE) || (swp_flags & SWP_SHOWWINDOW); + struct list *old_sibling = win->entry.next; if (win->parent && !is_visible( win->parent )) visible = 0; @@ -1679,6 +1680,14 @@ static void set_window_pos( struct window *win, struct window *previous, /* if the window is not visible, everything is easy */ if (!visible) return; + if (!(win->style & WS_VISIBLE) || + (swp_flags & SWP_SHOWWINDOW) || + (swp_flags & SWP_FRAMECHANGED) || + (old_sibling != win->entry.next) || + memcmp( &old_window_rect, &win->window_rect, sizeof(old_window_rect) ) || + memcmp( &old_client_rect, &win->client_rect, sizeof(old_client_rect) )) + set_cursor_pos( win->desktop, win->desktop->cursor.x, win->desktop->cursor.y ); + /* expose anything revealed by the change */ if (!(swp_flags & SWP_NOREDRAW))