Fixes a regression from 5d0efbcc6e88e2b7886f2a0cfb58c9100b452160, and 0d2fa879d735cd39e72c15014686001c13a089b8 (https://bugs.winehq.org/show_bug.cgi?id=56766).
-- v2: win32u: Get rid of move_window_bits_parent, using move_window_bits. win32u: Don't map points to the parent window in move_window_bits_parent. win32u: Use a dedicated helper to move bits from a previous surface. win32u: Restore surface rect, which may offsetted from the window rect.
From: Rémi Bernon rbernon@codeweavers.com
Some drivers only create surfaces over the visible part of the window, and the surface rect has an offset.
Fixes a regression from 5d0efbcc6e88e2b7886f2a0cfb58c9100b452160, which causes XSHM errors with partially offscreen windows. --- dlls/win32u/dce.c | 7 ++++--- dlls/wineandroid.drv/window.c | 2 +- dlls/winemac.drv/surface.c | 2 +- dlls/winewayland.drv/window_surface.c | 2 +- dlls/winex11.drv/bitblt.c | 2 +- include/wine/gdi_driver.h | 2 +- 6 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index f6726b49aa1..34acb1d10f6 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -188,7 +188,7 @@ void create_offscreen_window_surface( HWND hwnd, const RECT *visible_rect, struc /* create a new window surface */ *surface = NULL; if (!(impl = calloc(1, sizeof(*impl)))) return; - window_surface_init( &impl->header, &offscreen_window_surface_funcs, hwnd, info, 0 ); + window_surface_init( &impl->header, &offscreen_window_surface_funcs, hwnd, &surface_rect, info, 0 ); impl->info = *info;
TRACE( "created window surface %p\n", &impl->header ); @@ -199,7 +199,7 @@ void create_offscreen_window_surface( HWND hwnd, const RECT *visible_rect, struc /* window surface common helpers */
W32KAPI BOOL window_surface_init( struct window_surface *surface, const struct window_surface_funcs *funcs, - HWND hwnd, BITMAPINFO *info, HBITMAP bitmap ) + HWND hwnd, const RECT *rect, BITMAPINFO *info, HBITMAP bitmap ) { struct bitblt_coords coords = {0}; struct gdi_image_bits bits; @@ -208,7 +208,7 @@ W32KAPI BOOL window_surface_init( struct window_surface *surface, const struct w surface->funcs = funcs; surface->ref = 1; surface->hwnd = hwnd; - SetRect( &surface->rect, 0, 0, info->bmiHeader.biWidth, abs( info->bmiHeader.biHeight ) ); + surface->rect = *rect; pthread_mutex_init( &surface->mutex, NULL ); reset_bounds( &surface->bounds );
@@ -256,6 +256,7 @@ W32KAPI void window_surface_flush( struct window_surface *surface )
window_surface_lock( surface );
+ OffsetRect( &dirty, -dirty.left, -dirty.top ); if (intersect_rect( &dirty, &dirty, &surface->bounds )) { TRACE( "Flushing hwnd %p, surface %p %s, bounds %s, dirty %s\n", surface->hwnd, surface, diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index fa7b87522c5..7b7d680fe2e 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -792,7 +792,7 @@ static struct window_surface *create_surface( HWND hwnd, const RECT *rect,
surface = calloc( 1, FIELD_OFFSET( struct android_window_surface, info.bmiColors[3] )); if (!surface) return NULL; - if (!window_surface_init( &surface->header, &android_surface_funcs, hwnd, info, 0 )) goto failed; + if (!window_surface_init( &surface->header, &android_surface_funcs, hwnd, rect, info, 0 )) goto failed; memcpy( &surface->info, info, get_dib_info_size( info, DIB_RGB_COLORS ) );
surface->window = get_ioctl_window( hwnd ); diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index 82b7a382ec4..37e2c466926 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -147,7 +147,7 @@ struct window_surface *create_surface(HWND hwnd, macdrv_window window, const REC
surface = calloc(1, FIELD_OFFSET(struct macdrv_window_surface, info.bmiColors[3])); if (!surface) return NULL; - if (!window_surface_init(&surface->header, &macdrv_surface_funcs, hwnd, info, 0)) goto failed; + if (!window_surface_init(&surface->header, &macdrv_surface_funcs, hwnd, rect, info, 0)) goto failed; memcpy(&surface->info, info, offsetof(BITMAPINFO, bmiColors[3]));
surface->window = window; diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index c0b516c9288..fb3b8750001 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -470,7 +470,7 @@ struct window_surface *wayland_window_surface_create(HWND hwnd, const RECT *rect
wws = calloc(1, sizeof(*wws)); if (!wws) return NULL; - if (!window_surface_init(&wws->header, &wayland_window_surface_funcs, hwnd, info, 0)) goto failed; + if (!window_surface_init(&wws->header, &wayland_window_surface_funcs, hwnd, rect, info, 0)) goto failed; wws->info = *info;
TRACE("created %p hwnd %p %s bits [%p,%p)\n", wws, hwnd, wine_dbgstr_rect(rect), diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index ec6250048cf..8a001606420 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -2098,7 +2098,7 @@ struct window_surface *create_surface( HWND hwnd, Window window, const XVisualIn surface->image = image; surface->byteswap = byteswap;
- if (!window_surface_init( &surface->header, &x11drv_surface_funcs, hwnd, info, bitmap )) goto failed; + if (!window_surface_init( &surface->header, &x11drv_surface_funcs, hwnd, rect, info, bitmap )) goto failed; memcpy( &surface->info, info, get_dib_info_size( info, DIB_RGB_COLORS ) );
surface->window = window; diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index ce954a7f4d8..701e3031dc3 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -235,7 +235,7 @@ struct window_surface };
W32KAPI BOOL window_surface_init( struct window_surface *surface, const struct window_surface_funcs *funcs, - HWND hwnd, BITMAPINFO *info, HBITMAP bitmap ); + HWND hwnd, const RECT *rect, BITMAPINFO *info, HBITMAP bitmap ); W32KAPI void window_surface_add_ref( struct window_surface *surface ); W32KAPI void window_surface_release( struct window_surface *surface ); W32KAPI void window_surface_lock( struct window_surface *surface );
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56766 --- dlls/win32u/dce.c | 98 ++++++++++++++++++------------------ dlls/win32u/win32u_private.h | 6 +-- dlls/win32u/window.c | 6 ++- 3 files changed, 55 insertions(+), 55 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 34acb1d10f6..04c0fdfa248 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -1194,62 +1194,72 @@ static BOOL send_erase( HWND hwnd, UINT flags, HRGN client_rgn, * * Copy bits from a window surface; helper for move_window_bits and move_window_bits_parent. */ -static void copy_bits_from_surface( HWND hwnd, struct window_surface *surface, - const RECT *dst, const RECT *src, BOOL same ) +static void copy_bits_from_surface( HWND hwnd, const RECT *dst, const RECT *src ) { - char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; - BITMAPINFO *info = (BITMAPINFO *)buffer; - void *bits; 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 );
- if (same) - { - RECT rect = *src; - NtGdiStretchBlt( hdc, dst->left, dst->top, dst->right - dst->left, dst->bottom - dst->top, - hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SRCCOPY, 0 ); - } - else - { - bits = surface->funcs->get_info( surface, info ); - window_surface_lock( surface ); - NtGdiSetDIBitsToDeviceInternal( hdc, dst->left, dst->top, dst->right - dst->left, dst->bottom - dst->top, - src->left - surface->rect.left, surface->rect.bottom - src->bottom, - 0, surface->rect.bottom - surface->rect.top, - bits, info, DIB_RGB_COLORS, 0, 0, FALSE, NULL ); - window_surface_unlock( surface ); - } - + 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 ); NtUserReleaseDC( hwnd, hdc ); }
/*********************************************************************** * move_window_bits * - * Move the window bits when a window is resized or its surface recreated. + * Move the window bits when a window is resized. */ -void move_window_bits( HWND hwnd, struct window_surface *old_surface, - struct window_surface *new_surface, - const RECT *visible_rect, const RECT *old_visible_rect, +void move_window_bits( HWND hwnd, const RECT *visible_rect, const RECT *old_visible_rect, const RECT *window_rect, const RECT *valid_rects ) { RECT dst = valid_rects[0]; RECT src = valid_rects[1];
- if (new_surface != old_surface || - src.left - old_visible_rect->left != dst.left - visible_rect->left || + if (src.left - old_visible_rect->left != dst.left - visible_rect->left || src.top - old_visible_rect->top != dst.top - visible_rect->top) { TRACE( "copying %s -> %s\n", wine_dbgstr_rect( &src ), wine_dbgstr_rect( &dst )); - if (new_surface != old_surface) OffsetRect( &src, -old_visible_rect->left, -old_visible_rect->top ); - else OffsetRect( &src, -window_rect->left, -window_rect->top ); + OffsetRect( &src, -window_rect->left, -window_rect->top ); OffsetRect( &dst, -window_rect->left, -window_rect->top ); - copy_bits_from_surface( hwnd, old_surface, &dst, &src, new_surface == old_surface ); + copy_bits_from_surface( hwnd, &dst, &src ); } }
+/*********************************************************************** + * move_window_bits_surface + * + * Move the window bits from a previous window surface when its surface is recreated. + */ +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 ) +{ + char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; + BITMAPINFO *info = (BITMAPINFO *)buffer; + 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 ); + void *bits; + + RECT dst = valid_rects[0]; + RECT src = valid_rects[1]; + + TRACE( "copying %s -> %s\n", wine_dbgstr_rect( &src ), wine_dbgstr_rect( &dst )); + OffsetRect( &src, -old_visible_rect->left, -old_visible_rect->top ); + OffsetRect( &dst, -window_rect->left, -window_rect->top ); + + bits = old_surface->funcs->get_info( old_surface, info ); + window_surface_lock( old_surface ); + NtGdiSetDIBitsToDeviceInternal( hdc, dst.left, dst.top, dst.right - dst.left, dst.bottom - dst.top, + src.left - old_surface->rect.left, old_surface->rect.bottom - src.bottom, + 0, old_surface->rect.bottom - old_surface->rect.top, + bits, info, DIB_RGB_COLORS, 0, 0, FALSE, NULL ); + window_surface_unlock( old_surface ); + NtUserReleaseDC( hwnd, hdc ); +} + + /*********************************************************************** * move_window_bits_parent * @@ -1257,30 +1267,18 @@ void move_window_bits( HWND hwnd, struct window_surface *old_surface, */ void move_window_bits_parent( HWND hwnd, HWND parent, const RECT *window_rect, const RECT *valid_rects ) { - struct window_surface *surface; RECT dst = valid_rects[0]; RECT src = valid_rects[1]; - WND *win; - - if (src.left == dst.left && src.top == dst.top) return;
- if (!(win = get_win_ptr( parent ))) return; - if (win == WND_DESKTOP || win == WND_OTHER_PROCESS) return; - if (!(surface = win->surface)) + if (src.left != dst.left || src.top != dst.top) { - release_win_ptr( win ); - return; - } - - TRACE( "copying %s -> %s\n", wine_dbgstr_rect( &src ), wine_dbgstr_rect( &dst )); - map_window_points( NtUserGetAncestor( hwnd, GA_PARENT ), parent, (POINT *)&src, 2, get_thread_dpi() ); - OffsetRect( &src, -window_rect->left, -window_rect->top ); - OffsetRect( &dst, -window_rect->left, -window_rect->top ); - window_surface_add_ref( surface ); - release_win_ptr( win ); + TRACE( "copying %s -> %s\n", wine_dbgstr_rect( &src ), wine_dbgstr_rect( &dst )); + map_window_points( NtUserGetAncestor( hwnd, GA_PARENT ), parent, (POINT *)&src, 2, get_thread_dpi() ); + OffsetRect( &src, -window_rect->left, -window_rect->top ); + OffsetRect( &dst, -window_rect->left, -window_rect->top );
- copy_bits_from_surface( hwnd, surface, &dst, &src, TRUE ); - window_surface_release( surface ); + copy_bits_from_surface( hwnd, &dst, &src ); + } }
/*********************************************************************** diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 8aed662d2d8..54b3798d8fb 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -49,10 +49,10 @@ extern void create_offscreen_window_surface( HWND hwnd, const RECT *visible_rect struct window_surface **surface ); extern void erase_now( HWND hwnd, UINT rdw_flags ); extern void flush_window_surfaces( BOOL idle ); -extern void move_window_bits( HWND hwnd, struct window_surface *old_surface, - struct window_surface *new_surface, - const RECT *visible_rect, const RECT *old_visible_rect, +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_surface( HWND hwnd, const RECT *window_rect, struct window_surface *old_surface, + const RECT *old_visible_rect, const RECT *valid_rects ); extern void move_window_bits_parent( HWND hwnd, HWND parent, const RECT *window_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 12f2a9027f0..22e9e326d6e 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1929,8 +1929,10 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, { if (valid_rects) { - move_window_bits( hwnd, old_surface, new_surface, &visible_rect, - &old_visible_rect, window_rect, valid_rects ); + if (old_surface != new_surface) + move_window_bits_surface( hwnd, window_rect, old_surface, &old_visible_rect, valid_rects ); + else + move_window_bits( hwnd, &visible_rect, &old_visible_rect, window_rect, valid_rects ); valid_rects = NULL; /* prevent the driver from trying to also move the bits */ } window_surface_release( old_surface );
From: Rémi Bernon rbernon@codeweavers.com
We now use NtGdiStretchBlt, and the valid rects are relative to the window rect, not the parent.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56766 --- dlls/win32u/dce.c | 3 +-- dlls/win32u/win32u_private.h | 2 +- dlls/win32u/window.c | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 04c0fdfa248..47c624cacc6 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -1265,7 +1265,7 @@ void move_window_bits_surface( HWND hwnd, const RECT *window_rect, struct window * * Move the window bits in the parent surface when a child is moved. */ -void move_window_bits_parent( HWND hwnd, HWND parent, const RECT *window_rect, const RECT *valid_rects ) +void move_window_bits_parent( HWND hwnd, const RECT *window_rect, const RECT *valid_rects ) { RECT dst = valid_rects[0]; RECT src = valid_rects[1]; @@ -1273,7 +1273,6 @@ void move_window_bits_parent( HWND hwnd, HWND parent, const RECT *window_rect, c if (src.left != dst.left || src.top != dst.top) { TRACE( "copying %s -> %s\n", wine_dbgstr_rect( &src ), wine_dbgstr_rect( &dst )); - map_window_points( NtUserGetAncestor( hwnd, GA_PARENT ), parent, (POINT *)&src, 2, get_thread_dpi() ); OffsetRect( &src, -window_rect->left, -window_rect->top ); OffsetRect( &dst, -window_rect->left, -window_rect->top );
diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 54b3798d8fb..9ec941ca7d4 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -53,7 +53,7 @@ extern void move_window_bits( HWND hwnd, const RECT *visible_rect, const RECT *o const RECT *window_rect, 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 move_window_bits_parent( HWND hwnd, HWND parent, const RECT *window_rect, +extern void move_window_bits_parent( HWND hwnd, const RECT *window_rect, const RECT *valid_rects ); extern void register_window_surface( struct window_surface *old, struct window_surface *new ); diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 22e9e326d6e..b868053796d 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1959,7 +1959,7 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, rects[1] = old_visible_rect; valid_rects = rects; } - move_window_bits_parent( hwnd, surface_win, window_rect, valid_rects ); + move_window_bits_parent( hwnd, window_rect, valid_rects ); valid_rects = NULL; /* prevent the driver from trying to also move the bits */ } }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/dce.c | 47 +++++++----------------------------- dlls/win32u/win32u_private.h | 2 -- dlls/win32u/window.c | 2 +- 3 files changed, 10 insertions(+), 41 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 47c624cacc6..57a3ae59eff 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -1189,26 +1189,10 @@ static BOOL send_erase( HWND hwnd, UINT flags, HRGN client_rgn, return need_erase; }
-/*********************************************************************** - * copy_bits_from_surface - * - * Copy bits from a window surface; helper for move_window_bits and move_window_bits_parent. - */ -static void copy_bits_from_surface( HWND hwnd, const RECT *dst, const RECT *src ) -{ - 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 ); - - 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 ); - NtUserReleaseDC( hwnd, hdc ); -} - /*********************************************************************** * move_window_bits * - * Move the window bits when a window is resized. + * 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 ) @@ -1219,10 +1203,17 @@ void move_window_bits( HWND hwnd, const RECT *visible_rect, const RECT *old_visi if (src.left - old_visible_rect->left != dst.left - visible_rect->left || src.top - old_visible_rect->top != dst.top - visible_rect->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 ); - copy_bits_from_surface( hwnd, &dst, &src ); + + 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 ); + NtUserReleaseDC( hwnd, hdc ); } }
@@ -1260,26 +1251,6 @@ void move_window_bits_surface( HWND hwnd, const RECT *window_rect, struct window }
-/*********************************************************************** - * move_window_bits_parent - * - * Move the window bits in the parent surface when a child is moved. - */ -void move_window_bits_parent( HWND hwnd, const RECT *window_rect, const RECT *valid_rects ) -{ - RECT dst = valid_rects[0]; - RECT src = valid_rects[1]; - - if (src.left != dst.left || src.top != dst.top) - { - 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 ); - - copy_bits_from_surface( hwnd, &dst, &src ); - } -} - /*********************************************************************** * NtUserBeginPaint (win32u.@) */ diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 9ec941ca7d4..6539fb0bff1 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -53,8 +53,6 @@ extern void move_window_bits( HWND hwnd, const RECT *visible_rect, const RECT *o const RECT *window_rect, 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 move_window_bits_parent( HWND hwnd, const RECT *window_rect, - const RECT *valid_rects ); extern void register_window_surface( struct window_surface *old, struct window_surface *new );
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index b868053796d..0122ac2e4f7 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1959,7 +1959,7 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, rects[1] = old_visible_rect; valid_rects = rects; } - move_window_bits_parent( hwnd, window_rect, valid_rects ); + move_window_bits( hwnd, &visible_rect, &visible_rect, window_rect, valid_rects ); valid_rects = NULL; /* prevent the driver from trying to also move the bits */ } }
v2: Use `visible_rect` for the visible rect parameters when moving bits from the parent window. It makes no different in that case wrt the logic, as both rects are identical, but it's probably more appropriate.