Commit a663e7fd authored by Sammie Quon's avatar Sammie Quon Committed by Commit Bot

overview: Hide title bars before animating into overview mode.

The title bars should not visible while animating overview mode. This cl
hides the title bar if needed and waits until the next paint before
animating the windows. This will hide the title bar as expected while
keeping the benefits of DeferPaint.

Test: manual
Bug: 843851
Change-Id: I99cf7ca39fd1ae14314ac406abd0fec999e2c024
Reviewed-on: https://chromium-review.googlesource.com/1112774Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Reviewed-by: default avatarTao Wu <wutao@chromium.org>
Commit-Queue: Sammie Quon <sammiequon@chromium.org>
Cr-Commit-Position: refs/heads/master@{#573552}
parent 576a08d2
...@@ -70,9 +70,16 @@ class OverviewButtonTrayTest : public AshTestBase { ...@@ -70,9 +70,16 @@ class OverviewButtonTrayTest : public AshTestBase {
OverviewButtonTrayTest() = default; OverviewButtonTrayTest() = default;
~OverviewButtonTrayTest() override = default; ~OverviewButtonTrayTest() override = default;
void SetUp() override; void SetUp() override {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
::switches::kUseFirstDisplayAsInternal);
AshTestBase::SetUp();
}
void NotifySessionStateChanged(); void NotifySessionStateChanged() {
GetTray()->OnSessionStateChanged(
Shell::Get()->session_controller()->GetSessionState());
}
protected: protected:
views::ImageView* GetImageView(OverviewButtonTray* tray) { views::ImageView* GetImageView(OverviewButtonTray* tray) {
...@@ -83,17 +90,6 @@ class OverviewButtonTrayTest : public AshTestBase { ...@@ -83,17 +90,6 @@ class OverviewButtonTrayTest : public AshTestBase {
DISALLOW_COPY_AND_ASSIGN(OverviewButtonTrayTest); DISALLOW_COPY_AND_ASSIGN(OverviewButtonTrayTest);
}; };
void OverviewButtonTrayTest::SetUp() {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
::switches::kUseFirstDisplayAsInternal);
AshTestBase::SetUp();
}
void OverviewButtonTrayTest::NotifySessionStateChanged() {
GetTray()->OnSessionStateChanged(
Shell::Get()->session_controller()->GetSessionState());
}
// Ensures that creation doesn't cause any crashes and adds the image icon. // Ensures that creation doesn't cause any crashes and adds the image icon.
TEST_F(OverviewButtonTrayTest, BasicConstruction) { TEST_F(OverviewButtonTrayTest, BasicConstruction) {
EXPECT_TRUE(GetImageView(GetTray())); EXPECT_TRUE(GetImageView(GetTray()));
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "ash/test_shell_delegate.h" #include "ash/test_shell_delegate.h"
#include "ash/window_manager.h" #include "ash/window_manager.h"
#include "ash/window_manager_service.h" #include "ash/window_manager_service.h"
#include "ash/wm/overview/window_selector_item.h"
#include "ash/ws/window_service_owner.h" #include "ash/ws/window_service_owner.h"
#include "base/guid.h" #include "base/guid.h"
#include "base/run_loop.h" #include "base/run_loop.h"
...@@ -203,6 +204,10 @@ void AshTestHelper::SetUp(bool start_session, bool provide_local_state) { ...@@ -203,6 +204,10 @@ void AshTestHelper::SetUp(bool start_session, bool provide_local_state) {
ui::ScopedAnimationDurationScaleMode::ZERO_DURATION)); ui::ScopedAnimationDurationScaleMode::ZERO_DURATION));
ui::InitializeInputMethodForTesting(); ui::InitializeInputMethodForTesting();
// Overview mode normally hides the title bar and waits for the first
// composit to start animating its windows. Disable the waiting for tests.
WindowSelectorItem::SetDisallowDelayedAnimationForTests();
// Creates Shell and hook with Desktop. // Creates Shell and hook with Desktop.
if (!test_shell_delegate_) if (!test_shell_delegate_)
test_shell_delegate_ = new TestShellDelegate; test_shell_delegate_ = new TestShellDelegate;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <algorithm> #include <algorithm>
#include "ash/frame/custom_frame_view_ash.h"
#include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/ash_features.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/wm/overview/cleanup_animation_observer.h" #include "ash/wm/overview/cleanup_animation_observer.h"
...@@ -188,7 +189,15 @@ ScopedTransformOverviewWindow::ScopedTransformOverviewWindow( ...@@ -188,7 +189,15 @@ ScopedTransformOverviewWindow::ScopedTransformOverviewWindow(
type_ = GetWindowDimensionsType(window); type_ = GetWindowDimensionsType(window);
} }
ScopedTransformOverviewWindow::~ScopedTransformOverviewWindow() = default; ScopedTransformOverviewWindow::~ScopedTransformOverviewWindow() {
if (!window_)
return;
// |this| may still be observering |widget|'s compositor during shutdown.
views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window_);
if (widget)
widget->GetCompositor()->RemoveObserver(this);
}
void ScopedTransformOverviewWindow::RestoreWindow(bool reset_transform) { void ScopedTransformOverviewWindow::RestoreWindow(bool reset_transform) {
Shell::Get()->shadow_controller()->UpdateShadowForWindow(window_); Shell::Get()->shadow_controller()->UpdateShadowForWindow(window_);
...@@ -243,32 +252,51 @@ void ScopedTransformOverviewWindow::BeginScopedAnimation( ...@@ -243,32 +252,51 @@ void ScopedTransformOverviewWindow::BeginScopedAnimation(
window_->layer()->SetMaskLayer(original_mask_layer_); window_->layer()->SetMaskLayer(original_mask_layer_);
} }
for (auto* window : wm::GetTransientTreeIterator(GetOverviewWindow())) { PrepareAnimationSettings(animation_type, animation_settings);
auto settings = std::make_unique<ScopedOverviewAnimationSettings>(
animation_type, window);
settings->DeferPaint();
// If current |window_| is the first MRU window covering the available
// workspace, add the |window_animation_observer| to its
// ScopedOverviewAnimationSettings in order to monitor the complete of its
// exiting animation.
if (window == GetOverviewWindow() &&
selector_item_->ShouldBeObservedWhenExiting()) {
auto window_animation_observer_weak_ptr =
selector_item_->window_grid()->window_animation_observer();
if (window_animation_observer_weak_ptr)
settings->AddObserver(window_animation_observer_weak_ptr.get());
}
animation_settings->push_back(std::move(settings));
}
if (animation_type == OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS && if (animation_type == OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS &&
animation_settings->size() > 0u) { animation_settings->size() > 0u) {
animation_settings->front()->AddObserver(this); animation_settings->front()->AddObserver(this);
} }
} }
bool ScopedTransformOverviewWindow::HideTitleBarAndAnimate(
const gfx::Transform& transform,
OverviewAnimationType animation_type) {
// Defer animation until after title bar is hidden.
views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window_);
DCHECK(widget);
CustomFrameViewAsh* frame =
static_cast<CustomFrameViewAsh*>(widget->non_client_view()->frame_view());
if (!frame)
return false;
delayed_animation_data_ = base::make_optional<AnimationData>(
std::make_pair(transform, animation_type));
widget->GetCompositor()->AddObserver(this);
frame->SetShouldPaintHeader(false);
return true;
}
void ScopedTransformOverviewWindow::OnCompositingStarted(
ui::Compositor* compositor,
base::TimeTicks start_time) {
views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window_);
DCHECK(widget);
DCHECK_EQ(compositor, widget->GetCompositor());
widget->GetCompositor()->RemoveObserver(this);
DCHECK(delayed_animation_data_);
ScopedTransformOverviewWindow::ScopedAnimationSettings animation_settings;
PrepareAnimationSettings((*delayed_animation_data_).second,
&animation_settings);
SetTransform(window()->GetRootWindow(), (*delayed_animation_data_).first);
selector_item_->UpdateHeaderShadowBackdrop(
(*delayed_animation_data_).second,
WindowSelectorItem::HeaderFadeAndLayoutMode::kUpdate);
delayed_animation_data_ = base::nullopt;
}
bool ScopedTransformOverviewWindow::Contains(const aura::Window* target) const { bool ScopedTransformOverviewWindow::Contains(const aura::Window* target) const {
for (auto* window : wm::GetTransientTreeIterator(window_)) { for (auto* window : wm::GetTransientTreeIterator(window_)) {
if (window->Contains(target)) if (window->Contains(target))
...@@ -647,4 +675,28 @@ void ScopedTransformOverviewWindow::CreateAndApplyMaskAndShadow() { ...@@ -647,4 +675,28 @@ void ScopedTransformOverviewWindow::CreateAndApplyMaskAndShadow() {
selector_item_->EnableBackdropIfNeeded(); selector_item_->EnableBackdropIfNeeded();
} }
void ScopedTransformOverviewWindow::PrepareAnimationSettings(
OverviewAnimationType animation_type,
ScopedAnimationSettings* animation_settings) {
for (auto* window : wm::GetTransientTreeIterator(GetOverviewWindow())) {
auto settings = std::make_unique<ScopedOverviewAnimationSettings>(
animation_type, window);
settings->DeferPaint();
// If current |window_| is the first MRU window covering the available
// workspace, add the |window_animation_observer| to its
// ScopedOverviewAnimationSettings in order to monitor the complete of its
// exiting animation.
if (window == GetOverviewWindow() &&
selector_item_->ShouldBeObservedWhenExiting()) {
auto window_animation_observer_weak_ptr =
selector_item_->window_grid()->window_animation_observer();
if (window_animation_observer_weak_ptr)
settings->AddObserver(window_animation_observer_weak_ptr.get());
}
animation_settings->push_back(std::move(settings));
}
}
} // namespace ash } // namespace ash
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/optional.h" #include "base/optional.h"
#include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkColor.h"
#include "ui/compositor/compositor_observer.h"
#include "ui/compositor/layer_animation_observer.h" #include "ui/compositor/layer_animation_observer.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
...@@ -45,7 +46,8 @@ class WindowSelectorItem; ...@@ -45,7 +46,8 @@ class WindowSelectorItem;
// fit in certain bounds. The window's state is restored when this object is // fit in certain bounds. The window's state is restored when this object is
// destroyed. // destroyed.
class ASH_EXPORT ScopedTransformOverviewWindow class ASH_EXPORT ScopedTransformOverviewWindow
: public ui::ImplicitAnimationObserver { : public ui::ImplicitAnimationObserver,
public ui::CompositorObserver {
public: public:
// Overview windows have certain properties if their aspect ratio exceedes a // Overview windows have certain properties if their aspect ratio exceedes a
// threshold. This enum keeps track of which category the window falls into, // threshold. This enum keeps track of which category the window falls into,
...@@ -186,11 +188,26 @@ class ASH_EXPORT ScopedTransformOverviewWindow ...@@ -186,11 +188,26 @@ class ASH_EXPORT ScopedTransformOverviewWindow
// the bounds of the |window_|. // the bounds of the |window_|.
void ResizeMinimizedWidgetIfNeeded(); void ResizeMinimizedWidgetIfNeeded();
// Hides the title bar associated with |window_|, if it exists. Wait for the
// the compositor to paint the new title bar and then animate the overview
// item. Returns false if we could not find an associated title bar.
bool HideTitleBarAndAnimate(const gfx::Transform& transform,
OverviewAnimationType animation_type);
views::Widget* minimized_widget() { return minimized_widget_.get(); } views::Widget* minimized_widget() { return minimized_widget_.get(); }
// ui::ImplicitAnimationObserver: // ui::ImplicitAnimationObserver:
void OnImplicitAnimationsCompleted() override; void OnImplicitAnimationsCompleted() override;
// ui::CompositorObserver:
void OnCompositingDidCommit(ui::Compositor* compositor) override {}
void OnCompositingStarted(ui::Compositor* compositor,
base::TimeTicks start_time) override;
void OnCompositingEnded(ui::Compositor* compositor) override {}
void OnCompositingLockStateChanged(ui::Compositor* compositor) override {}
void OnCompositingChildResizing(ui::Compositor* compositor) override {}
void OnCompositingShuttingDown(ui::Compositor* compositor) override {}
private: private:
friend class WindowSelectorTest; friend class WindowSelectorTest;
class LayerCachingAndFilteringObserver; class LayerCachingAndFilteringObserver;
...@@ -205,6 +222,9 @@ class ASH_EXPORT ScopedTransformOverviewWindow ...@@ -205,6 +222,9 @@ class ASH_EXPORT ScopedTransformOverviewWindow
// mode. // mode.
void CreateAndApplyMaskAndShadow(); void CreateAndApplyMaskAndShadow();
void PrepareAnimationSettings(OverviewAnimationType animation_type,
ScopedAnimationSettings* animation_settings);
// Makes Close() execute synchronously when used in tests. // Makes Close() execute synchronously when used in tests.
static void SetImmediateCloseForTests(); static void SetImmediateCloseForTests();
...@@ -230,6 +250,11 @@ class ASH_EXPORT ScopedTransformOverviewWindow ...@@ -230,6 +250,11 @@ class ASH_EXPORT ScopedTransformOverviewWindow
// item should be if the window is too wide or too tall. // item should be if the window is too wide or too tall.
base::Optional<gfx::Rect> window_selector_bounds_; base::Optional<gfx::Rect> window_selector_bounds_;
using AnimationData = std::pair<gfx::Transform, OverviewAnimationType>;
// Stores the data needed to perform a animation, if we need to wait for the
// compositor to hide the title bar.
base::Optional<AnimationData> delayed_animation_data_;
// A widget that holds the content for the minimized window. // A widget that holds the content for the minimized window.
std::unique_ptr<views::Widget> minimized_widget_; std::unique_ptr<views::Widget> minimized_widget_;
......
...@@ -59,6 +59,10 @@ namespace ash { ...@@ -59,6 +59,10 @@ namespace ash {
namespace { namespace {
// When set to true by tests, item does not wait for header to finish painting
// before starting animation. This should be always be false for all tests.
bool disallow_delayed_animation_for_tests = false;
// In the conceptual overview table, the window margin is the space reserved // In the conceptual overview table, the window margin is the space reserved
// around the window within the cell. This margin does not overlap so the // around the window within the cell. This margin does not overlap so the
// closest distance between adjacent windows will be twice this amount. // closest distance between adjacent windows will be twice this amount.
...@@ -107,7 +111,7 @@ constexpr int kSelectorFadeInMilliseconds = 350; ...@@ -107,7 +111,7 @@ constexpr int kSelectorFadeInMilliseconds = 350;
constexpr int kExitFadeInMilliseconds = 30; constexpr int kExitFadeInMilliseconds = 30;
// Duration of the header and close button fade in/out when a drag is // Duration of the header and close button fade in/out when a drag is
// started/finished on a window selector item; // started/finished on a window selector item.
constexpr int kDragAnimationMs = 167; constexpr int kDragAnimationMs = 167;
// Before closing a window animate both the window and the caption to shrink by // Before closing a window animate both the window and the caption to shrink by
...@@ -664,6 +668,11 @@ class WindowSelectorItem::CaptionContainerView : public views::View { ...@@ -664,6 +668,11 @@ class WindowSelectorItem::CaptionContainerView : public views::View {
DISALLOW_COPY_AND_ASSIGN(CaptionContainerView); DISALLOW_COPY_AND_ASSIGN(CaptionContainerView);
}; };
// static
void WindowSelectorItem::SetDisallowDelayedAnimationForTests() {
disallow_delayed_animation_for_tests = true;
}
WindowSelectorItem::WindowSelectorItem(aura::Window* window, WindowSelectorItem::WindowSelectorItem(aura::Window* window,
WindowSelector* window_selector, WindowSelector* window_selector,
WindowGrid* window_grid) WindowGrid* window_grid)
...@@ -714,7 +723,8 @@ void WindowSelectorItem::RestoreWindow(bool reset_transform) { ...@@ -714,7 +723,8 @@ void WindowSelectorItem::RestoreWindow(bool reset_transform) {
background_view_->OnItemRestored(); background_view_->OnItemRestored();
background_view_ = nullptr; background_view_ = nullptr;
} }
UpdateHeaderLayout(HeaderFadeInMode::kExit, GetExitOverviewAnimationType()); UpdateHeaderLayout(HeaderFadeAndLayoutMode::kExit,
GetExitOverviewAnimationType());
} }
void WindowSelectorItem::EnsureVisible() { void WindowSelectorItem::EnsureVisible() {
...@@ -758,7 +768,7 @@ void WindowSelectorItem::PrepareForOverview() { ...@@ -758,7 +768,7 @@ void WindowSelectorItem::PrepareForOverview() {
wm::GetWindowState(GetWindow())->IsMinimized()) { wm::GetWindowState(GetWindow())->IsMinimized()) {
RestackItemWidget(); RestackItemWidget();
} }
UpdateHeaderLayout(HeaderFadeInMode::kEnter, UpdateHeaderLayout(HeaderFadeAndLayoutMode::kEnter,
OverviewAnimationType::OVERVIEW_ANIMATION_NONE); OverviewAnimationType::OVERVIEW_ANIMATION_NONE);
} }
...@@ -782,10 +792,10 @@ void WindowSelectorItem::SetBounds(const gfx::Rect& target_bounds, ...@@ -782,10 +792,10 @@ void WindowSelectorItem::SetBounds(const gfx::Rect& target_bounds,
// If |target_bounds_| is empty, this is the first update. For tablet mode, // If |target_bounds_| is empty, this is the first update. For tablet mode,
// let UpdateHeaderLayout know, as we do not want |item_widget_| to be // let UpdateHeaderLayout know, as we do not want |item_widget_| to be
// animated with the window. // animated with the window.
HeaderFadeInMode mode = HeaderFadeAndLayoutMode mode =
target_bounds_.IsEmpty() && UseTabletModeAnimations(GetWindow()) target_bounds_.IsEmpty() && UseTabletModeAnimations(GetWindow())
? HeaderFadeInMode::kFirstUpdate ? HeaderFadeAndLayoutMode::kFirstUpdate
: HeaderFadeInMode::kUpdate; : HeaderFadeAndLayoutMode::kUpdate;
target_bounds_ = target_bounds; target_bounds_ = target_bounds;
gfx::Rect inset_bounds(target_bounds); gfx::Rect inset_bounds(target_bounds);
...@@ -793,22 +803,14 @@ void WindowSelectorItem::SetBounds(const gfx::Rect& target_bounds, ...@@ -793,22 +803,14 @@ void WindowSelectorItem::SetBounds(const gfx::Rect& target_bounds,
if (wm::GetWindowState(GetWindow())->IsMinimized()) if (wm::GetWindowState(GetWindow())->IsMinimized())
new_animation_type = OVERVIEW_ANIMATION_NONE; new_animation_type = OVERVIEW_ANIMATION_NONE;
SetItemBounds(inset_bounds, new_animation_type); if (SetItemBounds(inset_bounds, new_animation_type)) {
// Delayed animation will handle updating the header, shadow and backdrop.
// SetItemBounds is called before UpdateHeaderLayout so the header can return;
// properly use the updated windows bounds.
UpdateHeaderLayout(mode, new_animation_type);
// Shadow is normally set after an animation is finished. In the case of no
// animations, manually set the shadow. Shadow relies on both the window
// transform and |item_widget_|'s new bounds so set it after SetItemBounds
// and UpdateHeaderLayout.
if (new_animation_type == OVERVIEW_ANIMATION_NONE) {
SetShadowBounds(
base::make_optional(transform_window_.GetTransformedBounds()));
} }
UpdateBackdropBounds(); // SetItemBounds is called before UpdateHeaderShadowBackdrop so the those
// elements can properly use the updated windows bounds.
UpdateHeaderShadowBackdrop(new_animation_type, mode);
} }
void WindowSelectorItem::SendAccessibleSelectionEvent() { void WindowSelectorItem::SendAccessibleSelectionEvent() {
...@@ -1133,6 +1135,23 @@ void WindowSelectorItem::SetShadowBounds( ...@@ -1133,6 +1135,23 @@ void WindowSelectorItem::SetShadowBounds(
shadow_->SetContentBounds(bounds_in_item); shadow_->SetContentBounds(bounds_in_item);
} }
void WindowSelectorItem::UpdateHeaderShadowBackdrop(
OverviewAnimationType animation_type,
HeaderFadeAndLayoutMode mode) {
UpdateHeaderLayout(mode, animation_type);
// Shadow is normally set after an animation is finished. In the case of no
// animations, manually set the shadow. Shadow relies on both the window
// transform and |item_widget_|'s new bounds so set it after SetItemBounds
// and UpdateHeaderLayout.
if (animation_type == OVERVIEW_ANIMATION_NONE) {
SetShadowBounds(
base::make_optional(transform_window_.GetTransformedBounds()));
}
UpdateBackdropBounds();
}
void WindowSelectorItem::SetOpacity(float opacity) { void WindowSelectorItem::SetOpacity(float opacity) {
item_widget_->SetOpacity(opacity); item_widget_->SetOpacity(opacity);
transform_window_.SetOpacity(opacity); transform_window_.SetOpacity(opacity);
...@@ -1197,7 +1216,7 @@ gfx::Rect WindowSelectorItem::GetTargetBoundsInScreen() const { ...@@ -1197,7 +1216,7 @@ gfx::Rect WindowSelectorItem::GetTargetBoundsInScreen() const {
return transform_window_.GetTargetBoundsInScreen(); return transform_window_.GetTargetBoundsInScreen();
} }
void WindowSelectorItem::SetItemBounds(const gfx::Rect& target_bounds, bool WindowSelectorItem::SetItemBounds(const gfx::Rect& target_bounds,
OverviewAnimationType animation_type) { OverviewAnimationType animation_type) {
DCHECK(root_window_ == GetWindow()->GetRootWindow()); DCHECK(root_window_ == GetWindow()->GetRootWindow());
gfx::Rect screen_rect = transform_window_.GetTargetBoundsInScreen(); gfx::Rect screen_rect = transform_window_.GetTargetBoundsInScreen();
...@@ -1214,9 +1233,23 @@ void WindowSelectorItem::SetItemBounds(const gfx::Rect& target_bounds, ...@@ -1214,9 +1233,23 @@ void WindowSelectorItem::SetItemBounds(const gfx::Rect& target_bounds,
screen_rect, target_bounds, top_view_inset, title_height); screen_rect, target_bounds, top_view_inset, title_height);
gfx::Transform transform = ScopedTransformOverviewWindow::GetTransformForRect( gfx::Transform transform = ScopedTransformOverviewWindow::GetTransformForRect(
screen_rect, selector_item_bounds); screen_rect, selector_item_bounds);
const bool delay_transform = !disallow_delayed_animation_for_tests &&
maybe_delay_animation_ &&
transform_window_.GetTopInset();
maybe_delay_animation_ = false;
if (delay_transform) {
// HideTitleBarAndAnimate will handle transforming the window as well as
// updating the header, shadow and backdrop. If no title bar was found then
// continue as normally.
if (transform_window_.HideTitleBarAndAnimate(transform, animation_type))
return true;
}
ScopedTransformOverviewWindow::ScopedAnimationSettings animation_settings; ScopedTransformOverviewWindow::ScopedAnimationSettings animation_settings;
transform_window_.BeginScopedAnimation(animation_type, &animation_settings); transform_window_.BeginScopedAnimation(animation_type, &animation_settings);
transform_window_.SetTransform(root_window_, transform); transform_window_.SetTransform(root_window_, transform);
return false;
} }
void WindowSelectorItem::CreateWindowLabel(const base::string16& title) { void WindowSelectorItem::CreateWindowLabel(const base::string16& title) {
...@@ -1303,11 +1336,11 @@ void WindowSelectorItem::CreateWindowLabel(const base::string16& title) { ...@@ -1303,11 +1336,11 @@ void WindowSelectorItem::CreateWindowLabel(const base::string16& title) {
} }
void WindowSelectorItem::UpdateHeaderLayout( void WindowSelectorItem::UpdateHeaderLayout(
HeaderFadeInMode mode, HeaderFadeAndLayoutMode mode,
OverviewAnimationType animation_type) { OverviewAnimationType animation_type) {
// Do not move the header on exit if the window is originally minimized // Do not move the header on exit if the window is originally minimized
// or in tablet mode. // or in tablet mode.
if (mode == HeaderFadeInMode::kExit && if (mode == HeaderFadeAndLayoutMode::kExit &&
(UseTabletModeAnimations(GetWindow()) || (UseTabletModeAnimations(GetWindow()) ||
wm::GetWindowState(GetWindow())->IsMinimized())) { wm::GetWindowState(GetWindow())->IsMinimized())) {
return; return;
...@@ -1322,20 +1355,20 @@ void WindowSelectorItem::UpdateHeaderLayout( ...@@ -1322,20 +1355,20 @@ void WindowSelectorItem::UpdateHeaderLayout(
label_rect.set_width(transformed_window_bounds.width()); label_rect.set_width(transformed_window_bounds.width());
// For tabbed windows the initial bounds of the caption are set such that it // For tabbed windows the initial bounds of the caption are set such that it
// appears to be "growing" up from the window content area. // appears to be "growing" up from the window content area.
label_rect.set_y( label_rect.set_y((mode != HeaderFadeAndLayoutMode::kEnter ||
(mode != HeaderFadeInMode::kEnter || transform_window_.GetTopInset()) transform_window_.GetTopInset())
? -label_rect.height() ? -label_rect.height()
: 0); : 0);
{ {
ui::ScopedLayerAnimationSettings layer_animation_settings( ui::ScopedLayerAnimationSettings layer_animation_settings(
item_widget_->GetLayer()->GetAnimator()); item_widget_->GetLayer()->GetAnimator());
if (background_view_) { if (background_view_) {
if (mode == HeaderFadeInMode::kEnter) { if (mode == HeaderFadeAndLayoutMode::kEnter) {
// Animate the color of |background_view_| once the fade in animation of // Animate the color of |background_view_| once the fade in animation of
// |item_widget_| ends. // |item_widget_| ends.
layer_animation_settings.AddObserver(background_view_); layer_animation_settings.AddObserver(background_view_);
} else if (mode == HeaderFadeInMode::kExit) { } else if (mode == HeaderFadeAndLayoutMode::kExit) {
// Make the header visible above the window. It will be faded out when // Make the header visible above the window. It will be faded out when
// the Shutdown() is called. // the Shutdown() is called.
background_view_->AnimateColor( background_view_->AnimateColor(
...@@ -1354,14 +1387,14 @@ void WindowSelectorItem::UpdateHeaderLayout( ...@@ -1354,14 +1387,14 @@ void WindowSelectorItem::UpdateHeaderLayout(
aura::Window* widget_window = item_widget_->GetNativeWindow(); aura::Window* widget_window = item_widget_->GetNativeWindow();
// For the first update, place the widget at its destination. // For the first update, place the widget at its destination.
ScopedOverviewAnimationSettings animation_settings( ScopedOverviewAnimationSettings animation_settings(
mode == HeaderFadeInMode::kFirstUpdate mode == HeaderFadeAndLayoutMode::kFirstUpdate
? OverviewAnimationType::OVERVIEW_ANIMATION_NONE ? OverviewAnimationType::OVERVIEW_ANIMATION_NONE
: animation_type, : animation_type,
widget_window); widget_window);
// |widget_window| covers both the transformed window and the header // |widget_window| covers both the transformed window and the header
// as well as the gap between the windows to prevent events from reaching // as well as the gap between the windows to prevent events from reaching
// the window including its sizing borders. // the window including its sizing borders.
if (mode != HeaderFadeInMode::kEnter) { if (mode != HeaderFadeAndLayoutMode::kEnter) {
label_rect.set_height(close_button_->GetPreferredSize().height() + label_rect.set_height(close_button_->GetPreferredSize().height() +
transformed_window_bounds.height()); transformed_window_bounds.height());
} }
......
...@@ -64,6 +64,23 @@ class ASH_EXPORT WindowSelectorItem : public views::ButtonListener, ...@@ -64,6 +64,23 @@ class ASH_EXPORT WindowSelectorItem : public views::ButtonListener,
DISALLOW_COPY_AND_ASSIGN(OverviewCloseButton); DISALLOW_COPY_AND_ASSIGN(OverviewCloseButton);
}; };
// The different ways the overview header can fade in or out and be laid out.
enum class HeaderFadeAndLayoutMode {
// Used when entering overview mode, to fade in the header background color.
kEnter,
// Used when the overview header bounds change for the first time, to
// skip animating when in tablet mode.
kFirstUpdate,
// Used when the overview header bounds change, to animate or move the
// header to the desired bounds.
kUpdate,
// Used when exiting overview mode, to fade out the header background color.
kExit,
};
// Do not waiting for first compositing commit when testing.
static void SetDisallowDelayedAnimationForTests();
WindowSelectorItem(aura::Window* window, WindowSelectorItem(aura::Window* window,
WindowSelector* window_selector, WindowSelector* window_selector,
WindowGrid* window_grid); WindowGrid* window_grid);
...@@ -216,6 +233,12 @@ class ASH_EXPORT WindowSelectorItem : public views::ButtonListener, ...@@ -216,6 +233,12 @@ class ASH_EXPORT WindowSelectorItem : public views::ButtonListener,
// the shadow is hidden. // the shadow is hidden.
void SetShadowBounds(base::Optional<gfx::Rect> bounds_in_screen); void SetShadowBounds(base::Optional<gfx::Rect> bounds_in_screen);
// Called after SetItemBounds to update the header, shadow and backdrop. Also
// called by ScopedOverviewTransformWindow if we need to delay the animation
// until after the title bar gets hidden.
void UpdateHeaderShadowBackdrop(OverviewAnimationType animation_type,
HeaderFadeAndLayoutMode mode);
// Changes the opacity of all the windows the item owns. // Changes the opacity of all the windows the item owns.
void SetOpacity(float opacity); void SetOpacity(float opacity);
float GetOpacity(); float GetOpacity();
...@@ -260,25 +283,11 @@ class ASH_EXPORT WindowSelectorItem : public views::ButtonListener, ...@@ -260,25 +283,11 @@ class ASH_EXPORT WindowSelectorItem : public views::ButtonListener,
FRIEND_TEST_ALL_PREFIXES(SplitViewWindowSelectorTest, FRIEND_TEST_ALL_PREFIXES(SplitViewWindowSelectorTest,
OverviewUnsnappableIndicatorVisibility); OverviewUnsnappableIndicatorVisibility);
// The different ways the overview header can fade in and be laid out.
enum class HeaderFadeInMode {
// Used when entering overview mode, to fade in the header background color.
kEnter,
// Used when the overview header bounds change for the first time, to
// skip animating when in tablet mode.
kFirstUpdate,
// Used when the overview header bounds change, to animate or move the
// header
// to the desired bounds.
kUpdate,
// Used when exiting overview mode, to fade out the header background color.
kExit,
};
// Sets the bounds of this selector's items to |target_bounds| in // Sets the bounds of this selector's items to |target_bounds| in
// |root_window_|. The bounds change will be animated as specified // |root_window_|. The bounds change will be animated as specified
// by |animation_type|. // by |animation_type|. Returns true if we want to delay the animation by one
void SetItemBounds(const gfx::Rect& target_bounds, // frame while the header gets hidden.
bool SetItemBounds(const gfx::Rect& target_bounds,
OverviewAnimationType animation_type); OverviewAnimationType animation_type);
// Creates the window label. // Creates the window label.
...@@ -289,7 +298,7 @@ class ASH_EXPORT WindowSelectorItem : public views::ButtonListener, ...@@ -289,7 +298,7 @@ class ASH_EXPORT WindowSelectorItem : public views::ButtonListener,
// |animation_type|. |mode| allows distinguishing the first time update which // |animation_type|. |mode| allows distinguishing the first time update which
// allows setting the initial bounds properly or exiting overview to fade out // allows setting the initial bounds properly or exiting overview to fade out
// gradually. // gradually.
void UpdateHeaderLayout(HeaderFadeInMode mode, void UpdateHeaderLayout(HeaderFadeAndLayoutMode mode,
OverviewAnimationType animation_type); OverviewAnimationType animation_type);
// Animates opacity of the |transform_window_| and its caption to |opacity| // Animates opacity of the |transform_window_| and its caption to |opacity|
...@@ -400,6 +409,11 @@ class ASH_EXPORT WindowSelectorItem : public views::ButtonListener, ...@@ -400,6 +409,11 @@ class ASH_EXPORT WindowSelectorItem : public views::ButtonListener,
// WindowGrid::PositionWindows. // WindowGrid::PositionWindows.
bool animating_to_close_ = false; bool animating_to_close_ = false;
// If this is true, windows which are showing their title bars, should hide
// the title bar on entering overview mode, and wait for the first compositor
// commit before animation everything else.
bool maybe_delay_animation_ = true;
// The shadow around the overview window. Shadows the original window, not // The shadow around the overview window. Shadows the original window, not
// |item_widget_|. Done here instead of on the original window because of the // |item_widget_|. Done here instead of on the original window because of the
// rounded edges mask applied on entering overview window. // rounded edges mask applied on entering overview window.
......
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