Module: wine Branch: master Commit: 2425488ef66d774485ba3da9277fc9973c8a6669 URL: https://source.winehq.org/git/wine.git/?a=commit;h=2425488ef66d774485ba3da92...
Author: Jacek Caban jacek@codeweavers.com Date: Tue Apr 19 15:30:18 2022 +0200
winex11: Use NtUserBuildHwndList for has_owned_popup implementation.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Huw Davies huw@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/winex11.drv/window.c | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 3f20fc9c7d2..c1fc008b7d3 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -39,6 +39,8 @@
/* avoid conflict with field names in included win32 headers */ #undef Status +#include "ntstatus.h" +#define WIN32_NO_STATUS #include "windef.h" #include "winbase.h" #include "wingdi.h" @@ -161,12 +163,6 @@ static void remove_startup_notification(Display *display, Window window) }
-struct has_popup_result -{ - HWND hwnd; - BOOL found; -}; - static BOOL is_managed( HWND hwnd ) { struct x11drv_win_data *data = get_win_data( hwnd ); @@ -175,24 +171,39 @@ static BOOL is_managed( HWND hwnd ) return ret; }
-static BOOL CALLBACK has_managed_popup( HWND hwnd, LPARAM lparam ) +static HWND *build_hwnd_list(void) { - struct has_popup_result *result = (struct has_popup_result *)lparam; + NTSTATUS status; + HWND *list; + UINT count = 128;
- if (hwnd == result->hwnd) return FALSE; /* popups are always above owner */ - if (GetWindow( hwnd, GW_OWNER ) != result->hwnd) return TRUE; - result->found = is_managed( hwnd ); - return !result->found; + for (;;) + { + if (!(list = malloc( count * sizeof(*list) ))) return NULL; + status = NtUserBuildHwndList( 0, 0, 0, 0, 0, count, list, &count ); + if (!status) return list; + free( list ); + if (status != STATUS_BUFFER_TOO_SMALL) return NULL; + } }
static BOOL has_owned_popups( HWND hwnd ) { - struct has_popup_result result; + HWND *list; + UINT i; + BOOL ret = FALSE;
- result.hwnd = hwnd; - result.found = FALSE; - EnumWindows( has_managed_popup, (LPARAM)&result ); - return result.found; + if (!(list = build_hwnd_list())) return FALSE; + + for (i = 0; list[i] != HWND_BOTTOM; i++) + { + if (list[i] == hwnd) break; /* popups are always above owner */ + if (NtUserGetWindowRelative( list[i], GW_OWNER ) != hwnd) continue; + if ((ret = is_managed( list[i] ))) break; + } + + free( list ); + return ret; }