[go: nahoru, domu]

Don't recalculate occlusion for popup window events.

Also, ignore poup windows when computing occlusion. Both these should
reduce the cost of computing occlusion on Windows, especially since
it will reduce the number of calls to IsWindowOnCurrentVirtualDesktop,
which profiling has shown to be expensive.

Bug: 1162132
Change-Id: I665ad477a26d88a1b71174893b6f9ad046a9355f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2611840
Reviewed-by: John Abd-El-Malek <jam@chromium.org>
Commit-Queue: David Bienvenu <davidbienvenu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#840479}
diff --git a/ui/aura/native_window_occlusion_tracker_unittest.cc b/ui/aura/native_window_occlusion_tracker_unittest.cc
index da4af6c..ed94675d 100644
--- a/ui/aura/native_window_occlusion_tracker_unittest.cc
+++ b/ui/aura/native_window_occlusion_tracker_unittest.cc
@@ -52,9 +52,10 @@
 
   TestNativeWindow* native_win() { return native_win_.get(); }
 
-  HWND CreateNativeWindow(DWORD ex_style) {
+  HWND CreateNativeWindow(DWORD style, DWORD ex_style) {
     native_win_ = std::make_unique<TestNativeWindow>();
-    native_win_->set_window_style(WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN);
+    native_win_->set_window_style(WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN |
+                                  style);
     native_win_->set_window_ex_style(ex_style);
     gfx::Rect bounds(0, 0, 100, 100);
     native_win_->Init(nullptr, bounds);
@@ -94,7 +95,7 @@
 };
 
 TEST_F(NativeWindowOcclusionTrackerTest, VisibleOpaqueWindow) {
-  HWND hwnd = CreateNativeWindow(/*ex_style=*/0);
+  HWND hwnd = CreateNativeWindow(/*style=*/0, /*ex_style=*/0);
   gfx::Rect returned_rect;
   // Normal windows should be visible.
   EXPECT_TRUE(CheckWindowVisibleAndFullyOpaque(hwnd, &returned_rect));
@@ -106,7 +107,7 @@
 }
 
 TEST_F(NativeWindowOcclusionTrackerTest, MinimizedWindow) {
-  HWND hwnd = CreateNativeWindow(/*ex_style=*/0);
+  HWND hwnd = CreateNativeWindow(/*style=*/0, /*ex_style=*/0);
   gfx::Rect win_rect;
   ShowWindow(hwnd, SW_MINIMIZE);
   // Minimized windows are not considered visible.
@@ -114,21 +115,21 @@
 }
 
 TEST_F(NativeWindowOcclusionTrackerTest, TransparentWindow) {
-  HWND hwnd = CreateNativeWindow(WS_EX_TRANSPARENT);
+  HWND hwnd = CreateNativeWindow(/*style=*/0, WS_EX_TRANSPARENT);
   gfx::Rect win_rect;
   // Transparent windows are not considered visible and opaque.
   EXPECT_FALSE(CheckWindowVisibleAndFullyOpaque(hwnd, &win_rect));
 }
 
 TEST_F(NativeWindowOcclusionTrackerTest, ToolWindow) {
-  HWND hwnd = CreateNativeWindow(WS_EX_TOOLWINDOW);
+  HWND hwnd = CreateNativeWindow(/*style=*/0, WS_EX_TOOLWINDOW);
   gfx::Rect win_rect;
   // Tool windows are not considered visible and opaque.
   EXPECT_FALSE(CheckWindowVisibleAndFullyOpaque(hwnd, &win_rect));
 }
 
 TEST_F(NativeWindowOcclusionTrackerTest, LayeredAlphaWindow) {
-  HWND hwnd = CreateNativeWindow(WS_EX_LAYERED);
+  HWND hwnd = CreateNativeWindow(/*style=*/0, WS_EX_LAYERED);
   gfx::Rect win_rect;
   BYTE alpha = 1;
   DWORD flags = LWA_ALPHA;
@@ -139,7 +140,7 @@
 }
 
 TEST_F(NativeWindowOcclusionTrackerTest, UpdatedLayeredAlphaWindow) {
-  HWND hwnd = CreateNativeWindow(WS_EX_LAYERED);
+  HWND hwnd = CreateNativeWindow(/*style=*/0, WS_EX_LAYERED);
   gfx::Rect win_rect;
   base::win::ScopedCreateDC hdc(::CreateCompatibleDC(nullptr));
   BLENDFUNCTION blend = {AC_SRC_OVER, 0x00, 0xFF, AC_SRC_ALPHA};
@@ -152,7 +153,7 @@
 }
 
 TEST_F(NativeWindowOcclusionTrackerTest, LayeredNonAlphaWindow) {
-  HWND hwnd = CreateNativeWindow(WS_EX_LAYERED);
+  HWND hwnd = CreateNativeWindow(/*style=*/0, WS_EX_LAYERED);
   gfx::Rect win_rect;
   BYTE alpha = 1;
   DWORD flags = 0;
@@ -163,7 +164,7 @@
 }
 
 TEST_F(NativeWindowOcclusionTrackerTest, ComplexRegionWindow) {
-  HWND hwnd = CreateNativeWindow(/*ex_style=*/0);
+  HWND hwnd = CreateNativeWindow(/*style=*/0, /*ex_style=*/0);
   gfx::Rect win_rect;
   // Create a region with rounded corners, which should be a complex region.
   base::win::ScopedRegion region(CreateRoundRectRgn(1, 1, 100, 100, 5, 5));
@@ -172,11 +173,18 @@
   EXPECT_FALSE(CheckWindowVisibleAndFullyOpaque(hwnd, &win_rect));
 }
 
+TEST_F(NativeWindowOcclusionTrackerTest, PopupWindow) {
+  HWND hwnd = CreateNativeWindow(WS_POPUP, /*ex_style=*/0);
+  gfx::Rect win_rect;
+  // Popup Windows are not considered visible.
+  EXPECT_FALSE(CheckWindowVisibleAndFullyOpaque(hwnd, &win_rect));
+}
+
 TEST_F(NativeWindowOcclusionTrackerTest, CloakedWindow) {
   // Cloaking is only supported in Windows 8 and above.
   if (base::win::GetVersion() < base::win::Version::WIN8)
     return;
-  HWND hwnd = CreateNativeWindow(/*ex_style=*/0);
+  HWND hwnd = CreateNativeWindow(/*style=*/0, /*ex_style=*/0);
   gfx::Rect win_rect;
   BOOL cloak = TRUE;
   DwmSetWindowAttribute(hwnd, DWMWA_CLOAK, &cloak, sizeof(cloak));
diff --git a/ui/aura/native_window_occlusion_tracker_win.cc b/ui/aura/native_window_occlusion_tracker_win.cc
index f96e592..746cb68 100644
--- a/ui/aura/native_window_occlusion_tracker_win.cc
+++ b/ui/aura/native_window_occlusion_tracker_win.cc
@@ -167,7 +167,12 @@
   if (IsIconic(hwnd))
     return false;
 
-  LONG ex_styles = GetWindowLong(hwnd, GWL_EXSTYLE);
+  LONG styles = ::GetWindowLong(hwnd, GWL_STYLE);
+  // Ignore popup windows since they're transient.
+  if (styles & WS_POPUP)
+    return false;
+
+  LONG ex_styles = ::GetWindowLong(hwnd, GWL_EXSTYLE);
   // Filter out "transparent" windows, windows where the mouse clicks fall
   // through them.
   if (ex_styles & WS_EX_TRANSPARENT)
@@ -663,6 +668,10 @@
   if (id_object != OBJID_WINDOW)
     return;
 
+  // We generally ignore events for poup windows, except for when the taskbar
+  // is hidden, in which case we recalculate occlusion.
+  bool calculate_occlusion = !(::GetWindowLong(hwnd, GWL_STYLE) & WS_POPUP);
+
   // Detect if either the alt tab view or the task list thumbnail is being
   // shown. If so, mark all non-hidden windows as occluded, and remember that
   // we're in the showing_thumbnails state. This lasts until we get told that
@@ -691,7 +700,9 @@
     if (hwnd_class_name == "MultitaskingViewFrame" ||
         hwnd_class_name == "TaskListThumbnailWnd") {
       showing_thumbnails_ = false;
-      // Let occlusion calculation fix occlusion state.
+      // Let occlusion calculation fix occlusion state, even though hwnd might
+      // be a popup window.
+      calculate_occlusion = true;
     }
   }
   // Don't continually calculate occlusion while a window is moving (unless it's
@@ -721,6 +732,9 @@
     }
   }
 
+  if (!calculate_occlusion)
+    return;
+
   // ProcessEventHookCallback is called from the task_runner's PeekMessage
   // call, on the task runner's thread, but before the task_tracker thread sets
   // up the thread sequence. In order to prevent DCHECK failures with the
diff --git a/ui/aura/native_window_occlusion_tracker_win.h b/ui/aura/native_window_occlusion_tracker_win.h
index 443089e..4934e8b 100644
--- a/ui/aura/native_window_occlusion_tracker_win.h
+++ b/ui/aura/native_window_occlusion_tracker_win.h
@@ -259,8 +259,8 @@
 
   // Returns true if we are interested in |hwnd| for purposes of occlusion
   // calculation. We are interested in |hwnd| if it is a window that is
-  // visible, opaque, and bounded. If we are interested in |hwnd|, stores the
-  // window rectangle in |window_rect|.
+  // visible, opaque, bounded, and not a popup or floating window. If we are
+  // interested in |hwnd|, stores the window rectangle in |window_rect|.
   static bool IsWindowVisibleAndFullyOpaque(HWND hwnd, gfx::Rect* window_rect);
 
   // Updates root windows occclusion state. If |show_all_windows| is true,