winex11: Add a DestroyNotify handler to catch a situation that is not supposed to happen.

This commit is contained in:
Alexandre Julliard 2008-03-05 16:51:09 +01:00
parent d6a17d2c93
commit 3b6f95c663
3 changed files with 26 additions and 6 deletions

View File

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

View File

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

View File

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