diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 30f0c573a8a..3373cf7263c 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -103,7 +103,7 @@ static struct event_handler handlers[MAX_EVENT_HANDLERS] = /* NoExpose */ /* VisibilityNotify */ /* CreateNotify */ - /* DestroyNotify */ + { DestroyNotify, X11DRV_DestroyNotify }, { UnmapNotify, X11DRV_UnmapNotify }, { MapNotify, X11DRV_MapNotify }, /* MapRequest */ @@ -123,7 +123,7 @@ static struct event_handler handlers[MAX_EVENT_HANDLERS] = { MappingNotify, X11DRV_MappingNotify }, }; -static int nb_event_handlers = 18; /* change this if you add handlers above */ +static int nb_event_handlers = 19; /* change this if you add handlers above */ /* return the name of an X event */ diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index d454b9b6d23..b98c6d8ca94 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1201,7 +1201,7 @@ static Window create_whole_window( Display *display, struct x11drv_win_data *dat * * Destroy the whole X window for a given window. */ -static void destroy_whole_window( Display *display, struct x11drv_win_data *data ) +static void destroy_whole_window( Display *display, struct x11drv_win_data *data, BOOL already_destroyed ) { struct x11drv_thread_data *thread_data = x11drv_thread_data(); @@ -1214,12 +1214,16 @@ static void destroy_whole_window( Display *display, struct x11drv_win_data *data wine_tsx11_lock(); XDeleteContext( display, data->whole_window, winContext ); XDeleteContext( display, data->client_window, winContext ); - XDestroyWindow( display, data->whole_window ); + if (!already_destroyed) XDestroyWindow( display, data->whole_window ); data->whole_window = data->client_window = 0; + data->wm_state = WithdrawnState; + data->net_wm_state = 0; + data->mapped = FALSE; if (data->xic) { XUnsetICFocus( data->xic ); XDestroyIC( data->xic ); + data->xic = 0; } /* Outlook stops processing messages after destroying a dialog, so we need an explicit flush */ XFlush( display ); @@ -1269,7 +1273,7 @@ void X11DRV_DestroyWindow( HWND hwnd ) wine_tsx11_unlock(); } - destroy_whole_window( display, data ); + destroy_whole_window( display, data, FALSE ); destroy_icon_window( display, data ); if (data->colormap) @@ -1289,6 +1293,21 @@ void X11DRV_DestroyWindow( HWND hwnd ) } +/*********************************************************************** + * X11DRV_DestroyNotify + */ +void X11DRV_DestroyNotify( HWND hwnd, XEvent *event ) +{ + Display *display = event->xdestroywindow.display; + struct x11drv_win_data *data; + + if (!(data = X11DRV_get_win_data( hwnd ))) return; + + FIXME( "window %p/%lx destroyed from the outside\n", hwnd, data->whole_window ); + destroy_whole_window( display, data, TRUE ); +} + + static struct x11drv_win_data *alloc_win_data( Display *display, HWND hwnd ) { struct x11drv_win_data *data; @@ -1562,7 +1581,7 @@ void X11DRV_SetParent( HWND hwnd, HWND parent, HWND old_parent ) if (old_parent == GetDesktopWindow()) { /* destroy the old X windows */ - destroy_whole_window( display, data ); + destroy_whole_window( display, data, FALSE ); destroy_icon_window( display, data ); if (data->managed) { diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 7b61d95e0d0..59685e9550c 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -626,6 +626,7 @@ extern void X11DRV_EnterNotify( HWND hwnd, XEvent *event ); extern void X11DRV_KeyEvent( HWND hwnd, XEvent *event ); extern void X11DRV_KeymapNotify( HWND hwnd, XEvent *event ); extern void X11DRV_Expose( HWND hwnd, XEvent *event ); +extern void X11DRV_DestroyNotify( HWND hwnd, XEvent *event ); extern void X11DRV_MapNotify( HWND hwnd, XEvent *event ); extern void X11DRV_UnmapNotify( HWND hwnd, XEvent *event ); extern void X11DRV_ConfigureNotify( HWND hwnd, XEvent *event );