Commit adf9dcd6 authored by Alexandre Julliard's avatar Alexandre Julliard

user32: Fix Z-order handling of windows that have a top-most owner.

parent 71fa5a36
...@@ -2159,7 +2159,7 @@ static void check_z_order_debug(HWND hwnd, HWND next, HWND prev, HWND owner, ...@@ -2159,7 +2159,7 @@ static void check_z_order_debug(HWND hwnd, HWND next, HWND prev, HWND owner,
/*trace("skipping next %p (%p)\n", test, UlongToHandle(GetWindowLongPtr(test, GWLP_HINSTANCE)));*/ /*trace("skipping next %p (%p)\n", test, UlongToHandle(GetWindowLongPtr(test, GWLP_HINSTANCE)));*/
test = GetWindow(test, GW_HWNDNEXT); test = GetWindow(test, GW_HWNDNEXT);
} }
ok_(file, line)(next == test, "expected next %p, got %p\n", next, test); ok_(file, line)(next == test, "%p: expected next %p, got %p\n", hwnd, next, test);
test = GetWindow(hwnd, GW_HWNDPREV); test = GetWindow(hwnd, GW_HWNDPREV);
/* skip foreign windows */ /* skip foreign windows */
...@@ -2171,13 +2171,14 @@ static void check_z_order_debug(HWND hwnd, HWND next, HWND prev, HWND owner, ...@@ -2171,13 +2171,14 @@ static void check_z_order_debug(HWND hwnd, HWND next, HWND prev, HWND owner,
/*trace("skipping prev %p (%p)\n", test, UlongToHandle(GetWindowLongPtr(test, GWLP_HINSTANCE)));*/ /*trace("skipping prev %p (%p)\n", test, UlongToHandle(GetWindowLongPtr(test, GWLP_HINSTANCE)));*/
test = GetWindow(test, GW_HWNDPREV); test = GetWindow(test, GW_HWNDPREV);
} }
ok_(file, line)(prev == test, "expected prev %p, got %p\n", prev, test); ok_(file, line)(prev == test, "%p: expected prev %p, got %p\n", hwnd, prev, test);
test = GetWindow(hwnd, GW_OWNER); test = GetWindow(hwnd, GW_OWNER);
ok_(file, line)(owner == test, "expected owner %p, got %p\n", owner, test); ok_(file, line)(owner == test, "%p: expected owner %p, got %p\n", hwnd, owner, test);
ex_style = GetWindowLong(hwnd, GWL_EXSTYLE); ex_style = GetWindowLong(hwnd, GWL_EXSTYLE);
ok_(file, line)(!(ex_style & WS_EX_TOPMOST) == !topmost, "expected %stopmost\n", topmost ? "" : "NOT "); ok_(file, line)(!(ex_style & WS_EX_TOPMOST) == !topmost, "%p: expected %stopmost\n",
hwnd, topmost ? "" : "NOT ");
} }
static void test_popup_zorder(HWND hwnd_D, HWND hwnd_E) static void test_popup_zorder(HWND hwnd_D, HWND hwnd_E)
...@@ -2258,6 +2259,20 @@ static void test_popup_zorder(HWND hwnd_D, HWND hwnd_E) ...@@ -2258,6 +2259,20 @@ static void test_popup_zorder(HWND hwnd_D, HWND hwnd_E)
check_z_order(hwnd_A, hwnd_D, 0, 0, TRUE); check_z_order(hwnd_A, hwnd_D, 0, 0, TRUE);
#endif #endif
/* make hwnd_C owned by a topmost window */
DestroyWindow( hwnd_C );
hwnd_C = CreateWindowEx(0, "MainWindowClass", NULL,
WS_POPUP,
100, 100, 100, 100,
hwnd_A, 0, GetModuleHandle(0), NULL);
trace("hwnd_C %p\n", hwnd_C);
check_z_order(hwnd_E, 0, hwnd_D, 0, FALSE);
check_z_order(hwnd_D, hwnd_E, hwnd_F, 0, FALSE);
check_z_order(hwnd_F, hwnd_D, hwnd_B, 0, FALSE);
check_z_order(hwnd_B, hwnd_F, hwnd_A, hwnd_F, TRUE);
check_z_order(hwnd_A, hwnd_B, hwnd_C, 0, TRUE);
check_z_order(hwnd_C, hwnd_A, 0, hwnd_A, TRUE);
DestroyWindow(hwnd_A); DestroyWindow(hwnd_A);
DestroyWindow(hwnd_B); DestroyWindow(hwnd_B);
DestroyWindow(hwnd_C); DestroyWindow(hwnd_C);
......
...@@ -1627,22 +1627,24 @@ static HWND SWP_DoOwnedPopups(HWND hwnd, HWND hwndInsertAfter) ...@@ -1627,22 +1627,24 @@ static HWND SWP_DoOwnedPopups(HWND hwnd, HWND hwndInsertAfter)
{ {
/* make sure this popup stays above the owner */ /* make sure this popup stays above the owner */
if (hwndInsertAfter != HWND_TOP && hwndInsertAfter != HWND_TOPMOST) if (hwndInsertAfter != HWND_TOPMOST)
{ {
if (!(list = WIN_ListChildren( GetDesktopWindow() ))) return hwndInsertAfter; if (!(list = WIN_ListChildren( GetDesktopWindow() ))) return hwndInsertAfter;
for (i = 0; list[i]; i++) for (i = 0; list[i]; i++)
{ {
BOOL topmost = (GetWindowLongW( list[i], GWL_EXSTYLE ) & WS_EX_TOPMOST) != 0;
if (list[i] == owner) if (list[i] == owner)
{ {
if (i > 0) hwndInsertAfter = list[i-1]; if (i > 0) hwndInsertAfter = list[i-1];
else hwndInsertAfter = HWND_TOP; else hwndInsertAfter = topmost ? HWND_TOPMOST : HWND_TOP;
break; break;
} }
if (hwndInsertAfter == HWND_NOTOPMOST) if (hwndInsertAfter == HWND_TOP || hwndInsertAfter == HWND_NOTOPMOST)
{ {
if (!(GetWindowLongW( list[i], GWL_EXSTYLE ) & WS_EX_TOPMOST)) break; if (!topmost) break;
} }
else if (list[i] == hwndInsertAfter) break; else if (list[i] == hwndInsertAfter) break;
} }
......
...@@ -187,9 +187,17 @@ static void link_window( struct window *win, struct window *previous ) ...@@ -187,9 +187,17 @@ static void link_window( struct window *win, struct window *previous )
struct list *entry = win->parent->children.next; struct list *entry = win->parent->children.next;
if (!(win->ex_style & WS_EX_TOPMOST)) /* put it above the first non-topmost window */ if (!(win->ex_style & WS_EX_TOPMOST)) /* put it above the first non-topmost window */
{ {
while (entry != &win->parent->children && while (entry != &win->parent->children)
LIST_ENTRY( entry, struct window, entry )->ex_style & WS_EX_TOPMOST) {
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 );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment