| 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 |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 remove_standard_frame_(false), | 312 remove_standard_frame_(false), |
| 313 use_system_default_icon_(false), | 313 use_system_default_icon_(false), |
| 314 restored_enabled_(false), | 314 restored_enabled_(false), |
| 315 current_cursor_(NULL), | 315 current_cursor_(NULL), |
| 316 previous_cursor_(NULL), | 316 previous_cursor_(NULL), |
| 317 active_mouse_tracking_flags_(0), | 317 active_mouse_tracking_flags_(0), |
| 318 is_right_mouse_pressed_on_caption_(false), | 318 is_right_mouse_pressed_on_caption_(false), |
| 319 lock_updates_count_(0), | 319 lock_updates_count_(0), |
| 320 ignore_window_pos_changes_(false), | 320 ignore_window_pos_changes_(false), |
| 321 last_monitor_(NULL), | 321 last_monitor_(NULL), |
| 322 use_layered_buffer_(false), | |
| 323 layered_alpha_(255), | |
| 324 waiting_for_redraw_layered_window_contents_(false), | |
| 325 is_first_nccalc_(true), | 322 is_first_nccalc_(true), |
| 326 menu_depth_(0), | 323 menu_depth_(0), |
| 327 id_generator_(0), | 324 id_generator_(0), |
| 328 needs_scroll_styles_(false), | 325 needs_scroll_styles_(false), |
| 329 in_size_loop_(false), | 326 in_size_loop_(false), |
| 330 touch_down_contexts_(0), | 327 touch_down_contexts_(0), |
| 331 last_mouse_hwheel_time_(0), | 328 last_mouse_hwheel_time_(0), |
| 332 msg_handled_(FALSE), | 329 msg_handled_(FALSE), |
| 333 dwm_transition_desired_(false), | 330 dwm_transition_desired_(false), |
| 334 autohide_factory_(this), | 331 autohide_factory_(this), |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 781 delegate_->HandleFrameChanged(); | 778 delegate_->HandleFrameChanged(); |
| 782 InvalidateRect(hwnd(), NULL, FALSE); | 779 InvalidateRect(hwnd(), NULL, FALSE); |
| 783 } else { | 780 } else { |
| 784 if (!custom_window_region_ && !delegate_->IsUsingCustomFrame()) | 781 if (!custom_window_region_ && !delegate_->IsUsingCustomFrame()) |
| 785 dwm_transition_desired_ = true; | 782 dwm_transition_desired_ = true; |
| 786 if (!dwm_transition_desired_ || !fullscreen_handler_->fullscreen()) | 783 if (!dwm_transition_desired_ || !fullscreen_handler_->fullscreen()) |
| 787 PerformDwmTransition(); | 784 PerformDwmTransition(); |
| 788 } | 785 } |
| 789 } | 786 } |
| 790 | 787 |
| 791 void HWNDMessageHandler::SchedulePaintInRect(const gfx::Rect& rect) { | |
| 792 if (use_layered_buffer_) { | |
| 793 // We must update the back-buffer immediately, since Windows' handling of | |
| 794 // invalid rects is somewhat mysterious. | |
| 795 invalid_rect_.Union(rect); | |
| 796 | |
| 797 // In some situations, such as drag and drop, when Windows itself runs a | |
| 798 // nested message loop our message loop appears to be starved and we don't | |
| 799 // receive calls to DidProcessMessage(). This only seems to affect layered | |
| 800 // windows, so we schedule a redraw manually using a task, since those never | |
| 801 // seem to be starved. Also, wtf. | |
| 802 if (!waiting_for_redraw_layered_window_contents_) { | |
| 803 waiting_for_redraw_layered_window_contents_ = true; | |
| 804 base::MessageLoop::current()->PostTask( | |
| 805 FROM_HERE, | |
| 806 base::Bind(&HWNDMessageHandler::RedrawLayeredWindowContents, | |
| 807 weak_factory_.GetWeakPtr())); | |
| 808 } | |
| 809 } else { | |
| 810 // InvalidateRect() expects client coordinates. | |
| 811 RECT r = rect.ToRECT(); | |
| 812 InvalidateRect(hwnd(), &r, FALSE); | |
| 813 } | |
| 814 } | |
| 815 | |
| 816 void HWNDMessageHandler::SetOpacity(BYTE opacity) { | |
| 817 layered_alpha_ = opacity; | |
| 818 } | |
| 819 | |
| 820 void HWNDMessageHandler::SetWindowIcons(const gfx::ImageSkia& window_icon, | 788 void HWNDMessageHandler::SetWindowIcons(const gfx::ImageSkia& window_icon, |
| 821 const gfx::ImageSkia& app_icon) { | 789 const gfx::ImageSkia& app_icon) { |
| 822 if (!window_icon.isNull()) { | 790 if (!window_icon.isNull()) { |
| 823 HICON windows_icon = IconUtil::CreateHICONFromSkBitmap( | 791 HICON windows_icon = IconUtil::CreateHICONFromSkBitmap( |
| 824 *window_icon.bitmap()); | 792 *window_icon.bitmap()); |
| 825 // We need to make sure to destroy the previous icon, otherwise we'll leak | 793 // We need to make sure to destroy the previous icon, otherwise we'll leak |
| 826 // these GDI objects until we crash! | 794 // these GDI objects until we crash! |
| 827 HICON old_icon = reinterpret_cast<HICON>( | 795 HICON old_icon = reinterpret_cast<HICON>( |
| 828 SendMessage(hwnd(), WM_SETICON, ICON_SMALL, | 796 SendMessage(hwnd(), WM_SETICON, ICON_SMALL, |
| 829 reinterpret_cast<LPARAM>(windows_icon))); | 797 reinterpret_cast<LPARAM>(windows_icon))); |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1101 TrackMouseEvent(&tme); | 1069 TrackMouseEvent(&tme); |
| 1102 } else if (mouse_tracking_flags != active_mouse_tracking_flags_) { | 1070 } else if (mouse_tracking_flags != active_mouse_tracking_flags_) { |
| 1103 TrackMouseEvents(active_mouse_tracking_flags_ | TME_CANCEL); | 1071 TrackMouseEvents(active_mouse_tracking_flags_ | TME_CANCEL); |
| 1104 TrackMouseEvents(mouse_tracking_flags); | 1072 TrackMouseEvents(mouse_tracking_flags); |
| 1105 } | 1073 } |
| 1106 } | 1074 } |
| 1107 | 1075 |
| 1108 void HWNDMessageHandler::ClientAreaSizeChanged() { | 1076 void HWNDMessageHandler::ClientAreaSizeChanged() { |
| 1109 gfx::Size s = GetClientAreaBounds().size(); | 1077 gfx::Size s = GetClientAreaBounds().size(); |
| 1110 delegate_->HandleClientSizeChanged(s); | 1078 delegate_->HandleClientSizeChanged(s); |
| 1111 if (use_layered_buffer_) | |
| 1112 layered_window_contents_.reset(new gfx::Canvas(s, 1.0f, false)); | |
| 1113 } | 1079 } |
| 1114 | 1080 |
| 1115 bool HWNDMessageHandler::GetClientAreaInsets(gfx::Insets* insets) const { | 1081 bool HWNDMessageHandler::GetClientAreaInsets(gfx::Insets* insets) const { |
| 1116 if (delegate_->GetClientAreaInsets(insets)) | 1082 if (delegate_->GetClientAreaInsets(insets)) |
| 1117 return true; | 1083 return true; |
| 1118 DCHECK(insets->empty()); | 1084 DCHECK(insets->empty()); |
| 1119 | 1085 |
| 1120 // Returning false causes the default handling in OnNCCalcSize() to | 1086 // Returning false causes the default handling in OnNCCalcSize() to |
| 1121 // be invoked. | 1087 // be invoked. |
| 1122 if (!delegate_->IsWidgetWindow() || | 1088 if (!delegate_->IsWidgetWindow() || |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1232 } | 1198 } |
| 1233 | 1199 |
| 1234 void HWNDMessageHandler::UnlockUpdates(bool force) { | 1200 void HWNDMessageHandler::UnlockUpdates(bool force) { |
| 1235 if ((force || !ui::win::IsAeroGlassEnabled()) && --lock_updates_count_ <= 0) { | 1201 if ((force || !ui::win::IsAeroGlassEnabled()) && --lock_updates_count_ <= 0) { |
| 1236 SetWindowLong(hwnd(), GWL_STYLE, | 1202 SetWindowLong(hwnd(), GWL_STYLE, |
| 1237 GetWindowLong(hwnd(), GWL_STYLE) | WS_VISIBLE); | 1203 GetWindowLong(hwnd(), GWL_STYLE) | WS_VISIBLE); |
| 1238 lock_updates_count_ = 0; | 1204 lock_updates_count_ = 0; |
| 1239 } | 1205 } |
| 1240 } | 1206 } |
| 1241 | 1207 |
| 1242 void HWNDMessageHandler::RedrawLayeredWindowContents() { | |
| 1243 waiting_for_redraw_layered_window_contents_ = false; | |
| 1244 if (invalid_rect_.IsEmpty()) | |
| 1245 return; | |
| 1246 | |
| 1247 // We need to clip to the dirty rect ourselves. | |
| 1248 layered_window_contents_->sk_canvas()->save(); | |
| 1249 double scale = gfx::GetDPIScale(); | |
| 1250 layered_window_contents_->sk_canvas()->scale( | |
| 1251 SkScalar(scale),SkScalar(scale)); | |
| 1252 layered_window_contents_->ClipRect(invalid_rect_); | |
| 1253 delegate_->PaintLayeredWindow(layered_window_contents_.get()); | |
| 1254 layered_window_contents_->sk_canvas()->scale( | |
| 1255 SkScalar(1.0/scale),SkScalar(1.0/scale)); | |
| 1256 layered_window_contents_->sk_canvas()->restore(); | |
| 1257 | |
| 1258 RECT wr; | |
| 1259 GetWindowRect(hwnd(), &wr); | |
| 1260 SIZE size = {wr.right - wr.left, wr.bottom - wr.top}; | |
| 1261 POINT position = {wr.left, wr.top}; | |
| 1262 HDC dib_dc = skia::BeginPlatformPaint(layered_window_contents_->sk_canvas()); | |
| 1263 POINT zero = {0, 0}; | |
| 1264 BLENDFUNCTION blend = {AC_SRC_OVER, 0, layered_alpha_, AC_SRC_ALPHA}; | |
| 1265 UpdateLayeredWindow(hwnd(), NULL, &position, &size, dib_dc, &zero, | |
| 1266 RGB(0xFF, 0xFF, 0xFF), &blend, ULW_ALPHA); | |
| 1267 invalid_rect_.SetRect(0, 0, 0, 0); | |
| 1268 skia::EndPlatformPaint(layered_window_contents_->sk_canvas()); | |
| 1269 } | |
| 1270 | |
| 1271 void HWNDMessageHandler::ForceRedrawWindow(int attempts) { | 1208 void HWNDMessageHandler::ForceRedrawWindow(int attempts) { |
| 1272 if (ui::IsWorkstationLocked()) { | 1209 if (ui::IsWorkstationLocked()) { |
| 1273 // Presents will continue to fail as long as the input desktop is | 1210 // Presents will continue to fail as long as the input desktop is |
| 1274 // unavailable. | 1211 // unavailable. |
| 1275 if (--attempts <= 0) | 1212 if (--attempts <= 0) |
| 1276 return; | 1213 return; |
| 1277 base::MessageLoop::current()->PostDelayedTask( | 1214 base::MessageLoop::current()->PostDelayedTask( |
| 1278 FROM_HERE, | 1215 FROM_HERE, |
| 1279 base::Bind(&HWNDMessageHandler::ForceRedrawWindow, | 1216 base::Bind(&HWNDMessageHandler::ForceRedrawWindow, |
| 1280 weak_factory_.GetWeakPtr(), | 1217 weak_factory_.GetWeakPtr(), |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1358 // should ignore it. | 1295 // should ignore it. |
| 1359 if (notification_code > 1 || delegate_->HandleAppCommand(command)) | 1296 if (notification_code > 1 || delegate_->HandleAppCommand(command)) |
| 1360 SetMsgHandled(FALSE); | 1297 SetMsgHandled(FALSE); |
| 1361 } | 1298 } |
| 1362 | 1299 |
| 1363 LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) { | 1300 LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) { |
| 1364 // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed. | 1301 // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed. |
| 1365 tracked_objects::ScopedTracker tracking_profile1( | 1302 tracked_objects::ScopedTracker tracking_profile1( |
| 1366 FROM_HERE_WITH_EXPLICIT_FUNCTION("440919 HWNDMessageHandler::OnCreate1")); | 1303 FROM_HERE_WITH_EXPLICIT_FUNCTION("440919 HWNDMessageHandler::OnCreate1")); |
| 1367 | 1304 |
| 1368 use_layered_buffer_ = !!(window_ex_style() & WS_EX_LAYERED); | |
| 1369 | |
| 1370 if (window_ex_style() & WS_EX_COMPOSITED) { | 1305 if (window_ex_style() & WS_EX_COMPOSITED) { |
| 1371 // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed. | 1306 // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed. |
| 1372 tracked_objects::ScopedTracker tracking_profile2( | 1307 tracked_objects::ScopedTracker tracking_profile2( |
| 1373 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1308 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1374 "440919 HWNDMessageHandler::OnCreate2")); | 1309 "440919 HWNDMessageHandler::OnCreate2")); |
| 1375 | 1310 |
| 1376 if (base::win::GetVersion() >= base::win::VERSION_VISTA) { | 1311 if (base::win::GetVersion() >= base::win::VERSION_VISTA) { |
| 1377 // This is part of the magic to emulate layered windows with Aura | 1312 // This is part of the magic to emulate layered windows with Aura |
| 1378 // see the explanation elsewere when we set WS_EX_COMPOSITED style. | 1313 // see the explanation elsewere when we set WS_EX_COMPOSITED style. |
| 1379 MARGINS margins = {-1,-1,-1,-1}; | 1314 MARGINS margins = {-1,-1,-1,-1}; |
| (...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2047 } else { | 1982 } else { |
| 2048 RECT rgn_bounding_box; | 1983 RECT rgn_bounding_box; |
| 2049 GetRgnBox(rgn, &rgn_bounding_box); | 1984 GetRgnBox(rgn, &rgn_bounding_box); |
| 2050 if (!IntersectRect(&dirty_region, &rgn_bounding_box, &window_rect)) | 1985 if (!IntersectRect(&dirty_region, &rgn_bounding_box, &window_rect)) |
| 2051 return; // Dirty region doesn't intersect window bounds, bale. | 1986 return; // Dirty region doesn't intersect window bounds, bale. |
| 2052 | 1987 |
| 2053 // rgn_bounding_box is in screen coordinates. Map it to window coordinates. | 1988 // rgn_bounding_box is in screen coordinates. Map it to window coordinates. |
| 2054 OffsetRect(&dirty_region, -window_rect.left, -window_rect.top); | 1989 OffsetRect(&dirty_region, -window_rect.left, -window_rect.top); |
| 2055 } | 1990 } |
| 2056 | 1991 |
| 2057 gfx::Rect old_paint_region = invalid_rect_; | |
| 2058 if (!old_paint_region.IsEmpty()) { | |
| 2059 // The root view has a region that needs to be painted. Include it in the | |
| 2060 // region we're going to paint. | |
| 2061 | |
| 2062 RECT old_paint_region_crect = old_paint_region.ToRECT(); | |
| 2063 RECT tmp = dirty_region; | |
| 2064 UnionRect(&dirty_region, &tmp, &old_paint_region_crect); | |
| 2065 } | |
| 2066 | |
| 2067 SchedulePaintInRect(gfx::Rect(dirty_region)); | |
| 2068 delegate_->HandlePaintAccelerated(gfx::Rect(dirty_region)); | 1992 delegate_->HandlePaintAccelerated(gfx::Rect(dirty_region)); |
| 2069 | 1993 |
| 2070 // When using a custom frame, we want to avoid calling DefWindowProc() since | 1994 // When using a custom frame, we want to avoid calling DefWindowProc() since |
| 2071 // that may render artifacts. | 1995 // that may render artifacts. |
| 2072 SetMsgHandled(delegate_->IsUsingCustomFrame()); | 1996 SetMsgHandled(delegate_->IsUsingCustomFrame()); |
| 2073 } | 1997 } |
| 2074 | 1998 |
| 2075 LRESULT HWNDMessageHandler::OnNCUAHDrawCaption(UINT message, | 1999 LRESULT HWNDMessageHandler::OnNCUAHDrawCaption(UINT message, |
| 2076 WPARAM w_param, | 2000 WPARAM w_param, |
| 2077 LPARAM l_param) { | 2001 LPARAM l_param) { |
| (...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2808 SetWindowPos(hwnd(), NULL, 0, 0, 0, 0, flags | SWP_HIDEWINDOW); | 2732 SetWindowPos(hwnd(), NULL, 0, 0, 0, 0, flags | SWP_HIDEWINDOW); |
| 2809 SetWindowPos(hwnd(), NULL, 0, 0, 0, 0, flags | SWP_SHOWWINDOW); | 2733 SetWindowPos(hwnd(), NULL, 0, 0, 0, 0, flags | SWP_SHOWWINDOW); |
| 2810 } | 2734 } |
| 2811 // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want | 2735 // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want |
| 2812 // to notify our children too, since we can have MDI child windows who need to | 2736 // to notify our children too, since we can have MDI child windows who need to |
| 2813 // update their appearance. | 2737 // update their appearance. |
| 2814 EnumChildWindows(hwnd(), &SendDwmCompositionChanged, NULL); | 2738 EnumChildWindows(hwnd(), &SendDwmCompositionChanged, NULL); |
| 2815 } | 2739 } |
| 2816 | 2740 |
| 2817 } // namespace views | 2741 } // namespace views |
| OLD | NEW |