Alexandre Julliard : user32: Copy the bits of child windows when the parent has a surface.
Alexandre Julliard
julliard at winehq.org
Thu Jul 13 14:41:33 CDT 2017
Module: wine
Branch: master
Commit: 5b9c69b93ffa9dc9e4d71660cf076c43d4e05c60
URL: http://source.winehq.org/git/wine.git/?a=commit;h=5b9c69b93ffa9dc9e4d71660cf076c43d4e05c60
Author: Alexandre Julliard <julliard at 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 at 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 );
}
More information about the wine-cvs
mailing list