In apply_window_pos, to notify any parent or children and let them make the necessary changes for offscreen rendering.
-- v3: win32u: Update client surfaces starting from toplevel window. winex11: Update window position in client surface update callback.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/init.c | 39 +++++++++++++++++++++++++++++++-------- dlls/winex11.drv/window.c | 28 ---------------------------- 2 files changed, 31 insertions(+), 36 deletions(-)
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 5ac239e68e5..5da09b3f101 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -261,6 +261,7 @@ static const struct client_surface_funcs x11drv_client_surface_funcs; struct x11drv_client_surface { struct client_surface client; + XWindowChanges changes; Colormap colormap; Window window; RECT rect; @@ -303,18 +304,40 @@ static void x11drv_client_surface_detach( struct client_surface *client ) } }
-static void client_surface_update_size( HWND hwnd, struct x11drv_client_surface *surface ) +static void client_surface_update_geometry( HWND hwnd, struct x11drv_client_surface *surface ) { - XWindowChanges changes; + HWND toplevel = NtUserGetAncestor( hwnd, GA_ROOT ); + XWindowChanges changes = surface->changes; + struct x11drv_win_data *data; + int mask = 0; RECT rect;
if (!NtUserGetClientRect( hwnd, &rect, NtUserGetDpiForWindow( hwnd ) )) return; - if (EqualRect( &surface->rect, &rect )) return; + NtUserMapWindowPoints( hwnd, toplevel, (POINT *)&rect, 2, NtUserGetDpiForWindow( hwnd ) ); + if ((data = get_win_data( toplevel ))) + { + OffsetRect( &rect, data->rects.client.left - data->rects.visible.left, + data->rects.client.top - data->rects.visible.top ); + release_win_data( data ); + }
- changes.width = min( max( 1, rect.right ), 65535 ); - changes.height = min( max( 1, rect.bottom ), 65535 ); - XConfigureWindow( gdi_display, surface->window, CWWidth | CWHeight, &changes ); + changes.x = rect.left; + changes.y = rect.top; + changes.width = min( max( 1, rect.right - rect.left ), 65535 ); + changes.height = min( max( 1, rect.bottom - rect.top ), 65535 ); + OffsetRect( &rect, -rect.left, -rect.top ); surface->rect = rect; + + if (changes.x != surface->changes.x) mask |= CWX; + if (changes.y != surface->changes.y) mask |= CWY; + if (changes.width != surface->changes.width) mask |= CWWidth; + if (changes.height != surface->changes.height) mask |= CWHeight; + if (!mask) return; + + surface->changes = changes; + TRACE( "client window %p/%lx, requesting position %d,%d size %d,%d mask %#x\n", hwnd, + surface->window, changes.x, changes.y, changes.width, changes.height, mask ); + XConfigureWindow( gdi_display, surface->window, mask, &changes ); }
static void client_surface_update_offscreen( HWND hwnd, struct x11drv_client_surface *surface ) @@ -377,7 +400,7 @@ static void x11drv_client_surface_update( struct client_surface *client )
TRACE( "%s\n", debugstr_client_surface( client ) );
- client_surface_update_size( hwnd, surface ); + client_surface_update_geometry( hwnd, surface ); client_surface_update_offscreen( hwnd, surface ); }
@@ -392,7 +415,7 @@ static void X11DRV_client_surface_present( struct client_surface *client, HDC hd
TRACE( "%s\n", debugstr_client_surface( client ) );
- client_surface_update_size( hwnd, surface ); + client_surface_update_geometry( hwnd, surface ); client_surface_update_offscreen( hwnd, surface );
if (!hdc) return; diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 650dcf12cfa..92a96fd70cc 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2146,32 +2146,6 @@ static void sync_window_position( struct x11drv_win_data *data, UINT swp_flags, }
-/*********************************************************************** - * sync_client_position - * - * Synchronize the X client window position with the Windows one - */ -static void sync_client_position( struct x11drv_win_data *data, const struct window_rects *old_rects ) -{ - int mask = 0; - XWindowChanges changes; - - if (!data->client_window) return; - - changes.x = data->rects.client.left - data->rects.visible.left; - changes.y = data->rects.client.top - data->rects.visible.top; - if (changes.x != old_rects->client.left - old_rects->visible.left) mask |= CWX; - if (changes.y != old_rects->client.top - old_rects->visible.top) mask |= CWY; - - if (mask) - { - TRACE( "setting client win %lx pos %d,%d changes=%x\n", - data->client_window, changes.x, changes.y, mask ); - XConfigureWindow( gdi_display, data->client_window, mask, &changes ); - } -} - - /*********************************************************************** * move_window_bits * @@ -3296,8 +3270,6 @@ void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, HWND owner_hint, UIN
XFlush( gdi_display ); /* make sure painting is done before we move the window */
- sync_client_position( data, &old_rects ); - if (!data->whole_window) { release_win_data( data );
From: Rémi Bernon rbernon@codeweavers.com
In apply_window_pos, to notify any parent or children and let them make the necessary changes for offscreen rendering. --- dlls/win32u/window.c | 41 +++++++++-------------------------------- 1 file changed, 9 insertions(+), 32 deletions(-)
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 9355873e343..8724175ac0c 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1615,24 +1615,6 @@ int get_window_pixel_format( HWND hwnd ) return ret; }
-static int window_has_client_surface( HWND hwnd ) -{ - struct client_surface *surface; - WND *win = get_win_ptr( hwnd ); - BOOL ret; - - if (!win || win == WND_DESKTOP || win == WND_OTHER_PROCESS) return FALSE; - ret = win->pixel_format || win->current_drawable; - release_win_ptr( win ); - if (ret) return TRUE; - - pthread_mutex_lock( &surfaces_lock ); - LIST_FOR_EACH_ENTRY( surface, &client_surfaces, struct client_surface, entry ) - if ((ret = surface->hwnd == hwnd)) break; - pthread_mutex_unlock( &surfaces_lock ); - return ret; -} - /*********************************************************************** * NtUserGetProp (win32u.@) * @@ -2149,20 +2131,16 @@ static struct window_surface *get_window_surface( HWND hwnd, UINT swp_flags, BOO return new_surface; }
-static void update_children_window_state( HWND hwnd ) +static void update_window_client_surfaces( HWND hwnd ) { HWND *children; int i;
if (!(children = list_window_children( hwnd ))) return; - - for (i = 0; children[i]; i++) - { - if (!window_has_client_surface( children[i] )) continue; - update_window_state( children[i] ); - } - + for (i = 0; children[i]; i++) update_window_client_surfaces( children[i] ); free( children ); + + update_client_surfaces( hwnd ); }
static HICON get_icon_info( HICON icon, ICONINFO *ii ) @@ -2199,7 +2177,7 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru { struct window_rects monitor_rects; WND *win; - HWND owner_hint, surface_win = 0, parent = NtUserGetAncestor( hwnd, GA_PARENT ); + HWND owner_hint, surface_win = 0, toplevel; UINT raw_dpi, monitor_dpi, dpi = get_thread_dpi(); BOOL ret, is_layered, is_child, need_icons = FALSE; struct window_rects old_rects; @@ -2208,10 +2186,11 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru HICON icon, icon_small; ICONINFO ii, ii_small;
+ toplevel = NtUserGetAncestor( hwnd, GA_ROOT ); is_layered = new_surface && new_surface->alpha_mask; - is_child = parent && parent != NtUserGetDesktopWindow(); + is_child = toplevel && toplevel != hwnd;
- if (is_child) monitor_dpi = get_win_monitor_dpi( parent, &raw_dpi ); + if (is_child) monitor_dpi = get_win_monitor_dpi( toplevel, &raw_dpi ); else monitor_dpi = monitor_dpi_from_rect( new_rects->window, dpi, &raw_dpi );
get_window_rects( hwnd, COORDS_PARENT, &old_rects, dpi ); @@ -2368,9 +2347,7 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru
user_driver->pWindowPosChanged( hwnd, insert_after, owner_hint, swp_flags, &monitor_rects, get_driver_window_surface( new_surface, raw_dpi ) ); - update_client_surfaces( hwnd ); - - update_children_window_state( hwnd ); + update_window_client_surfaces( toplevel ); }
return ret;