diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-23 17:50:56 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-23 17:50:56 +0000 |
commit | 0a119c96c644fce867059839ab24fb7cc38e4047 (patch) | |
tree | 40c94228fe028f0df40a9a6522fd77c0123211de /views/window | |
parent | 529623ed3b5c444fa30203fb982c2e69c97825a5 (diff) | |
download | chromium_src-0a119c96c644fce867059839ab24fb7cc38e4047.zip chromium_src-0a119c96c644fce867059839ab24fb7cc38e4047.tar.gz chromium_src-0a119c96c644fce867059839ab24fb7cc38e4047.tar.bz2 |
Dramatically simplify view painting by getting rid of RootView's redundant knowledge of invalid rects.The OS is capable of doing this for us (see: InvalidateRect, etc.), so we should just defer to it.I was also able to remove all of the custom logic in WindowWin::OnNCPaint and replace it with a simple SetMsgHandled check.http://crbug.com/72040TEST=none
Review URL: http://codereview.chromium.org/6469096
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@75758 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/window')
-rw-r--r-- | views/window/window_win.cc | 121 |
1 files changed, 5 insertions, 116 deletions
diff --git a/views/window/window_win.cc b/views/window/window_win.cc index be578834..239226d 100644 --- a/views/window/window_win.cc +++ b/views/window/window_win.cc @@ -854,18 +854,11 @@ void WindowWin::OnMouseLeave() { LRESULT WindowWin::OnNCActivate(BOOL active) { is_active_ = !!active; - // We need to force a synchronous repaint, otherwise we'll be left in the - // wrong activation state until something else causes a repaint later. - // Both the native and non-native frames may render activation-state - // dependent UI. + // The frame may need to redraw as a result of the activation change. // We can get WM_NCACTIVATE before we're actually visible. If we're not // visible, no need to paint. - if (IsWindowVisible(GetNativeView())) { + if (IsVisible()) non_client_view_->SchedulePaint(); - // We need to force a paint now, as a user dragging a window will block - // painting operations while the move is in progress. - PaintNow(root_view_->GetScheduledPaintRect()); - } // If we're active again, we should be allowed to render as inactive, so // tell the non-client view. This must be done independently of the check for @@ -976,114 +969,10 @@ LRESULT WindowWin::OnNCHitTest(const CPoint& point) { return WidgetWin::OnNCHitTest(point); } -namespace { -struct ClipState { - // The window being painted. - HWND parent; - - // DC painting to. - HDC dc; - - // Origin of the window in terms of the screen. - int x; - int y; -}; - -// See comments in OnNCPaint for details of this function. -static BOOL CALLBACK ClipDCToChild(HWND window, LPARAM param) { - ClipState* clip_state = reinterpret_cast<ClipState*>(param); - if (GetParent(window) == clip_state->parent && IsWindowVisible(window)) { - RECT bounds; - GetWindowRect(window, &bounds); - ExcludeClipRect(clip_state->dc, - bounds.left - clip_state->x, - bounds.top - clip_state->y, - bounds.right - clip_state->x, - bounds.bottom - clip_state->y); - } - return TRUE; -} -} // namespace - void WindowWin::OnNCPaint(HRGN rgn) { - // We only do non-client painting if we're not using the native frame. - // It's required to avoid some native painting artifacts from appearing when - // the window is resized. - if (non_client_view_->UseNativeFrame()) { - WidgetWin::OnNCPaint(rgn); - return; - } - - // We have an NC region and need to paint it. We expand the NC region to - // include the dirty region of the root view. This is done to minimize - // paints. - CRect window_rect; - GetWindowRect(&window_rect); - - if (window_rect.Width() != root_view_->width() || - window_rect.Height() != root_view_->height()) { - // If the size of the window differs from the size of the root view it - // means we're being asked to paint before we've gotten a WM_SIZE. This can - // happen when the user is interactively resizing the window. To avoid - // mass flickering we don't do anything here. Once we get the WM_SIZE we'll - // reset the region of the window which triggers another WM_NCPAINT and - // all is well. - return; - } - - CRect dirty_region; - // A value of 1 indicates paint all. - if (!rgn || rgn == reinterpret_cast<HRGN>(1)) { - dirty_region = CRect(0, 0, window_rect.Width(), window_rect.Height()); - } else { - RECT rgn_bounding_box; - GetRgnBox(rgn, &rgn_bounding_box); - if (!IntersectRect(&dirty_region, &rgn_bounding_box, &window_rect)) - return; // Dirty region doesn't intersect window bounds, bale. - - // rgn_bounding_box is in screen coordinates. Map it to window coordinates. - OffsetRect(&dirty_region, -window_rect.left, -window_rect.top); - } - - // In theory GetDCEx should do what we want, but I couldn't get it to work. - // In particular the docs mentiond DCX_CLIPCHILDREN, but as far as I can tell - // it doesn't work at all. So, instead we get the DC for the window then - // manually clip out the children. - HDC dc = GetWindowDC(GetNativeView()); - ClipState clip_state; - clip_state.x = window_rect.left; - clip_state.y = window_rect.top; - clip_state.parent = GetNativeView(); - clip_state.dc = dc; - EnumChildWindows(GetNativeView(), &ClipDCToChild, - reinterpret_cast<LPARAM>(&clip_state)); - - RootView* root_view = GetRootView(); - gfx::Rect old_paint_region = - root_view->GetScheduledPaintRectConstrainedToSize(); - - if (!old_paint_region.IsEmpty()) { - // The root view has a region that needs to be painted. Include it in the - // region we're going to paint. - - CRect old_paint_region_crect = old_paint_region.ToRECT(); - CRect tmp = dirty_region; - UnionRect(&dirty_region, &tmp, &old_paint_region_crect); - } - - root_view->SchedulePaintInRect(gfx::Rect(dirty_region), false); - - // gfx::CanvasSkiaPaint's destructor does the actual painting. As such, wrap - // the following in a block to force paint to occur so that we can release - // the dc. - { - gfx::CanvasSkiaPaint canvas(dc, opaque(), dirty_region.left, - dirty_region.top, dirty_region.Width(), - dirty_region.Height()); - root_view->Paint(&canvas); - } - - ReleaseDC(GetNativeView(), dc); + // When using a custom frame, we want to avoid calling DefWindowProc() since + // that may render artifacts. + SetMsgHandled(!non_client_view_->UseNativeFrame()); } void WindowWin::OnNCLButtonDown(UINT ht_component, const CPoint& point) { |