Commit 20bc10c3 authored by Alexandre Julliard's avatar Alexandre Julliard

winex11: Properly forget about a foreign window when it's destroyed through DestroyWindow().

parent 9de2ed97
...@@ -78,6 +78,7 @@ static XContext win_data_context; ...@@ -78,6 +78,7 @@ static XContext win_data_context;
static Time last_user_time; static Time last_user_time;
static Window user_time_window; static Window user_time_window;
static const char foreign_window_prop[] = "__wine_x11_foreign_window";
static const char whole_window_prop[] = "__wine_x11_whole_window"; static const char whole_window_prop[] = "__wine_x11_whole_window";
static const char client_window_prop[]= "__wine_x11_client_window"; static const char client_window_prop[]= "__wine_x11_client_window";
static const char icon_window_prop[] = "__wine_x11_icon_window"; static const char icon_window_prop[] = "__wine_x11_icon_window";
...@@ -1753,7 +1754,23 @@ done: ...@@ -1753,7 +1754,23 @@ done:
*/ */
static void destroy_whole_window( Display *display, struct x11drv_win_data *data, BOOL already_destroyed ) static void destroy_whole_window( Display *display, struct x11drv_win_data *data, BOOL already_destroyed )
{ {
if (!data->whole_window) return; if (!data->whole_window)
{
if (data->embedded)
{
Window xwin = (Window)GetPropA( data->hwnd, foreign_window_prop );
if (xwin)
{
wine_tsx11_lock();
if (!already_destroyed) XSelectInput( display, xwin, 0 );
XDeleteContext( display, xwin, winContext );
wine_tsx11_unlock();
RemovePropA( data->hwnd, foreign_window_prop );
}
}
return;
}
TRACE( "win %p xwin %lx/%lx\n", data->hwnd, data->whole_window, data->client_window ); TRACE( "win %p xwin %lx/%lx\n", data->hwnd, data->whole_window, data->client_window );
wine_tsx11_lock(); wine_tsx11_lock();
...@@ -1894,14 +1911,7 @@ void X11DRV_DestroyNotify( HWND hwnd, XEvent *event ) ...@@ -1894,14 +1911,7 @@ void X11DRV_DestroyNotify( HWND hwnd, XEvent *event )
if (!(data = X11DRV_get_win_data( hwnd ))) return; if (!(data = X11DRV_get_win_data( hwnd ))) return;
if (!data->embedded) FIXME( "window %p/%lx destroyed from the outside\n", hwnd, data->whole_window ); if (!data->embedded) FIXME( "window %p/%lx destroyed from the outside\n", hwnd, data->whole_window );
if (!data->whole_window) destroy_whole_window( display, data, TRUE );
{
wine_tsx11_lock();
XDeleteContext( display, event->xdestroywindow.window, winContext );
wine_tsx11_unlock();
}
else destroy_whole_window( display, data, TRUE );
if (data->embedded) SendMessageW( hwnd, WM_CLOSE, 0, 0 ); if (data->embedded) SendMessageW( hwnd, WM_CLOSE, 0, 0 );
} }
...@@ -2153,6 +2163,7 @@ HWND create_foreign_window( Display *display, Window xwin ) ...@@ -2153,6 +2163,7 @@ HWND create_foreign_window( Display *display, Window xwin )
data->embedded = TRUE; data->embedded = TRUE;
data->mapped = TRUE; data->mapped = TRUE;
SetPropA( hwnd, foreign_window_prop, (HANDLE)xwin );
wine_tsx11_lock(); wine_tsx11_lock();
XSaveContext( display, xwin, winContext, (char *)data->hwnd ); XSaveContext( display, xwin, winContext, (char *)data->hwnd );
wine_tsx11_unlock(); wine_tsx11_unlock();
......
...@@ -197,7 +197,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] = ...@@ -197,7 +197,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
*/ */
static inline BOOL ignore_error( Display *display, XErrorEvent *event ) static inline BOOL ignore_error( Display *display, XErrorEvent *event )
{ {
if (event->request_code == X_SetInputFocus && if ((event->request_code == X_SetInputFocus || event->request_code == X_ChangeWindowAttributes) &&
(event->error_code == BadMatch || event->error_code == BadWindow)) return TRUE; (event->error_code == BadMatch || event->error_code == BadWindow)) return TRUE;
/* ignore a number of errors on gdi display caused by creating/destroying windows */ /* ignore a number of errors on gdi display caused by creating/destroying windows */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment