server: Store a separate flag for windows that need to be erased in WM_PAINT.
This avoids the need to invalidate the window after WM_ERASEBKGND.
This commit is contained in:
parent
5bd497f3ca
commit
df13cee288
|
@ -243,7 +243,7 @@ static HRGN send_ncpaint( HWND hwnd, HWND *child, UINT *flags )
|
||||||
static BOOL send_erase( HWND hwnd, UINT flags, HRGN client_rgn,
|
static BOOL send_erase( HWND hwnd, UINT flags, HRGN client_rgn,
|
||||||
RECT *clip_rect, HDC *hdc_ret )
|
RECT *clip_rect, HDC *hdc_ret )
|
||||||
{
|
{
|
||||||
BOOL need_erase = FALSE;
|
BOOL need_erase = (flags & UPDATE_DELAYED_ERASE) != 0;
|
||||||
HDC hdc = 0;
|
HDC hdc = 0;
|
||||||
RECT dummy;
|
RECT dummy;
|
||||||
|
|
||||||
|
@ -263,12 +263,7 @@ static BOOL send_erase( HWND hwnd, UINT flags, HRGN client_rgn,
|
||||||
if (type != NULLREGION)
|
if (type != NULLREGION)
|
||||||
need_erase = !SendMessageW( hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0 );
|
need_erase = !SendMessageW( hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0 );
|
||||||
}
|
}
|
||||||
if (!hdc_ret)
|
if (!hdc_ret) USER_Driver->pReleaseDC( hwnd, hdc, TRUE );
|
||||||
{
|
|
||||||
if (need_erase && hwnd != GetDesktopWindow()) /* FIXME: mark it as needing erase again */
|
|
||||||
RedrawWindow( hwnd, clip_rect, 0, RDW_INVALIDATE | RDW_ERASE | RDW_NOCHILDREN );
|
|
||||||
USER_Driver->pReleaseDC( hwnd, hdc, TRUE );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdc_ret) *hdc_ret = hdc;
|
if (hdc_ret) *hdc_ret = hdc;
|
||||||
|
@ -287,6 +282,7 @@ void erase_now( HWND hwnd, UINT rdw_flags )
|
||||||
{
|
{
|
||||||
HWND child = 0;
|
HWND child = 0;
|
||||||
HRGN hrgn;
|
HRGN hrgn;
|
||||||
|
BOOL need_erase = FALSE;
|
||||||
|
|
||||||
/* loop while we find a child to repaint */
|
/* loop while we find a child to repaint */
|
||||||
for (;;)
|
for (;;)
|
||||||
|
@ -295,12 +291,13 @@ void erase_now( HWND hwnd, UINT rdw_flags )
|
||||||
|
|
||||||
if (rdw_flags & RDW_NOCHILDREN) flags |= UPDATE_NOCHILDREN;
|
if (rdw_flags & RDW_NOCHILDREN) flags |= UPDATE_NOCHILDREN;
|
||||||
else if (rdw_flags & RDW_ALLCHILDREN) flags |= UPDATE_ALLCHILDREN;
|
else if (rdw_flags & RDW_ALLCHILDREN) flags |= UPDATE_ALLCHILDREN;
|
||||||
|
if (need_erase) flags |= UPDATE_DELAYED_ERASE;
|
||||||
|
|
||||||
if (!(hrgn = send_ncpaint( hwnd, &child, &flags ))) break;
|
if (!(hrgn = send_ncpaint( hwnd, &child, &flags ))) break;
|
||||||
send_erase( child, flags, hrgn, NULL, NULL );
|
need_erase = send_erase( child, flags, hrgn, NULL, NULL );
|
||||||
|
|
||||||
if (!flags) break; /* nothing more to do */
|
if (!flags) break; /* nothing more to do */
|
||||||
if (rdw_flags & RDW_NOCHILDREN) break;
|
if ((rdw_flags & RDW_NOCHILDREN) && !need_erase) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -736,7 +733,11 @@ INT WINAPI GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
|
||||||
POINT offset;
|
POINT offset;
|
||||||
|
|
||||||
retval = CombineRgn( hrgn, update_rgn, 0, RGN_COPY );
|
retval = CombineRgn( hrgn, update_rgn, 0, RGN_COPY );
|
||||||
send_erase( hwnd, flags, update_rgn, NULL, NULL );
|
if (send_erase( hwnd, flags, update_rgn, NULL, NULL ))
|
||||||
|
{
|
||||||
|
flags = UPDATE_DELAYED_ERASE;
|
||||||
|
get_update_flags( hwnd, NULL, &flags );
|
||||||
|
}
|
||||||
/* map region to client coordinates */
|
/* map region to client coordinates */
|
||||||
offset.x = offset.y = 0;
|
offset.x = offset.y = 0;
|
||||||
ScreenToClient( hwnd, &offset );
|
ScreenToClient( hwnd, &offset );
|
||||||
|
@ -753,6 +754,7 @@ BOOL WINAPI GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase )
|
||||||
{
|
{
|
||||||
UINT flags = UPDATE_NOCHILDREN;
|
UINT flags = UPDATE_NOCHILDREN;
|
||||||
HRGN update_rgn;
|
HRGN update_rgn;
|
||||||
|
BOOL need_erase;
|
||||||
|
|
||||||
if (erase) flags |= UPDATE_NONCLIENT | UPDATE_ERASE;
|
if (erase) flags |= UPDATE_NONCLIENT | UPDATE_ERASE;
|
||||||
|
|
||||||
|
@ -768,10 +770,11 @@ BOOL WINAPI GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase )
|
||||||
ReleaseDC( hwnd, hdc );
|
ReleaseDC( hwnd, hdc );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
send_erase( hwnd, flags, update_rgn, NULL, NULL );
|
need_erase = send_erase( hwnd, flags, update_rgn, NULL, NULL );
|
||||||
|
|
||||||
/* check if we still have an update region */
|
/* check if we still have an update region */
|
||||||
flags = UPDATE_PAINT | UPDATE_NOCHILDREN;
|
flags = UPDATE_PAINT | UPDATE_NOCHILDREN;
|
||||||
|
if (need_erase) flags |= UPDATE_DELAYED_ERASE;
|
||||||
return (get_update_flags( hwnd, NULL, &flags ) && (flags & UPDATE_PAINT));
|
return (get_update_flags( hwnd, NULL, &flags ) && (flags & UPDATE_PAINT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3073,6 +3073,7 @@ struct get_update_region_reply
|
||||||
#define UPDATE_ALLCHILDREN 0x10
|
#define UPDATE_ALLCHILDREN 0x10
|
||||||
#define UPDATE_NOCHILDREN 0x20
|
#define UPDATE_NOCHILDREN 0x20
|
||||||
#define UPDATE_NOREGION 0x40
|
#define UPDATE_NOREGION 0x40
|
||||||
|
#define UPDATE_DELAYED_ERASE 0x80
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -4730,6 +4731,6 @@ union generic_reply
|
||||||
struct make_process_system_reply make_process_system_reply;
|
struct make_process_system_reply make_process_system_reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 309
|
#define SERVER_PROTOCOL_VERSION 310
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -2256,6 +2256,7 @@ enum message_type
|
||||||
#define UPDATE_ALLCHILDREN 0x10 /* force repaint of all children */
|
#define UPDATE_ALLCHILDREN 0x10 /* force repaint of all children */
|
||||||
#define UPDATE_NOCHILDREN 0x20 /* don't try to repaint any children */
|
#define UPDATE_NOCHILDREN 0x20 /* don't try to repaint any children */
|
||||||
#define UPDATE_NOREGION 0x40 /* don't return a region, only the flags */
|
#define UPDATE_NOREGION 0x40 /* don't return a region, only the flags */
|
||||||
|
#define UPDATE_DELAYED_ERASE 0x80 /* still needs erase after BeginPaint */
|
||||||
|
|
||||||
|
|
||||||
/* Update the z order of a window so that a given rectangle is fully visible */
|
/* Update the z order of a window so that a given rectangle is fully visible */
|
||||||
|
|
|
@ -88,9 +88,10 @@ struct window
|
||||||
char extra_bytes[1]; /* extra bytes storage */
|
char extra_bytes[1]; /* extra bytes storage */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PAINT_INTERNAL 0x01 /* internal WM_PAINT pending */
|
#define PAINT_INTERNAL 0x01 /* internal WM_PAINT pending */
|
||||||
#define PAINT_ERASE 0x02 /* needs WM_ERASEBKGND */
|
#define PAINT_ERASE 0x02 /* needs WM_ERASEBKGND */
|
||||||
#define PAINT_NONCLIENT 0x04 /* needs WM_NCPAINT */
|
#define PAINT_NONCLIENT 0x04 /* needs WM_NCPAINT */
|
||||||
|
#define PAINT_DELAYED_ERASE 0x08 /* still needs erase after WM_ERASEBKGND */
|
||||||
|
|
||||||
/* growable array of user handles */
|
/* growable array of user handles */
|
||||||
struct user_handle_array
|
struct user_handle_array
|
||||||
|
@ -978,7 +979,7 @@ static void set_update_region( struct window *win, struct region *region )
|
||||||
inc_window_paint_count( win, -1 );
|
inc_window_paint_count( win, -1 );
|
||||||
free_region( win->update_region );
|
free_region( win->update_region );
|
||||||
}
|
}
|
||||||
win->paint_flags &= ~(PAINT_ERASE | PAINT_NONCLIENT);
|
win->paint_flags &= ~(PAINT_ERASE | PAINT_DELAYED_ERASE | PAINT_NONCLIENT);
|
||||||
win->update_region = NULL;
|
win->update_region = NULL;
|
||||||
if (region) free_region( region );
|
if (region) free_region( region );
|
||||||
}
|
}
|
||||||
|
@ -1122,7 +1123,7 @@ static void redraw_window( struct window *win, struct region *region, int frame,
|
||||||
set_update_region( win, tmp );
|
set_update_region( win, tmp );
|
||||||
}
|
}
|
||||||
if (flags & RDW_NOFRAME) validate_non_client( win );
|
if (flags & RDW_NOFRAME) validate_non_client( win );
|
||||||
if (flags & RDW_NOERASE) win->paint_flags &= ~PAINT_ERASE;
|
if (flags & RDW_NOERASE) win->paint_flags &= ~(PAINT_ERASE | PAINT_DELAYED_ERASE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1178,11 +1179,19 @@ static unsigned int get_update_flags( struct window *win, unsigned int flags )
|
||||||
}
|
}
|
||||||
if (flags & UPDATE_PAINT)
|
if (flags & UPDATE_PAINT)
|
||||||
{
|
{
|
||||||
if (win->update_region) ret |= UPDATE_PAINT;
|
if (win->update_region)
|
||||||
|
{
|
||||||
|
if (win->paint_flags & PAINT_DELAYED_ERASE) ret |= UPDATE_DELAYED_ERASE;
|
||||||
|
ret |= UPDATE_PAINT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (flags & UPDATE_INTERNALPAINT)
|
if (flags & UPDATE_INTERNALPAINT)
|
||||||
{
|
{
|
||||||
if (win->paint_flags & PAINT_INTERNAL) ret |= UPDATE_INTERNALPAINT;
|
if (win->paint_flags & PAINT_INTERNAL)
|
||||||
|
{
|
||||||
|
ret |= UPDATE_INTERNALPAINT;
|
||||||
|
if (win->paint_flags & PAINT_DELAYED_ERASE) ret |= UPDATE_DELAYED_ERASE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1943,6 +1952,12 @@ DECL_HANDLER(get_update_region)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags & UPDATE_DELAYED_ERASE) /* this means that the previous call didn't erase */
|
||||||
|
{
|
||||||
|
if (from_child) from_child->paint_flags |= PAINT_DELAYED_ERASE;
|
||||||
|
else win->paint_flags |= PAINT_DELAYED_ERASE;
|
||||||
|
}
|
||||||
|
|
||||||
reply->flags = get_window_update_flags( win, from_child, flags, &win );
|
reply->flags = get_window_update_flags( win, from_child, flags, &win );
|
||||||
reply->child = win->handle;
|
reply->child = win->handle;
|
||||||
|
|
||||||
|
@ -1975,7 +1990,7 @@ DECL_HANDLER(get_update_region)
|
||||||
if (reply->flags & UPDATE_NONCLIENT) validate_non_client( win );
|
if (reply->flags & UPDATE_NONCLIENT) validate_non_client( win );
|
||||||
if (reply->flags & UPDATE_ERASE)
|
if (reply->flags & UPDATE_ERASE)
|
||||||
{
|
{
|
||||||
win->paint_flags &= ~PAINT_ERASE;
|
win->paint_flags &= ~(PAINT_ERASE | PAINT_DELAYED_ERASE);
|
||||||
/* desktop window only gets erased, not repainted */
|
/* desktop window only gets erased, not repainted */
|
||||||
if (is_desktop_window(win)) validate_whole_window( win );
|
if (is_desktop_window(win)) validate_whole_window( win );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue