| 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 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 // Records the HWND visibility at the time of creation. | 293 // Records the HWND visibility at the time of creation. |
| 294 bool was_visible_; | 294 bool was_visible_; |
| 295 // A flag indicating that the unlock operation was canceled. | 295 // A flag indicating that the unlock operation was canceled. |
| 296 bool cancel_unlock_; | 296 bool cancel_unlock_; |
| 297 // If true, perform the redraw lock regardless of Aero state. | 297 // If true, perform the redraw lock regardless of Aero state. |
| 298 bool force_; | 298 bool force_; |
| 299 | 299 |
| 300 DISALLOW_COPY_AND_ASSIGN(ScopedRedrawLock); | 300 DISALLOW_COPY_AND_ASSIGN(ScopedRedrawLock); |
| 301 }; | 301 }; |
| 302 | 302 |
| 303 // static HWNDMessageHandler member initialization. |
| 304 base::LazyInstance<HWNDMessageHandler::FullscreenWindowMonitorMap> |
| 305 HWNDMessageHandler::fullscreen_monitor_map_ = LAZY_INSTANCE_INITIALIZER; |
| 306 |
| 303 //////////////////////////////////////////////////////////////////////////////// | 307 //////////////////////////////////////////////////////////////////////////////// |
| 304 // HWNDMessageHandler, public: | 308 // HWNDMessageHandler, public: |
| 305 | 309 |
| 306 long HWNDMessageHandler::last_touch_message_time_ = 0; | 310 long HWNDMessageHandler::last_touch_message_time_ = 0; |
| 307 | 311 |
| 308 HWNDMessageHandler::HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate) | 312 HWNDMessageHandler::HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate) |
| 309 : msg_handled_(FALSE), | 313 : msg_handled_(FALSE), |
| 310 delegate_(delegate), | 314 delegate_(delegate), |
| 311 fullscreen_handler_(new FullscreenHandler), | 315 fullscreen_handler_(new FullscreenHandler), |
| 312 waiting_for_close_now_(false), | 316 waiting_for_close_now_(false), |
| (...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 806 } | 810 } |
| 807 } | 811 } |
| 808 | 812 |
| 809 void HWNDMessageHandler::SetFullscreen(bool fullscreen) { | 813 void HWNDMessageHandler::SetFullscreen(bool fullscreen) { |
| 810 background_fullscreen_hack_ = false; | 814 background_fullscreen_hack_ = false; |
| 811 fullscreen_handler()->SetFullscreen(fullscreen); | 815 fullscreen_handler()->SetFullscreen(fullscreen); |
| 812 // If we are out of fullscreen and there was a pending DWM transition for the | 816 // If we are out of fullscreen and there was a pending DWM transition for the |
| 813 // window, then go ahead and do it now. | 817 // window, then go ahead and do it now. |
| 814 if (!fullscreen && dwm_transition_desired_) | 818 if (!fullscreen && dwm_transition_desired_) |
| 815 PerformDwmTransition(); | 819 PerformDwmTransition(); |
| 820 |
| 821 // Add the fullscreen window to the fullscreen window map which is used to |
| 822 // handle window activations. |
| 823 HMONITOR monitor = MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY); |
| 824 if (fullscreen) { |
| 825 (fullscreen_monitor_map_.Get())[monitor] = this; |
| 826 } else { |
| 827 FullscreenWindowMonitorMap::iterator iter = |
| 828 fullscreen_monitor_map_.Get().find(monitor); |
| 829 if (iter != fullscreen_monitor_map_.Get().end()) |
| 830 fullscreen_monitor_map_.Get().erase(iter); |
| 831 } |
| 816 } | 832 } |
| 817 | 833 |
| 818 void HWNDMessageHandler::SizeConstraintsChanged() { | 834 void HWNDMessageHandler::SizeConstraintsChanged() { |
| 819 LONG style = GetWindowLong(hwnd(), GWL_STYLE); | 835 LONG style = GetWindowLong(hwnd(), GWL_STYLE); |
| 820 // Ignore if this is not a standard window. | 836 // Ignore if this is not a standard window. |
| 821 if (style & (WS_POPUP | WS_CHILD)) | 837 if (style & (WS_POPUP | WS_CHILD)) |
| 822 return; | 838 return; |
| 823 | 839 |
| 824 LONG exstyle = GetWindowLong(hwnd(), GWL_EXSTYLE); | 840 LONG exstyle = GetWindowLong(hwnd(), GWL_EXSTYLE); |
| 825 // Windows cannot have WS_THICKFRAME set if WS_EX_COMPOSITED is set. | 841 // Windows cannot have WS_THICKFRAME set if WS_EX_COMPOSITED is set. |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1014 // If the window losing activation is a fullscreen window, we reduce the size | 1030 // If the window losing activation is a fullscreen window, we reduce the size |
| 1015 // of the window by 1px. i.e. Not fullscreen. This is to work around an | 1031 // of the window by 1px. i.e. Not fullscreen. This is to work around an |
| 1016 // apparent bug in the Windows taskbar where in it tracks fullscreen state on | 1032 // apparent bug in the Windows taskbar where in it tracks fullscreen state on |
| 1017 // a per thread basis. This causes it not be a topmost window when any | 1033 // a per thread basis. This causes it not be a topmost window when any |
| 1018 // maximized window on a thread which has a fullscreen window is active. This | 1034 // maximized window on a thread which has a fullscreen window is active. This |
| 1019 // affects the way these windows interact with the taskbar, they obscure it | 1035 // affects the way these windows interact with the taskbar, they obscure it |
| 1020 // when maximized, autohide does not work correctly, etc. | 1036 // when maximized, autohide does not work correctly, etc. |
| 1021 // By reducing the size of the fullscreen window by 1px, we ensure that the | 1037 // By reducing the size of the fullscreen window by 1px, we ensure that the |
| 1022 // taskbar no longer treats the window and in turn the thread as a fullscreen | 1038 // taskbar no longer treats the window and in turn the thread as a fullscreen |
| 1023 // thread. This in turn ensures that maximized windows on the same thread | 1039 // thread. This in turn ensures that maximized windows on the same thread |
| 1024 /// don't obscure the taskbar, etc. | 1040 // don't obscure the taskbar, etc. |
| 1041 // Please note that this taskbar behavior only occurs if the window becoming |
| 1042 // active is on the same monitor as the fullscreen window. |
| 1025 if (!active) { | 1043 if (!active) { |
| 1026 if (IsFullscreen() && ::IsWindow(window_gaining_or_losing_activation)) { | 1044 if (IsFullscreen() && ::IsWindow(window_gaining_or_losing_activation)) { |
| 1027 // Reduce the bounds of the window by 1px to ensure that Windows does | 1045 HMONITOR active_window_monitor = MonitorFromWindow( |
| 1028 // not treat this like a fullscreen window. | 1046 window_gaining_or_losing_activation, MONITOR_DEFAULTTOPRIMARY); |
| 1029 MONITORINFO monitor_info = {sizeof(monitor_info)}; | 1047 HMONITOR fullscreen_window_monitor = |
| 1030 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), | 1048 MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY); |
| 1031 &monitor_info); | 1049 |
| 1032 gfx::Rect shrunk_rect(monitor_info.rcMonitor); | 1050 if (active_window_monitor == fullscreen_window_monitor) |
| 1033 shrunk_rect.set_height(shrunk_rect.height() - 1); | 1051 OnBackgroundFullscreen(); |
| 1034 background_fullscreen_hack_ = true; | |
| 1035 SetBoundsInternal(shrunk_rect, false); | |
| 1036 } | 1052 } |
| 1037 } else if (background_fullscreen_hack_) { | 1053 } else if (background_fullscreen_hack_) { |
| 1038 // Restore the bounds of the window to fullscreen. | 1054 // Restore the bounds of the window to fullscreen. |
| 1039 DCHECK(IsFullscreen()); | 1055 DCHECK(IsFullscreen()); |
| 1040 MONITORINFO monitor_info = {sizeof(monitor_info)}; | 1056 MONITORINFO monitor_info = {sizeof(monitor_info)}; |
| 1041 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), | 1057 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), |
| 1042 &monitor_info); | 1058 &monitor_info); |
| 1043 SetBoundsInternal(gfx::Rect(monitor_info.rcMonitor), false); | 1059 SetBoundsInternal(gfx::Rect(monitor_info.rcMonitor), false); |
| 1044 background_fullscreen_hack_ = false; | 1060 background_fullscreen_hack_ = false; |
| 1061 } else { |
| 1062 // If the window becoming active has a fullscreen window on the same |
| 1063 // monitor then we need to reduce the size of the fullscreen window by |
| 1064 // 1 px. Please refer to the comments above for the reasoning behind |
| 1065 // this. |
| 1066 CheckAndHandleBackgroundFullscreenOnMonitor( |
| 1067 window_gaining_or_losing_activation); |
| 1045 } | 1068 } |
| 1046 } | 1069 } |
| 1047 | 1070 |
| 1048 void HWNDMessageHandler::RestoreEnabledIfNecessary() { | 1071 void HWNDMessageHandler::RestoreEnabledIfNecessary() { |
| 1049 if (delegate_->IsModal() && !restored_enabled_) { | 1072 if (delegate_->IsModal() && !restored_enabled_) { |
| 1050 restored_enabled_ = true; | 1073 restored_enabled_ = true; |
| 1051 // If we were run modally, we need to undo the disabled-ness we inflicted on | 1074 // If we were run modally, we need to undo the disabled-ness we inflicted on |
| 1052 // the owner's parent hierarchy. | 1075 // the owner's parent hierarchy. |
| 1053 HWND start = ::GetWindow(hwnd(), GW_OWNER); | 1076 HWND start = ::GetWindow(hwnd(), GW_OWNER); |
| 1054 while (start) { | 1077 while (start) { |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1330 base::Bind(&HWNDMessageHandler::OnSessionChange, | 1353 base::Bind(&HWNDMessageHandler::OnSessionChange, |
| 1331 base::Unretained(this)))); | 1354 base::Unretained(this)))); |
| 1332 | 1355 |
| 1333 // TODO(beng): move more of NWW::OnCreate here. | 1356 // TODO(beng): move more of NWW::OnCreate here. |
| 1334 return 0; | 1357 return 0; |
| 1335 } | 1358 } |
| 1336 | 1359 |
| 1337 void HWNDMessageHandler::OnDestroy() { | 1360 void HWNDMessageHandler::OnDestroy() { |
| 1338 windows_session_change_observer_.reset(nullptr); | 1361 windows_session_change_observer_.reset(nullptr); |
| 1339 delegate_->HandleDestroying(); | 1362 delegate_->HandleDestroying(); |
| 1363 // If the window going away is a fullscreen window then remove its references |
| 1364 // from the full screen window map. |
| 1365 for (auto iter = fullscreen_monitor_map_.Get().begin(); |
| 1366 iter != fullscreen_monitor_map_.Get().end(); |
| 1367 iter++) { |
| 1368 if (iter->second == this) { |
| 1369 fullscreen_monitor_map_.Get().erase(iter); |
| 1370 break; |
| 1371 } |
| 1372 } |
| 1340 } | 1373 } |
| 1341 | 1374 |
| 1342 void HWNDMessageHandler::OnDisplayChange(UINT bits_per_pixel, | 1375 void HWNDMessageHandler::OnDisplayChange(UINT bits_per_pixel, |
| 1343 const gfx::Size& screen_size) { | 1376 const gfx::Size& screen_size) { |
| 1344 delegate_->HandleDisplayChange(); | 1377 delegate_->HandleDisplayChange(); |
| 1345 // Force a WM_NCCALCSIZE to occur to ensure that we handle auto hide | 1378 // Force a WM_NCCALCSIZE to occur to ensure that we handle auto hide |
| 1346 // taskbars correctly. | 1379 // taskbars correctly. |
| 1347 SendFrameChanged(); | 1380 SendFrameChanged(); |
| 1348 } | 1381 } |
| 1349 | 1382 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1390 void HWNDMessageHandler::OnExitSizeMove() { | 1423 void HWNDMessageHandler::OnExitSizeMove() { |
| 1391 delegate_->HandleEndWMSizeMove(); | 1424 delegate_->HandleEndWMSizeMove(); |
| 1392 SetMsgHandled(FALSE); | 1425 SetMsgHandled(FALSE); |
| 1393 // Please refer to the notes in the OnSize function for information about | 1426 // Please refer to the notes in the OnSize function for information about |
| 1394 // the scrolling hack. | 1427 // the scrolling hack. |
| 1395 // We hide the Windows scrollbar in the OnEnterSizeMove function. We need | 1428 // We hide the Windows scrollbar in the OnEnterSizeMove function. We need |
| 1396 // to add the scroll styles back to ensure that scrolling works in legacy | 1429 // to add the scroll styles back to ensure that scrolling works in legacy |
| 1397 // trackpoint drivers. | 1430 // trackpoint drivers. |
| 1398 if (in_size_loop_ && needs_scroll_styles_) | 1431 if (in_size_loop_ && needs_scroll_styles_) |
| 1399 AddScrollStylesToWindow(hwnd()); | 1432 AddScrollStylesToWindow(hwnd()); |
| 1433 // If the window was moved to a monitor which has a fullscreen window active, |
| 1434 // we need to reduce the size of the fullscreen window by 1px. |
| 1435 CheckAndHandleBackgroundFullscreenOnMonitor(hwnd()); |
| 1400 } | 1436 } |
| 1401 | 1437 |
| 1402 void HWNDMessageHandler::OnGetMinMaxInfo(MINMAXINFO* minmax_info) { | 1438 void HWNDMessageHandler::OnGetMinMaxInfo(MINMAXINFO* minmax_info) { |
| 1403 gfx::Size min_window_size; | 1439 gfx::Size min_window_size; |
| 1404 gfx::Size max_window_size; | 1440 gfx::Size max_window_size; |
| 1405 delegate_->GetMinMaxSize(&min_window_size, &max_window_size); | 1441 delegate_->GetMinMaxSize(&min_window_size, &max_window_size); |
| 1406 min_window_size = delegate_->DIPToScreenSize(min_window_size); | 1442 min_window_size = delegate_->DIPToScreenSize(min_window_size); |
| 1407 max_window_size = delegate_->DIPToScreenSize(max_window_size); | 1443 max_window_size = delegate_->DIPToScreenSize(max_window_size); |
| 1408 | 1444 |
| 1409 | 1445 |
| (...skipping 1266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2676 if (old_size == bounds_in_pixels.size() && force_size_changed && | 2712 if (old_size == bounds_in_pixels.size() && force_size_changed && |
| 2677 !background_fullscreen_hack_) { | 2713 !background_fullscreen_hack_) { |
| 2678 delegate_->HandleClientSizeChanged(GetClientAreaBounds().size()); | 2714 delegate_->HandleClientSizeChanged(GetClientAreaBounds().size()); |
| 2679 ResetWindowRegion(false, true); | 2715 ResetWindowRegion(false, true); |
| 2680 } | 2716 } |
| 2681 | 2717 |
| 2682 if (direct_manipulation_helper_) | 2718 if (direct_manipulation_helper_) |
| 2683 direct_manipulation_helper_->SetBounds(bounds_in_pixels); | 2719 direct_manipulation_helper_->SetBounds(bounds_in_pixels); |
| 2684 } | 2720 } |
| 2685 | 2721 |
| 2722 void HWNDMessageHandler::CheckAndHandleBackgroundFullscreenOnMonitor( |
| 2723 HWND window) { |
| 2724 HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY); |
| 2725 |
| 2726 FullscreenWindowMonitorMap::iterator iter = |
| 2727 fullscreen_monitor_map_.Get().find(monitor); |
| 2728 if (iter != fullscreen_monitor_map_.Get().end()) { |
| 2729 DCHECK(iter->second); |
| 2730 if (window != iter->second->hwnd()) |
| 2731 iter->second->OnBackgroundFullscreen(); |
| 2732 } |
| 2733 } |
| 2734 |
| 2735 void HWNDMessageHandler::OnBackgroundFullscreen() { |
| 2736 // Reduce the bounds of the window by 1px to ensure that Windows does |
| 2737 // not treat this like a fullscreen window. |
| 2738 MONITORINFO monitor_info = {sizeof(monitor_info)}; |
| 2739 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), |
| 2740 &monitor_info); |
| 2741 gfx::Rect shrunk_rect(monitor_info.rcMonitor); |
| 2742 shrunk_rect.set_height(shrunk_rect.height() - 1); |
| 2743 background_fullscreen_hack_ = true; |
| 2744 SetBoundsInternal(shrunk_rect, false); |
| 2745 } |
| 2686 | 2746 |
| 2687 } // namespace views | 2747 } // namespace views |
| OLD | NEW |