diff options
author | ananta <ananta@chromium.org> | 2015-11-23 13:28:27 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-23 21:29:03 +0000 |
commit | c64c903e110dc5f34a6348eb9b83e15900d96fbf (patch) | |
tree | ad36b31c8619de97ddd520e68aa574f38f0c4d6e | |
parent | 34957445f6f2bf3c8de2f087d4038bf05e27a030 (diff) | |
download | chromium_src-c64c903e110dc5f34a6348eb9b83e15900d96fbf.zip chromium_src-c64c903e110dc5f34a6348eb9b83e15900d96fbf.tar.gz chromium_src-c64c903e110dc5f34a6348eb9b83e15900d96fbf.tar.bz2 |
Fix for a long standing bug in Chrome windows with the auto hide taskbar.
This bug reproduces at times with multiple monitors and occurs when our attempt to
retrieve the taskbar edge information via the ABM_GETAUTOHIDEBAR appbar message fails.
msdn recommends using the ABM_GETAUTOHIDEBAREX call with the monitor rectangle for the multiple
monitor case. However that does not work.
The following fallback does work though.
1. Query for the auto hide status of the taskbar.
2. Retrieve its position and check if the edge information returned in this call matches the
edge we are looking for. This along with the monitor check is sufficient.
BUG=472139
TEST=Set taskbar to autohide. Connect multiple monitors to the machine and start chrome on the
primary monitor and attempt to reproduce this case. If it does not repro then move chrome to
the other monitor and attempt the test case. If that fails, disconnect the secondary monitor
exit chrome and try. One of these cases should reproduce the problem.
Review URL: https://codereview.chromium.org/1462373003
Cr-Commit-Position: refs/heads/master@{#361188}
-rw-r--r-- | chrome/browser/ui/views/chrome_views_delegate.cc | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/chrome/browser/ui/views/chrome_views_delegate.cc b/chrome/browser/ui/views/chrome_views_delegate.cc index f7637f9..b7c33b3 100644 --- a/chrome/browser/ui/views/chrome_views_delegate.cc +++ b/chrome/browser/ui/views/chrome_views_delegate.cc @@ -94,6 +94,7 @@ PrefService* GetPrefsForWindow(const views::Widget* window) { #if defined(OS_WIN) bool MonitorHasTopmostAutohideTaskbarForEdge(UINT edge, HMONITOR monitor) { APPBARDATA taskbar_data = { sizeof(APPBARDATA), NULL, 0, edge }; + taskbar_data.hWnd = ::GetForegroundWindow(); // TODO(robliao): Remove ScopedTracker below once crbug.com/462368 is fixed. tracked_objects::ScopedTracker tracking_profile( @@ -105,12 +106,31 @@ bool MonitorHasTopmostAutohideTaskbarForEdge(UINT edge, HMONITOR monitor) { // idea for multi-monitor systems. Unfortunately, it appears to not work at // least some of the time (erroneously returning NULL) and there's almost no // online documentation or other sample code using it that suggests ways to - // address this problem. So we just use ABM_GETAUTOHIDEBAR and hope the user - // only cares about autohide bars on the monitor with the primary taskbar. - // + // address this problem. We do the following:- + // 1. Use the ABM_GETAUTOHIDEBAR message. If it works, i.e. returns a valid + // window we are done. + // 2. If the ABM_GETAUTOHIDEBAR message does not work we query the auto hide + // state of the taskbar and then retrieve its position. That call returns + // the edge on which the taskbar is present. If it matches the edge we + // are looking for, we are done. // NOTE: This call spins a nested message loop. HWND taskbar = reinterpret_cast<HWND>(SHAppBarMessage(ABM_GETAUTOHIDEBAR, &taskbar_data)); + if (!::IsWindow(taskbar)) { + APPBARDATA taskbar_data = { sizeof(APPBARDATA), 0, 0, 0}; + unsigned int taskbar_state = SHAppBarMessage(ABM_GETSTATE, + &taskbar_data); + if (!(taskbar_state & ABS_AUTOHIDE)) + return false; + + taskbar_data.hWnd = ::FindWindow(L"Shell_TrayWnd", NULL); + if (!::IsWindow(taskbar_data.hWnd)) + return false; + + SHAppBarMessage(ABM_GETTASKBARPOS, &taskbar_data); + if (taskbar_data.uEdge == edge) + taskbar = taskbar_data.hWnd; + } return ::IsWindow(taskbar) && (MonitorFromWindow(taskbar, MONITOR_DEFAULTTONULL) == monitor) && (GetWindowLong(taskbar, GWL_EXSTYLE) & WS_EX_TOPMOST); |