Jacek Caban : winex11: Use NtUserBuildHwndList for has_owned_popup implementation.

Alexandre Julliard julliard at winehq.org
Tue Apr 19 16:20:13 CDT 2022


Module: wine
Branch: master
Commit: 2425488ef66d774485ba3da9277fc9973c8a6669
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=2425488ef66d774485ba3da9277fc9973c8a6669

Author: Jacek Caban <jacek at 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 at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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;
 }
 
 




More information about the wine-cvs mailing list