Commit eb02603b authored by Ahmed Fakhry's avatar Ahmed Fakhry Committed by Commit Bot

Occlusion Tracker: Fix occlusion state of forced-visible descendants of hidden windows

This CL fixes a bug in which a forced-visible window that is a descendant
of a hidden window used to be considered occluded along with its descendants.
This causes problems with virtual desks, since a browser window may be
forced visible (while projecting), but the desk it resides on is switched,
hence its container is hidden.
In this case, the browser window, as well as its descendants should be
considered visible from an occlusion stand point.

BUG=998214
TEST=Added a new test

Change-Id: I7031f16f4fbfd6e86228670f5d58ef1ac135eab1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1810104Reviewed-by: default avatarScott Violet <sky@chromium.org>
Commit-Queue: Ahmed Fakhry <afakhry@chromium.org>
Cr-Commit-Position: refs/heads/master@{#697826}
parent 1662bf88
...@@ -485,8 +485,10 @@ void WindowOcclusionTracker::SetWindowAndDescendantsAreOccluded( ...@@ -485,8 +485,10 @@ void WindowOcclusionTracker::SetWindowAndDescendantsAreOccluded(
Window* window, Window* window,
bool is_occluded, bool is_occluded,
bool is_parent_visible) { bool is_parent_visible) {
const bool is_visible = WindowIsForcedVisible(window) || const bool force_visible = WindowIsForcedVisible(window);
(is_parent_visible && window->layer()->visible()); const bool is_visible =
force_visible || (is_parent_visible && window->layer()->visible());
is_occluded = is_occluded && !force_visible;
SetOccluded(window, is_occluded, is_visible, SkRegion()); SetOccluded(window, is_occluded, is_visible, SkRegion());
for (Window* child_window : window->children()) for (Window* child_window : window->children())
SetWindowAndDescendantsAreOccluded(child_window, is_occluded, is_visible); SetWindowAndDescendantsAreOccluded(child_window, is_occluded, is_visible);
......
...@@ -2267,6 +2267,50 @@ TEST_F(WindowOcclusionTrackerTest, ScopedForceVisibleWithOccludedSibling) { ...@@ -2267,6 +2267,50 @@ TEST_F(WindowOcclusionTrackerTest, ScopedForceVisibleWithOccludedSibling) {
parent_window->Show(); parent_window->Show();
} }
// Simulates a scenario in which a browser window is forced visible (e.g. while
// projecting) and its parent container (e.g. a virtual desks container) was
// hidden. Verifies that the browser window and its descendants remain visible
// from an occlusion stand point.
TEST_F(WindowOcclusionTrackerTest, ScopedForceVisibleHiddenContainer) {
std::unique_ptr<WindowOcclusionTracker::ScopedPause>
pause_occlusion_tracking =
std::make_unique<WindowOcclusionTracker::ScopedPause>();
MockWindowDelegate* root_delegate = new MockWindowDelegate();
Window* root = CreateTrackedWindow(root_delegate, gfx::Rect(0, 0, 100, 100));
MockWindowDelegate* container_delegate = new MockWindowDelegate();
Window* container =
CreateTrackedWindow(container_delegate, gfx::Rect(0, 0, 100, 100), root);
MockWindowDelegate* browser_delegate = new MockWindowDelegate();
Window* browser =
CreateTrackedWindow(browser_delegate, gfx::Rect(0, 0, 10, 10), container);
MockWindowDelegate* webcontents_delegate = new MockWindowDelegate();
Window* webcontents = CreateTrackedWindow(webcontents_delegate,
gfx::Rect(0, 0, 10, 10), browser);
root_delegate->set_expectation(Window::OcclusionState::VISIBLE);
container_delegate->set_expectation(Window::OcclusionState::VISIBLE);
browser_delegate->set_expectation(Window::OcclusionState::VISIBLE);
webcontents_delegate->set_expectation(Window::OcclusionState::VISIBLE);
pause_occlusion_tracking.reset();
EXPECT_FALSE(root_delegate->is_expecting_call());
EXPECT_FALSE(container_delegate->is_expecting_call());
EXPECT_FALSE(browser_delegate->is_expecting_call());
EXPECT_FALSE(webcontents_delegate->is_expecting_call());
WindowOcclusionTracker::ScopedForceVisible force_visible(browser);
container_delegate->set_expectation(Window::OcclusionState::HIDDEN);
container->Hide();
EXPECT_FALSE(root_delegate->is_expecting_call());
EXPECT_FALSE(container_delegate->is_expecting_call());
EXPECT_FALSE(browser_delegate->is_expecting_call());
EXPECT_FALSE(webcontents_delegate->is_expecting_call());
EXPECT_EQ(Window::OcclusionState::VISIBLE, webcontents->occlusion_state());
EXPECT_TRUE(webcontents->TargetVisibility());
container_delegate->set_expectation(Window::OcclusionState::VISIBLE);
container->Show();
}
TEST_F(WindowOcclusionTrackerTest, ComputeTargetOcclusionForWindow) { TEST_F(WindowOcclusionTrackerTest, ComputeTargetOcclusionForWindow) {
auto* window_a = CreateUntrackedWindow(gfx::Rect(0, 0, 10, 10)); auto* window_a = CreateUntrackedWindow(gfx::Rect(0, 0, 10, 10));
CreateUntrackedWindow(gfx::Rect(9, 9, 5, 5)); CreateUntrackedWindow(gfx::Rect(9, 9, 5, 5));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment