summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorananta <ananta@chromium.org>2015-11-23 13:28:27 -0800
committerCommit bot <commit-bot@chromium.org>2015-11-23 21:29:03 +0000
commitc64c903e110dc5f34a6348eb9b83e15900d96fbf (patch)
treead36b31c8619de97ddd520e68aa574f38f0c4d6e
parent34957445f6f2bf3c8de2f087d4038bf05e27a030 (diff)
downloadchromium_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.cc26
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);