Jacek Caban : server: Don't immediately destroy child windows belonging to different thread in free_window_handle.
Alexandre Julliard
julliard at winehq.org
Wed Feb 9 16:03:49 CST 2022
Module: wine
Branch: master
Commit: 078bcc066ccf4eeee84a4f00e94c802988363093
URL: https://source.winehq.org/git/wine.git/?a=commit;h=078bcc066ccf4eeee84a4f00e94c802988363093
Author: Jacek Caban <jacek at codeweavers.com>
Date: Tue Feb 8 13:13:00 2022 +0100
server: Don't immediately destroy child windows belonging to different thread in free_window_handle.
Notify their thread instead.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/user32/user_private.h | 18 ------------------
dlls/user32/win.c | 12 +-----------
include/ntuser.h | 19 +++++++++++++++++++
server/window.c | 14 +++++++++-----
4 files changed, 29 insertions(+), 34 deletions(-)
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 9e65e9f1f66..73f01871d8c 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -44,24 +44,6 @@
struct window_surface;
-/* internal messages codes */
-enum wine_internal_message
-{
- WM_WINE_DESTROYWINDOW = 0x80000000,
- WM_WINE_SETWINDOWPOS,
- WM_WINE_SHOWWINDOW,
- WM_WINE_SETPARENT,
- WM_WINE_SETWINDOWLONG,
- WM_WINE_SETSTYLE,
- WM_WINE_SETACTIVEWINDOW,
- WM_WINE_KEYBOARD_LL_HOOK,
- WM_WINE_MOUSE_LL_HOOK,
- WM_WINE_CLIPCURSOR,
- WM_WINE_UPDATEWINDOWSTATE,
- WM_WINE_FIRST_DRIVER_MSG = 0x80001000, /* range of messages reserved for the USER driver */
- WM_WINE_LAST_DRIVER_MSG = 0x80001fff
-};
-
extern const struct user_driver_funcs *USER_Driver DECLSPEC_HIDDEN;
extern void USER_unload_driver(void) DECLSPEC_HIDDEN;
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index 02891cd34ce..4f860889024 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -1208,16 +1208,14 @@ static WND *next_thread_window( HWND *hwnd )
void destroy_thread_windows(void)
{
WND *wndPtr;
- HWND hwnd = 0, *list;
+ HWND hwnd = 0;
HMENU menu, sys_menu;
struct window_surface *surface;
- int i;
while ((wndPtr = next_thread_window( &hwnd )))
{
/* destroy the client-side storage */
- list = WIN_ListChildren( hwnd );
menu = ((wndPtr->dwStyle & (WS_CHILD | WS_POPUP)) != WS_CHILD) ? (HMENU)wndPtr->wIDmenu : 0;
sys_menu = wndPtr->hSysMenu;
free_dce( wndPtr->dce, hwnd );
@@ -1232,14 +1230,6 @@ void destroy_thread_windows(void)
register_window_surface( surface, NULL );
window_surface_release( surface );
}
-
- /* free child windows */
-
- if (!list) continue;
- for (i = 0; list[i]; i++)
- if (!WIN_IsCurrentThread( list[i] ))
- SendNotifyMessageW( list[i], WM_WINE_DESTROYWINDOW, 0, 0 );
- HeapFree( GetProcessHeap(), 0, list );
}
}
diff --git a/include/ntuser.h b/include/ntuser.h
index a9dd8d2e3fd..4b665e6a364 100644
--- a/include/ntuser.h
+++ b/include/ntuser.h
@@ -102,6 +102,25 @@ struct user_thread_info
C_ASSERT( sizeof(struct user_thread_info) <= sizeof(((TEB *)0)->Win32ClientInfo) );
+/* internal messages codes */
+enum wine_internal_message
+{
+ WM_WINE_DESTROYWINDOW = 0x80000000,
+ WM_WINE_SETWINDOWPOS,
+ WM_WINE_SHOWWINDOW,
+ WM_WINE_SETPARENT,
+ WM_WINE_SETWINDOWLONG,
+ WM_WINE_SETSTYLE,
+ WM_WINE_SETACTIVEWINDOW,
+ WM_WINE_KEYBOARD_LL_HOOK,
+ WM_WINE_MOUSE_LL_HOOK,
+ WM_WINE_CLIPCURSOR,
+ WM_WINE_UPDATEWINDOWSTATE,
+ WM_WINE_FIRST_DRIVER_MSG = 0x80001000, /* range of messages reserved for the USER driver */
+ WM_WINE_LAST_DRIVER_MSG = 0x80001fff
+};
+
+
HKL WINAPI NtUserActivateKeyboardLayout( HKL layout, UINT flags );
BOOL WINAPI NtUserAddClipboardFormatListener( HWND hwnd );
BOOL WINAPI NtUserAttachThreadInput( DWORD from, DWORD to, BOOL attach );
diff --git a/server/window.c b/server/window.c
index 9fd67656eea..506f0269ee1 100644
--- a/server/window.c
+++ b/server/window.c
@@ -27,9 +27,7 @@
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winternl.h"
+#include "ntuser.h"
#include "object.h"
#include "request.h"
@@ -1965,12 +1963,18 @@ void free_window_handle( struct window *win )
LIST_FOR_EACH_ENTRY_SAFE( child, next, &win->children, struct window, entry )
{
if (!child->handle) continue;
- free_window_handle( child );
+ if (!win->thread || !child->thread || win->thread == child->thread)
+ free_window_handle( child );
+ else
+ send_notify_message( child->handle, WM_WINE_DESTROYWINDOW, 0, 0 );
}
LIST_FOR_EACH_ENTRY_SAFE( child, next, &win->children, struct window, entry )
{
if (!child->handle) continue;
- free_window_handle( child );
+ if (!win->thread || !child->thread || win->thread == child->thread)
+ free_window_handle( child );
+ else
+ send_notify_message( child->handle, WM_WINE_DESTROYWINDOW, 0, 0 );
}
/* reset global window pointers, if the corresponding window is destroyed */
More information about the wine-cvs
mailing list