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 f632827ca29663e93365929d151c4c1c5add9d49..0d099c18c0580307be9a41f6bd77fc7119d4a631 100644 |
| --- a/ui/views/win/hwnd_message_handler.cc |
| +++ b/ui/views/win/hwnd_message_handler.cc |
| @@ -333,6 +333,7 @@ HWNDMessageHandler::HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate) |
| dwm_transition_desired_(false), |
| sent_window_size_changing_(false), |
| left_button_down_on_caption_(false), |
| + background_fullscreen_hack_(false), |
| autohide_factory_(this), |
| weak_factory_(this) {} |
| @@ -537,7 +538,8 @@ void HWNDMessageHandler::SetBounds(const gfx::Rect& bounds_in_pixels, |
| // If HWND size is not changed, we will not receive standard size change |
| // notifications. If |force_size_changed| is |true|, we should pretend size is |
| // changed. |
| - if (old_size == bounds_in_pixels.size() && force_size_changed) { |
| + if (old_size == bounds_in_pixels.size() && force_size_changed && |
| + !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
|
| delegate_->HandleClientSizeChanged(GetClientAreaBounds().size()); |
| ResetWindowRegion(false, true); |
| } |
| @@ -844,6 +846,7 @@ void HWNDMessageHandler::SetWindowIcons(const gfx::ImageSkia& window_icon, |
| } |
| void HWNDMessageHandler::SetFullscreen(bool fullscreen) { |
| + set_background_fullscreen_hack(false); |
| fullscreen_handler()->SetFullscreen(fullscreen); |
| // If we are out of fullscreen and there was a pending DWM transition for the |
| // window, then go ahead and do it now. |
| @@ -929,7 +932,8 @@ LRESULT HWNDMessageHandler::OnWndProc(UINT message, |
| } |
| if (message == WM_ACTIVATE && IsTopLevelWindow(window)) |
| - PostProcessActivateMessage(LOWORD(w_param), !!HIWORD(w_param)); |
| + PostProcessActivateMessage(LOWORD(w_param), !!HIWORD(w_param), |
| + reinterpret_cast<HWND>(l_param)); |
| return result; |
| } |
| @@ -1027,12 +1031,52 @@ void HWNDMessageHandler::SetInitialFocus() { |
| } |
| } |
| -void HWNDMessageHandler::PostProcessActivateMessage(int activation_state, |
| - bool minimized) { |
| +void HWNDMessageHandler::PostProcessActivateMessage( |
| + int activation_state, |
| + bool minimized, |
| + HWND window_gaining_or_losing_activation) { |
| DCHECK(IsTopLevelWindow(hwnd())); |
| const bool active = activation_state != WA_INACTIVE && !minimized; |
| if (delegate_->CanActivate()) |
| delegate_->HandleActivationChanged(active); |
| + |
| + if (!::IsWindow(window_gaining_or_losing_activation)) |
| + window_gaining_or_losing_activation = ::GetForegroundWindow(); |
| + |
| + // If the window losing activation is a fullscreen window, we reduce the size |
| + // of the window by 1px. i.e. Not fullscreen. This is to work around an |
| + // apparent bug in the Windows taskbar where in it tracks fullscreen state on |
| + // a per thread basis. This causes it not be a topmost window when any |
| + // maximized window on a thread which has a fullscreen window is active. This |
| + // affects the way these windows interact with the taskbar, they obscure it |
| + // when maximized, autohide does not work correctly, etc. |
| + // 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. |
| + if (!active) { |
| + if (fullscreen_handler_->fullscreen() && |
| + ::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); |
| + set_background_fullscreen_hack(true); |
| + SetBounds(shrunk_rect, false); |
| + } |
| + } else if (background_fullscreen_hack()) { |
| + // Restore the bounds of the window to fullscreen. |
| + DCHECK(fullscreen_handler_->fullscreen()); |
| + set_background_fullscreen_hack(false); |
| + MONITORINFO monitor_info = {sizeof(monitor_info)}; |
| + GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), |
| + &monitor_info); |
| + SetBounds(gfx::Rect(monitor_info.rcMonitor), false); |
| + } |
| + |
| } |
| void HWNDMessageHandler::RestoreEnabledIfNecessary() { |
| @@ -1078,6 +1122,9 @@ void HWNDMessageHandler::TrackMouseEvents(DWORD mouse_tracking_flags) { |
| } |
| void HWNDMessageHandler::ClientAreaSizeChanged() { |
| + // Ignore size changes due to fullscreen windows losing activation. |
| + if (background_fullscreen_hack()) |
| + return; |
| gfx::Size s = GetClientAreaBounds().size(); |
| delegate_->HandleClientSizeChanged(s); |
| } |
| @@ -2167,7 +2214,8 @@ void HWNDMessageHandler::OnWindowPosChanging(WINDOWPOS* window_pos) { |
| (work_area != last_work_area_); |
| if (monitor && (monitor == last_monitor_) && |
| ((fullscreen_handler_->fullscreen() && |
| - !fullscreen_handler_->metro_snap()) || |
| + !fullscreen_handler_->metro_snap() && |
| + !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
|
| work_area_changed)) { |
| // A rect for the monitor we're on changed. Normally Windows notifies |
| // us about this (and thus we're reaching here due to the SetWindowPos() |