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 |