Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: ui/views/win/hwnd_message_handler.cc

Issue 1127393004: Remove layered window painting support from HWNDMessageHandler (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/views/win/hwnd_message_handler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « ui/views/win/hwnd_message_handler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698