Chromium Code Reviews| 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 #include <tchar.h> | 10 #include <tchar.h> |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 326 is_first_nccalc_(true), | 326 is_first_nccalc_(true), |
| 327 menu_depth_(0), | 327 menu_depth_(0), |
| 328 id_generator_(0), | 328 id_generator_(0), |
| 329 needs_scroll_styles_(false), | 329 needs_scroll_styles_(false), |
| 330 in_size_loop_(false), | 330 in_size_loop_(false), |
| 331 touch_down_contexts_(0), | 331 touch_down_contexts_(0), |
| 332 last_mouse_hwheel_time_(0), | 332 last_mouse_hwheel_time_(0), |
| 333 dwm_transition_desired_(false), | 333 dwm_transition_desired_(false), |
| 334 sent_window_size_changing_(false), | 334 sent_window_size_changing_(false), |
| 335 left_button_down_on_caption_(false), | 335 left_button_down_on_caption_(false), |
| 336 background_fullscreen_hack_(false), | |
| 336 autohide_factory_(this), | 337 autohide_factory_(this), |
| 337 weak_factory_(this) {} | 338 weak_factory_(this) {} |
| 338 | 339 |
| 339 HWNDMessageHandler::~HWNDMessageHandler() { | 340 HWNDMessageHandler::~HWNDMessageHandler() { |
| 340 delegate_ = NULL; | 341 delegate_ = NULL; |
| 341 // Prevent calls back into this class via WNDPROC now that we've been | 342 // Prevent calls back into this class via WNDPROC now that we've been |
| 342 // destroyed. | 343 // destroyed. |
| 343 ClearUserData(); | 344 ClearUserData(); |
| 344 } | 345 } |
| 345 | 346 |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 530 SetWindowLong(hwnd(), GWL_STYLE, style & ~WS_MAXIMIZE); | 531 SetWindowLong(hwnd(), GWL_STYLE, style & ~WS_MAXIMIZE); |
| 531 | 532 |
| 532 gfx::Size old_size = GetClientAreaBounds().size(); | 533 gfx::Size old_size = GetClientAreaBounds().size(); |
| 533 SetWindowPos(hwnd(), NULL, bounds_in_pixels.x(), bounds_in_pixels.y(), | 534 SetWindowPos(hwnd(), NULL, bounds_in_pixels.x(), bounds_in_pixels.y(), |
| 534 bounds_in_pixels.width(), bounds_in_pixels.height(), | 535 bounds_in_pixels.width(), bounds_in_pixels.height(), |
| 535 SWP_NOACTIVATE | SWP_NOZORDER); | 536 SWP_NOACTIVATE | SWP_NOZORDER); |
| 536 | 537 |
| 537 // If HWND size is not changed, we will not receive standard size change | 538 // If HWND size is not changed, we will not receive standard size change |
| 538 // notifications. If |force_size_changed| is |true|, we should pretend size is | 539 // notifications. If |force_size_changed| is |true|, we should pretend size is |
| 539 // changed. | 540 // changed. |
| 540 if (old_size == bounds_in_pixels.size() && force_size_changed) { | 541 if (old_size == bounds_in_pixels.size() && force_size_changed && |
| 542 !background_fullscreen_hack()) { | |
|
sky
2016/02/19 22:30:50
Shouldn't SetBounds() reset background_fullscreen_
ananta
2016/02/19 23:21:26
Done. Added a SetBoundsInternal private function w
| |
| 541 delegate_->HandleClientSizeChanged(GetClientAreaBounds().size()); | 543 delegate_->HandleClientSizeChanged(GetClientAreaBounds().size()); |
| 542 ResetWindowRegion(false, true); | 544 ResetWindowRegion(false, true); |
| 543 } | 545 } |
| 544 | 546 |
| 545 if (direct_manipulation_helper_) | 547 if (direct_manipulation_helper_) |
| 546 direct_manipulation_helper_->SetBounds(bounds_in_pixels); | 548 direct_manipulation_helper_->SetBounds(bounds_in_pixels); |
| 547 } | 549 } |
| 548 | 550 |
| 549 void HWNDMessageHandler::SetSize(const gfx::Size& size) { | 551 void HWNDMessageHandler::SetSize(const gfx::Size& size) { |
| 550 SetWindowPos(hwnd(), NULL, 0, 0, size.width(), size.height(), | 552 SetWindowPos(hwnd(), NULL, 0, 0, size.width(), size.height(), |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 837 } | 839 } |
| 838 if (!app_icon.isNull()) { | 840 if (!app_icon.isNull()) { |
| 839 base::win::ScopedHICON previous_icon = app_icon_.Pass(); | 841 base::win::ScopedHICON previous_icon = app_icon_.Pass(); |
| 840 app_icon_ = IconUtil::CreateHICONFromSkBitmap(*app_icon.bitmap()).Pass(); | 842 app_icon_ = IconUtil::CreateHICONFromSkBitmap(*app_icon.bitmap()).Pass(); |
| 841 SendMessage(hwnd(), WM_SETICON, ICON_BIG, | 843 SendMessage(hwnd(), WM_SETICON, ICON_BIG, |
| 842 reinterpret_cast<LPARAM>(app_icon_.get())); | 844 reinterpret_cast<LPARAM>(app_icon_.get())); |
| 843 } | 845 } |
| 844 } | 846 } |
| 845 | 847 |
| 846 void HWNDMessageHandler::SetFullscreen(bool fullscreen) { | 848 void HWNDMessageHandler::SetFullscreen(bool fullscreen) { |
| 849 set_background_fullscreen_hack(false); | |
| 847 fullscreen_handler()->SetFullscreen(fullscreen); | 850 fullscreen_handler()->SetFullscreen(fullscreen); |
| 848 // If we are out of fullscreen and there was a pending DWM transition for the | 851 // If we are out of fullscreen and there was a pending DWM transition for the |
| 849 // window, then go ahead and do it now. | 852 // window, then go ahead and do it now. |
| 850 if (!fullscreen && dwm_transition_desired_) | 853 if (!fullscreen && dwm_transition_desired_) |
| 851 PerformDwmTransition(); | 854 PerformDwmTransition(); |
| 852 } | 855 } |
| 853 | 856 |
| 854 void HWNDMessageHandler::SizeConstraintsChanged() { | 857 void HWNDMessageHandler::SizeConstraintsChanged() { |
| 855 LONG style = GetWindowLong(hwnd(), GWL_STYLE); | 858 LONG style = GetWindowLong(hwnd(), GWL_STYLE); |
| 856 // Ignore if this is not a standard window. | 859 // Ignore if this is not a standard window. |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 922 return result; | 925 return result; |
| 923 } | 926 } |
| 924 | 927 |
| 925 if (delegate_) { | 928 if (delegate_) { |
| 926 delegate_->PostHandleMSG(message, w_param, l_param); | 929 delegate_->PostHandleMSG(message, w_param, l_param); |
| 927 if (message == WM_NCDESTROY) | 930 if (message == WM_NCDESTROY) |
| 928 delegate_->HandleDestroyed(); | 931 delegate_->HandleDestroyed(); |
| 929 } | 932 } |
| 930 | 933 |
| 931 if (message == WM_ACTIVATE && IsTopLevelWindow(window)) | 934 if (message == WM_ACTIVATE && IsTopLevelWindow(window)) |
| 932 PostProcessActivateMessage(LOWORD(w_param), !!HIWORD(w_param)); | 935 PostProcessActivateMessage(LOWORD(w_param), !!HIWORD(w_param), |
| 936 reinterpret_cast<HWND>(l_param)); | |
| 933 return result; | 937 return result; |
| 934 } | 938 } |
| 935 | 939 |
| 936 LRESULT HWNDMessageHandler::HandleMouseMessage(unsigned int message, | 940 LRESULT HWNDMessageHandler::HandleMouseMessage(unsigned int message, |
| 937 WPARAM w_param, | 941 WPARAM w_param, |
| 938 LPARAM l_param, | 942 LPARAM l_param, |
| 939 bool* handled) { | 943 bool* handled) { |
| 940 // Don't track forwarded mouse messages. We expect the caller to track the | 944 // Don't track forwarded mouse messages. We expect the caller to track the |
| 941 // mouse. | 945 // mouse. |
| 942 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); | 946 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1020 } | 1024 } |
| 1021 | 1025 |
| 1022 void HWNDMessageHandler::SetInitialFocus() { | 1026 void HWNDMessageHandler::SetInitialFocus() { |
| 1023 if (!(GetWindowLong(hwnd(), GWL_EXSTYLE) & WS_EX_TRANSPARENT) && | 1027 if (!(GetWindowLong(hwnd(), GWL_EXSTYLE) & WS_EX_TRANSPARENT) && |
| 1024 !(GetWindowLong(hwnd(), GWL_EXSTYLE) & WS_EX_NOACTIVATE)) { | 1028 !(GetWindowLong(hwnd(), GWL_EXSTYLE) & WS_EX_NOACTIVATE)) { |
| 1025 // The window does not get keyboard messages unless we focus it. | 1029 // The window does not get keyboard messages unless we focus it. |
| 1026 SetFocus(hwnd()); | 1030 SetFocus(hwnd()); |
| 1027 } | 1031 } |
| 1028 } | 1032 } |
| 1029 | 1033 |
| 1030 void HWNDMessageHandler::PostProcessActivateMessage(int activation_state, | 1034 void HWNDMessageHandler::PostProcessActivateMessage( |
| 1031 bool minimized) { | 1035 int activation_state, |
| 1036 bool minimized, | |
| 1037 HWND window_gaining_or_losing_activation) { | |
| 1032 DCHECK(IsTopLevelWindow(hwnd())); | 1038 DCHECK(IsTopLevelWindow(hwnd())); |
| 1033 const bool active = activation_state != WA_INACTIVE && !minimized; | 1039 const bool active = activation_state != WA_INACTIVE && !minimized; |
| 1034 if (delegate_->CanActivate()) | 1040 if (delegate_->CanActivate()) |
| 1035 delegate_->HandleActivationChanged(active); | 1041 delegate_->HandleActivationChanged(active); |
| 1042 | |
| 1043 if (!::IsWindow(window_gaining_or_losing_activation)) | |
| 1044 window_gaining_or_losing_activation = ::GetForegroundWindow(); | |
| 1045 | |
| 1046 // If the window losing activation is a fullscreen window, we reduce the size | |
| 1047 // of the window by 1px. i.e. Not fullscreen. This is to work around an | |
| 1048 // apparent bug in the Windows taskbar where in it tracks fullscreen state on | |
| 1049 // a per thread basis. This causes it not be a topmost window when any | |
| 1050 // maximized window on a thread which has a fullscreen window is active. This | |
| 1051 // affects the way these windows interact with the taskbar, they obscure it | |
| 1052 // when maximized, autohide does not work correctly, etc. | |
| 1053 // By reducing the size of the fullscreen window by 1px, we ensure that the | |
| 1054 // taskbar no longer treats the window and in turn the thread as a fullscreen | |
| 1055 // thread. This in turn ensures that maximized windows on the same thread | |
| 1056 /// don't obscure the taskbar, etc. | |
| 1057 if (!active) { | |
| 1058 if (fullscreen_handler_->fullscreen() && | |
| 1059 ::IsWindow(window_gaining_or_losing_activation)) { | |
| 1060 // Reduce the bounds of the window by 1px to ensure that Windows does | |
| 1061 // not treat this like a fullscreen window. | |
| 1062 MONITORINFO monitor_info = {sizeof(monitor_info)}; | |
| 1063 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), | |
| 1064 &monitor_info); | |
| 1065 gfx::Rect shrunk_rect(monitor_info.rcMonitor); | |
| 1066 shrunk_rect.set_height(shrunk_rect.height() - 1); | |
| 1067 set_background_fullscreen_hack(true); | |
| 1068 SetBounds(shrunk_rect, false); | |
| 1069 } | |
| 1070 } else if (background_fullscreen_hack()) { | |
| 1071 // Restore the bounds of the window to fullscreen. | |
| 1072 DCHECK(fullscreen_handler_->fullscreen()); | |
| 1073 set_background_fullscreen_hack(false); | |
| 1074 MONITORINFO monitor_info = {sizeof(monitor_info)}; | |
| 1075 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), | |
| 1076 &monitor_info); | |
| 1077 SetBounds(gfx::Rect(monitor_info.rcMonitor), false); | |
| 1078 } | |
| 1079 | |
| 1036 } | 1080 } |
| 1037 | 1081 |
| 1038 void HWNDMessageHandler::RestoreEnabledIfNecessary() { | 1082 void HWNDMessageHandler::RestoreEnabledIfNecessary() { |
| 1039 if (delegate_->IsModal() && !restored_enabled_) { | 1083 if (delegate_->IsModal() && !restored_enabled_) { |
| 1040 restored_enabled_ = true; | 1084 restored_enabled_ = true; |
| 1041 // If we were run modally, we need to undo the disabled-ness we inflicted on | 1085 // If we were run modally, we need to undo the disabled-ness we inflicted on |
| 1042 // the owner's parent hierarchy. | 1086 // the owner's parent hierarchy. |
| 1043 HWND start = ::GetWindow(hwnd(), GW_OWNER); | 1087 HWND start = ::GetWindow(hwnd(), GW_OWNER); |
| 1044 while (start) { | 1088 while (start) { |
| 1045 ::EnableWindow(start, TRUE); | 1089 ::EnableWindow(start, TRUE); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1071 tme.hwndTrack = hwnd(); | 1115 tme.hwndTrack = hwnd(); |
| 1072 tme.dwHoverTime = 0; | 1116 tme.dwHoverTime = 0; |
| 1073 TrackMouseEvent(&tme); | 1117 TrackMouseEvent(&tme); |
| 1074 } else if (mouse_tracking_flags != active_mouse_tracking_flags_) { | 1118 } else if (mouse_tracking_flags != active_mouse_tracking_flags_) { |
| 1075 TrackMouseEvents(active_mouse_tracking_flags_ | TME_CANCEL); | 1119 TrackMouseEvents(active_mouse_tracking_flags_ | TME_CANCEL); |
| 1076 TrackMouseEvents(mouse_tracking_flags); | 1120 TrackMouseEvents(mouse_tracking_flags); |
| 1077 } | 1121 } |
| 1078 } | 1122 } |
| 1079 | 1123 |
| 1080 void HWNDMessageHandler::ClientAreaSizeChanged() { | 1124 void HWNDMessageHandler::ClientAreaSizeChanged() { |
| 1125 // Ignore size changes due to fullscreen windows losing activation. | |
| 1126 if (background_fullscreen_hack()) | |
| 1127 return; | |
| 1081 gfx::Size s = GetClientAreaBounds().size(); | 1128 gfx::Size s = GetClientAreaBounds().size(); |
| 1082 delegate_->HandleClientSizeChanged(s); | 1129 delegate_->HandleClientSizeChanged(s); |
| 1083 } | 1130 } |
| 1084 | 1131 |
| 1085 bool HWNDMessageHandler::GetClientAreaInsets(gfx::Insets* insets) const { | 1132 bool HWNDMessageHandler::GetClientAreaInsets(gfx::Insets* insets) const { |
| 1086 if (delegate_->GetClientAreaInsets(insets)) | 1133 if (delegate_->GetClientAreaInsets(insets)) |
| 1087 return true; | 1134 return true; |
| 1088 DCHECK(insets->IsEmpty()); | 1135 DCHECK(insets->IsEmpty()); |
| 1089 | 1136 |
| 1090 // Returning false causes the default handling in OnNCCalcSize() to | 1137 // Returning false causes the default handling in OnNCCalcSize() to |
| (...skipping 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2160 } else if (!GetParent(hwnd())) { | 2207 } else if (!GetParent(hwnd())) { |
| 2161 RECT window_rect; | 2208 RECT window_rect; |
| 2162 HMONITOR monitor; | 2209 HMONITOR monitor; |
| 2163 gfx::Rect monitor_rect, work_area; | 2210 gfx::Rect monitor_rect, work_area; |
| 2164 if (GetWindowRect(hwnd(), &window_rect) && | 2211 if (GetWindowRect(hwnd(), &window_rect) && |
| 2165 GetMonitorAndRects(window_rect, &monitor, &monitor_rect, &work_area)) { | 2212 GetMonitorAndRects(window_rect, &monitor, &monitor_rect, &work_area)) { |
| 2166 bool work_area_changed = (monitor_rect == last_monitor_rect_) && | 2213 bool work_area_changed = (monitor_rect == last_monitor_rect_) && |
| 2167 (work_area != last_work_area_); | 2214 (work_area != last_work_area_); |
| 2168 if (monitor && (monitor == last_monitor_) && | 2215 if (monitor && (monitor == last_monitor_) && |
| 2169 ((fullscreen_handler_->fullscreen() && | 2216 ((fullscreen_handler_->fullscreen() && |
| 2170 !fullscreen_handler_->metro_snap()) || | 2217 !fullscreen_handler_->metro_snap() && |
| 2218 !background_fullscreen_hack()) || | |
|
sky
2016/02/19 22:30:50
Shouldn't this reset background_fullscreen_hack_ i
ananta
2016/02/19 23:21:26
Done. We reset the flag if it is true and the boun
| |
| 2171 work_area_changed)) { | 2219 work_area_changed)) { |
| 2172 // A rect for the monitor we're on changed. Normally Windows notifies | 2220 // A rect for the monitor we're on changed. Normally Windows notifies |
| 2173 // us about this (and thus we're reaching here due to the SetWindowPos() | 2221 // us about this (and thus we're reaching here due to the SetWindowPos() |
| 2174 // call in OnSettingChange() above), but with some software (e.g. | 2222 // call in OnSettingChange() above), but with some software (e.g. |
| 2175 // nVidia's nView desktop manager) the work area can change asynchronous | 2223 // nVidia's nView desktop manager) the work area can change asynchronous |
| 2176 // to any notification, and we're just sent a SetWindowPos() call with a | 2224 // to any notification, and we're just sent a SetWindowPos() call with a |
| 2177 // new (frequently incorrect) position/size. In either case, the best | 2225 // new (frequently incorrect) position/size. In either case, the best |
| 2178 // response is to throw away the existing position/size information in | 2226 // response is to throw away the existing position/size information in |
| 2179 // |window_pos| and recalculate it based on the new work rect. | 2227 // |window_pos| and recalculate it based on the new work rect. |
| 2180 gfx::Rect new_window_rect; | 2228 gfx::Rect new_window_rect; |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2570 | 2618 |
| 2571 default: | 2619 default: |
| 2572 left_button_down_on_caption_ = false; | 2620 left_button_down_on_caption_ = false; |
| 2573 break; | 2621 break; |
| 2574 } | 2622 } |
| 2575 return handled; | 2623 return handled; |
| 2576 } | 2624 } |
| 2577 | 2625 |
| 2578 | 2626 |
| 2579 } // namespace views | 2627 } // namespace views |
| OLD | NEW |