Properly compute the client area valid rects and pass them to the
server in set_window_pos to avoid invalidating areas that remain
valid.
diff --git a/server/protocol.def b/server/protocol.def
index 6873faa..3307e93 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1825,9 +1825,9 @@
user_handle_t top_win; /* top window to clip against */
user_handle_t previous; /* previous window in Z order */
unsigned int flags; /* SWP_* flags */
- unsigned int redraw_flags; /* WVR_* flags */
rectangle_t window; /* window rectangle */
rectangle_t client; /* client rectangle */
+ VARARG(valid,rectangles); /* valid rectangles from WM_NCCALCSIZE */
@REPLY
unsigned int new_style; /* new window style */
@END
diff --git a/server/trace.c b/server/trace.c
index d54294d..146d0f2 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2174,12 +2174,14 @@
fprintf( stderr, " top_win=%p,", req->top_win );
fprintf( stderr, " previous=%p,", req->previous );
fprintf( stderr, " flags=%08x,", req->flags );
- fprintf( stderr, " redraw_flags=%08x,", req->redraw_flags );
fprintf( stderr, " window=" );
dump_rectangle( &req->window );
fprintf( stderr, "," );
fprintf( stderr, " client=" );
dump_rectangle( &req->client );
+ fprintf( stderr, "," );
+ fprintf( stderr, " valid=" );
+ dump_varargs_rectangles( cur_size );
}
static void dump_set_window_pos_reply( const struct set_window_pos_reply *req )
diff --git a/server/window.c b/server/window.c
index c7af5e8..5e1509c 100644
--- a/server/window.c
+++ b/server/window.c
@@ -1075,8 +1075,8 @@
/* set the window and client rectangles, updating the update region if necessary */
static void set_window_pos( struct window *win, struct window *top, struct window *previous,
- unsigned int swp_flags, unsigned int wvr_flags,
- const rectangle_t *window_rect, const rectangle_t *client_rect )
+ unsigned int swp_flags, const rectangle_t *window_rect,
+ const rectangle_t *client_rect, const rectangle_t *valid_rects )
{
struct region *old_vis_rgn, *new_vis_rgn;
const rectangle_t old_window_rect = win->window_rect;
@@ -1114,9 +1114,13 @@
/* expose anything revealed by the change */
- offset_region( old_vis_rgn, old_window_rect.left - window_rect->left,
- old_window_rect.top - window_rect->top );
- if (xor_region( new_vis_rgn, old_vis_rgn, new_vis_rgn )) expose_window( win, top, new_vis_rgn );
+ if (!(swp_flags & SWP_NOREDRAW))
+ {
+ offset_region( old_vis_rgn, old_window_rect.left - window_rect->left,
+ old_window_rect.top - window_rect->top );
+ if (xor_region( new_vis_rgn, old_vis_rgn, new_vis_rgn ))
+ expose_window( win, top, new_vis_rgn );
+ }
free_region( old_vis_rgn );
if (!(win->style & WS_VISIBLE))
@@ -1126,32 +1130,36 @@
goto done;
}
+ if (swp_flags & SWP_NOREDRAW) goto done; /* do not repaint anything */
+
/* expose the whole non-client area if it changed in any way */
if ((swp_flags & SWP_FRAMECHANGED) ||
memcmp( window_rect, &old_window_rect, sizeof(old_window_rect) ) ||
memcmp( client_rect, &old_client_rect, sizeof(old_client_rect) ))
{
- struct region *tmp = create_region( client_rect, 1 );
+ struct region *tmp;
+
+ /* subtract the valid portion of client rect from the total region */
+ if (!memcmp( client_rect, &old_client_rect, sizeof(old_client_rect) ))
+ tmp = create_region( client_rect, 1 );
+ else if (valid_rects)
+ tmp = create_region( &valid_rects[0], 1 );
+ else
+ tmp = create_empty_region();
if (tmp)
{
set_region_rect( new_vis_rgn, window_rect );
if (subtract_region( tmp, new_vis_rgn, tmp ))
{
- offset_region( tmp, -window_rect->left, -window_rect->top );
- add_update_region( win, tmp );
+ offset_region( tmp, -client_rect->left, -client_rect->top );
+ redraw_window( win, tmp, 1, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN );
}
- else free_region( tmp );
+ free_region( tmp );
}
}
- /* expose/validate new client areas + children */
-
- /* FIXME: expose everything for now */
- if (memcmp( client_rect, &old_client_rect, sizeof(old_client_rect) ))
- redraw_window( win, 0, 0, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN );
-
done:
free_region( new_vis_rgn );
clear_error(); /* we ignore out of memory errors once the new rects have been set */
@@ -1434,6 +1442,7 @@
/* set the position and Z order of a window */
DECL_HANDLER(set_window_pos)
{
+ const rectangle_t *valid_rects = NULL;
struct window *previous = NULL;
struct window *top = top_window;
struct window *win = get_window( req->handle );
@@ -1476,7 +1485,9 @@
return;
}
- set_window_pos( win, top, previous, flags, req->redraw_flags, &req->window, &req->client );
+ if (get_req_data_size() >= 2 * sizeof(rectangle_t)) valid_rects = get_req_data();
+
+ set_window_pos( win, top, previous, flags, &req->window, &req->client, valid_rects );
reply->new_style = win->style;
}