Chromium Code Reviews| Index: ui/views/win/hwnd_message_handler.cc |
| diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc |
| index e98ba078a14388ae916e5f800cea879623fcc698..777b999d30439e0b4d3dbeefe78a4f90b0f585fe 100644 |
| --- a/ui/views/win/hwnd_message_handler.cc |
| +++ b/ui/views/win/hwnd_message_handler.cc |
| @@ -300,6 +300,12 @@ class HWNDMessageHandler::ScopedRedrawLock { |
| DISALLOW_COPY_AND_ASSIGN(ScopedRedrawLock); |
| }; |
| + |
| +// static HWNDMessageHandler member initialization. |
| +HWNDMessageHandler::FullscreenWindowMonitorMap* |
|
sky
2016/05/13 23:32:36
Use LazyInstance, it's less error prone than what
ananta
2016/05/16 19:56:43
Done.
|
| + HWNDMessageHandler::fullscreen_monitor_map_ = nullptr; |
| +int32_t HWNDMessageHandler::instance_count_ = 0; |
| + |
| //////////////////////////////////////////////////////////////////////////////// |
| // HWNDMessageHandler, public: |
| @@ -338,6 +344,10 @@ HWNDMessageHandler::~HWNDMessageHandler() { |
| // Prevent calls back into this class via WNDPROC now that we've been |
| // destroyed. |
| ClearUserData(); |
| + instance_count_--; |
| + if (!instance_count_) { |
| + delete fullscreen_monitor_map_; |
| + } |
| } |
| void HWNDMessageHandler::Init(HWND parent, const gfx::Rect& bounds) { |
| @@ -383,6 +393,10 @@ void HWNDMessageHandler::Init(HWND parent, const gfx::Rect& bounds) { |
| // Disable pen flicks (http://crbug.com/506977) |
| base::win::DisableFlicks(hwnd()); |
| + |
| + instance_count_++; |
| + if (!fullscreen_monitor_map_) |
| + fullscreen_monitor_map_ = new FullscreenWindowMonitorMap; |
| } |
| void HWNDMessageHandler::InitModalType(ui::ModalType modal_type) { |
| @@ -813,6 +827,16 @@ void HWNDMessageHandler::SetFullscreen(bool fullscreen) { |
| // window, then go ahead and do it now. |
| if (!fullscreen && dwm_transition_desired_) |
| PerformDwmTransition(); |
| + |
| + // Add the fullscreen window to the fullscreen window map which is used to |
| + // handle window activations. |
| + HMONITOR monitor = MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY); |
| + DCHECK(fullscreen_monitor_map_); |
| + if (fullscreen) { |
| + (*fullscreen_monitor_map_)[monitor] = hwnd(); |
| + } else { |
| + fullscreen_monitor_map_->erase(fullscreen_monitor_map_->find(monitor)); |
| + } |
| } |
| void HWNDMessageHandler::SizeConstraintsChanged() { |
| @@ -1021,18 +1045,18 @@ void HWNDMessageHandler::PostProcessActivateMessage( |
| // By reducing the size of the fullscreen window by 1px, we ensure that the |
| // taskbar no longer treats the window and in turn the thread as a fullscreen |
| // thread. This in turn ensures that maximized windows on the same thread |
| - /// don't obscure the taskbar, etc. |
| + // don't obscure the taskbar, etc. |
| + // Please note that this taskbar behavior only occurs if the window becoming |
| + // active is on the same monitor as the fullscreen window. |
| if (!active) { |
| if (IsFullscreen() && ::IsWindow(window_gaining_or_losing_activation)) { |
| - // Reduce the bounds of the window by 1px to ensure that Windows does |
| - // not treat this like a fullscreen window. |
| - MONITORINFO monitor_info = {sizeof(monitor_info)}; |
| - GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), |
| - &monitor_info); |
| - gfx::Rect shrunk_rect(monitor_info.rcMonitor); |
| - shrunk_rect.set_height(shrunk_rect.height() - 1); |
| - background_fullscreen_hack_ = true; |
| - SetBoundsInternal(shrunk_rect, false); |
| + HMONITOR active_window_monitor = MonitorFromWindow( |
| + window_gaining_or_losing_activation, MONITOR_DEFAULTTOPRIMARY); |
| + HMONITOR fullscreen_window_monitor = MonitorFromWindow( |
| + hwnd(), MONITOR_DEFAULTTOPRIMARY); |
| + |
| + if (active_window_monitor == fullscreen_window_monitor) |
| + OnBackgroundFullscreen(0, 0, 0); |
| } |
| } else if (background_fullscreen_hack_) { |
| // Restore the bounds of the window to fullscreen. |
| @@ -1042,6 +1066,13 @@ void HWNDMessageHandler::PostProcessActivateMessage( |
| &monitor_info); |
| SetBoundsInternal(gfx::Rect(monitor_info.rcMonitor), false); |
| background_fullscreen_hack_ = false; |
| + } else { |
| + // If the window becoming active has a fullscreen window on the same |
| + // monitor then we need to reduce the size of the fullscreen window by |
| + // 1 px. Please refer to the comments above for the reasoning behind |
| + // this. |
| + CheckAndHandleBackgroundFullscreenOnMonitor( |
| + window_gaining_or_losing_activation); |
| } |
| } |
| @@ -1337,6 +1368,18 @@ LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) { |
| void HWNDMessageHandler::OnDestroy() { |
| windows_session_change_observer_.reset(nullptr); |
| delegate_->HandleDestroying(); |
| + // If the window going away is a fullscreen window then remove its references |
| + // from the full screen window map. |
| + FullscreenWindowMonitorMap::iterator index; |
| + DCHECK(fullscreen_monitor_map_); |
| + for (index = fullscreen_monitor_map_->begin(); |
| + index != fullscreen_monitor_map_->end(); |
| + index++) { |
| + if (index->second == hwnd()) { |
| + fullscreen_monitor_map_->erase(index); |
| + break; |
| + } |
| + } |
| } |
| void HWNDMessageHandler::OnDisplayChange(UINT bits_per_pixel, |
| @@ -1397,6 +1440,9 @@ void HWNDMessageHandler::OnExitSizeMove() { |
| // trackpoint drivers. |
| if (in_size_loop_ && needs_scroll_styles_) |
| AddScrollStylesToWindow(hwnd()); |
| + // If the window was moved to a monitor which has a fullscreen window active, |
| + // we need to reduce the size of the fullscreen window by 1px. |
| + CheckAndHandleBackgroundFullscreenOnMonitor(hwnd()); |
| } |
| void HWNDMessageHandler::OnGetMinMaxInfo(MINMAXINFO* minmax_info) { |
| @@ -2344,6 +2390,21 @@ void HWNDMessageHandler::OnWindowPosChanged(WINDOWPOS* window_pos) { |
| SetMsgHandled(FALSE); |
| } |
| +LRESULT HWNDMessageHandler::OnBackgroundFullscreen(UINT message, |
| + WPARAM w_param, |
| + LPARAM l_param) { |
| + // Reduce the bounds of the window by 1px to ensure that Windows does |
| + // not treat this like a fullscreen window. |
| + MONITORINFO monitor_info = { sizeof(monitor_info) }; |
| + GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), |
| + &monitor_info); |
| + gfx::Rect shrunk_rect(monitor_info.rcMonitor); |
| + shrunk_rect.set_height(shrunk_rect.height() - 1); |
| + background_fullscreen_hack_ = true; |
| + SetBoundsInternal(shrunk_rect, false); |
| + return 0; |
| +} |
| + |
| void HWNDMessageHandler::OnSessionChange(WPARAM status_code) { |
| // Direct3D presents are ignored while the screen is locked, so force the |
| // window to be redrawn on unlock. |
| @@ -2683,5 +2744,19 @@ void HWNDMessageHandler::SetBoundsInternal(const gfx::Rect& bounds_in_pixels, |
| direct_manipulation_helper_->SetBounds(bounds_in_pixels); |
| } |
| +void HWNDMessageHandler::CheckAndHandleBackgroundFullscreenOnMonitor( |
| + HWND window) { |
| + HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY); |
| + |
| + DCHECK(fullscreen_monitor_map_); |
| + FullscreenWindowMonitorMap::iterator index = fullscreen_monitor_map_->find( |
| + monitor); |
| + if (index != fullscreen_monitor_map_->end() && window != index->second) { |
| + PostMessage(index->second, |
|
sky
2016/05/13 23:32:36
Why bother with the PostMessage? Why not call the
ananta
2016/05/16 19:56:43
The fullscreen window could be a different instanc
ananta
2016/05/16 21:35:42
yeah. done.
|
| + WM_CUSTOM_MESSAGE_HANDLE_BACKGROUND_FULLSCREEN, |
| + 0, |
| + 0); |
| + } |
| +} |
| } // namespace views |