Module: wine Branch: master Commit: e95d0c684915c625aba0bfe4332a6c3e5259701c URL: https://source.winehq.org/git/wine.git/?a=commit;h=e95d0c684915c625aba0bfe43...
Author: Alexandre Julliard julliard@winehq.org Date: Mon May 7 12:00:17 2018 +0200
user32: Take into account the offset between old and new parent in SetParent().
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/user32/message.c | 2 +- dlls/user32/tests/msg.c | 2 +- dlls/user32/user_private.h | 2 +- dlls/user32/win.c | 23 +++++++++++++++-------- dlls/user32/winpos.c | 25 +++++++++++++------------ 5 files changed, 31 insertions(+), 23 deletions(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c index d2e6a75..79ea577 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -1858,7 +1858,7 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR return WIN_DestroyWindow( hwnd ); case WM_WINE_SETWINDOWPOS: if (is_desktop_window( hwnd )) return 0; - return USER_SetWindowPos( (WINDOWPOS *)lparam ); + return USER_SetWindowPos( (WINDOWPOS *)lparam, 0, 0 ); case WM_WINE_SHOWWINDOW: if (is_desktop_window( hwnd )) return 0; return ShowWindow( hwnd, wparam ); diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index 69841d3..a0f2cbe 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -15433,7 +15433,7 @@ static void test_SetParent(void)
SetParent(child, parent2); flush_events(); - ok_sequence(WmSetParentSeq_1, "SetParent() visible WS_CHILD", TRUE); + ok_sequence(WmSetParentSeq_1, "SetParent() visible WS_CHILD", FALSE);
ok(GetWindowLongA(child, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n"); ok(!IsWindowVisible(child), "IsWindowVisible() should return FALSE\n"); diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 30ab511..9699297 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -254,7 +254,7 @@ extern void SYSPARAMS_Init(void) DECLSPEC_HIDDEN; extern void USER_CheckNotLock(void) DECLSPEC_HIDDEN; extern BOOL USER_IsExitingThread( DWORD tid ) DECLSPEC_HIDDEN;
-extern BOOL USER_SetWindowPos( WINDOWPOS * winpos ) DECLSPEC_HIDDEN; +extern BOOL USER_SetWindowPos( WINDOWPOS * winpos, int parent_x, int parent_y ) DECLSPEC_HIDDEN;
typedef LRESULT (*winproc_callback_t)( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result, void *arg ); diff --git a/dlls/user32/win.c b/dlls/user32/win.c index 7bb0088..0d694a1 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -3014,12 +3014,13 @@ HWND WINAPI GetAncestor( HWND hwnd, UINT type ) */ HWND WINAPI SetParent( HWND hwnd, HWND parent ) { + WINDOWPOS winpos; HWND full_handle; HWND old_parent = 0; BOOL was_visible; WND *wndPtr; - POINT pt; BOOL ret; + RECT window_rect, old_screen_rect, new_screen_rect;
TRACE("(%p %p)\n", hwnd, parent);
@@ -3062,8 +3063,8 @@ HWND WINAPI SetParent( HWND hwnd, HWND parent ) wndPtr = WIN_GetPtr( hwnd ); if (!wndPtr || wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP) return 0;
- pt.x = wndPtr->rectWindow.left; - pt.y = wndPtr->rectWindow.top; + WIN_GetRectangles( hwnd, COORDS_PARENT, &window_rect, NULL ); + WIN_GetRectangles( hwnd, COORDS_SCREEN, &old_screen_rect, NULL );
SERVER_START_REQ( set_parent ) { @@ -3082,11 +3083,17 @@ HWND WINAPI SetParent( HWND hwnd, HWND parent )
USER_Driver->pSetParent( full_handle, parent, old_parent );
- /* SetParent additionally needs to make hwnd the topmost window - in the x-order and send the expected WM_WINDOWPOSCHANGING and - WM_WINDOWPOSCHANGED notification messages. - */ - SetWindowPos( hwnd, HWND_TOP, pt.x, pt.y, 0, 0, SWP_NOSIZE ); + winpos.hwnd = hwnd; + winpos.hwndInsertAfter = HWND_TOP; + winpos.x = window_rect.left; + winpos.y = window_rect.top; + winpos.cx = 0; + winpos.cy = 0; + winpos.flags = SWP_NOSIZE; + + WIN_GetRectangles( hwnd, COORDS_SCREEN, &new_screen_rect, NULL ); + USER_SetWindowPos( &winpos, new_screen_rect.left - old_screen_rect.left, + new_screen_rect.top - old_screen_rect.top );
if (was_visible) ShowWindow( hwnd, SW_SHOW );
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c index 434fe6e..19ab297 100644 --- a/dlls/user32/winpos.c +++ b/dlls/user32/winpos.c @@ -1855,7 +1855,8 @@ done: * SWP_DoNCCalcSize */ static UINT SWP_DoNCCalcSize( WINDOWPOS *pWinpos, const RECT *old_window_rect, const RECT *old_client_rect, - const RECT *new_window_rect, RECT *new_client_rect, RECT *validRects ) + const RECT *new_window_rect, RECT *new_client_rect, RECT *validRects, + int parent_x, int parent_y ) { UINT wvrFlags = 0;
@@ -1879,8 +1880,8 @@ static UINT SWP_DoNCCalcSize( WINDOWPOS *pWinpos, const RECT *old_window_rect, c wine_dbgstr_rect(old_window_rect), wine_dbgstr_rect(old_client_rect), wine_dbgstr_rect(new_window_rect), wine_dbgstr_rect(new_client_rect) );
- if (new_client_rect->left != old_client_rect->left || - new_client_rect->top != old_client_rect->top) + if (new_client_rect->left != old_client_rect->left - parent_x || + new_client_rect->top != old_client_rect->top - parent_y) pWinpos->flags &= ~SWP_NOCLIENTMOVE;
if( (new_client_rect->right - new_client_rect->left != @@ -1901,8 +1902,8 @@ static UINT SWP_DoNCCalcSize( WINDOWPOS *pWinpos, const RECT *old_window_rect, c else { if (!(pWinpos->flags & SWP_NOMOVE) && - (new_client_rect->left != old_client_rect->left || - new_client_rect->top != old_client_rect->top)) + (new_client_rect->left != old_client_rect->left - parent_x || + new_client_rect->top != old_client_rect->top - parent_y)) pWinpos->flags &= ~SWP_NOCLIENTMOVE; }
@@ -1917,7 +1918,7 @@ static UINT SWP_DoNCCalcSize( WINDOWPOS *pWinpos, const RECT *old_window_rect, c }
/* fix redundant flags and values in the WINDOWPOS structure */ -static BOOL fixup_flags( WINDOWPOS *winpos, const RECT *old_window_rect ) +static BOOL fixup_flags( WINDOWPOS *winpos, const RECT *old_window_rect, int parent_x, int parent_y ) { HWND parent; WND *wndPtr = WIN_GetPtr( winpos->hwnd ); @@ -1955,7 +1956,7 @@ static BOOL fixup_flags( WINDOWPOS *winpos, const RECT *old_window_rect ) (old_window_rect->bottom - old_window_rect->top == winpos->cy)) winpos->flags |= SWP_NOSIZE; /* Already the right size */
- if ((old_window_rect->left == winpos->x) && (old_window_rect->top == winpos->y)) + if ((old_window_rect->left - parent_x == winpos->x) && (old_window_rect->top - parent_y == winpos->y)) winpos->flags |= SWP_NOMOVE; /* Already the right position */
if ((wndPtr->dwStyle & (WS_POPUP | WS_CHILD)) != WS_CHILD) @@ -2203,7 +2204,7 @@ BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, * * User32 internal function */ -BOOL USER_SetWindowPos( WINDOWPOS * winpos ) +BOOL USER_SetWindowPos( WINDOWPOS * winpos, int parent_x, int parent_y ) { RECT old_window_rect, old_client_rect, new_window_rect, new_client_rect, valid_rects[2]; UINT orig_flags; @@ -2251,7 +2252,7 @@ BOOL USER_SetWindowPos( WINDOWPOS * winpos ) &new_window_rect, &new_client_rect )) return FALSE;
/* Fix redundant flags */ - if (!fixup_flags( winpos, &old_window_rect )) return FALSE; + if (!fixup_flags( winpos, &old_window_rect, parent_x, parent_y )) return FALSE;
if((winpos->flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) != SWP_NOZORDER) { @@ -2262,7 +2263,7 @@ BOOL USER_SetWindowPos( WINDOWPOS * winpos ) /* Common operations */
SWP_DoNCCalcSize( winpos, &old_window_rect, &old_client_rect, - &new_window_rect, &new_client_rect, valid_rects ); + &new_window_rect, &new_client_rect, valid_rects, parent_x, parent_y );
if (!set_window_pos( winpos->hwnd, winpos->hwndInsertAfter, winpos->flags, &new_window_rect, &new_client_rect, valid_rects )) @@ -2350,7 +2351,7 @@ BOOL WINAPI SetWindowPos( HWND hwnd, HWND hwndInsertAfter, winpos.flags = flags;
if (WIN_IsCurrentThread( hwnd )) - return USER_SetWindowPos(&winpos); + return USER_SetWindowPos( &winpos, 0, 0 );
return SendMessageW( winpos.hwnd, WM_WINE_SETWINDOWPOS, 0, (LPARAM)&winpos ); } @@ -2499,7 +2500,7 @@ BOOL WINAPI EndDeferWindowPos( HDWP hdwp ) winpos->cx, winpos->cy, winpos->flags);
if (WIN_IsCurrentThread( winpos->hwnd )) - USER_SetWindowPos( winpos ); + USER_SetWindowPos( winpos, 0, 0 ); else SendMessageW( winpos->hwnd, WM_WINE_SETWINDOWPOS, 0, (LPARAM)winpos ); }