Commit 3308bfd8 authored by Sammie Quon's avatar Sammie Quon Committed by Commit Bot

overview: Hide status bubble.

Its really hard to see, and almost impossible to read when shrunk. But
animating the transform/opacity will add extra animations for most
overview operations.

This call is a no-op because we now suspend shelf changes until overview
mode is animated in/out. The calls in workspace manager handled updating
the shelf even without the suspend changes, so this was not needed for a
 while.

Test: none
Bug: 946780, 914147
Change-Id: Ica1c61ea5ae408addd401a9e797fcf4c5aa5003c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1544231
Commit-Queue: Sammie Quon <sammiequon@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#649218}
parent 67cb9c0e
......@@ -1888,6 +1888,7 @@ test("ash_unittests") {
"wm/window_positioner_unittest.cc",
"wm/window_preview_view_unittest.cc",
"wm/window_state_unittest.cc",
"wm/window_transient_descendant_iterator_unittest.cc",
"wm/window_util_unittest.cc",
"wm/wm_toplevel_window_event_handler_unittest.cc",
"wm/workspace/magnetism_matcher_unittest.cc",
......
......@@ -76,6 +76,9 @@ void RegisterWindowProperties(aura::PropertyConverter* property_converter) {
aura::client::kGestureDragFromClientAreaTopMovesWindow,
mojom::kGestureDragFromClientAreaTopMovesWindow_Property,
aura::PropertyConverter::CreateAcceptAnyValueCallback());
property_converter->RegisterPrimitiveProperty(
kHideInOverviewKey, mojom::kHideInOverview_Property,
aura::PropertyConverter::CreateAcceptAnyValueCallback());
property_converter->RegisterPrimitiveProperty(
kHideShelfWhenFullscreenKey, mojom::kHideShelfWhenFullscreen_Property,
aura::PropertyConverter::CreateAcceptAnyValueCallback());
......
......@@ -23,6 +23,9 @@ const string kCanAttachToAnotherWindow_Property =
const string kCanConsumeSystemKeys_Property =
"ash:can-consume-system-keys";
// True if the window should be hidden in ash overview mode. Type: bool.
const string kHideInOverview_Property = "ash:hide_in_overview";
// True if the shelf should be hidden when this window is put into fullscreen.
// Exposed because some windows want to explicitly opt-out of this.
const string kHideShelfWhenFullscreen_Property =
......
......@@ -9,7 +9,6 @@
#include "ash/public/cpp/ash_features.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/public/cpp/window_properties.h"
#include "ash/scoped_animation_disabler.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
......@@ -116,7 +115,6 @@ OverviewItem::OverviewItem(aura::Window* window,
wm::WindowTransientDescendantIterator(GetWindow()))) {
window_iter->AddObserver(this);
}
GetWindow()->SetProperty(ash::kIsShowingInOverviewKey, true);
}
OverviewItem::~OverviewItem() {
......@@ -124,7 +122,6 @@ OverviewItem::~OverviewItem() {
wm::WindowTransientDescendantIterator(GetWindow()))) {
window_iter->RemoveObserver(this);
}
GetWindow()->ClearProperty(ash::kIsShowingInOverviewKey);
}
aura::Window* OverviewItem::GetWindow() {
......
......@@ -58,12 +58,6 @@ constexpr SkColor kNoItemsIndicatorBackgroundColor =
SkColorSetA(SK_ColorBLACK, 204);
constexpr SkColor kNoItemsIndicatorTextColor = SK_ColorWHITE;
// Triggers a shelf visibility update on all root window controllers.
void UpdateShelfVisibility() {
for (aura::Window* root : Shell::GetAllRootWindows())
Shelf::ForWindow(root)->UpdateVisibilityState();
}
// Returns the bounds for the overview window grid according to the split view
// state. If split view mode is active, the overview window should open on the
// opposite side of the default snap window. If |divider_changed| is true, maybe
......@@ -185,8 +179,8 @@ void OverviewSession::Init(const WindowList& windows,
const WindowList& hide_windows) {
Shell::Get()->AddShellObserver(this);
hide_overview_windows_ =
std::make_unique<ScopedOverviewHideWindows>(std::move(hide_windows));
hide_overview_windows_ = std::make_unique<ScopedOverviewHideWindows>(
std::move(hide_windows), /*force_hidden=*/false);
if (restore_focus_window_)
restore_focus_window_->AddObserver(this);
......@@ -280,8 +274,6 @@ void OverviewSession::Init(const WindowList& windows,
Shell::Get()->accessibility_controller()->TriggerAccessibilityAlert(
mojom::AccessibilityAlert::WINDOW_OVERVIEW_MODE_ENTERED);
UpdateShelfVisibility();
ignore_activations_ = false;
}
......@@ -335,7 +327,6 @@ void OverviewSession::Shutdown() {
base::Time::Now() - overview_start_time_);
grid_list_.clear();
UpdateShelfVisibility();
if (no_windows_widget_) {
// Fade out the no windows widget. This animation continues past the
......
......@@ -231,10 +231,19 @@ std::unique_ptr<views::Widget> CreateBackgroundWidget(aura::Window* root_window,
return widget;
}
wm::WindowTransientDescendantIteratorRange GetVisibleTransientTreeIterator(
aura::Window* window) {
auto hide_predicate = [](aura::Window* window) {
return !window->IsVisible();
};
return wm::GetTransientTreeIterator(window,
base::BindRepeating(hide_predicate));
}
gfx::RectF GetTransformedBounds(aura::Window* transformed_window,
int top_inset) {
gfx::RectF bounds;
for (auto* window : wm::GetTransientTreeIterator(transformed_window)) {
for (auto* window : GetVisibleTransientTreeIterator(transformed_window)) {
// Ignore other window types when computing bounding box of overview target
// item.
if (window != transformed_window &&
......@@ -264,7 +273,7 @@ gfx::RectF GetTransformedBounds(aura::Window* transformed_window,
gfx::RectF GetTargetBoundsInScreen(aura::Window* window) {
gfx::RectF bounds;
for (auto* window_iter : wm::GetTransientTreeIterator(window)) {
for (auto* window_iter : GetVisibleTransientTreeIterator(window)) {
// Ignore other window types when computing bounding box of overview target
// item.
if (window_iter != window &&
......@@ -280,7 +289,7 @@ gfx::RectF GetTargetBoundsInScreen(aura::Window* window) {
void SetTransform(aura::Window* window, const gfx::Transform& transform) {
gfx::PointF target_origin(GetTargetBoundsInScreen(window).origin());
for (auto* window_iter : wm::GetTransientTreeIterator(window)) {
for (auto* window_iter : GetVisibleTransientTreeIterator(window)) {
aura::Window* parent_window = window_iter->parent();
gfx::RectF original_bounds(window_iter->GetTargetBounds());
::wm::TranslateRectToScreen(parent_window, &original_bounds);
......
......@@ -9,6 +9,7 @@
#include "ash/ash_export.h"
#include "ash/wm/overview/overview_animation_type.h"
#include "ash/wm/window_transient_descendant_iterator.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/compositor/layer_type.h"
#include "ui/gfx/geometry/rect.h"
......@@ -61,6 +62,11 @@ std::unique_ptr<views::Widget> CreateBackgroundWidget(aura::Window* root_window,
bool stack_on_top,
bool accept_events);
// Iterates through all the windows in the transient tree associated with
// |window| that are visible.
wm::WindowTransientDescendantIteratorRange GetVisibleTransientTreeIterator(
aura::Window* window);
// Calculates the bounds of the |transformed_window|. Those bounds are a union
// of all regular (normal and panel) windows in the |transformed_window|'s
// transient hierarchy. The returned Rect is in virtual screen coordinates. The
......@@ -76,7 +82,8 @@ gfx::RectF GetTargetBoundsInScreen(aura::Window* window);
// Applies the |transform| to |window| and all of its transient children. Note
// |transform| is the transform that is applied to |window| and needs to be
// adjusted for the transient child windows.
void SetTransform(aura::Window* window, const gfx::Transform& transform);
ASH_EXPORT void SetTransform(aura::Window* window,
const gfx::Transform& transform);
// Checks if we are currently in sliding up on the shelf to hide overview mode.
bool IsSlidingOutOverviewFromShelf();
......
......@@ -10,7 +10,9 @@
namespace ash {
ScopedOverviewHideWindows::ScopedOverviewHideWindows(
const std::vector<aura::Window*>& windows) {
const std::vector<aura::Window*>& windows,
bool force_hidden)
: force_hidden_(force_hidden) {
for (auto* window : windows) {
window->AddObserver(this);
window_visibility_.emplace(window, window->IsVisible());
......@@ -29,14 +31,24 @@ ScopedOverviewHideWindows::~ScopedOverviewHideWindows() {
void ScopedOverviewHideWindows::OnWindowDestroying(aura::Window* window) {
window_visibility_.erase(window);
window->RemoveObserver(this);
}
void ScopedOverviewHideWindows::OnWindowVisibilityChanged(aura::Window* window,
bool visible) {
// It's expected that windows hidden in overview should not make them visible
// without exiting overview.
if (visible)
if (!visible)
return;
// It's expected that windows hidden in overview, unless they are forcefully
// hidden should not be shown while in overview.
if (!force_hidden_)
NOTREACHED();
// Do not let |window| change to visible during the lifetime of |this|. Also
// update |window_visibility_| so that we can restore the window visibility
// correctly.
window->Hide();
window_visibility_[window] = true;
}
} // namespace ash
......@@ -22,8 +22,11 @@ namespace ash {
// remembers their visibility and recovers the visibility after overview mode.
class ASH_EXPORT ScopedOverviewHideWindows : public aura::WindowObserver {
public:
// |windows| the list of windows to hide in overview mode.
explicit ScopedOverviewHideWindows(const std::vector<aura::Window*>& windows);
// |windows| the list of windows to hide in overview mode. If |force_hidden|
// is true, the hidden windows may have their visibility altered during
// overview, but we want to keep them hidden.
ScopedOverviewHideWindows(const std::vector<aura::Window*>& windows,
bool force_hidden);
~ScopedOverviewHideWindows() override;
// aura::WindowObserver:
......@@ -32,6 +35,8 @@ class ASH_EXPORT ScopedOverviewHideWindows : public aura::WindowObserver {
private:
std::map<aura::Window*, bool> window_visibility_;
bool force_hidden_;
DISALLOW_COPY_AND_ASSIGN(ScopedOverviewHideWindows);
};
......
......@@ -5,6 +5,7 @@
#include "ash/wm/overview/scoped_overview_transform_window.h"
#include <algorithm>
#include <utility>
#include "ash/public/cpp/ash_features.h"
#include "ash/public/cpp/window_properties.h"
......@@ -179,9 +180,27 @@ ScopedOverviewTransformWindow::ScopedOverviewTransformWindow(
type_ = GetWindowDimensionsType(window);
original_event_targeting_policy_ = window_->event_targeting_policy();
window_->SetEventTargetingPolicy(ws::mojom::EventTargetingPolicy::NONE);
window_->SetProperty(kIsShowingInOverviewKey, true);
// Hide transient children which have been specified to be hidden in overview
// mode.
std::vector<aura::Window*> transient_children_to_hide;
for (auto* transient : wm::GetTransientTreeIterator(window)) {
if (transient == window)
continue;
if (transient->GetProperty(kHideInOverviewKey))
transient_children_to_hide.push_back(transient);
}
if (!transient_children_to_hide.empty()) {
hidden_transient_children_ = std::make_unique<ScopedOverviewHideWindows>(
std::move(transient_children_to_hide), /*forced_hidden=*/true);
}
}
ScopedOverviewTransformWindow::~ScopedOverviewTransformWindow() {
window_->ClearProperty(ash::kIsShowingInOverviewKey);
window_->SetEventTargetingPolicy(original_event_targeting_policy_);
UpdateMask(/*show=*/false);
StopObservingImplicitAnimations();
......@@ -253,7 +272,7 @@ void ScopedOverviewTransformWindow::BeginScopedAnimation(
if (animation_type == OVERVIEW_ANIMATION_NONE)
return;
for (auto* window : wm::GetTransientTreeIterator(GetOverviewWindow())) {
for (auto* window : GetVisibleTransientTreeIterator(GetOverviewWindow())) {
auto settings = std::make_unique<ScopedOverviewAnimationSettings>(
animation_type, window);
settings->DeferPaint();
......@@ -295,7 +314,7 @@ int ScopedOverviewTransformWindow::GetTopInset() const {
// Mirror window doesn't have insets.
if (minimized_widget_)
return 0;
for (auto* window : wm::GetTransientTreeIterator(window_)) {
for (auto* window : GetVisibleTransientTreeIterator(window_)) {
// If there are regular windows in the transient ancestor tree, all those
// windows are shown in the same overview item and the header is not masked.
if (window != window_ &&
......@@ -311,7 +330,7 @@ void ScopedOverviewTransformWindow::OnWindowDestroyed() {
}
void ScopedOverviewTransformWindow::SetOpacity(float opacity) {
for (auto* window : wm::GetTransientTreeIterator(GetOverviewWindow()))
for (auto* window : GetVisibleTransientTreeIterator(GetOverviewWindow()))
window->layer()->SetOpacity(opacity);
}
......@@ -412,7 +431,7 @@ void ScopedOverviewTransformWindow::PrepareForOverview() {
// enter animation and the whole time during overview mode. For the exit
// animation of overview mode, we need to add those requests again.
if (features::IsTrilinearFilteringEnabled()) {
for (auto* window : wm::GetTransientTreeIterator(GetOverviewWindow())) {
for (auto* window : GetVisibleTransientTreeIterator(GetOverviewWindow())) {
cached_and_filtered_layer_observers_.push_back(
std::make_unique<LayerCachingAndFilteringObserver>(window->layer()));
}
......
......@@ -34,9 +34,9 @@ class Widget;
}
namespace ash {
class ScopedOverviewAnimationSettings;
class OverviewItem;
class ScopedOverviewAnimationSettings;
class ScopedOverviewHideWindows;
// Manages a window, and its transient children, in the overview mode. This
// class allows transforming the windows with a helper to determine the best
......@@ -238,6 +238,8 @@ class ASH_EXPORT ScopedOverviewTransformWindow
// The original mask layer of the window before entering overview mode.
ui::Layer* original_mask_layer_ = nullptr;
std::unique_ptr<ScopedOverviewHideWindows> hidden_transient_children_;
base::WeakPtrFactory<ScopedOverviewTransformWindow> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ScopedOverviewTransformWindow);
......
......@@ -5,13 +5,16 @@
#include "ash/wm/overview/scoped_overview_transform_window.h"
#include "ash/public/cpp/ash_features.h"
#include "ash/public/cpp/window_properties.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/overview/overview_utils.h"
#include "ash/wm/window_state.h"
#include "base/test/scoped_feature_list.h"
#include "ui/aura/window.h"
#include "ui/display/display.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/screen.h"
#include "ui/wm/core/window_util.h"
namespace ash {
......@@ -247,6 +250,40 @@ TEST_F(ScopedOverviewTransformWindowTest, ExtremeWindowBounds) {
EXPECT_EQ(GridWindowFillMode::kNormal, scoped_normal.type());
}
// Tests that transients which should be invisible in overview do not have their
// transforms or opacities altered.
TEST_F(ScopedOverviewTransformWindowTest, InvisibleTransients) {
auto window = CreateTestWindow(gfx::Rect(200, 200));
auto child = CreateTestWindow(gfx::Rect(100, 190, 100, 10),
aura::client::WINDOW_TYPE_POPUP);
auto child2 = CreateTestWindow(gfx::Rect(0, 190, 100, 10),
aura::client::WINDOW_TYPE_POPUP);
::wm::AddTransientChild(window.get(), child.get());
::wm::AddTransientChild(window.get(), child2.get());
child2->SetProperty(kHideInOverviewKey, true);
for (auto* it : {window.get(), child.get(), child2.get()}) {
it->SetTransform(gfx::Transform());
it->layer()->SetOpacity(1.f);
}
ScopedOverviewTransformWindow scoped_window(nullptr, window.get());
scoped_window.SetOpacity(0.5f);
EXPECT_EQ(0.5f, window->layer()->opacity());
EXPECT_EQ(0.5f, child->layer()->opacity());
EXPECT_EQ(0.f, child2->layer()->opacity());
EXPECT_TRUE(window->IsVisible());
EXPECT_TRUE(child->IsVisible());
EXPECT_FALSE(child2->IsVisible());
gfx::Transform transform(1.f, 0.f, 0.f, 1.f, 10.f, 10.f);
SetTransform(window.get(), transform);
EXPECT_EQ(transform, window->transform());
EXPECT_EQ(transform, child->transform());
EXPECT_TRUE(child2->transform().IsIdentity());
}
class ScopedOverviewTransformWindowWithMaskTest
: public ScopedOverviewTransformWindowTest {
public:
......
......@@ -6,6 +6,8 @@
#include "ash/disconnected_app_handler.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/public/cpp/window_properties.h"
#include "ash/public/interfaces/window_properties.mojom.h"
#include "ash/root_window_controller.h"
#include "ash/root_window_settings.h"
#include "ash/shell.h"
......@@ -214,6 +216,16 @@ aura::Window* CreateAndParentTopLevelWindow(
properties->erase(translucent_iter);
}
auto hide_in_overview_iter =
properties->find(ash::mojom::kHideInOverview_Property);
if (hide_in_overview_iter != properties->end()) {
bool hide_in_overview =
mojo::ConvertTo<bool>(hide_in_overview_iter->second);
window->SetProperty(kHideInOverviewKey, hide_in_overview);
// No need to persist this value.
properties->erase(hide_in_overview_iter);
}
return window;
}
......
......@@ -4,50 +4,78 @@
#include "ash/wm/window_transient_descendant_iterator.h"
#include <algorithm>
#include "ash/wm/window_util.h"
#include "ui/aura/window.h"
#include "ui/wm/core/window_util.h"
namespace ash {
namespace wm {
namespace {
WindowTransientDescendantIterator::WindowTransientDescendantIterator()
: current_window_(nullptr) {}
WindowTransientDescendantIterator::WindowTransientDescendantIterator(
aura::Window* root_window)
: current_window_(root_window) {
}
// Performs a pre-order traversal of the transient descendants.
const WindowTransientDescendantIterator& WindowTransientDescendantIterator::
operator++() {
DCHECK(current_window_);
// Helper that returns the next window in the preorder traversal.
aura::Window* GetNextWindow(aura::Window* current_window) {
const aura::Window::Windows transient_children =
::wm::GetTransientChildren(current_window_);
::wm::GetTransientChildren(current_window);
if (!transient_children.empty()) {
current_window_ = transient_children.front();
current_window = transient_children.front();
} else {
while (current_window_) {
aura::Window* parent = ::wm::GetTransientParent(current_window_);
while (current_window) {
aura::Window* parent = ::wm::GetTransientParent(current_window);
if (!parent) {
current_window_ = nullptr;
current_window = nullptr;
break;
}
const aura::Window::Windows transient_siblings =
::wm::GetTransientChildren(parent);
auto iter = std::find(transient_siblings.begin(),
transient_siblings.end(), current_window_);
transient_siblings.end(), current_window);
++iter;
if (iter != transient_siblings.end()) {
current_window_ = *iter;
current_window = *iter;
break;
}
current_window_ = ::wm::GetTransientParent(current_window_);
current_window = ::wm::GetTransientParent(current_window);
}
}
return current_window;
}
} // namespace
WindowTransientDescendantIterator::WindowTransientDescendantIterator()
: current_window_(nullptr) {}
WindowTransientDescendantIterator::~WindowTransientDescendantIterator() =
default;
WindowTransientDescendantIterator::WindowTransientDescendantIterator(
const WindowTransientDescendantIterator& other) = default;
WindowTransientDescendantIterator::WindowTransientDescendantIterator(
aura::Window* root_window)
: current_window_(root_window) {}
WindowTransientDescendantIterator::WindowTransientDescendantIterator(
aura::Window* root_window,
TransientTreeIgnorePredicate hide_predicate)
: current_window_(root_window), hide_predicate_(hide_predicate) {}
// Performs a pre-order traversal of the transient descendants.
const WindowTransientDescendantIterator& WindowTransientDescendantIterator::
operator++() {
DCHECK(current_window_);
aura::Window* next_window = GetNextWindow(current_window_);
// Find the next preorder window if |hide_predicate_| is satisfied.
if (!hide_predicate_.is_null()) {
while (next_window && hide_predicate_.Run(next_window))
next_window = GetNextWindow(next_window);
}
current_window_ = next_window;
return *this;
}
......@@ -70,5 +98,13 @@ WindowTransientDescendantIteratorRange GetTransientTreeIterator(
WindowTransientDescendantIterator(::wm::GetTransientRoot(window)));
}
WindowTransientDescendantIteratorRange GetTransientTreeIterator(
aura::Window* window,
TransientTreeIgnorePredicate hide_predicate) {
return WindowTransientDescendantIteratorRange(
WindowTransientDescendantIterator(::wm::GetTransientRoot(window),
hide_predicate));
}
} // namespace wm
} // namespace ash
......@@ -5,6 +5,10 @@
#ifndef ASH_WM_WINDOW_TRANSIENT_DESCENDANT_ITERATOR_H_
#define ASH_WM_WINDOW_TRANSIENT_DESCENDANT_ITERATOR_H_
#include "ash/ash_export.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
namespace aura {
class Window;
}
......@@ -12,20 +16,29 @@ class Window;
namespace ash {
namespace wm {
using TransientTreeIgnorePredicate =
base::RepeatingCallback<bool(aura::Window*)>;
// An iterator class that traverses an aura::Window and all of its transient
// descendants.
class WindowTransientDescendantIterator {
class ASH_EXPORT WindowTransientDescendantIterator {
public:
// Creates an empty iterator.
WindowTransientDescendantIterator();
~WindowTransientDescendantIterator();
// Copy constructor required for iterator purposes.
WindowTransientDescendantIterator(
const WindowTransientDescendantIterator& other) = default;
const WindowTransientDescendantIterator& other);
// Iterates over |root_window| and all of its transient descendants.
explicit WindowTransientDescendantIterator(aura::Window* root_window);
WindowTransientDescendantIterator(
aura::Window* root_window,
TransientTreeIgnorePredicate hide_predicate);
// Prefix increment operator. This assumes there are more items (i.e.
// *this != TransientDescendantIterator()).
const WindowTransientDescendantIterator& operator++();
......@@ -45,6 +58,9 @@ class WindowTransientDescendantIterator {
// The current window that |this| refers to. A null |current_window_| denotes
// an empty iterator and is used as the last possible value in the traversal.
aura::Window* current_window_;
// Windows that satisfy this predicate will not be shown.
TransientTreeIgnorePredicate hide_predicate_ = base::NullCallback();
};
// Provides a virtual container implementing begin() and end() for a sequence of
......@@ -73,9 +89,13 @@ class WindowTransientDescendantIteratorRange {
};
// Returns the range to iterate over the entire transient-window hierarchy which
// |window| belongs to.
WindowTransientDescendantIteratorRange GetTransientTreeIterator(
aura::Window* window);
// |window| belongs to. If |hide_predicate| is given, windows that satisfy that
// condition will be skipped.
ASH_EXPORT WindowTransientDescendantIteratorRange
GetTransientTreeIterator(aura::Window* window);
ASH_EXPORT WindowTransientDescendantIteratorRange
GetTransientTreeIterator(aura::Window* window,
TransientTreeIgnorePredicate hide_predicate);
} // namespace wm
} // namespace ash
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/wm/window_transient_descendant_iterator.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/window_state.h"
#include "ui/aura/window.h"
#include "ui/wm/core/window_util.h"
namespace ash {
class WindowTransientDescendantIteratorTest : public AshTestBase {
public:
WindowTransientDescendantIteratorTest() = default;
~WindowTransientDescendantIteratorTest() override = default;
// Creates a test set of windows parented like a linked list. The result
// vector will have window in order: ABCD.
void CreateTestLinkedList(
std::vector<std::unique_ptr<aura::Window>>* out_result) {
ASSERT_TRUE(out_result->empty());
for (char c : {'A', 'B', 'C', 'D'}) {
auto window = CreateTestWindow();
window->SetName(std::string(1, c));
if (!out_result->empty())
::wm::AddTransientChild(out_result->back().get(), window.get());
out_result->push_back(std::move(window));
}
}
// A
// / \
// B F
// / \
// C E
// /
// D
// Creates a test set of windows parented like in the diagram above. The
// result vector will have the windows in preorder: ABCDEF.
void CreateTestInOrderTree(
std::vector<std::unique_ptr<aura::Window>>* out_result) {
ASSERT_TRUE(out_result->empty());
auto window_a = CreateTestWindow();
auto window_b = CreateTestWindow();
auto window_c = CreateTestWindow();
auto window_d = CreateTestWindow();
auto window_e = CreateTestWindow();
auto window_f = CreateTestWindow();
window_a->SetName("A");
window_b->SetName("B");
window_c->SetName("C");
window_d->SetName("D");
window_e->SetName("E");
window_f->SetName("F");
// Create the tree structure.
::wm::AddTransientChild(window_a.get(), window_b.get());
::wm::AddTransientChild(window_a.get(), window_f.get());
::wm::AddTransientChild(window_b.get(), window_c.get());
::wm::AddTransientChild(window_b.get(), window_e.get());
::wm::AddTransientChild(window_c.get(), window_d.get());
// Insert windows in preorder traversal: ABCDEF.
out_result->push_back(std::move(window_a));
out_result->push_back(std::move(window_b));
out_result->push_back(std::move(window_c));
out_result->push_back(std::move(window_d));
out_result->push_back(std::move(window_e));
out_result->push_back(std::move(window_f));
}
private:
DISALLOW_COPY_AND_ASSIGN(WindowTransientDescendantIteratorTest);
};
// Tests that case that windows a parented transiently like a linked list.
TEST_F(WindowTransientDescendantIteratorTest, LinkedList) {
std::vector<std::unique_ptr<aura::Window>> windows;
CreateTestLinkedList(&windows);
int index = 0;
std::string str;
for (auto* window : wm::GetTransientTreeIterator(windows[0].get())) {
EXPECT_EQ(windows[index].get(), window);
str += window->GetName();
++index;
}
EXPECT_EQ("ABCD", str);
}
// Tests that case that windows a parented transiently like a tree. The iterator
// should go through the windows with preorder traversal.
TEST_F(WindowTransientDescendantIteratorTest, Tree) {
std::vector<std::unique_ptr<aura::Window>> windows;
CreateTestInOrderTree(&windows);
// The windows in |window| are added with preorder traversal, so they should
// match exactly the window order from the transient iterator.
int index = 0;
std::string str;
for (auto* window : wm::GetTransientTreeIterator(windows[0].get())) {
EXPECT_EQ(windows[index].get(), window);
str += window->GetName();
++index;
}
EXPECT_EQ("ABCDEF", str);
}
// Tests that windows that affected by a given predicate do not show up when
// iterating.
TEST_F(WindowTransientDescendantIteratorTest, LinkedListWithPredicate) {
std::vector<std::unique_ptr<aura::Window>> windows;
CreateTestLinkedList(&windows);
auto predicate = [](aura::Window* w) { return w->GetName() == "C"; };
std::string str;
for (auto* window : wm::GetTransientTreeIterator(
windows[0].get(), base::BindRepeating(predicate))) {
str += window->GetName();
}
EXPECT_EQ("ABD", str);
}
TEST_F(WindowTransientDescendantIteratorTest, TreeWithPredicate) {
std::vector<std::unique_ptr<aura::Window>> windows;
CreateTestInOrderTree(&windows);
auto predicate = [](aura::Window* w) {
return w->GetName() == "B" || w->GetName() == "E";
};
std::string str;
for (auto* window : wm::GetTransientTreeIterator(
windows[0].get(), base::BindRepeating(predicate))) {
str += window->GetName();
}
EXPECT_EQ("ACDF", str);
}
} // namespace ash
......@@ -5,6 +5,7 @@
#include "chrome/browser/ui/views/status_bubble_views.h"
#include <algorithm>
#include <utility>
#include "base/bind.h"
#include "base/i18n/rtl.h"
......@@ -43,6 +44,13 @@
#include "ui/views/widget/widget.h"
#include "url/gurl.h"
#if defined(OS_CHROMEOS)
#include "ash/public/cpp/window_properties.h"
#include "ash/public/interfaces/window_properties.mojom.h"
#include "services/ws/public/cpp/property_type_converters.h"
#include "ui/aura/window.h"
#endif
namespace {
// The alpha and color of the bubble's shadow.
......@@ -666,11 +674,18 @@ void StatusBubbleViews::InitPopup() {
params.parent = frame->GetNativeView();
params.context = frame->GetNativeWindow();
params.name = "StatusBubble";
#if defined(OS_CHROMEOS)
params.mus_properties[ash::mojom::kHideInOverview_Property] =
mojo::ConvertTo<std::vector<uint8_t>>(true);
#endif
popup_->Init(params);
// We do our own animation and don't want any from the system.
popup_->SetVisibilityChangedAnimationsEnabled(false);
popup_->SetOpacity(0.f);
popup_->SetContentsView(view_);
#if defined(OS_CHROMEOS)
popup_->GetNativeWindow()->SetProperty(ash::kHideInOverviewKey, true);
#endif
RepositionPopup();
}
}
......
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