Module: wine Branch: master Commit: 5b9c69b93ffa9dc9e4d71660cf076c43d4e05c60 URL: http://source.winehq.org/git/wine.git/?a=commit;h=5b9c69b93ffa9dc9e4d71660cf...
Author: Alexandre Julliard julliard@winehq.org Date: Thu Jul 13 11:04:52 2017 +0200
user32: Copy the bits of child windows when the parent has a surface.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/user32/painting.c | 35 +++++++++++++++++++++++++++++++++++ dlls/user32/user_private.h | 2 ++ dlls/user32/winpos.c | 35 +++++++++++++++++++++++++++++++---- 3 files changed, 68 insertions(+), 4 deletions(-)
diff --git a/dlls/user32/painting.c b/dlls/user32/painting.c index 1bfb86d..3c7f220 100644 --- a/dlls/user32/painting.c +++ b/dlls/user32/painting.c @@ -811,6 +811,41 @@ void move_window_bits( HWND hwnd, struct window_surface *old_surface,
/*********************************************************************** + * move_window_bits_parent + * + * 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 ) +{ + 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 = WIN_GetPtr( parent ))) return; + if (win == WND_DESKTOP || win == WND_OTHER_PROCESS) return; + if (!(surface = win->surface)) + { + WIN_ReleasePtr( win ); + return; + } + + TRACE( "copying %s -> %s\n", wine_dbgstr_rect( &src ), wine_dbgstr_rect( &dst )); + MapWindowPoints( GetAncestor( hwnd, GA_PARENT ), parent, (POINT *)&src, 2 ); + OffsetRect( &src, win->rectClient.left - win->visible_rect.left, + win->rectClient.top - win->visible_rect.top ); + OffsetRect( &dst, -window_rect->left, -window_rect->top ); + window_surface_add_ref( surface ); + WIN_ReleasePtr( win ); + + copy_bits_from_surface( hwnd, surface, &dst, &src ); + window_surface_release( surface ); +} + + +/*********************************************************************** * update_now * * Implementation of RDW_UPDATENOW behavior. diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index a697fd9..052fdd8 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -232,6 +232,8 @@ 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, const RECT *window_rect, const RECT *valid_rects ) DECLSPEC_HIDDEN; +extern void move_window_bits_parent( HWND hwnd, HWND parent, const RECT *window_rect, + const RECT *valid_rects ) DECLSPEC_HIDDEN; extern void *get_hook_proc( void *proc, const WCHAR *module, HMODULE *free_module ) DECLSPEC_HIDDEN; extern RECT get_virtual_screen_rect(void) DECLSPEC_HIDDEN; extern LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN; diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c index a37ab7c..a89c60d 100644 --- a/dlls/user32/winpos.c +++ b/dlls/user32/winpos.c @@ -2060,8 +2060,7 @@ BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, WND *win; HWND surface_win = 0, parent = GetAncestor( hwnd, GA_PARENT ); BOOL ret, needs_update = FALSE; - int old_width; - RECT visible_rect, old_visible_rect, old_window_rect; + RECT visible_rect, old_visible_rect, old_window_rect, old_client_rect; struct window_surface *old_surface, *new_surface = NULL;
if (!parent || parent == GetDesktopWindow()) @@ -2080,8 +2079,8 @@ BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, if (new_surface) window_surface_release( new_surface ); return FALSE; } - old_width = win->rectClient.right - win->rectClient.left; old_visible_rect = win->visible_rect; + old_client_rect = win->rectClient; old_surface = win->surface; if (old_surface != new_surface) swp_flags |= SWP_FRAMECHANGED; /* force refreshing non-client area */
@@ -2126,7 +2125,8 @@ BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, mirror_rect( &client, &win->visible_rect ); } /* if an RTL window is resized the children have moved */ - if (win->dwExStyle & WS_EX_LAYOUTRTL && client_rect->right - client_rect->left != old_width) + if (win->dwExStyle & WS_EX_LAYOUTRTL && + client_rect->right - client_rect->left != old_client_rect.right - old_client_rect.left) win->flags |= WIN_CHILDREN_MOVED; } } @@ -2156,6 +2156,33 @@ BOOL set_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, } window_surface_release( old_surface ); } + else if (surface_win && surface_win != hwnd) + { + if (!IsRectEmpty( valid_rects )) + { + RECT rects[2]; + int x_offset = old_visible_rect.left - visible_rect.left; + int y_offset = old_visible_rect.top - visible_rect.top; + + /* if all that happened is that the whole window moved, copy everything */ + if (!(swp_flags & SWP_FRAMECHANGED) && + old_visible_rect.right - visible_rect.right == x_offset && + old_visible_rect.bottom - visible_rect.bottom == y_offset && + old_client_rect.left - client_rect->left == x_offset && + old_client_rect.right - client_rect->right == x_offset && + old_client_rect.top - client_rect->top == y_offset && + old_client_rect.bottom - client_rect->bottom == y_offset && + EqualRect( &valid_rects[0], client_rect )) + { + rects[0] = visible_rect; + rects[1] = old_visible_rect; + valid_rects = rects; + } + move_window_bits_parent( hwnd, surface_win, window_rect, valid_rects ); + valid_rects = NULL; /* prevent the driver from trying to also move the bits */ + } + } + USER_Driver->pWindowPosChanged( hwnd, insert_after, swp_flags, window_rect, client_rect, &visible_rect, valid_rects, new_surface ); }