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() |