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@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2022-02-08 13:13:00 +01:00 committed by Alexandre Julliard
parent d52e454c12
commit 078bcc066c
4 changed files with 29 additions and 34 deletions

View File

@ -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;

View File

@ -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 );
}
}

View File

@ -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 );

View File

@ -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 */