From: Paul Gofman pgofman@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=20190 --- dlls/user32/tests/win.c | 56 +++++++++++++++++++++++++++++++++++++++-- dlls/win32u/window.c | 18 +++++++++++++ 2 files changed, 72 insertions(+), 2 deletions(-)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index 4c2af09d0c6..82afff70887 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -3073,6 +3073,7 @@ static void test_SetWindowPos(HWND hwnd, HWND hwnd2) RECT orig_win_rc, rect; LONG_PTR old_proc; HWND hwnd_grandchild, hwnd_child, hwnd_child2; + DWORD style, ex_style; HWND hwnd_desktop; RECT rc_expected; RECT rc1, rc2; @@ -3170,7 +3171,7 @@ static void test_SetWindowPos(HWND hwnd, HWND hwnd2) ret = SetWindowPos(hwnd_child, HWND_NOTOPMOST, 1, 2, 3, 4, 0); ok(ret, "Got %d.\n", ret); GetWindowRect(hwnd_child, &rc2); - todo_wine ok(EqualRect(&rc1, &rc2), "%s != %s.\n", wine_dbgstr_rect(&rc1), wine_dbgstr_rect(&rc2)); + ok(EqualRect(&rc1, &rc2), "%s != %s.\n", wine_dbgstr_rect(&rc1), wine_dbgstr_rect(&rc2)); check_active_state(hwnd2, hwnd2, hwnd2); SetWindowPos(hwnd_child, HWND_NOTOPMOST, 0, 0, rc1.right - rc1.left, rc1.bottom - rc1.top, 0);
@@ -3178,7 +3179,58 @@ static void test_SetWindowPos(HWND hwnd, HWND hwnd2) ret = SetWindowPos(hwnd_child, HWND_TOPMOST, 1, 2, 3, 4, 0); ok(ret, "Got %d.\n", ret); GetWindowRect(hwnd_child, &rc2); - todo_wine ok(EqualRect(&rc1, &rc2), "%s != %s.\n", wine_dbgstr_rect(&rc1), wine_dbgstr_rect(&rc2)); + ok(EqualRect(&rc1, &rc2), "%s != %s.\n", wine_dbgstr_rect(&rc1), wine_dbgstr_rect(&rc2)); + check_active_state(hwnd2, hwnd2, hwnd2); + SetWindowPos(hwnd_child, HWND_TOPMOST, 0, 0, rc1.right - rc1.left, rc1.bottom - rc1.top, 0); + + /* Child windows with desktop window parent are not treated as child. */ + SetParent(hwnd_child, NULL); + ex_style = GetWindowLongA(hwnd_child, GWL_EXSTYLE); + ok(!(ex_style & WS_EX_TOPMOST), "got ex_style %#lx.\n", ex_style); + GetWindowRect(hwnd_child, &rc1); + rc_expected.left = rc1.left + 1; + rc_expected.top = rc1.top + 2; + rc_expected.right = rc1.left + 4; + rc_expected.bottom = rc1.top + 6; + ret = SetWindowPos(hwnd_child, HWND_TOPMOST, 1, 2, 3, 4, 0); + ok(ret, "Got %d.\n", ret); + GetWindowRect(hwnd_child, &rc2); + ok(EqualRect(&rc_expected, &rc2), "%s != %s.\n", + wine_dbgstr_rect(&rc_expected), wine_dbgstr_rect(&rc2)); + check_active_state(hwnd2, hwnd2, hwnd2); + SetWindowPos(hwnd_child, HWND_TOPMOST, 0, 0, rc1.right - rc1.left, rc1.bottom - rc1.top, 0); + + style = GetWindowLongA(hwnd_child, GWL_STYLE); + ok(style & WS_CHILD, "got style %#lx.\n", style); + ex_style = GetWindowLongA(hwnd_child, GWL_EXSTYLE); + ok(ex_style & WS_EX_TOPMOST, "got ex_style %#lx.\n", ex_style); + + SetParent(hwnd_child, hwnd); + ex_style = GetWindowLongA(hwnd_child, GWL_EXSTYLE); + ok(ex_style & WS_EX_TOPMOST, "got ex_style %#lx.\n", ex_style); + + SetParent(hwnd_child, NULL); + GetWindowRect(hwnd_child, &rc1); + rc_expected.left = rc1.left + 1; + rc_expected.top = rc1.top + 2; + rc_expected.right = rc1.left + 4; + rc_expected.bottom = rc1.top + 6; + ret = SetWindowPos(hwnd_child, HWND_NOTOPMOST, 1, 2, 3, 4, 0); + ok(ret, "Got %d.\n", ret); + GetWindowRect(hwnd_child, &rc2); + ok(EqualRect(&rc_expected, &rc2), "%s != %s.\n", + wine_dbgstr_rect(&rc_expected), wine_dbgstr_rect(&rc2)); + check_active_state(hwnd2, hwnd2, hwnd2); + SetWindowPos(hwnd_child, HWND_NOTOPMOST, 0, 0, rc1.right - rc1.left, rc1.bottom - rc1.top, 0); + SetParent(hwnd_child, hwnd); + ex_style = GetWindowLongA(hwnd_child, GWL_EXSTYLE); + ok(!(ex_style & WS_EX_TOPMOST), "got ex_style %#lx.\n", ex_style); + + GetWindowRect(hwnd_child, &rc1); + ret = SetWindowPos(hwnd_child, HWND_NOTOPMOST, 1, 2, 3, 4, 0); + ok(ret, "Got %d.\n", ret); + GetWindowRect(hwnd_child, &rc2); + ok(EqualRect(&rc1, &rc2), "%s != %s.\n", wine_dbgstr_rect(&rc1), wine_dbgstr_rect(&rc2)); check_active_state(hwnd2, hwnd2, hwnd2); SetWindowPos(hwnd_child, HWND_TOPMOST, 0, 0, rc1.right - rc1.left, rc1.bottom - rc1.top, 0);
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 0aa10d9ec65..e0b01f74be4 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -3387,6 +3387,24 @@ BOOL set_window_pos( WINDOWPOS *winpos, int parent_x, int parent_y ) if (!insertafter_parent) return FALSE; if (insertafter_parent != parent) return TRUE; } + else if (winpos->hwndInsertAfter == HWND_TOPMOST || winpos->hwndInsertAfter == HWND_NOTOPMOST) + { + BOOL is_child_window; + HWND parent; + WND *win; + + if ((win = get_win_ptr( winpos->hwnd )) && win != WND_DESKTOP && win != WND_OTHER_PROCESS) + { + is_child_window = (win->dwStyle & (WS_POPUP | WS_CHILD)) == WS_CHILD; + release_win_ptr( win ); + if (is_child_window && (parent = NtUserGetAncestor( winpos->hwnd, GA_PARENT )) + && parent != get_desktop_window()) + { + TRACE( "Not changing topmost state for a child window.\n" ); + return TRUE; + } + } + } }
/* Make sure that coordinates are valid for WM_WINDOWPOSCHANGING */