Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57302
The blamed commit in the bug isn't the right one, but it indeed triggers a regression because the increased window surface rounding value prevents the surface from being recreated, and the move_window_bits code path is then used instead of move_window_bits_surface.
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57302 --- dlls/winex11.drv/window.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index ab17cb40a1c..da855b67f59 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1399,12 +1399,10 @@ static void sync_client_position( struct x11drv_win_data *data, const struct win * * Move the window bits when a window is moved. */ -static void move_window_bits( HWND hwnd, Window window, const RECT *old_rect, const RECT *new_rect, - const RECT *old_client_rect, const RECT *new_client_rect, - const RECT *new_window_rect ) +static void move_window_bits( HWND hwnd, Window window, const struct window_rects *old_rects, + const struct window_rects *new_rects, const RECT *valid_rects ) { - RECT src_rect = *old_rect; - RECT dst_rect = *new_rect; + RECT src_rect = valid_rects[1], dst_rect = valid_rects[0]; HDC hdc_src, hdc_dst; INT code; HRGN rgn; @@ -1412,16 +1410,16 @@ static void move_window_bits( HWND hwnd, Window window, const RECT *old_rect, co
if (!window) { - OffsetRect( &dst_rect, -new_window_rect->left, -new_window_rect->top ); + OffsetRect( &dst_rect, -new_rects->window.left, -new_rects->window.top ); parent = NtUserGetAncestor( hwnd, GA_PARENT ); hdc_src = NtUserGetDCEx( parent, 0, DCX_CACHE ); hdc_dst = NtUserGetDCEx( hwnd, 0, DCX_CACHE | DCX_WINDOW ); } else { - OffsetRect( &dst_rect, -new_client_rect->left, -new_client_rect->top ); + OffsetRect( &dst_rect, -new_rects->client.left, -new_rects->client.top ); /* make src rect relative to the old position of the window */ - OffsetRect( &src_rect, -old_client_rect->left, -old_client_rect->top ); + OffsetRect( &src_rect, -old_rects->client.left, -old_rects->client.top ); if (dst_rect.left == src_rect.left && dst_rect.top == src_rect.top) return; hdc_src = hdc_dst = NtUserGetDCEx( hwnd, 0, DCX_CACHE ); } @@ -1458,8 +1456,8 @@ static void move_window_bits( HWND hwnd, Window window, const RECT *old_rect, co if (!window) { /* map region to client rect since we are using DCX_WINDOW */ - NtGdiOffsetRgn( rgn, new_window_rect->left - new_client_rect->left, - new_window_rect->top - new_client_rect->top ); + NtGdiOffsetRgn( rgn, new_rects->window.left - new_rects->client.left, + new_rects->window.top - new_rects->client.top ); NtUserRedrawWindow( hwnd, NULL, rgn, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ALLCHILDREN ); } else NtUserRedrawWindow( hwnd, NULL, rgn, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN ); @@ -2530,13 +2528,11 @@ void X11DRV_MoveWindowBits( HWND hwnd, const struct window_rects *old_rects, { /* if we have an X window the bits will be moved by the X server */ if (!window && (valid_rects[0].left - valid_rects[1].left || valid_rects[0].top - valid_rects[1].top)) - move_window_bits( hwnd, 0, &old_rects->visible, &new_rects->visible, - &old_rects->client, &new_rects->client, &new_rects->window ); + move_window_bits( hwnd, 0, old_rects, new_rects, valid_rects ); } else { - move_window_bits( hwnd, window, &valid_rects[1], &valid_rects[0], - &old_rects->client, &new_rects->client, &new_rects->window ); + move_window_bits( hwnd, window, old_rects, new_rects, valid_rects ); } }
From: Rémi Bernon rbernon@codeweavers.com
Instead of the visible rects, which may change with decoration mask changes.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57302 --- dlls/win32u/window.c | 14 +++++++------- dlls/winex11.drv/window.c | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 9f0a412740b..64213996d41 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2107,9 +2107,10 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru } else if (valid_rects) { - RECT rects[2]; + RECT rects[2] = {valid_rects[0], valid_rects[1]}; int x_offset = old_rects.visible.left - new_rects->visible.left; int y_offset = old_rects.visible.top - new_rects->visible.top; + valid_rects = rects;
/* if all that happened is that the whole window moved, copy everything */ if (!(swp_flags & SWP_FRAMECHANGED) && @@ -2121,15 +2122,14 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru old_rects.client.bottom - new_rects->client.bottom == y_offset && EqualRect( &valid_rects[0], &new_rects->client )) { - rects[0] = new_rects->visible; - rects[1] = old_rects.visible; - valid_rects = rects; + rects[0] = new_rects->window; + rects[1] = old_rects.window; }
- if (surface_win && surface_win != hwnd) - move_window_bits( hwnd, &new_rects->visible, &new_rects->visible, &new_rects->window, valid_rects ); - else + if (!surface_win || surface_win == hwnd) user_driver->pMoveWindowBits( hwnd, &old_rects, new_rects, valid_rects ); + else + move_window_bits( hwnd, &new_rects->visible, &new_rects->visible, &new_rects->window, valid_rects ); }
user_driver->pWindowPosChanged( hwnd, insert_after, swp_flags, is_fullscreen, &monitor_rects, get_driver_window_surface( new_surface, monitor_dpi ) ); diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index da855b67f59..f9ef26b22d2 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2524,7 +2524,7 @@ void X11DRV_MoveWindowBits( HWND hwnd, const struct window_rects *old_rects, release_win_data( data );
/* if all that happened is that the whole window moved, copy everything */ - if (EqualRect( &valid_rects[0], &new_rects->visible ) && EqualRect( &valid_rects[1], &old_rects->visible )) + if (EqualRect( &valid_rects[0], &new_rects->window ) && EqualRect( &valid_rects[1], &old_rects->window )) { /* if we have an X window the bits will be moved by the X server */ if (!window && (valid_rects[0].left - valid_rects[1].left || valid_rects[0].top - valid_rects[1].top))
From: Rémi Bernon rbernon@codeweavers.com
When moving bits within the same surface when decoration masks are modified we need to compensate the visible rect changes to move the visible bits from their old position in the surface to the new position.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57302 --- dlls/win32u/dce.c | 14 ++++++-------- dlls/win32u/win32u_private.h | 3 +-- dlls/win32u/window.c | 13 +++++++++++-- 3 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index edeef880e43..3fa18fc8ace 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -1612,22 +1612,20 @@ static BOOL send_erase( HWND hwnd, UINT flags, HRGN client_rgn, * * Move the window bits when a window is resized, or moved within a parent window. */ -void move_window_bits( HWND hwnd, const RECT *visible_rect, const RECT *old_visible_rect, - const RECT *window_rect, const RECT *valid_rects ) +void move_window_bits( HWND hwnd, const struct window_rects *rects, const RECT *valid_rects ) { - RECT dst = valid_rects[0]; - RECT src = valid_rects[1]; + RECT dst = valid_rects[0], src = valid_rects[1];
- if (src.left - old_visible_rect->left != dst.left - visible_rect->left || - src.top - old_visible_rect->top != dst.top - visible_rect->top) + if (src.left - rects->visible.left != dst.left - rects->visible.left || + src.top - rects->visible.top != dst.top - rects->visible.top) { UINT flags = UPDATE_NOCHILDREN | UPDATE_CLIPCHILDREN; HRGN rgn = get_update_region( hwnd, &flags, NULL ); HDC hdc = NtUserGetDCEx( hwnd, rgn, DCX_CACHE | DCX_WINDOW | DCX_EXCLUDERGN );
TRACE( "copying %s -> %s\n", wine_dbgstr_rect( &src ), wine_dbgstr_rect( &dst )); - OffsetRect( &src, -window_rect->left, -window_rect->top ); - OffsetRect( &dst, -window_rect->left, -window_rect->top ); + OffsetRect( &src, -rects->window.left, -rects->window.top ); + OffsetRect( &dst, -rects->window.left, -rects->window.top );
NtGdiStretchBlt( hdc, dst.left, dst.top, dst.right - dst.left, dst.bottom - dst.top, hdc, src.left, src.top, src.right - src.left, src.bottom - src.top, SRCCOPY, 0 ); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index f79052562f1..8956f83af75 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -50,8 +50,7 @@ extern void create_window_surface( HWND hwnd, BOOL create_layered, const RECT *s extern struct window_surface *get_driver_window_surface( struct window_surface *surface, UINT monitor_dpi ); extern void erase_now( HWND hwnd, UINT rdw_flags ); extern void flush_window_surfaces( BOOL idle ); -extern void move_window_bits( HWND hwnd, const RECT *visible_rect, const RECT *old_visible_rect, - const RECT *window_rect, const RECT *valid_rects ); +extern void move_window_bits( HWND hwnd, const struct window_rects *rects, const RECT *valid_rects ); extern void move_window_bits_surface( HWND hwnd, const RECT *window_rect, struct window_surface *old_surface, const RECT *old_visible_rect, const RECT *valid_rects ); extern void register_window_surface( struct window_surface *old, diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 64213996d41..f67ddc2903c 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2098,10 +2098,16 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru { if (valid_rects) { + RECT rects[2] = {valid_rects[0], valid_rects[1]}; + valid_rects = rects; + if (old_surface != new_surface) move_window_bits_surface( hwnd, &new_rects->window, old_surface, &old_rects.visible, valid_rects ); else - move_window_bits( hwnd, &new_rects->visible, &old_rects.visible, &new_rects->window, valid_rects ); + { + OffsetRect( &rects[1], new_rects->visible.left - old_rects.visible.left, new_rects->visible.top - old_rects.visible.top ); + move_window_bits( hwnd, new_rects, valid_rects ); + } } window_surface_release( old_surface ); } @@ -2129,7 +2135,10 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru if (!surface_win || surface_win == hwnd) user_driver->pMoveWindowBits( hwnd, &old_rects, new_rects, valid_rects ); else - move_window_bits( hwnd, &new_rects->visible, &new_rects->visible, &new_rects->window, valid_rects ); + { + OffsetRect( &rects[1], new_rects->visible.left - old_rects.visible.left, new_rects->visible.top - old_rects.visible.top ); + move_window_bits( hwnd, new_rects, valid_rects ); + } }
user_driver->pWindowPosChanged( hwnd, insert_after, swp_flags, is_fullscreen, &monitor_rects, get_driver_window_surface( new_surface, monitor_dpi ) );