Commit 614415c6 authored by wutao's avatar wutao Committed by Commit Bot

cros: Handle AlwaysOnTop window in new Overview animations.

This cl handles the correct z-order of visible windows including
AlwaysOnTop windows in the new Overview animations.

Bug: 812497
Test: WindowSelectorTest.HandleAlwaysOnTopWindow
Change-Id: I29dfc6beaa4bf9a5b549a78d9291acd861f17764
Reviewed-on: https://chromium-review.googlesource.com/936453Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Commit-Queue: Tao Wu <wutao@chromium.org>
Cr-Commit-Position: refs/heads/master@{#540390}
parent c4255857
...@@ -492,16 +492,17 @@ WindowSelectorItem* WindowGrid::SelectedWindow() const { ...@@ -492,16 +492,17 @@ WindowSelectorItem* WindowGrid::SelectedWindow() const {
return window_list_[selected_index_].get(); return window_list_[selected_index_].get();
} }
bool WindowGrid::Contains(const aura::Window* window) const { WindowSelectorItem* WindowGrid::GetWindowSelectorItemContaining(
const aura::Window* window) const {
for (const auto& window_item : window_list_) { for (const auto& window_item : window_list_) {
if (window_item->Contains(window)) if (window_item->Contains(window))
return true; return window_item.get();
} }
return false; return nullptr;
} }
void WindowGrid::AddItem(aura::Window* window) { void WindowGrid::AddItem(aura::Window* window) {
DCHECK(!Contains(window)); DCHECK(!GetWindowSelectorItemContaining(window));
window_observer_.Add(window); window_observer_.Add(window);
window_state_observer_.Add(wm::GetWindowState(window)); window_state_observer_.Add(wm::GetWindowState(window));
...@@ -671,8 +672,6 @@ bool WindowGrid::IsNoItemsIndicatorLabelVisibleForTesting() { ...@@ -671,8 +672,6 @@ bool WindowGrid::IsNoItemsIndicatorLabelVisibleForTesting() {
return shield_view_ && shield_view_->IsLabelVisible(); return shield_view_ && shield_view_->IsLabelVisible();
} }
// TODO(https://crbug.com/812497): Handle the correct z-order of always-on-top
// windows.
void WindowGrid::SetWindowListAnimationStates( void WindowGrid::SetWindowListAnimationStates(
WindowSelectorItem* selected_item, WindowSelectorItem* selected_item,
WindowSelector::OverviewTransition transition) { WindowSelector::OverviewTransition transition) {
...@@ -681,14 +680,49 @@ void WindowGrid::SetWindowListAnimationStates( ...@@ -681,14 +680,49 @@ void WindowGrid::SetWindowListAnimationStates(
selected_item == nullptr); selected_item == nullptr);
bool has_covered_available_workspace = false; bool has_covered_available_workspace = false;
// Check the |selected_item| first. The order matters when the |selected_item| bool has_checked_selected_item = false;
// window can cover available workspace. if (!selected_item ||
SetWindowSelectorItemAnimationState(selected_item, !wm::GetWindowState(selected_item->GetWindow())->IsFullscreen()) {
&has_covered_available_workspace, // Check the always on top window first if |selected_item| is nullptr or the
/*selected=*/true, transition); // |selected_item|'s window is not fullscreen. Because always on top windows
// are visible and may have a window which can cover available workspace.
// If the |selected_item| is fullscreen, we will depromote all always on top
// windows.
aura::Window* always_on_top_container =
RootWindowController::ForWindow(root_window_)
->GetContainer(kShellWindowId_AlwaysOnTopContainer);
aura::Window::Windows top_windows = always_on_top_container->children();
for (aura::Window::Windows::const_reverse_iterator
it = top_windows.rbegin(),
rend = top_windows.rend();
it != rend; ++it) {
aura::Window* top_window = *it;
WindowSelectorItem* container_item =
GetWindowSelectorItemContaining(top_window);
if (!container_item)
continue;
const bool is_selected_item = (selected_item == container_item);
if (!has_checked_selected_item && is_selected_item)
has_checked_selected_item = true;
SetWindowSelectorItemAnimationState(
container_item, &has_covered_available_workspace,
/*selected=*/is_selected_item, transition);
}
}
if (!has_checked_selected_item) {
SetWindowSelectorItemAnimationState(selected_item,
&has_covered_available_workspace,
/*selected=*/true, transition);
}
for (const auto& item : window_list_) { for (const auto& item : window_list_) {
// Has checked the |selected_item|.
if (selected_item == item.get()) if (selected_item == item.get())
continue; continue;
// Has checked all always on top windows.
if (item->GetWindow()->GetProperty(aura::client::kAlwaysOnTopKey))
continue;
SetWindowSelectorItemAnimationState(item.get(), SetWindowSelectorItemAnimationState(item.get(),
&has_covered_available_workspace, &has_covered_available_workspace,
/*selected=*/false, transition); /*selected=*/false, transition);
...@@ -951,7 +985,7 @@ void WindowGrid::SetWindowSelectorItemAnimationState( ...@@ -951,7 +985,7 @@ void WindowGrid::SetWindowSelectorItemAnimationState(
aura::Window* window = selector_item->GetWindow(); aura::Window* window = selector_item->GetWindow();
// |selector_item| should be contained in the |window_list_|. // |selector_item| should be contained in the |window_list_|.
DCHECK(Contains(window)); DCHECK(GetWindowSelectorItemContaining(window));
bool can_cover_available_workspace = CanCoverAvailableWorkspace(window); bool can_cover_available_workspace = CanCoverAvailableWorkspace(window);
const bool should_animate = selected || !(*has_covered_available_workspace); const bool should_animate = selected || !(*has_covered_available_workspace);
......
...@@ -91,9 +91,11 @@ class ASH_EXPORT WindowGrid : public aura::WindowObserver, ...@@ -91,9 +91,11 @@ class ASH_EXPORT WindowGrid : public aura::WindowObserver,
// Returns the target selected window, or NULL if there is none selected. // Returns the target selected window, or NULL if there is none selected.
WindowSelectorItem* SelectedWindow() const; WindowSelectorItem* SelectedWindow() const;
// Returns true if a window is contained in any of the WindowSelectorItems // Returns the WindowSelectorItem if a window is contained in any of the
// this grid owns. // WindowSelectorItems this grid owns. Returns nullptr if no such a
bool Contains(const aura::Window* window) const; // WindowSelectorItem exist.
WindowSelectorItem* GetWindowSelectorItemContaining(
const aura::Window* window) const;
// Adds |window| to the grid. Intended to be used by split view. |window| // Adds |window| to the grid. Intended to be used by split view. |window|
// cannot already be on the grid. // cannot already be on the grid.
......
...@@ -509,7 +509,7 @@ WindowGrid* WindowSelector::GetGridWithRootWindow(aura::Window* root_window) { ...@@ -509,7 +509,7 @@ WindowGrid* WindowSelector::GetGridWithRootWindow(aura::Window* root_window) {
void WindowSelector::AddItem(aura::Window* window) { void WindowSelector::AddItem(aura::Window* window) {
// Early exit if a grid already contains |window|. // Early exit if a grid already contains |window|.
WindowGrid* grid = GetGridWithRootWindow(window->GetRootWindow()); WindowGrid* grid = GetGridWithRootWindow(window->GetRootWindow());
if (!grid || grid->Contains(window)) if (!grid || grid->GetWindowSelectorItemContaining(window))
return; return;
// This is meant to be called when a item in split view mode was previously // This is meant to be called when a item in split view mode was previously
...@@ -540,7 +540,7 @@ void WindowSelector::RemoveWindowSelectorItem(WindowSelectorItem* item) { ...@@ -540,7 +540,7 @@ void WindowSelector::RemoveWindowSelectorItem(WindowSelectorItem* item) {
// Remove |item| from the corresponding grid. // Remove |item| from the corresponding grid.
for (std::unique_ptr<WindowGrid>& grid : grid_list_) { for (std::unique_ptr<WindowGrid>& grid : grid_list_) {
if (grid->Contains(item->GetWindow())) { if (grid->GetWindowSelectorItemContaining(item->GetWindow())) {
grid->RemoveItem(item); grid->RemoveItem(item);
if (grid->empty()) if (grid->empty())
OnGridEmpty(grid.get()); OnGridEmpty(grid.get());
......
This diff is collapsed.
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