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 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 } | 531 } |
532 | 532 |
533 void HWNDMessageHandler::CenterWindow(const gfx::Size& size) { | 533 void HWNDMessageHandler::CenterWindow(const gfx::Size& size) { |
534 HWND parent = GetParent(hwnd()); | 534 HWND parent = GetParent(hwnd()); |
535 if (!IsWindow(hwnd())) | 535 if (!IsWindow(hwnd())) |
536 parent = ::GetWindow(hwnd(), GW_OWNER); | 536 parent = ::GetWindow(hwnd(), GW_OWNER); |
537 gfx::CenterAndSizeWindow(parent, hwnd(), size); | 537 gfx::CenterAndSizeWindow(parent, hwnd(), size); |
538 } | 538 } |
539 | 539 |
540 void HWNDMessageHandler::SetRegion(HRGN region) { | 540 void HWNDMessageHandler::SetRegion(HRGN region) { |
541 custom_window_region_.Set(region); | 541 custom_window_region_.reset(region); |
542 ResetWindowRegion(true, true); | 542 ResetWindowRegion(true, true); |
543 } | 543 } |
544 | 544 |
545 void HWNDMessageHandler::StackAbove(HWND other_hwnd) { | 545 void HWNDMessageHandler::StackAbove(HWND other_hwnd) { |
546 // Windows API allows to stack behind another windows only. | 546 // Windows API allows to stack behind another windows only. |
547 DCHECK(other_hwnd); | 547 DCHECK(other_hwnd); |
548 HWND next_window = GetNextWindow(other_hwnd, GW_HWNDPREV); | 548 HWND next_window = GetNextWindow(other_hwnd, GW_HWNDPREV); |
549 SetWindowPos(hwnd(), next_window ? next_window : HWND_TOP, 0, 0, 0, 0, | 549 SetWindowPos(hwnd(), next_window ? next_window : HWND_TOP, 0, 0, 0, 0, |
550 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); | 550 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); |
551 } | 551 } |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS | | 723 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS | |
724 SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREPOSITION | | 724 SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREPOSITION | |
725 SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER); | 725 SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER); |
726 } | 726 } |
727 | 727 |
728 void HWNDMessageHandler::FlashFrame(bool flash) { | 728 void HWNDMessageHandler::FlashFrame(bool flash) { |
729 FLASHWINFO fwi; | 729 FLASHWINFO fwi; |
730 fwi.cbSize = sizeof(fwi); | 730 fwi.cbSize = sizeof(fwi); |
731 fwi.hwnd = hwnd(); | 731 fwi.hwnd = hwnd(); |
732 if (flash) { | 732 if (flash) { |
733 fwi.dwFlags = custom_window_region_ ? FLASHW_TRAY : FLASHW_ALL; | 733 fwi.dwFlags = custom_window_region_.is_valid() ? FLASHW_TRAY : FLASHW_ALL; |
734 fwi.uCount = 4; | 734 fwi.uCount = 4; |
735 fwi.dwTimeout = 0; | 735 fwi.dwTimeout = 0; |
736 } else { | 736 } else { |
737 fwi.dwFlags = FLASHW_STOP; | 737 fwi.dwFlags = FLASHW_STOP; |
738 } | 738 } |
739 FlashWindowEx(&fwi); | 739 FlashWindowEx(&fwi); |
740 } | 740 } |
741 | 741 |
742 void HWNDMessageHandler::ClearNativeFocus() { | 742 void HWNDMessageHandler::ClearNativeFocus() { |
743 ::SetFocus(hwnd()); | 743 ::SetFocus(hwnd()); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
791 } | 791 } |
792 | 792 |
793 void HWNDMessageHandler::FrameTypeChanged() { | 793 void HWNDMessageHandler::FrameTypeChanged() { |
794 if (base::win::GetVersion() < base::win::VERSION_VISTA) { | 794 if (base::win::GetVersion() < base::win::VERSION_VISTA) { |
795 // Don't redraw the window here, because we invalidate the window later. | 795 // Don't redraw the window here, because we invalidate the window later. |
796 ResetWindowRegion(true, false); | 796 ResetWindowRegion(true, false); |
797 // The non-client view needs to update too. | 797 // The non-client view needs to update too. |
798 delegate_->HandleFrameChanged(); | 798 delegate_->HandleFrameChanged(); |
799 InvalidateRect(hwnd(), NULL, FALSE); | 799 InvalidateRect(hwnd(), NULL, FALSE); |
800 } else { | 800 } else { |
801 if (!custom_window_region_ && !delegate_->IsUsingCustomFrame()) | 801 if (!custom_window_region_.is_valid() && !delegate_->IsUsingCustomFrame()) |
802 dwm_transition_desired_ = true; | 802 dwm_transition_desired_ = true; |
803 if (!dwm_transition_desired_ || !fullscreen_handler_->fullscreen()) | 803 if (!dwm_transition_desired_ || !fullscreen_handler_->fullscreen()) |
804 PerformDwmTransition(); | 804 PerformDwmTransition(); |
805 } | 805 } |
806 } | 806 } |
807 | 807 |
808 void HWNDMessageHandler::SetWindowIcons(const gfx::ImageSkia& window_icon, | 808 void HWNDMessageHandler::SetWindowIcons(const gfx::ImageSkia& window_icon, |
809 const gfx::ImageSkia& app_icon) { | 809 const gfx::ImageSkia& app_icon) { |
810 if (!window_icon.isNull()) { | 810 if (!window_icon.isNull()) { |
811 HICON windows_icon = IconUtil::CreateHICONFromSkBitmap( | 811 base::win::ScopedHICON previous_icon = window_icon_.Pass(); |
812 *window_icon.bitmap()); | 812 window_icon_.reset( |
813 // We need to make sure to destroy the previous icon, otherwise we'll leak | 813 IconUtil::CreateHICONFromSkBitmap(*window_icon.bitmap())); |
814 // these GDI objects until we crash! | 814 SendMessage(hwnd(), WM_SETICON, ICON_SMALL, |
815 HICON old_icon = reinterpret_cast<HICON>( | 815 reinterpret_cast<LPARAM>(window_icon_.get())); |
816 SendMessage(hwnd(), WM_SETICON, ICON_SMALL, | |
817 reinterpret_cast<LPARAM>(windows_icon))); | |
818 if (old_icon) | |
819 DestroyIcon(old_icon); | |
820 } | 816 } |
821 if (!app_icon.isNull()) { | 817 if (!app_icon.isNull()) { |
822 HICON windows_icon = IconUtil::CreateHICONFromSkBitmap(*app_icon.bitmap()); | 818 base::win::ScopedHICON previous_icon = app_icon_.Pass(); |
823 HICON old_icon = reinterpret_cast<HICON>( | 819 app_icon_.reset(IconUtil::CreateHICONFromSkBitmap(*app_icon.bitmap())); |
824 SendMessage(hwnd(), WM_SETICON, ICON_BIG, | 820 SendMessage(hwnd(), WM_SETICON, ICON_BIG, |
825 reinterpret_cast<LPARAM>(windows_icon))); | 821 reinterpret_cast<LPARAM>(app_icon_.get())); |
826 if (old_icon) | |
827 DestroyIcon(old_icon); | |
828 } | 822 } |
829 } | 823 } |
830 | 824 |
831 void HWNDMessageHandler::SetFullscreen(bool fullscreen) { | 825 void HWNDMessageHandler::SetFullscreen(bool fullscreen) { |
832 fullscreen_handler()->SetFullscreen(fullscreen); | 826 fullscreen_handler()->SetFullscreen(fullscreen); |
833 // If we are out of fullscreen and there was a pending DWM transition for the | 827 // If we are out of fullscreen and there was a pending DWM transition for the |
834 // window, then go ahead and do it now. | 828 // window, then go ahead and do it now. |
835 if (!fullscreen && dwm_transition_desired_) | 829 if (!fullscreen && dwm_transition_desired_) |
836 PerformDwmTransition(); | 830 PerformDwmTransition(); |
837 } | 831 } |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1094 return true; | 1088 return true; |
1095 } | 1089 } |
1096 | 1090 |
1097 void HWNDMessageHandler::ResetWindowRegion(bool force, bool redraw) { | 1091 void HWNDMessageHandler::ResetWindowRegion(bool force, bool redraw) { |
1098 // A native frame uses the native window region, and we don't want to mess | 1092 // A native frame uses the native window region, and we don't want to mess |
1099 // with it. | 1093 // with it. |
1100 // WS_EX_COMPOSITED is used instead of WS_EX_LAYERED under aura. WS_EX_LAYERED | 1094 // WS_EX_COMPOSITED is used instead of WS_EX_LAYERED under aura. WS_EX_LAYERED |
1101 // automatically makes clicks on transparent pixels fall through, that isn't | 1095 // automatically makes clicks on transparent pixels fall through, that isn't |
1102 // the case with WS_EX_COMPOSITED. So, we route WS_EX_COMPOSITED through to | 1096 // the case with WS_EX_COMPOSITED. So, we route WS_EX_COMPOSITED through to |
1103 // the delegate to allow for a custom hit mask. | 1097 // the delegate to allow for a custom hit mask. |
1104 if ((window_ex_style() & WS_EX_COMPOSITED) == 0 && !custom_window_region_ && | 1098 if ((window_ex_style() & WS_EX_COMPOSITED) == 0 && |
| 1099 !custom_window_region_.is_valid() && |
1105 (!delegate_->IsUsingCustomFrame() || !delegate_->IsWidgetWindow())) { | 1100 (!delegate_->IsUsingCustomFrame() || !delegate_->IsWidgetWindow())) { |
1106 if (force) | 1101 if (force) |
1107 SetWindowRgn(hwnd(), NULL, redraw); | 1102 SetWindowRgn(hwnd(), NULL, redraw); |
1108 return; | 1103 return; |
1109 } | 1104 } |
1110 | 1105 |
1111 // Changing the window region is going to force a paint. Only change the | 1106 // Changing the window region is going to force a paint. Only change the |
1112 // window region if the region really differs. | 1107 // window region if the region really differs. |
1113 base::win::ScopedRegion current_rgn(CreateRectRgn(0, 0, 0, 0)); | 1108 base::win::ScopedRegion current_rgn(CreateRectRgn(0, 0, 0, 0)); |
1114 GetWindowRgn(hwnd(), current_rgn); | 1109 GetWindowRgn(hwnd(), current_rgn.get()); |
1115 | 1110 |
1116 RECT window_rect; | 1111 RECT window_rect; |
1117 GetWindowRect(hwnd(), &window_rect); | 1112 GetWindowRect(hwnd(), &window_rect); |
1118 base::win::ScopedRegion new_region; | 1113 base::win::ScopedRegion new_region; |
1119 if (custom_window_region_) { | 1114 if (custom_window_region_.is_valid()) { |
1120 new_region.Set(::CreateRectRgn(0, 0, 0, 0)); | 1115 new_region.reset(CreateRectRgn(0, 0, 0, 0)); |
1121 ::CombineRgn(new_region, custom_window_region_.Get(), NULL, RGN_COPY); | 1116 CombineRgn(new_region.get(), custom_window_region_.get(), NULL, RGN_COPY); |
1122 } else if (IsMaximized()) { | 1117 } else if (IsMaximized()) { |
1123 HMONITOR monitor = MonitorFromWindow(hwnd(), MONITOR_DEFAULTTONEAREST); | 1118 HMONITOR monitor = MonitorFromWindow(hwnd(), MONITOR_DEFAULTTONEAREST); |
1124 MONITORINFO mi; | 1119 MONITORINFO mi; |
1125 mi.cbSize = sizeof mi; | 1120 mi.cbSize = sizeof mi; |
1126 GetMonitorInfo(monitor, &mi); | 1121 GetMonitorInfo(monitor, &mi); |
1127 RECT work_rect = mi.rcWork; | 1122 RECT work_rect = mi.rcWork; |
1128 OffsetRect(&work_rect, -window_rect.left, -window_rect.top); | 1123 OffsetRect(&work_rect, -window_rect.left, -window_rect.top); |
1129 new_region.Set(CreateRectRgnIndirect(&work_rect)); | 1124 new_region.reset(CreateRectRgnIndirect(&work_rect)); |
1130 } else { | 1125 } else { |
1131 gfx::Path window_mask; | 1126 gfx::Path window_mask; |
1132 delegate_->GetWindowMask(gfx::Size(window_rect.right - window_rect.left, | 1127 delegate_->GetWindowMask(gfx::Size(window_rect.right - window_rect.left, |
1133 window_rect.bottom - window_rect.top), | 1128 window_rect.bottom - window_rect.top), |
1134 &window_mask); | 1129 &window_mask); |
1135 if (!window_mask.isEmpty()) | 1130 if (!window_mask.isEmpty()) |
1136 new_region.Set(gfx::CreateHRGNFromSkPath(window_mask)); | 1131 new_region.reset(gfx::CreateHRGNFromSkPath(window_mask)); |
1137 } | 1132 } |
1138 | 1133 |
1139 const bool has_current_region = current_rgn != 0; | 1134 const bool has_current_region = current_rgn != 0; |
1140 const bool has_new_region = new_region != 0; | 1135 const bool has_new_region = new_region != 0; |
1141 if (has_current_region != has_new_region || | 1136 if (has_current_region != has_new_region || |
1142 (has_current_region && !EqualRgn(current_rgn, new_region))) { | 1137 (has_current_region && !EqualRgn(current_rgn.get(), new_region.get()))) { |
1143 // SetWindowRgn takes ownership of the HRGN. | 1138 // SetWindowRgn takes ownership of the HRGN. |
1144 SetWindowRgn(hwnd(), new_region.release(), redraw); | 1139 SetWindowRgn(hwnd(), new_region.release(), redraw); |
1145 } | 1140 } |
1146 } | 1141 } |
1147 | 1142 |
1148 void HWNDMessageHandler::UpdateDwmNcRenderingPolicy() { | 1143 void HWNDMessageHandler::UpdateDwmNcRenderingPolicy() { |
1149 if (base::win::GetVersion() < base::win::VERSION_VISTA) | 1144 if (base::win::GetVersion() < base::win::VERSION_VISTA) |
1150 return; | 1145 return; |
1151 | 1146 |
1152 if (fullscreen_handler_->fullscreen()) | 1147 if (fullscreen_handler_->fullscreen()) |
1153 return; | 1148 return; |
1154 | 1149 |
1155 DWMNCRENDERINGPOLICY policy = | 1150 DWMNCRENDERINGPOLICY policy = |
1156 custom_window_region_ || delegate_->IsUsingCustomFrame() ? | 1151 custom_window_region_.is_valid() || delegate_->IsUsingCustomFrame() |
1157 DWMNCRP_DISABLED : DWMNCRP_ENABLED; | 1152 ? DWMNCRP_DISABLED |
| 1153 : DWMNCRP_ENABLED; |
1158 | 1154 |
1159 DwmSetWindowAttribute(hwnd(), DWMWA_NCRENDERING_POLICY, | 1155 DwmSetWindowAttribute(hwnd(), DWMWA_NCRENDERING_POLICY, |
1160 &policy, sizeof(DWMNCRENDERINGPOLICY)); | 1156 &policy, sizeof(DWMNCRENDERINGPOLICY)); |
1161 } | 1157 } |
1162 | 1158 |
1163 LRESULT HWNDMessageHandler::DefWindowProcWithRedrawLock(UINT message, | 1159 LRESULT HWNDMessageHandler::DefWindowProcWithRedrawLock(UINT message, |
1164 WPARAM w_param, | 1160 WPARAM w_param, |
1165 LPARAM l_param) { | 1161 LPARAM l_param) { |
1166 ScopedRedrawLock lock(this); | 1162 ScopedRedrawLock lock(this); |
1167 // The Widget and HWND can be destroyed in the call to DefWindowProc, so use | 1163 // The Widget and HWND can be destroyed in the call to DefWindowProc, so use |
(...skipping 1292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2460 ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, | 2456 ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, |
2461 0, | 2457 0, |
2462 0, | 2458 0, |
2463 event_time, | 2459 event_time, |
2464 1); | 2460 1); |
2465 | 2461 |
2466 touch_events->push_back(event); | 2462 touch_events->push_back(event); |
2467 } | 2463 } |
2468 | 2464 |
2469 } // namespace views | 2465 } // namespace views |
OLD | NEW |