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

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

Issue 484963002: Fix a long standing painting problem seen in the tabstrip on Windows Desktop Chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Code review comments Created 6 years, 4 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 | Annotate | Revision Log
« 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 #include <wtsapi32.h> 10 #include <wtsapi32.h>
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 layered_alpha_(255), 352 layered_alpha_(255),
353 waiting_for_redraw_layered_window_contents_(false), 353 waiting_for_redraw_layered_window_contents_(false),
354 is_first_nccalc_(true), 354 is_first_nccalc_(true),
355 menu_depth_(0), 355 menu_depth_(0),
356 autohide_factory_(this), 356 autohide_factory_(this),
357 id_generator_(0), 357 id_generator_(0),
358 needs_scroll_styles_(false), 358 needs_scroll_styles_(false),
359 in_size_loop_(false), 359 in_size_loop_(false),
360 touch_down_contexts_(0), 360 touch_down_contexts_(0),
361 last_mouse_hwheel_time_(0), 361 last_mouse_hwheel_time_(0),
362 msg_handled_(FALSE) { 362 msg_handled_(FALSE),
363 dwm_transition_desired_(false) {
363 } 364 }
364 365
365 HWNDMessageHandler::~HWNDMessageHandler() { 366 HWNDMessageHandler::~HWNDMessageHandler() {
366 delegate_ = NULL; 367 delegate_ = NULL;
367 // Prevent calls back into this class via WNDPROC now that we've been 368 // Prevent calls back into this class via WNDPROC now that we've been
368 // destroyed. 369 // destroyed.
369 ClearUserData(); 370 ClearUserData();
370 } 371 }
371 372
372 void HWNDMessageHandler::Init(HWND parent, const gfx::Rect& bounds) { 373 void HWNDMessageHandler::Init(HWND parent, const gfx::Rect& bounds) {
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 if (cursor) { 788 if (cursor) {
788 previous_cursor_ = ::SetCursor(cursor); 789 previous_cursor_ = ::SetCursor(cursor);
789 current_cursor_ = cursor; 790 current_cursor_ = cursor;
790 } else if (previous_cursor_) { 791 } else if (previous_cursor_) {
791 ::SetCursor(previous_cursor_); 792 ::SetCursor(previous_cursor_);
792 previous_cursor_ = NULL; 793 previous_cursor_ = NULL;
793 } 794 }
794 } 795 }
795 796
796 void HWNDMessageHandler::FrameTypeChanged() { 797 void HWNDMessageHandler::FrameTypeChanged() {
797 // Called when the frame type could possibly be changing (theme change or 798 if (base::win::GetVersion() < base::win::VERSION_VISTA) {
798 // DWM composition change). 799 // Don't redraw the window here, because we invalidate the window later.
799 UpdateDwmNcRenderingPolicy(); 800 ResetWindowRegion(true, false);
800 801 // The non-client view needs to update too.
801 // Don't redraw the window here, because we need to hide and show the window 802 delegate_->HandleFrameChanged();
802 // which will also trigger a redraw. 803 InvalidateRect(hwnd(), NULL, FALSE);
803 ResetWindowRegion(true, false); 804 } else {
804 805 if (!custom_window_region_ && !delegate_->IsUsingCustomFrame())
805 // The non-client view needs to update too. 806 dwm_transition_desired_ = true;
806 delegate_->HandleFrameChanged(); 807 if (!dwm_transition_desired_ || !fullscreen_handler_->fullscreen())
807 808 PerformDwmTransition();
808 if (IsVisible() && !delegate_->IsUsingCustomFrame()) {
809 // For some reason, we need to hide the window after we change from a custom
810 // frame to a native frame. If we don't, the client area will be filled
811 // with black. This seems to be related to an interaction between DWM and
812 // SetWindowRgn, but the details aren't clear. Additionally, we need to
813 // specify SWP_NOZORDER here, otherwise if you have multiple chrome windows
814 // open they will re-appear with a non-deterministic Z-order.
815 UINT flags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER;
816 SetWindowPos(hwnd(), NULL, 0, 0, 0, 0, flags | SWP_HIDEWINDOW);
817 SetWindowPos(hwnd(), NULL, 0, 0, 0, 0, flags | SWP_SHOWWINDOW);
818 } 809 }
819
820 // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want
821 // to notify our children too, since we can have MDI child windows who need to
822 // update their appearance.
823 EnumChildWindows(hwnd(), &SendDwmCompositionChanged, NULL);
824 } 810 }
825 811
826 void HWNDMessageHandler::SchedulePaintInRect(const gfx::Rect& rect) { 812 void HWNDMessageHandler::SchedulePaintInRect(const gfx::Rect& rect) {
827 if (use_layered_buffer_) { 813 if (use_layered_buffer_) {
828 // We must update the back-buffer immediately, since Windows' handling of 814 // We must update the back-buffer immediately, since Windows' handling of
829 // invalid rects is somewhat mysterious. 815 // invalid rects is somewhat mysterious.
830 invalid_rect_.Union(rect); 816 invalid_rect_.Union(rect);
831 817
832 // In some situations, such as drag and drop, when Windows itself runs a 818 // In some situations, such as drag and drop, when Windows itself runs a
833 // nested message loop our message loop appears to be starved and we don't 819 // nested message loop our message loop appears to be starved and we don't
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 if (!app_icon.isNull()) { 854 if (!app_icon.isNull()) {
869 HICON windows_icon = IconUtil::CreateHICONFromSkBitmap(*app_icon.bitmap()); 855 HICON windows_icon = IconUtil::CreateHICONFromSkBitmap(*app_icon.bitmap());
870 HICON old_icon = reinterpret_cast<HICON>( 856 HICON old_icon = reinterpret_cast<HICON>(
871 SendMessage(hwnd(), WM_SETICON, ICON_BIG, 857 SendMessage(hwnd(), WM_SETICON, ICON_BIG,
872 reinterpret_cast<LPARAM>(windows_icon))); 858 reinterpret_cast<LPARAM>(windows_icon)));
873 if (old_icon) 859 if (old_icon)
874 DestroyIcon(old_icon); 860 DestroyIcon(old_icon);
875 } 861 }
876 } 862 }
877 863
864 void HWNDMessageHandler::SetFullscreen(bool fullscreen) {
865 fullscreen_handler()->SetFullscreen(fullscreen);
866 // If we are out of fullscreen and there was a pending DWM transition for the
867 // window, then go ahead and do it now.
868 if (!fullscreen && dwm_transition_desired_)
869 PerformDwmTransition();
870 }
871
878 //////////////////////////////////////////////////////////////////////////////// 872 ////////////////////////////////////////////////////////////////////////////////
879 // HWNDMessageHandler, InputMethodDelegate implementation: 873 // HWNDMessageHandler, InputMethodDelegate implementation:
880 874
881 void HWNDMessageHandler::DispatchKeyEventPostIME(const ui::KeyEvent& key) { 875 void HWNDMessageHandler::DispatchKeyEventPostIME(const ui::KeyEvent& key) {
882 SetMsgHandled(delegate_->HandleKeyEvent(key)); 876 SetMsgHandled(delegate_->HandleKeyEvent(key));
883 } 877 }
884 878
885 //////////////////////////////////////////////////////////////////////////////// 879 ////////////////////////////////////////////////////////////////////////////////
886 // HWNDMessageHandler, gfx::WindowImpl overrides: 880 // HWNDMessageHandler, gfx::WindowImpl overrides:
887 881
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
1146 DeleteObject(new_region); 1140 DeleteObject(new_region);
1147 } 1141 }
1148 1142
1149 DeleteObject(current_rgn); 1143 DeleteObject(current_rgn);
1150 } 1144 }
1151 1145
1152 void HWNDMessageHandler::UpdateDwmNcRenderingPolicy() { 1146 void HWNDMessageHandler::UpdateDwmNcRenderingPolicy() {
1153 if (base::win::GetVersion() < base::win::VERSION_VISTA) 1147 if (base::win::GetVersion() < base::win::VERSION_VISTA)
1154 return; 1148 return;
1155 1149
1150 if (fullscreen_handler_->fullscreen())
1151 return;
1152
1156 DWMNCRENDERINGPOLICY policy = 1153 DWMNCRENDERINGPOLICY policy =
1157 custom_window_region_ || delegate_->IsUsingCustomFrame() ? 1154 custom_window_region_ || delegate_->IsUsingCustomFrame() ?
1158 DWMNCRP_DISABLED : DWMNCRP_ENABLED; 1155 DWMNCRP_DISABLED : DWMNCRP_ENABLED;
1159 1156
1160 DwmSetWindowAttribute(hwnd(), DWMWA_NCRENDERING_POLICY, 1157 DwmSetWindowAttribute(hwnd(), DWMWA_NCRENDERING_POLICY,
1161 &policy, sizeof(DWMNCRENDERINGPOLICY)); 1158 &policy, sizeof(DWMNCRENDERINGPOLICY));
1162 } 1159 }
1163 1160
1164 LRESULT HWNDMessageHandler::DefWindowProcWithRedrawLock(UINT message, 1161 LRESULT HWNDMessageHandler::DefWindowProcWithRedrawLock(UINT message,
1165 WPARAM w_param, 1162 WPARAM w_param,
(...skipping 1270 matching lines...) Expand 10 before | Expand all | Expand 10 after
2436 ::ClientToScreen(hwnd(), &mouse_location); 2433 ::ClientToScreen(hwnd(), &mouse_location);
2437 POINT cursor_pos = {0}; 2434 POINT cursor_pos = {0};
2438 ::GetCursorPos(&cursor_pos); 2435 ::GetCursorPos(&cursor_pos);
2439 if (memcmp(&cursor_pos, &mouse_location, sizeof(POINT))) 2436 if (memcmp(&cursor_pos, &mouse_location, sizeof(POINT)))
2440 return false; 2437 return false;
2441 return true; 2438 return true;
2442 } 2439 }
2443 return false; 2440 return false;
2444 } 2441 }
2445 2442
2443 void HWNDMessageHandler::PerformDwmTransition() {
2444 dwm_transition_desired_ = false;
2445
2446 UpdateDwmNcRenderingPolicy();
2447 // Don't redraw the window here, because we need to hide and show the window
2448 // which will also trigger a redraw.
2449 ResetWindowRegion(true, false);
2450 // The non-client view needs to update too.
2451 delegate_->HandleFrameChanged();
2452
2453 if (IsVisible() && !delegate_->IsUsingCustomFrame()) {
2454 // For some reason, we need to hide the window after we change from a custom
2455 // frame to a native frame. If we don't, the client area will be filled
2456 // with black. This seems to be related to an interaction between DWM and
2457 // SetWindowRgn, but the details aren't clear. Additionally, we need to
2458 // specify SWP_NOZORDER here, otherwise if you have multiple chrome windows
2459 // open they will re-appear with a non-deterministic Z-order.
2460 UINT flags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER;
2461 SetWindowPos(hwnd(), NULL, 0, 0, 0, 0, flags | SWP_HIDEWINDOW);
2462 SetWindowPos(hwnd(), NULL, 0, 0, 0, 0, flags | SWP_SHOWWINDOW);
2463 }
2464 // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want
2465 // to notify our children too, since we can have MDI child windows who need to
2466 // update their appearance.
2467 EnumChildWindows(hwnd(), &SendDwmCompositionChanged, NULL);
2468 }
2469
2446 } // namespace views 2470 } // 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