Alexandre Julliard : user32: Fix Z-order handling of windows that have a top-most owner.
Alexandre Julliard
julliard at winehq.org
Fri Feb 19 09:21:35 CST 2010
Module: wine
Branch: master
Commit: adf9dcd6a70ef2c125e154f4cd095a616e5505f8
URL: http://source.winehq.org/git/wine.git/?a=commit;h=adf9dcd6a70ef2c125e154f4cd095a616e5505f8
Author: Alexandre Julliard <julliard at winehq.org>
Date: Fri Feb 19 13:05:08 2010 +0100
user32: Fix Z-order handling of windows that have a top-most owner.
---
dlls/user32/tests/win.c | 23 +++++++++++++++++++----
dlls/user32/winpos.c | 10 ++++++----
server/window.c | 12 ++++++++++--
3 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index 2799ec8..cd83749 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -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)));*/
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);
/* skip foreign windows */
@@ -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)));*/
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);
- 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);
- 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)
@@ -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);
#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_B);
DestroyWindow(hwnd_C);
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c
index 65e9389..f8a3c41 100644
--- a/dlls/user32/winpos.c
+++ b/dlls/user32/winpos.c
@@ -1627,22 +1627,24 @@ static HWND SWP_DoOwnedPopups(HWND hwnd, HWND hwndInsertAfter)
{
/* 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;
for (i = 0; list[i]; i++)
{
+ BOOL topmost = (GetWindowLongW( list[i], GWL_EXSTYLE ) & WS_EX_TOPMOST) != 0;
+
if (list[i] == owner)
{
if (i > 0) hwndInsertAfter = list[i-1];
- else hwndInsertAfter = HWND_TOP;
+ else hwndInsertAfter = topmost ? HWND_TOPMOST : HWND_TOP;
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;
}
diff --git a/server/window.c b/server/window.c
index a0e0788..5fd6f71 100644
--- a/server/window.c
+++ b/server/window.c
@@ -187,9 +187,17 @@ static void link_window( struct window *win, struct window *previous )
struct list *entry = win->parent->children.next;
if (!(win->ex_style & WS_EX_TOPMOST)) /* put it above the first non-topmost window */
{
- while (entry != &win->parent->children &&
- LIST_ENTRY( entry, struct window, entry )->ex_style & WS_EX_TOPMOST)
+ while (entry != &win->parent->children)
+ {
+ 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;
+ }
}
list_add_before( entry, &win->entry );
}
More information about the wine-cvs
mailing list