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 |