From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/window.c | 54 +++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 14 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 95fa466c994..8dfe8aeaf63 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1456,8 +1456,21 @@ static void sync_client_position( struct x11drv_win_data *data,
if (!data->client_window) return;
- changes.x = data->client_rect.left - data->whole_rect.left; - changes.y = data->client_rect.top - data->whole_rect.top; + if (data->whole_window) + { + changes.x = data->client_rect.left - data->whole_rect.left; + changes.y = data->client_rect.top - data->whole_rect.top; + } + else + { + HWND toplevel = NtUserGetAncestor( data->hwnd, GA_ROOT ); + POINT pos = {data->client_rect.left, data->client_rect.top}; + + NtUserMapWindowPoints( toplevel, toplevel, &pos, 1 ); + changes.x = pos.x; + changes.y = pos.y; + } + changes.width = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 ); changes.height = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 );
@@ -1610,11 +1623,8 @@ void detach_client_window( struct x11drv_win_data *data, Window client_window )
TRACE( "%p/%lx detaching client window %lx\n", data->hwnd, data->whole_window, client_window );
- if (data->whole_window) - { - client_window_events_disable( data, client_window ); - XReparentWindow( gdi_display, client_window, get_dummy_parent(), 0, 0 ); - } + client_window_events_disable( data, client_window ); + XReparentWindow( gdi_display, client_window, get_dummy_parent(), 0, 0 );
data->client_window = 0; } @@ -1625,18 +1635,33 @@ void detach_client_window( struct x11drv_win_data *data, Window client_window ) */ void attach_client_window( struct x11drv_win_data *data, Window client_window ) { + Window whole_window; + POINT pos = {0}; + 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) + if ((whole_window = data->whole_window)) + { + pos.x = data->client_rect.left - data->whole_rect.left; + pos.y = data->client_rect.top - data->whole_rect.top; + } + else { - 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 ); + HWND toplevel = NtUserGetAncestor( data->hwnd, GA_ROOT ); + whole_window = X11DRV_get_whole_window( toplevel ); + + pos.x = data->client_rect.left; + pos.y = data->client_rect.top; + NtUserMapWindowPoints( toplevel, toplevel, &pos, 1 ); } + if (!whole_window) whole_window = get_dummy_parent(); + + client_window_events_enable( data, client_window ); + XReparentWindow( gdi_display, client_window, whole_window, pos.x, pos.y );
data->client_window = client_window; } @@ -1800,6 +1825,9 @@ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_des { TRACE( "win %p xwin %lx/%lx\n", data->hwnd, data->whole_window, data->client_window );
+ if (!already_destroyed) detach_client_window( data, data->client_window ); + else if (data->client_window) client_window_events_disable( data, data->client_window ); + if (!data->whole_window) { if (data->embedded) @@ -1821,8 +1849,6 @@ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_des } else { - if (!already_destroyed) detach_client_window( data, data->client_window ); - else if (data->client_window) client_window_events_disable( data, data->client_window ); XDeleteContext( data->display, data->whole_window, winContext ); if (!already_destroyed) { @@ -1831,7 +1857,7 @@ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_des } } if (data->whole_colormap) XFreeColormap( data->display, data->whole_colormap ); - data->whole_window = data->client_window = 0; + data->whole_window = 0; data->whole_colormap = 0; data->wm_state = WithdrawnState; data->net_wm_state = 0;