| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/views/win/hwnd_message_handler.h" | 5 #include "ui/views/win/hwnd_message_handler.h" |
| 6 | 6 |
| 7 #include <dwmapi.h> | 7 #include <dwmapi.h> |
| 8 #include <oleacc.h> | 8 #include <oleacc.h> |
| 9 #include <shellapi.h> | 9 #include <shellapi.h> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
| 13 #include "base/profiler/scoped_tracker.h" | 13 #include "base/profiler/scoped_tracker.h" |
| 14 #include "base/trace_event/trace_event.h" | 14 #include "base/trace_event/trace_event.h" |
| 15 #include "base/tracked_objects.h" | 15 #include "base/tracked_objects.h" |
| 16 #include "base/win/scoped_gdi_object.h" | 16 #include "base/win/scoped_gdi_object.h" |
| 17 #include "base/win/win_util.h" | 17 #include "base/win/win_util.h" |
| 18 #include "base/win/windows_version.h" | 18 #include "base/win/windows_version.h" |
| 19 #include "ui/base/touch/touch_enabled.h" | 19 #include "ui/base/touch/touch_enabled.h" |
| 20 #include "ui/base/view_prop.h" | 20 #include "ui/base/view_prop.h" |
| 21 #include "ui/base/win/internal_constants.h" | 21 #include "ui/base/win/internal_constants.h" |
| 22 #include "ui/base/win/lock_state.h" | 22 #include "ui/base/win/lock_state.h" |
| 23 #include "ui/base/win/mouse_wheel_util.h" | 23 #include "ui/base/win/mouse_wheel_util.h" |
| 24 #include "ui/base/win/shell.h" | 24 #include "ui/base/win/shell.h" |
| 25 #include "ui/base/win/touch_input.h" | 25 #include "ui/base/win/touch_input.h" |
| 26 #include "ui/events/event.h" | 26 #include "ui/events/event.h" |
| 27 #include "ui/events/event_utils.h" | 27 #include "ui/events/event_utils.h" |
| 28 #include "ui/events/keycodes/keyboard_code_conversion_win.h" | 28 #include "ui/events/keycodes/keyboard_code_conversion_win.h" |
| 29 #include "ui/gfx/canvas.h" | 29 #include "ui/gfx/canvas.h" |
| 30 #include "ui/gfx/canvas_skia_paint.h" | |
| 31 #include "ui/gfx/geometry/insets.h" | 30 #include "ui/gfx/geometry/insets.h" |
| 32 #include "ui/gfx/icon_util.h" | 31 #include "ui/gfx/icon_util.h" |
| 33 #include "ui/gfx/path.h" | 32 #include "ui/gfx/path.h" |
| 34 #include "ui/gfx/path_win.h" | 33 #include "ui/gfx/path_win.h" |
| 35 #include "ui/gfx/screen.h" | 34 #include "ui/gfx/screen.h" |
| 36 #include "ui/gfx/win/dpi.h" | 35 #include "ui/gfx/win/dpi.h" |
| 37 #include "ui/gfx/win/hwnd_util.h" | 36 #include "ui/gfx/win/hwnd_util.h" |
| 38 #include "ui/native_theme/native_theme_win.h" | 37 #include "ui/native_theme/native_theme_win.h" |
| 39 #include "ui/views/views_delegate.h" | 38 #include "ui/views/views_delegate.h" |
| 40 #include "ui/views/widget/monitor_win.h" | 39 #include "ui/views/widget/monitor_win.h" |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 EnableMenuItem(menu, command, flags); | 199 EnableMenuItem(menu, command, flags); |
| 201 } | 200 } |
| 202 | 201 |
| 203 // Callback used to notify child windows that the top level window received a | 202 // Callback used to notify child windows that the top level window received a |
| 204 // DWMCompositionChanged message. | 203 // DWMCompositionChanged message. |
| 205 BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) { | 204 BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) { |
| 206 SendMessage(window, WM_DWMCOMPOSITIONCHANGED, 0, 0); | 205 SendMessage(window, WM_DWMCOMPOSITIONCHANGED, 0, 0); |
| 207 return TRUE; | 206 return TRUE; |
| 208 } | 207 } |
| 209 | 208 |
| 210 // See comments in OnNCPaint() for details of this struct. | |
| 211 struct ClipState { | |
| 212 // The window being painted. | |
| 213 HWND parent; | |
| 214 | |
| 215 // DC painting to. | |
| 216 HDC dc; | |
| 217 | |
| 218 // Origin of the window in terms of the screen. | |
| 219 int x; | |
| 220 int y; | |
| 221 }; | |
| 222 | |
| 223 // See comments in OnNCPaint() for details of this function. | |
| 224 static BOOL CALLBACK ClipDCToChild(HWND window, LPARAM param) { | |
| 225 ClipState* clip_state = reinterpret_cast<ClipState*>(param); | |
| 226 if (GetParent(window) == clip_state->parent && IsWindowVisible(window)) { | |
| 227 RECT bounds; | |
| 228 GetWindowRect(window, &bounds); | |
| 229 ExcludeClipRect(clip_state->dc, | |
| 230 bounds.left - clip_state->x, | |
| 231 bounds.top - clip_state->y, | |
| 232 bounds.right - clip_state->x, | |
| 233 bounds.bottom - clip_state->y); | |
| 234 } | |
| 235 return TRUE; | |
| 236 } | |
| 237 | |
| 238 // The thickness of an auto-hide taskbar in pixels. | 209 // The thickness of an auto-hide taskbar in pixels. |
| 239 const int kAutoHideTaskbarThicknessPx = 2; | 210 const int kAutoHideTaskbarThicknessPx = 2; |
| 240 | 211 |
| 241 bool IsTopLevelWindow(HWND window) { | 212 bool IsTopLevelWindow(HWND window) { |
| 242 long style = ::GetWindowLong(window, GWL_STYLE); | 213 long style = ::GetWindowLong(window, GWL_STYLE); |
| 243 if (!(style & WS_CHILD)) | 214 if (!(style & WS_CHILD)) |
| 244 return true; | 215 return true; |
| 245 HWND parent = ::GetParent(window); | 216 HWND parent = ::GetParent(window); |
| 246 return !parent || (parent == ::GetDesktopWindow()); | 217 return !parent || (parent == ::GetDesktopWindow()); |
| 247 } | 218 } |
| (...skipping 1828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2076 } else { | 2047 } else { |
| 2077 RECT rgn_bounding_box; | 2048 RECT rgn_bounding_box; |
| 2078 GetRgnBox(rgn, &rgn_bounding_box); | 2049 GetRgnBox(rgn, &rgn_bounding_box); |
| 2079 if (!IntersectRect(&dirty_region, &rgn_bounding_box, &window_rect)) | 2050 if (!IntersectRect(&dirty_region, &rgn_bounding_box, &window_rect)) |
| 2080 return; // Dirty region doesn't intersect window bounds, bale. | 2051 return; // Dirty region doesn't intersect window bounds, bale. |
| 2081 | 2052 |
| 2082 // rgn_bounding_box is in screen coordinates. Map it to window coordinates. | 2053 // rgn_bounding_box is in screen coordinates. Map it to window coordinates. |
| 2083 OffsetRect(&dirty_region, -window_rect.left, -window_rect.top); | 2054 OffsetRect(&dirty_region, -window_rect.left, -window_rect.top); |
| 2084 } | 2055 } |
| 2085 | 2056 |
| 2086 // In theory GetDCEx should do what we want, but I couldn't get it to work. | |
| 2087 // In particular the docs mentiond DCX_CLIPCHILDREN, but as far as I can tell | |
| 2088 // it doesn't work at all. So, instead we get the DC for the window then | |
| 2089 // manually clip out the children. | |
| 2090 HDC dc = GetWindowDC(hwnd()); | |
| 2091 ClipState clip_state; | |
| 2092 clip_state.x = window_rect.left; | |
| 2093 clip_state.y = window_rect.top; | |
| 2094 clip_state.parent = hwnd(); | |
| 2095 clip_state.dc = dc; | |
| 2096 EnumChildWindows(hwnd(), &ClipDCToChild, | |
| 2097 reinterpret_cast<LPARAM>(&clip_state)); | |
| 2098 | |
| 2099 gfx::Rect old_paint_region = invalid_rect_; | 2057 gfx::Rect old_paint_region = invalid_rect_; |
| 2100 if (!old_paint_region.IsEmpty()) { | 2058 if (!old_paint_region.IsEmpty()) { |
| 2101 // The root view has a region that needs to be painted. Include it in the | 2059 // The root view has a region that needs to be painted. Include it in the |
| 2102 // region we're going to paint. | 2060 // region we're going to paint. |
| 2103 | 2061 |
| 2104 RECT old_paint_region_crect = old_paint_region.ToRECT(); | 2062 RECT old_paint_region_crect = old_paint_region.ToRECT(); |
| 2105 RECT tmp = dirty_region; | 2063 RECT tmp = dirty_region; |
| 2106 UnionRect(&dirty_region, &tmp, &old_paint_region_crect); | 2064 UnionRect(&dirty_region, &tmp, &old_paint_region_crect); |
| 2107 } | 2065 } |
| 2108 | 2066 |
| 2109 SchedulePaintInRect(gfx::Rect(dirty_region)); | 2067 SchedulePaintInRect(gfx::Rect(dirty_region)); |
| 2068 delegate_->HandlePaintAccelerated(gfx::Rect(dirty_region)); |
| 2110 | 2069 |
| 2111 // gfx::CanvasSkiaPaint's destructor does the actual painting. As such, wrap | |
| 2112 // the following in a block to force paint to occur so that we can release | |
| 2113 // the dc. | |
| 2114 if (!delegate_->HandlePaintAccelerated(gfx::Rect(dirty_region))) { | |
| 2115 gfx::CanvasSkiaPaint canvas(dc, | |
| 2116 true, | |
| 2117 dirty_region.left, | |
| 2118 dirty_region.top, | |
| 2119 dirty_region.right - dirty_region.left, | |
| 2120 dirty_region.bottom - dirty_region.top); | |
| 2121 delegate_->HandlePaint(&canvas); | |
| 2122 } | |
| 2123 | |
| 2124 ReleaseDC(hwnd(), dc); | |
| 2125 // When using a custom frame, we want to avoid calling DefWindowProc() since | 2070 // When using a custom frame, we want to avoid calling DefWindowProc() since |
| 2126 // that may render artifacts. | 2071 // that may render artifacts. |
| 2127 SetMsgHandled(delegate_->IsUsingCustomFrame()); | 2072 SetMsgHandled(delegate_->IsUsingCustomFrame()); |
| 2128 } | 2073 } |
| 2129 | 2074 |
| 2130 LRESULT HWNDMessageHandler::OnNCUAHDrawCaption(UINT message, | 2075 LRESULT HWNDMessageHandler::OnNCUAHDrawCaption(UINT message, |
| 2131 WPARAM w_param, | 2076 WPARAM w_param, |
| 2132 LPARAM l_param) { | 2077 LPARAM l_param) { |
| 2133 // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed. | 2078 // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed. |
| 2134 tracked_objects::ScopedTracker tracking_profile( | 2079 tracked_objects::ScopedTracker tracking_profile( |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2171 FROM_HERE_WITH_EXPLICIT_FUNCTION("440919 HWNDMessageHandler::OnPaint")); | 2116 FROM_HERE_WITH_EXPLICIT_FUNCTION("440919 HWNDMessageHandler::OnPaint")); |
| 2172 | 2117 |
| 2173 // Call BeginPaint()/EndPaint() around the paint handling, as that seems | 2118 // Call BeginPaint()/EndPaint() around the paint handling, as that seems |
| 2174 // to do more to actually validate the window's drawing region. This only | 2119 // to do more to actually validate the window's drawing region. This only |
| 2175 // appears to matter for Windows that have the WS_EX_COMPOSITED style set | 2120 // appears to matter for Windows that have the WS_EX_COMPOSITED style set |
| 2176 // but will be valid in general too. | 2121 // but will be valid in general too. |
| 2177 PAINTSTRUCT ps; | 2122 PAINTSTRUCT ps; |
| 2178 HDC display_dc = BeginPaint(hwnd(), &ps); | 2123 HDC display_dc = BeginPaint(hwnd(), &ps); |
| 2179 CHECK(display_dc); | 2124 CHECK(display_dc); |
| 2180 | 2125 |
| 2181 // Try to paint accelerated first. | 2126 if (!IsRectEmpty(&ps.rcPaint)) |
| 2182 if (!IsRectEmpty(&ps.rcPaint) && | 2127 delegate_->HandlePaintAccelerated(gfx::Rect(ps.rcPaint)); |
| 2183 !delegate_->HandlePaintAccelerated(gfx::Rect(ps.rcPaint))) { | |
| 2184 delegate_->HandlePaint(NULL); | |
| 2185 } | |
| 2186 | 2128 |
| 2187 EndPaint(hwnd(), &ps); | 2129 EndPaint(hwnd(), &ps); |
| 2188 } | 2130 } |
| 2189 | 2131 |
| 2190 LRESULT HWNDMessageHandler::OnReflectedMessage(UINT message, | 2132 LRESULT HWNDMessageHandler::OnReflectedMessage(UINT message, |
| 2191 WPARAM w_param, | 2133 WPARAM w_param, |
| 2192 LPARAM l_param) { | 2134 LPARAM l_param) { |
| 2193 SetMsgHandled(FALSE); | 2135 SetMsgHandled(FALSE); |
| 2194 return 0; | 2136 return 0; |
| 2195 } | 2137 } |
| (...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2866 SetWindowPos(hwnd(), NULL, 0, 0, 0, 0, flags | SWP_HIDEWINDOW); | 2808 SetWindowPos(hwnd(), NULL, 0, 0, 0, 0, flags | SWP_HIDEWINDOW); |
| 2867 SetWindowPos(hwnd(), NULL, 0, 0, 0, 0, flags | SWP_SHOWWINDOW); | 2809 SetWindowPos(hwnd(), NULL, 0, 0, 0, 0, flags | SWP_SHOWWINDOW); |
| 2868 } | 2810 } |
| 2869 // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want | 2811 // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want |
| 2870 // to notify our children too, since we can have MDI child windows who need to | 2812 // to notify our children too, since we can have MDI child windows who need to |
| 2871 // update their appearance. | 2813 // update their appearance. |
| 2872 EnumChildWindows(hwnd(), &SendDwmCompositionChanged, NULL); | 2814 EnumChildWindows(hwnd(), &SendDwmCompositionChanged, NULL); |
| 2873 } | 2815 } |
| 2874 | 2816 |
| 2875 } // namespace views | 2817 } // namespace views |
| OLD | NEW |