Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3280)

Unified Diff: chrome/browser/ui/views/chrome_views_delegate.cc

Issue 2542533002: Don't check autohide taskbar for WS_EX_TOPMOST when we are querying the autohide state. (Closed)
Patch Set: Added comments Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | ui/views/win/hwnd_message_handler.h » ('j') | ui/views/win/hwnd_message_handler.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/views/chrome_views_delegate.cc
diff --git a/chrome/browser/ui/views/chrome_views_delegate.cc b/chrome/browser/ui/views/chrome_views_delegate.cc
index 3d66274647c07cd4dde40679454665a7c93361e0..7c09713b40a7b34348af42c59441eb7c83587bc2 100644
--- a/chrome/browser/ui/views/chrome_views_delegate.cc
+++ b/chrome/browser/ui/views/chrome_views_delegate.cc
@@ -99,14 +99,14 @@ PrefService* GetPrefsForWindow(const views::Widget* window) {
}
#if defined(OS_WIN)
-bool MonitorHasTopmostAutohideTaskbarForEdge(UINT edge, HMONITOR monitor) {
+bool MonitorHasAutohideTaskbarForEdge(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(
FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "462368 MonitorHasTopmostAutohideTaskbarForEdge"));
+ "462368 MonitorHasAutohideTaskbarForEdge"));
// MSDN documents an ABM_GETAUTOHIDEBAREX, which supposedly takes a monitor
// rect and returns autohide bars on that monitor. This sounds like a good
@@ -139,8 +139,7 @@ bool MonitorHasTopmostAutohideTaskbarForEdge(UINT edge, HMONITOR monitor) {
taskbar = taskbar_data.hWnd;
}
- if (::IsWindow(taskbar) &&
- (GetWindowLong(taskbar, GWL_EXSTYLE) & WS_EX_TOPMOST)) {
+ if (::IsWindow(taskbar)) {
if (MonitorFromWindow(taskbar, MONITOR_DEFAULTTONEAREST) == monitor)
return true;
// In some cases like when the autohide taskbar is on the left of the
@@ -159,13 +158,13 @@ int GetAppbarAutohideEdgesOnWorkerThread(HMONITOR monitor) {
DCHECK(monitor);
int edges = 0;
- if (MonitorHasTopmostAutohideTaskbarForEdge(ABE_LEFT, monitor))
+ if (MonitorHasAutohideTaskbarForEdge(ABE_LEFT, monitor))
edges |= views::ViewsDelegate::EDGE_LEFT;
- if (MonitorHasTopmostAutohideTaskbarForEdge(ABE_TOP, monitor))
+ if (MonitorHasAutohideTaskbarForEdge(ABE_TOP, monitor))
edges |= views::ViewsDelegate::EDGE_TOP;
- if (MonitorHasTopmostAutohideTaskbarForEdge(ABE_RIGHT, monitor))
+ if (MonitorHasAutohideTaskbarForEdge(ABE_RIGHT, monitor))
edges |= views::ViewsDelegate::EDGE_RIGHT;
- if (MonitorHasTopmostAutohideTaskbarForEdge(ABE_BOTTOM, monitor))
+ if (MonitorHasAutohideTaskbarForEdge(ABE_BOTTOM, monitor))
edges |= views::ViewsDelegate::EDGE_BOTTOM;
return edges;
}
@@ -467,6 +466,29 @@ std::string ChromeViewsDelegate::GetApplicationName() {
}
#if defined(OS_WIN)
+// We use the SHAppBarMessage API to get the taskbar autohide state. This API
Peter Kasting 2016/12/02 01:56:41 Perhaps this comment should be moved up to where w
ananta 2016/12/02 06:09:14 Done.
+// spins a modal loop which could cause callers to be reentered. This may not
+// be desirable and to avoid that we retrieve the taskbar state in a worker
+// thread. This fixes the reentrancy problems but introduces subtle timing
+// issues like the one below:
+// 1. A maximized chrome window is fullscreened.
+// 2. It is switched back to maximized.
+// 3. In the process the window gets a WM_NCCACLSIZE message which calls us to
+// get the autohide state.
+// 4. The worker thread is invoked and the main thread is suspended. The worker
Peter Kasting 2016/12/02 01:56:41 Is the main thread always suspended, or is it just
ananta 2016/12/02 06:09:14 The latter.
+// thread calls the API to get the autohide state. The code also checked
+// whether the taskbar was a topmost window. That fails in this case because
+// the main window on the main thread is still in the process of switching
+// away from fullscreen.
+// 5. The main thread resumes and does not leave space for the taskbar and
+// hence it does not popup up when hovered on.
+//
+// To fix point 4 above we removed the check for the WS_EX_TOPMOST style as
+// that is the default on Windows 7+. Additionally we also want to ensure
+// that we query the taskbar state at the point when a window switches fully
+// away from fullscreen. The best time appears to be when we receive the
+// ABN_FULLSCREENAPP notification from the shell. Please refer to the
+// HWNDMessageHandler::OnAppBarMessage() for the code.
int ChromeViewsDelegate::GetAppbarAutohideEdges(HMONITOR monitor,
const base::Closure& callback) {
// Initialize the map with EDGE_BOTTOM. This is important, as if we return an
« no previous file with comments | « no previous file | ui/views/win/hwnd_message_handler.h » ('j') | ui/views/win/hwnd_message_handler.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698