From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/window.c | 50 ++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 14 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 23391b069dd..26cfee427ab 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1587,6 +1587,13 @@ Window get_dummy_parent(void) return dummy_parent; }
+static void client_window_events_enable( struct x11drv_win_data *data, Window client_window ) +{ + XSaveContext( data->display, client_window, winContext, (char *)data->hwnd ); + XSync( data->display, False ); /* make sure client_window is known from data->display */ + XSelectInput( data->display, client_window, ExposureMask ); +} + static void client_window_events_disable( struct x11drv_win_data *data, Window client_window ) { XSelectInput( data->display, client_window, 0 ); @@ -1613,6 +1620,28 @@ static void detach_client_window( struct x11drv_win_data *data, Window client_wi }
+/********************************************************************** + * attach_client_window + */ +static void attach_client_window( struct x11drv_win_data *data, Window client_window ) +{ + if (data->client_window == client_window || !client_window) return; + + TRACE( "%p/%lx attaching client window %lx\n", data->hwnd, data->whole_window, client_window ); + + detach_client_window( data, data->client_window ); + + if (data->whole_window) + { + client_window_events_enable( data, client_window ); + XReparentWindow( gdi_display, client_window, data->whole_window, data->client_rect.left - data->whole_rect.left, + data->client_rect.top - data->whole_rect.top ); + } + + data->client_window = client_window; +} + + /********************************************************************** * destroy_client_window */ @@ -1682,9 +1711,7 @@ Window create_client_window( HWND hwnd, const XVisualInfo *visual, Colormap colo if (data->whole_window) { XFlush( gdi_display ); /* make sure client_window is created for XSelectInput */ - XSaveContext( data->display, data->client_window, winContext, (char *)data->hwnd ); - XSync( data->display, False ); /* make sure client_window is known from data->display */ - XSelectInput( data->display, data->client_window, ExposureMask ); + client_window_events_enable( data, data->client_window ); } TRACE( "%p xwin %lx/%lx\n", data->hwnd, data->whole_window, data->client_window ); } @@ -1832,7 +1859,6 @@ void set_window_visual( struct x11drv_win_data *data, const XVisualInfo *vis, BO { BOOL same_visual = (data->vis.visualid == vis->visualid); Window client_window = data->client_window; - Window whole_window = data->whole_window;
if (!data->use_alpha == !use_alpha && same_visual) return; if (data->surface) window_surface_release( data->surface ); @@ -1840,18 +1866,14 @@ void set_window_visual( struct x11drv_win_data *data, const XVisualInfo *vis, BO data->use_alpha = use_alpha;
if (same_visual) return; - data->client_window = 0; - destroy_whole_window( data, client_window != 0 /* don't destroy whole_window until reparented */ ); + client_window = data->client_window; + /* detach the client before re-creating whole_window */ + detach_client_window( data, client_window ); + destroy_whole_window( data, FALSE ); data->vis = *vis; create_whole_window( data ); - if (!client_window) return; - /* move the client to the new parent */ - XReparentWindow( gdi_display, client_window, data->whole_window, - data->client_rect.left - data->whole_rect.left, - data->client_rect.top - data->whole_rect.top ); - data->client_window = client_window; - XSync( gdi_display, False ); /* make sure XReparentWindow requests have completed before destroying whole_window */ - XDestroyWindow( data->display, whole_window ); + /* attach the client back to the re-created whole_window */ + attach_client_window( data, client_window ); }