From: "Jiajin Cui" Subject: [PATCH v6 4/4] server: Make that subwindows shouldn`t change existing WS_EX_TOPMOST extended styles. Message-Id: <2020070211361031876715@uniontech.com> Date: Thu, 2 Jul 2020 11:36:10 +0800 From fd9f645b23cd380174ab00dea58a8aa9ae8512b4 Mon Sep 17 00:00:00 2001 From: Jiajin Cui Date: Wed, 1 Jul 2020 18:50:36 +0800 Subject: [PATCH v6 4/4] server: Make that subwindows shouldn`t change existing WS_EX_TOPMOST extended styles. Signed-off-by: Jiajin Cui --- dlls/user32/tests/msg.c | 2 +- dlls/user32/tests/win.c | 16 +++---- server/window.c | 97 +++++++++++++++++++++++++++-------------- 3 files changed, 73 insertions(+), 42 deletions(-) diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index 92b14ef52c..284ea57470 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -5802,7 +5802,7 @@ static void test_setwindowpos(void) hwnd, 0, GetModuleHandleA(NULL), NULL); ok_sequence(WmCreateChildtopmostSeq, "CreateChildWindow", FALSE); ok(hwnd_A != NULL, "Failed to create child witch WS_EX_TOPMOST\n"); - todo_wine ok(GetWindowLongA(hwnd_A, GWL_EXSTYLE) & WS_EX_TOPMOST, "%p: expected topmost\n", hwnd_A); + ok(GetWindowLongA(hwnd_A, GWL_EXSTYLE) & WS_EX_TOPMOST, "%p: expected topmost\n", hwnd_A); /* repeat */ flush_events(); diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index 18ef4f0f74..33cdc43c13 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -3036,42 +3036,42 @@ static void test_child_topmost_zorder(HWND hwnd_D) hwnd_D, 0, GetModuleHandleA(NULL), NULL); check_z_order(hwnd_C, hwnd_B, 0, 0, FALSE); check_z_order(hwnd_B, hwnd_A, hwnd_C, 0, FALSE); -todo_wine check_z_order(hwnd_A, 0, hwnd_B, 0, TRUE); + check_z_order(hwnd_A, 0, hwnd_B, 0, TRUE); SetWindowPos(hwnd_A, HWND_TOP, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE); check_z_order(hwnd_C, hwnd_B, hwnd_A, 0, FALSE); check_z_order(hwnd_B, 0, hwnd_C, 0, FALSE); -todo_wine check_z_order(hwnd_A, hwnd_C, 0, 0, TRUE); + check_z_order(hwnd_A, hwnd_C, 0, 0, TRUE); SetWindowPos(hwnd_A, HWND_TOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE); check_z_order(hwnd_C, hwnd_B, hwnd_A, 0, FALSE); check_z_order(hwnd_B, 0, hwnd_C, 0, FALSE); -todo_wine check_z_order(hwnd_A, hwnd_C, 0, 0, TRUE); + check_z_order(hwnd_A, hwnd_C, 0, 0, TRUE); SetWindowPos(hwnd_B, HWND_TOP, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE); check_z_order(hwnd_C, 0, hwnd_A, 0, FALSE); check_z_order(hwnd_B, hwnd_A, 0, 0, FALSE); -todo_wine check_z_order(hwnd_A, hwnd_C, hwnd_B, 0, TRUE); + check_z_order(hwnd_A, hwnd_C, hwnd_B, 0, TRUE); SetWindowPos(hwnd_A, HWND_NOTOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE); check_z_order(hwnd_C, 0, hwnd_A, 0, FALSE); check_z_order(hwnd_B, hwnd_A, 0, 0, FALSE); -todo_wine check_z_order(hwnd_A, hwnd_C, hwnd_B, 0, TRUE); + check_z_order(hwnd_A, hwnd_C, hwnd_B, 0, TRUE); SetWindowPos(hwnd_A, HWND_BOTTOM, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE); check_z_order(hwnd_C, hwnd_A, hwnd_B, 0, FALSE); check_z_order(hwnd_B, hwnd_C, 0, 0, FALSE); -todo_wine check_z_order(hwnd_A, 0, hwnd_C, 0, TRUE); + check_z_order(hwnd_A, 0, hwnd_C, 0, TRUE); SetWindowPos(hwnd_C, HWND_TOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE); check_z_order(hwnd_C, hwnd_A, hwnd_B, 0, FALSE); check_z_order(hwnd_B, hwnd_C, 0, 0, FALSE); -todo_wine check_z_order(hwnd_A, 0, hwnd_C, 0, TRUE); + check_z_order(hwnd_A, 0, hwnd_C, 0, TRUE); SetWindowPos(hwnd_C, HWND_TOP, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE); check_z_order(hwnd_C, hwnd_B, 0, 0, FALSE); check_z_order(hwnd_B, hwnd_A, hwnd_C, 0, FALSE); -todo_wine check_z_order(hwnd_A, 0, hwnd_B, 0, TRUE); + check_z_order(hwnd_A, 0, hwnd_B, 0, TRUE); DestroyWindow(hwnd_A); DestroyWindow(hwnd_B); diff --git a/server/window.c b/server/window.c index 3a88b7f34f..3e7b2d5007 100644 --- a/server/window.c +++ b/server/window.c @@ -191,52 +191,83 @@ static unsigned int get_monitor_dpi( struct window *win ) /* link a window at the right place in the siblings list */ static void link_window( struct window *win, struct window *previous ) { - if (previous == WINPTR_NOTOPMOST) + if (win->style & WS_CHILD) { - if (!(win->ex_style & WS_EX_TOPMOST) && win->is_linked) return; /* nothing to do */ - win->ex_style &= ~WS_EX_TOPMOST; - previous = WINPTR_TOP; /* fallback to the HWND_TOP case */ - } + if (previous == WINPTR_NOTOPMOST) + { + if (!(win->ex_style & WS_EX_TOPMOST) && win->is_linked) return; /* nothing to do */ + previous = WINPTR_TOP; /* fallback to the HWND_TOP case */ + } - list_remove( &win->entry ); /* unlink it from the previous location */ + list_remove( &win->entry ); /* unlink it from the previous location */ - if (previous == WINPTR_BOTTOM) - { - list_add_tail( &win->parent->children, &win->entry ); - win->ex_style &= ~WS_EX_TOPMOST; - } - else if (previous == WINPTR_TOPMOST) - { - list_add_head( &win->parent->children, &win->entry ); - win->ex_style |= WS_EX_TOPMOST; + if (previous == WINPTR_BOTTOM) + { + list_add_tail( &win->parent->children, &win->entry ); + } + else if (previous == WINPTR_TOPMOST) + { + list_add_head( &win->parent->children, &win->entry ); + } + else if (previous == WINPTR_TOP) + { + struct list *entry = win->parent->children.next; + list_add_before( entry, &win->entry ); + } + else + { + list_add_after( &previous->entry, &win->entry ); + } } - else if (previous == WINPTR_TOP) + else { - struct list *entry = win->parent->children.next; - if (!(win->ex_style & WS_EX_TOPMOST)) /* put it above the first non-topmost window */ + if (previous == WINPTR_NOTOPMOST) + { + if (!(win->ex_style & WS_EX_TOPMOST) && win->is_linked) return; /* nothing to do */ + win->ex_style &= ~WS_EX_TOPMOST; + previous = WINPTR_TOP; /* fallback to the HWND_TOP case */ + } + + list_remove( &win->entry ); /* unlink it from the previous location */ + + if (previous == WINPTR_BOTTOM) + { + list_add_tail( &win->parent->children, &win->entry ); + win->ex_style &= ~WS_EX_TOPMOST; + } + else if (previous == WINPTR_TOPMOST) { - while (entry != &win->parent->children) + list_add_head( &win->parent->children, &win->entry ); + win->ex_style |= WS_EX_TOPMOST; + } + else if (previous == WINPTR_TOP) + { + struct list *entry = win->parent->children.next; + if (!(win->ex_style & WS_EX_TOPMOST)) /* put it above the first non-topmost window */ { - struct window *next = LIST_ENTRY( entry, struct window, entry ); - if (!(next->ex_style & WS_EX_TOPMOST)) break; - if (next->handle == win->owner) /* keep it above owner */ + while (entry != &win->parent->children) { - win->ex_style |= WS_EX_TOPMOST; - break; + struct window *next = LIST_ENTRY( entry, struct window, entry ); + if (!(next->ex_style & WS_EX_TOPMOST)) break; + if (next->handle == win->owner) /* keep it above owner */ + { + win->ex_style |= WS_EX_TOPMOST; + break; + } + entry = entry->next; } - entry = entry->next; } + list_add_before( entry, &win->entry ); } - list_add_before( entry, &win->entry ); - } - else - { - list_add_after( &previous->entry, &win->entry ); - if (!(previous->ex_style & WS_EX_TOPMOST)) win->ex_style &= ~WS_EX_TOPMOST; else { - struct window *next = get_next_window( win ); - if (next && (next->ex_style & WS_EX_TOPMOST)) win->ex_style |= WS_EX_TOPMOST; + list_add_after( &previous->entry, &win->entry ); + if (!(previous->ex_style & WS_EX_TOPMOST)) win->ex_style &= ~WS_EX_TOPMOST; + else + { + struct window *next = get_next_window( win ); + if (next && (next->ex_style & WS_EX_TOPMOST)) win->ex_style |= WS_EX_TOPMOST; + } } } -- 2.20.1