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 ) );