server: Also crop the update region of children when moving a window.
This commit is contained in:
parent
e02969ddf0
commit
bc25119c6e
@ -5811,6 +5811,19 @@ static void test_paint_messages(void)
|
|||||||
SetRectRgn( hrgn, 10, 10, 40, 40 );
|
SetRectRgn( hrgn, 10, 10, 40, 40 );
|
||||||
check_update_rgn( hchild, hrgn );
|
check_update_rgn( hchild, hrgn );
|
||||||
|
|
||||||
|
/* moving parent off-screen does too */
|
||||||
|
SetRect( &rect, 0, 0, 100, 100 );
|
||||||
|
RedrawWindow( hparent, &rect, 0, RDW_INVALIDATE | RDW_ERASE | RDW_NOCHILDREN );
|
||||||
|
SetRectRgn( hrgn, 0, 0, 100, 100 );
|
||||||
|
check_update_rgn( hparent, hrgn );
|
||||||
|
SetRectRgn( hrgn, 10, 10, 40, 40 );
|
||||||
|
check_update_rgn( hchild, hrgn );
|
||||||
|
MoveWindow( hparent, -20, -20, 200, 200, FALSE );
|
||||||
|
SetRectRgn( hrgn, 20, 20, 100, 100 );
|
||||||
|
check_update_rgn( hparent, hrgn );
|
||||||
|
SetRectRgn( hrgn, 30, 30, 40, 40 );
|
||||||
|
check_update_rgn( hchild, hrgn );
|
||||||
|
|
||||||
DestroyWindow( hparent );
|
DestroyWindow( hparent );
|
||||||
ok(!IsWindow(hchild), "child must be destroyed with its parent\n");
|
ok(!IsWindow(hchild), "child must be destroyed with its parent\n");
|
||||||
flush_sequence();
|
flush_sequence();
|
||||||
|
@ -1097,6 +1097,45 @@ static int add_update_region( struct window *win, struct region *region )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* crop the update region of children to the specified rectangle, in client coords */
|
||||||
|
static void crop_children_update_region( struct window *win, rectangle_t *rect )
|
||||||
|
{
|
||||||
|
struct window *child;
|
||||||
|
struct region *tmp = create_empty_region();
|
||||||
|
rectangle_t child_rect;
|
||||||
|
|
||||||
|
LIST_FOR_EACH_ENTRY( child, &win->children, struct window, entry )
|
||||||
|
{
|
||||||
|
if (!(child->style & WS_VISIBLE)) continue;
|
||||||
|
if (!rect) /* crop everything out */
|
||||||
|
{
|
||||||
|
crop_children_update_region( child, NULL );
|
||||||
|
set_update_region( child, NULL );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* nothing to do if child is completely inside rect */
|
||||||
|
if (child->window_rect.left >= rect->left &&
|
||||||
|
child->window_rect.top >= rect->top &&
|
||||||
|
child->window_rect.right <= rect->right &&
|
||||||
|
child->window_rect.bottom <= rect->bottom) continue;
|
||||||
|
|
||||||
|
/* map to child client coords and crop grand-children */
|
||||||
|
child_rect = *rect;
|
||||||
|
offset_rect( &child_rect, -child->client_rect.left, -child->client_rect.top );
|
||||||
|
crop_children_update_region( child, &child_rect );
|
||||||
|
|
||||||
|
/* now crop the child itself */
|
||||||
|
if (!child->update_region) continue;
|
||||||
|
if (!(tmp = create_empty_region())) continue;
|
||||||
|
set_region_rect( tmp, rect );
|
||||||
|
offset_region( tmp, -child->window_rect.left, -child->window_rect.top );
|
||||||
|
if (intersect_region( tmp, child->update_region, tmp )) set_update_region( child, tmp );
|
||||||
|
else free_region( tmp );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* validate the non client area of a window */
|
/* validate the non client area of a window */
|
||||||
static void validate_non_client( struct window *win )
|
static void validate_non_client( struct window *win )
|
||||||
{
|
{
|
||||||
@ -1521,6 +1560,17 @@ static void set_window_pos( struct window *win, struct window *previous,
|
|||||||
else set_update_region( win, NULL ); /* visible rect is empty */
|
else set_update_region( win, NULL ); /* visible rect is empty */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* crop children regions to the new window rect */
|
||||||
|
|
||||||
|
if (get_window_visible_rect( win, &rect, 0 ))
|
||||||
|
{
|
||||||
|
/* map to client coords */
|
||||||
|
offset_rect( &rect, win->window_rect.left - win->client_rect.left,
|
||||||
|
win->window_rect.top - win->client_rect.top );
|
||||||
|
crop_children_update_region( win, &rect );
|
||||||
|
}
|
||||||
|
else crop_children_update_region( win, NULL );
|
||||||
|
|
||||||
if (swp_flags & SWP_NOREDRAW) goto done; /* do not repaint anything */
|
if (swp_flags & SWP_NOREDRAW) goto done; /* do not repaint anything */
|
||||||
|
|
||||||
/* expose the whole non-client area if it changed in any way */
|
/* expose the whole non-client area if it changed in any way */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user