diff --git a/dlls/user32/painting.c b/dlls/user32/painting.c index 79db23062a5..9178b61bcc4 100644 --- a/dlls/user32/painting.c +++ b/dlls/user32/painting.c @@ -1227,8 +1227,6 @@ BOOL WINAPI RedrawWindow( HWND hwnd, const RECT *rect, HRGN hrgn, UINT flags ) static const RECT empty; BOOL ret; - if (!hwnd) hwnd = GetDesktopWindow(); - if (TRACE_ON(win)) { if (hrgn) @@ -1272,6 +1270,8 @@ BOOL WINAPI RedrawWindow( HWND hwnd, const RECT *rect, HRGN hrgn, UINT flags ) HeapFree( GetProcessHeap(), 0, data ); } + if (!hwnd) hwnd = GetDesktopWindow(); + if (flags & RDW_UPDATENOW) update_now( hwnd, flags ); else if (flags & RDW_ERASENOW) erase_now( hwnd, flags ); diff --git a/dlls/user32/sysparams.c b/dlls/user32/sysparams.c index fc55b063ae1..13bd4252928 100644 --- a/dlls/user32/sysparams.c +++ b/dlls/user32/sysparams.c @@ -2938,8 +2938,7 @@ BOOL WINAPI SetSysColors( INT count, const INT *colors, const COLORREF *values ) /* Repaint affected portions of all visible windows */ - RedrawWindow( GetDesktopWindow(), NULL, 0, - RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN ); + RedrawWindow( 0, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN ); return TRUE; } diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index 80c699f7264..55d8994023e 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -7229,7 +7229,8 @@ void dump_region(HRGN hrgn) HeapFree( GetProcessHeap(), 0, data ); } -static void check_update_rgn( HWND hwnd, HRGN hrgn ) +#define check_update_rgn( hwnd, hrgn ) check_update_rgn_( __LINE__, hwnd, hrgn ) +static void check_update_rgn_( int line, HWND hwnd, HRGN hrgn ) { INT ret; RECT r1, r2; @@ -7240,13 +7241,13 @@ static void check_update_rgn( HWND hwnd, HRGN hrgn ) ok( ret != ERROR, "GetUpdateRgn failed\n" ); if (ret == NULLREGION) { - ok( !hrgn, "Update region shouldn't be empty\n" ); + ok_(__FILE__,line)( !hrgn, "Update region shouldn't be empty\n" ); } else { if (CombineRgn( tmp, hrgn, update, RGN_XOR ) != NULLREGION) { - ok( 0, "Regions are different\n" ); + ok_(__FILE__,line)( 0, "Regions are different\n" ); if (winetest_debug > 0) { printf( "Update region: " ); @@ -7258,8 +7259,8 @@ static void check_update_rgn( HWND hwnd, HRGN hrgn ) } GetRgnBox( update, &r1 ); GetUpdateRect( hwnd, &r2, FALSE ); - ok( EqualRect( &r1, &r2 ), "Rectangles are different: %s / %s\n", wine_dbgstr_rect( &r1 ), - wine_dbgstr_rect( &r2 )); + ok_(__FILE__,line)( EqualRect( &r1, &r2 ), "Rectangles are different: %s / %s\n", + wine_dbgstr_rect( &r1 ), wine_dbgstr_rect( &r2 )); DeleteObject( tmp ); DeleteObject( update ); @@ -7455,9 +7456,76 @@ static void test_paint_messages(void) /* MSDN: if hwnd parameter is NULL, InvalidateRect invalidates and redraws * all windows and sends WM_ERASEBKGND and WM_NCPAINT. */ - trace("testing InvalidateRect(0, NULL, FALSE)\n"); SetRectEmpty( &rect ); - ok(InvalidateRect(0, &rect, FALSE), "InvalidateRect(0, &rc, FALSE) should fail\n"); + ok(InvalidateRect(0, &rect, FALSE), "InvalidateRect(0, &rc, FALSE) failed\n"); + check_update_rgn( hwnd, hrgn ); + ok_sequence( WmInvalidateErase, "InvalidateErase", FALSE ); + flush_events(); + ok_sequence( WmPaint, "Paint", FALSE ); + RedrawWindow( hwnd, NULL, NULL, RDW_VALIDATE ); + check_update_rgn( hwnd, 0 ); + + SetRectEmpty( &rect ); + ok(RedrawWindow(0, &rect, 0, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ERASENOW ), + "RedrawWindow failed\n"); + check_update_rgn( hwnd, 0 ); + + SetRectEmpty( &rect ); + ok(RedrawWindow(0, &rect, 0, RDW_ALLCHILDREN | RDW_VALIDATE | RDW_FRAME | RDW_ERASE | RDW_ERASENOW ), + "RedrawWindow failed\n"); + check_update_rgn( hwnd, 0 ); + + GetWindowRect( hwnd, &rect ); + ok(RedrawWindow(0, &rect, 0, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ERASENOW ), + "RedrawWindow failed\n"); + check_update_rgn( hwnd, 0 ); + + flush_events(); + ok(RedrawWindow(0, &rect, 0, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ERASENOW ), + "RedrawWindow failed\n"); + check_update_rgn( hwnd, hrgn ); + ok_sequence( WmInvalidateErase, "InvalidateErase", FALSE ); + flush_events(); + ok_sequence( WmPaint, "Paint", FALSE ); + RedrawWindow( hwnd, NULL, NULL, RDW_VALIDATE ); + check_update_rgn( hwnd, 0 ); + + ok(RedrawWindow(GetDesktopWindow(), &rect, 0, + RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ERASENOW ), + "RedrawWindow failed\n"); + ret = GetUpdateRgn( hwnd, hrgn2, FALSE ); + ok( ret == NULLREGION || broken(ret == SIMPLEREGION), /* <= win7 */ + "region should be null (%d)\n", ret ); + if (ret == SIMPLEREGION) ok_sequence( WmInvalidateErase, "InvalidateErase", FALSE ); + RedrawWindow( hwnd, NULL, NULL, RDW_VALIDATE ); + flush_events(); + + ok(RedrawWindow(GetDesktopWindow(), NULL, 0, + RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ERASENOW ), + "RedrawWindow failed\n"); + ret = GetUpdateRgn( hwnd, hrgn2, FALSE ); + ok( ret == NULLREGION || broken(ret == SIMPLEREGION), /* <= win7 */ + "region should be null (%d)\n", ret ); + if (ret == SIMPLEREGION) ok_sequence( WmInvalidateErase, "InvalidateErase", FALSE ); + RedrawWindow( hwnd, NULL, NULL, RDW_VALIDATE ); + flush_events(); + + SetRectRgn( hrgn2, rect.left, rect.top, rect.right, rect.bottom ); + ok(RedrawWindow(0, NULL, hrgn2, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ERASENOW ), + "RedrawWindow failed\n"); + check_update_rgn( hwnd, hrgn ); + ok_sequence( WmInvalidateErase, "InvalidateErase", FALSE ); + flush_events(); + ok_sequence( WmPaint, "Paint", FALSE ); + RedrawWindow( hwnd, NULL, NULL, RDW_VALIDATE ); + check_update_rgn( hwnd, 0 ); + + ok(RedrawWindow(0, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW ), + "RedrawWindow failed\n"); + check_update_rgn( hwnd, 0 ); + + ok(RedrawWindow(0, NULL, 0, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW ), + "RedrawWindow failed\n"); check_update_rgn( hwnd, hrgn ); ok_sequence( WmInvalidateErase, "InvalidateErase", FALSE ); flush_events(); @@ -7468,7 +7536,6 @@ static void test_paint_messages(void) /* MSDN: if hwnd parameter is NULL, ValidateRect invalidates and redraws * all windows and sends WM_ERASEBKGND and WM_NCPAINT. */ - trace("testing ValidateRect(0, NULL)\n"); SetRectEmpty( &rect ); if (ValidateRect(0, &rect) && /* not supported on Win9x */ GetUpdateRect(hwnd, NULL, FALSE)) /* or >= Win 8 */ @@ -7481,7 +7548,6 @@ static void test_paint_messages(void) check_update_rgn( hwnd, 0 ); } - trace("testing InvalidateRgn(0, NULL, FALSE)\n"); SetLastError(0xdeadbeef); ok(!InvalidateRgn(0, NULL, FALSE), "InvalidateRgn(0, NULL, FALSE) should fail\n"); ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE || GetLastError() == 0xdeadbeef, @@ -7490,7 +7556,6 @@ static void test_paint_messages(void) flush_events(); ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE ); - trace("testing ValidateRgn(0, NULL)\n"); SetLastError(0xdeadbeef); ok(!ValidateRgn(0, NULL), "ValidateRgn(0, NULL) should fail\n"); ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE || @@ -7500,7 +7565,6 @@ static void test_paint_messages(void) flush_events(); ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE ); - trace("testing UpdateWindow(NULL)\n"); SetLastError(0xdeadbeef); ok(!UpdateWindow(NULL), "UpdateWindow(NULL) should fail\n"); ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE || diff --git a/server/window.c b/server/window.c index 322001d8e32..532edd8939e 100644 --- a/server/window.c +++ b/server/window.c @@ -2634,13 +2634,23 @@ DECL_HANDLER(update_window_zorder) /* mark parts of a window as needing a redraw */ DECL_HANDLER(redraw_window) { + unsigned int flags = req->flags; struct region *region = NULL; - struct window *win = get_window( req->window ); + struct window *win; + + if (!req->window) + { + if (!(win = get_desktop_window( current ))) return; + } + else + { + if (!(win = get_window( req->window ))) return; + if (is_desktop_window( win )) flags &= ~RDW_ALLCHILDREN; + } - if (!win) return; if (!is_visible( win )) return; /* nothing to do */ - if (req->flags & (RDW_VALIDATE|RDW_INVALIDATE)) + if (flags & (RDW_VALIDATE|RDW_INVALIDATE)) { if (get_req_data_size()) /* no data means whole rectangle */ { @@ -2650,8 +2660,7 @@ DECL_HANDLER(redraw_window) } } - redraw_window( win, region, (req->flags & RDW_INVALIDATE) && (req->flags & RDW_FRAME), - req->flags ); + redraw_window( win, region, (flags & RDW_INVALIDATE) && (flags & RDW_FRAME), flags ); if (region) free_region( region ); }