Commit 5ace5a1e authored by Ahmed Fakhry's avatar Ahmed Fakhry Committed by Commit Bot

Virtual Desks: The desk remove animation

BUG=977434, 866622

Change-Id: I56569fb480cdcee8c483dd6100be880cb1ae094c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1720797Reviewed-by: default avatarJames Cook <jamescook@chromium.org>
Commit-Queue: Ahmed Fakhry <afakhry@chromium.org>
Cr-Commit-Position: refs/heads/master@{#682914}
parent a25b308a
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <utility> #include <utility>
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/wm/desks/desks_controller.h"
#include "ash/wm/overview/overview_controller.h" #include "ash/wm/overview/overview_controller.h"
#include "ash/wm/window_transient_descendant_iterator.h" #include "ash/wm/window_transient_descendant_iterator.h"
#include "base/time/time.h" #include "base/time/time.h"
......
This diff is collapsed.
...@@ -26,9 +26,7 @@ class Desk; ...@@ -26,9 +26,7 @@ class Desk;
// Defines a controller for creating, destroying and managing virtual desks and // Defines a controller for creating, destroying and managing virtual desks and
// their windows. // their windows.
class ASH_EXPORT DesksController class ASH_EXPORT DesksController : public wm::ActivationChangeObserver {
: public RootWindowDeskSwitchAnimator::Delegate,
public ::wm::ActivationChangeObserver {
public: public:
class Observer { class Observer {
public: public:
...@@ -93,6 +91,8 @@ class ASH_EXPORT DesksController ...@@ -93,6 +91,8 @@ class ASH_EXPORT DesksController
// Removes and deletes the given |desk|. |desk| must already exist, and // Removes and deletes the given |desk|. |desk| must already exist, and
// CanRemoveDesks() must be checked before this. // CanRemoveDesks() must be checked before this.
// This will trigger the `DeskRemovalAnimation` if the active desk is being
// removed outside of overview.
void RemoveDesk(const Desk* desk, DesksCreationRemovalSource source); void RemoveDesk(const Desk* desk, DesksCreationRemovalSource source);
// Performs the desk switch animation on all root windows to activate the // Performs the desk switch animation on all root windows to activate the
...@@ -100,6 +100,7 @@ class ASH_EXPORT DesksController ...@@ -100,6 +100,7 @@ class ASH_EXPORT DesksController
// an existing desk. The active window on the currently active desk will be // an existing desk. The active window on the currently active desk will be
// deactivated, and the most-recently used window from the newly-activated // deactivated, and the most-recently used window from the newly-activated
// desk will be activated. // desk will be activated.
// This will trigger the `DeskActivationAnimation`.
void ActivateDesk(const Desk* desk, DesksSwitchSource source); void ActivateDesk(const Desk* desk, DesksSwitchSource source);
// Activates the desk to the left or right of the current desk, if it exists. // Activates the desk to the left or right of the current desk, if it exists.
...@@ -122,11 +123,6 @@ class ASH_EXPORT DesksController ...@@ -122,11 +123,6 @@ class ASH_EXPORT DesksController
void OnRootWindowAdded(aura::Window* root_window); void OnRootWindowAdded(aura::Window* root_window);
void OnRootWindowClosing(aura::Window* root_window); void OnRootWindowClosing(aura::Window* root_window);
// RootWindowDeskSwitchAnimator::Delegate:
void OnStartingDeskScreenshotTaken(const Desk* ending_desk) override;
void OnEndingDeskScreenshotTaken() override;
void OnDeskSwitchAnimationFinished() override;
// ::wm::ActivationChangeObserver: // ::wm::ActivationChangeObserver:
void OnWindowActivating(ActivationReason reason, void OnWindowActivating(ActivationReason reason,
aura::Window* gaining_active, aura::Window* gaining_active,
...@@ -136,6 +132,12 @@ class ASH_EXPORT DesksController ...@@ -136,6 +132,12 @@ class ASH_EXPORT DesksController
aura::Window* lost_active) override; aura::Window* lost_active) override;
private: private:
class DeskAnimationBase;
class DeskActivationAnimation;
class DeskRemovalAnimation;
void OnAnimationFinished(DeskAnimationBase* animation);
bool HasDesk(const Desk* desk) const; bool HasDesk(const Desk* desk) const;
int GetDeskIndex(const Desk* desk) const; int GetDeskIndex(const Desk* desk) const;
...@@ -151,6 +153,9 @@ class ASH_EXPORT DesksController ...@@ -151,6 +153,9 @@ class ASH_EXPORT DesksController
// active. // active.
void ActivateDeskInternal(const Desk* desk, bool update_window_activation); void ActivateDeskInternal(const Desk* desk, bool update_window_activation);
// Removes `desk` without animation.
void RemoveDeskInternal(const Desk* desk, DesksCreationRemovalSource source);
// Returns the desk to which |window| belongs or nullptr if it doesn't belong // Returns the desk to which |window| belongs or nullptr if it doesn't belong
// to any desk. // to any desk.
const Desk* FindDeskOfWindow(aura::Window* window) const; const Desk* FindDeskOfWindow(aura::Window* window) const;
...@@ -170,10 +175,8 @@ class ASH_EXPORT DesksController ...@@ -170,10 +175,8 @@ class ASH_EXPORT DesksController
// mode as a result of desks modifications. // mode as a result of desks modifications.
bool are_desks_being_modified_ = false; bool are_desks_being_modified_ = false;
// An animator object per each root. Once all the animations are complete, // List of on-going desks animations.
// this list is cleared. std::vector<std::unique_ptr<DeskAnimationBase>> animations_;
std::vector<std::unique_ptr<RootWindowDeskSwitchAnimator>>
desk_switch_animators_;
// A free list of desk container IDs to be used for newly-created desks. New // A free list of desk container IDs to be used for newly-created desks. New
// desks pops from this queue and removed desks's associated container IDs are // desks pops from this queue and removed desks's associated container IDs are
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
#include "ash/wm/desks/desks_test_util.h" #include "ash/wm/desks/desks_test_util.h"
#include "ash/shell.h"
#include "ash/wm/desks/desk.h" #include "ash/wm/desks/desk.h"
#include "ash/wm/overview/overview_controller.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace ash { namespace ash {
...@@ -45,4 +47,15 @@ void ActivateDesk(const Desk* desk) { ...@@ -45,4 +47,15 @@ void ActivateDesk(const Desk* desk) {
ASSERT_TRUE(desk->is_active()); ASSERT_TRUE(desk->is_active());
} }
void RemoveDesk(const Desk* desk) {
auto* controller = DesksController::Get();
const bool in_overview =
Shell::Get()->overview_controller()->InOverviewSession();
const bool should_wait = controller->active_desk() == desk && !in_overview;
DeskSwitchAnimationWaiter waiter;
controller->RemoveDesk(desk, DesksCreationRemovalSource::kButton);
if (should_wait)
waiter.Wait();
}
} // namespace ash } // namespace ash
...@@ -37,6 +37,10 @@ class DeskSwitchAnimationWaiter : public DesksController::Observer { ...@@ -37,6 +37,10 @@ class DeskSwitchAnimationWaiter : public DesksController::Observer {
// complete before returning. // complete before returning.
void ActivateDesk(const Desk* desk); void ActivateDesk(const Desk* desk);
// Removes the given |desk| and waits for the desk-removal animation to finish
// if one would launch.
void RemoveDesk(const Desk* desk);
} // namespace ash } // namespace ash
#endif // ASH_WM_DESKS_DESKS_TEST_UTIL_H_ #endif // ASH_WM_DESKS_DESKS_TEST_UTIL_H_
...@@ -55,10 +55,6 @@ void NewDesk() { ...@@ -55,10 +55,6 @@ void NewDesk() {
DesksController::Get()->NewDesk(DesksCreationRemovalSource::kButton); DesksController::Get()->NewDesk(DesksCreationRemovalSource::kButton);
} }
void RemoveDesk(const Desk* desk) {
DesksController::Get()->RemoveDesk(desk, DesksCreationRemovalSource::kButton);
}
std::unique_ptr<aura::Window> CreateTransientWindow( std::unique_ptr<aura::Window> CreateTransientWindow(
aura::Window* transient_parent, aura::Window* transient_parent,
const gfx::Rect& bounds) { const gfx::Rect& bounds) {
...@@ -2024,7 +2020,9 @@ TEST_F(DesksAcceleratorsTest, RemoveDesk) { ...@@ -2024,7 +2020,9 @@ TEST_F(DesksAcceleratorsTest, RemoveDesk) {
Desk* desk_3 = controller->desks()[2].get(); Desk* desk_3 = controller->desks()[2].get();
EXPECT_TRUE(desk_1->is_active()); EXPECT_TRUE(desk_1->is_active());
const int flags = ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN; const int flags = ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN;
DeskSwitchAnimationWaiter waiter;
SendAccelerator(ui::VKEY_OEM_MINUS, flags); SendAccelerator(ui::VKEY_OEM_MINUS, flags);
waiter.Wait();
ASSERT_EQ(2u, controller->desks().size()); ASSERT_EQ(2u, controller->desks().size());
EXPECT_TRUE(desk_2->is_active()); EXPECT_TRUE(desk_2->is_active());
...@@ -2038,6 +2036,35 @@ TEST_F(DesksAcceleratorsTest, RemoveDesk) { ...@@ -2038,6 +2036,35 @@ TEST_F(DesksAcceleratorsTest, RemoveDesk) {
EXPECT_TRUE(overview_controller->InOverviewSession()); EXPECT_TRUE(overview_controller->InOverviewSession());
} }
TEST_F(DesksAcceleratorsTest, RemoveRightmostDesk) {
auto* controller = DesksController::Get();
// Create a few desks and remove them outside and inside overview using the
// shortcut.
NewDesk();
NewDesk();
ASSERT_EQ(3u, controller->desks().size());
Desk* desk_1 = controller->desks()[0].get();
Desk* desk_2 = controller->desks()[1].get();
Desk* desk_3 = controller->desks()[2].get();
ActivateDesk(desk_3);
EXPECT_TRUE(desk_3->is_active());
const int flags = ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN;
{
DeskSwitchAnimationWaiter waiter;
SendAccelerator(ui::VKEY_OEM_MINUS, flags);
waiter.Wait();
}
ASSERT_EQ(2u, controller->desks().size());
EXPECT_TRUE(desk_2->is_active());
{
DeskSwitchAnimationWaiter waiter;
SendAccelerator(ui::VKEY_OEM_MINUS, flags);
waiter.Wait();
}
ASSERT_EQ(1u, controller->desks().size());
EXPECT_TRUE(desk_1->is_active());
}
TEST_F(DesksAcceleratorsTest, LeftRightDeskActivation) { TEST_F(DesksAcceleratorsTest, LeftRightDeskActivation) {
auto* controller = DesksController::Get(); auto* controller = DesksController::Get();
NewDesk(); NewDesk();
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#include "ash/wm/desks/root_window_desk_switch_animator.h" #include "ash/wm/desks/root_window_desk_switch_animator.h"
#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/shell_window_ids.h"
#include "ash/wm/desks/desk.h"
#include "ash/wm/desks/desks_controller.h"
#include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h" #include "components/viz/common/frame_sinks/copy_output_result.h"
#include "third_party/khronos/GLES2/gl2.h" #include "third_party/khronos/GLES2/gl2.h"
...@@ -14,6 +16,7 @@ ...@@ -14,6 +16,7 @@
#include "ui/compositor/layer_animation_observer.h" #include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/layer_tree_owner.h" #include "ui/compositor/layer_tree_owner.h"
#include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/wm/core/window_util.h"
namespace ash { namespace ash {
...@@ -30,6 +33,12 @@ constexpr int kMaxScreenshotRetries = 2; ...@@ -30,6 +33,12 @@ constexpr int kMaxScreenshotRetries = 2;
constexpr base::TimeDelta kAnimationDuration = constexpr base::TimeDelta kAnimationDuration =
base::TimeDelta::FromMilliseconds(300); base::TimeDelta::FromMilliseconds(300);
// The amount, by which the detached old layers of the removed desk's windows,
// is translated vertically during the for-remove desk switch animation.
constexpr int kRemovedDeskWindowYTranslation = 20;
constexpr base::TimeDelta kRemovedDeskWindowTranslationDuration =
base::TimeDelta::FromMilliseconds(100);
// Create the layer that will be the parent of the screenshot layer, with a // Create the layer that will be the parent of the screenshot layer, with a
// solid black color to act as the background showing behind the two // solid black color to act as the background showing behind the two
// screenshot layers in the |kDesksSpacing| region between them. // screenshot layers in the |kDesksSpacing| region between them.
...@@ -100,14 +109,18 @@ RootWindowDeskSwitchAnimator::RootWindowDeskSwitchAnimator( ...@@ -100,14 +109,18 @@ RootWindowDeskSwitchAnimator::RootWindowDeskSwitchAnimator(
aura::Window* root, aura::Window* root,
const Desk* ending_desk, const Desk* ending_desk,
Delegate* delegate, Delegate* delegate,
bool move_left) bool move_left,
bool for_remove)
: root_window_(root), : root_window_(root),
starting_desk_(DesksController::Get()->active_desk()),
ending_desk_(ending_desk), ending_desk_(ending_desk),
delegate_(delegate), delegate_(delegate),
animation_layer_owner_(CreateAnimationLayerOwner(root)), animation_layer_owner_(CreateAnimationLayerOwner(root)),
x_translation_offset_(root->layer()->size().width() + kDesksSpacing), x_translation_offset_(root->layer()->size().width() + kDesksSpacing),
move_left_(move_left) { move_left_(move_left),
for_remove_(for_remove) {
DCHECK(root_window_); DCHECK(root_window_);
DCHECK(starting_desk_);
DCHECK(ending_desk_); DCHECK(ending_desk_);
DCHECK(delegate_); DCHECK(delegate_);
} }
...@@ -122,6 +135,23 @@ RootWindowDeskSwitchAnimator::~RootWindowDeskSwitchAnimator() { ...@@ -122,6 +135,23 @@ RootWindowDeskSwitchAnimator::~RootWindowDeskSwitchAnimator() {
} }
void RootWindowDeskSwitchAnimator::TakeStartingDeskScreenshot() { void RootWindowDeskSwitchAnimator::TakeStartingDeskScreenshot() {
if (for_remove_) {
// The active desk is about to be removed. Recreate and detach its old
// layers to animate them in a jump-like animation.
auto* desk_container =
starting_desk_->GetDeskContainerForRoot(root_window_);
old_windows_layer_tree_owner_ = wm::RecreateLayers(desk_container);
root_window_->layer()->Add(old_windows_layer_tree_owner_->root());
root_window_->layer()->StackAtTop(old_windows_layer_tree_owner_->root());
// We don't take a screenshot of the soon-to-be-removed desk, we use an
// empty black solid color layer.
auto black_layer = std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR);
black_layer->SetColor(SK_ColorBLACK);
CompleteAnimationPhase1WithLayer(std::move(black_layer));
return;
}
TakeScreenshot( TakeScreenshot(
root_window_, root_window_,
base::BindOnce( base::BindOnce(
...@@ -179,6 +209,22 @@ void RootWindowDeskSwitchAnimator::StartAnimation() { ...@@ -179,6 +209,22 @@ void RootWindowDeskSwitchAnimator::StartAnimation() {
settings.SetTransitionDuration(kAnimationDuration); settings.SetTransitionDuration(kAnimationDuration);
settings.SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN); settings.SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN);
animation_layer->SetTransform(animation_layer_ending_transfrom); animation_layer->SetTransform(animation_layer_ending_transfrom);
if (for_remove_) {
DCHECK(old_windows_layer_tree_owner_);
auto* old_windows_layer = old_windows_layer_tree_owner_->root();
DCHECK(old_windows_layer);
// Translate the old layers of removed desk's windows back down by
// `kRemovedDeskWindowYTranslation`.
gfx::Transform transform = old_windows_layer->GetTargetTransform();
ui::ScopedLayerAnimationSettings settings(old_windows_layer->GetAnimator());
settings.SetPreemptionStrategy(ui::LayerAnimator::ENQUEUE_NEW_ANIMATION);
settings.SetTransitionDuration(kRemovedDeskWindowTranslationDuration);
settings.SetTweenType(gfx::Tween::EASE_IN);
transform.Translate(0, kRemovedDeskWindowYTranslation);
old_windows_layer->SetTransform(transform);
}
} }
void RootWindowDeskSwitchAnimator::OnImplicitAnimationsCompleted() { void RootWindowDeskSwitchAnimator::OnImplicitAnimationsCompleted() {
...@@ -188,27 +234,11 @@ void RootWindowDeskSwitchAnimator::OnImplicitAnimationsCompleted() { ...@@ -188,27 +234,11 @@ void RootWindowDeskSwitchAnimator::OnImplicitAnimationsCompleted() {
delegate_->OnDeskSwitchAnimationFinished(); delegate_->OnDeskSwitchAnimationFinished();
} }
void RootWindowDeskSwitchAnimator::OnStartingDeskScreenshotTaken( void RootWindowDeskSwitchAnimator::CompleteAnimationPhase1WithLayer(
std::unique_ptr<viz::CopyOutputResult> copy_result) { std::unique_ptr<ui::Layer> layer) {
if (!copy_result || copy_result->IsEmpty()) { DCHECK(layer);
// A frame may be activated before the screenshot requests are satisfied,
// leading to us getting an empty |result|. Rerequest the screenshot.
// (See viz::Surface::ActivateFrame()).
if (++starting_desk_screenshot_retries_ <= kMaxScreenshotRetries) {
TakeStartingDeskScreenshot();
} else {
LOG(ERROR) << "Received multiple empty screenshots of the starting desk.";
NOTREACHED();
starting_desk_screenshot_taken_ = true;
delegate_->OnStartingDeskScreenshotTaken(ending_desk_);
}
return;
}
ui::Layer* starting_desk_screenshot_layer =
CreateLayerFromScreenshotResult(std::move(copy_result)).release();
ui::Layer* starting_desk_screenshot_layer = layer.release();
gfx::Rect screenshot_bounds(root_window_->layer()->size()); gfx::Rect screenshot_bounds(root_window_->layer()->size());
gfx::Transform animation_layer_starting_transfrom; gfx::Transform animation_layer_starting_transfrom;
...@@ -251,12 +281,53 @@ void RootWindowDeskSwitchAnimator::OnStartingDeskScreenshotTaken( ...@@ -251,12 +281,53 @@ void RootWindowDeskSwitchAnimator::OnStartingDeskScreenshotTaken(
// etc.) are not visible to the user. // etc.) are not visible to the user.
auto* root_layer = root_window_->layer(); auto* root_layer = root_window_->layer();
root_layer->Add(animation_layer); root_layer->Add(animation_layer);
root_layer->StackAtTop(animation_layer);
if (for_remove_) {
DCHECK(old_windows_layer_tree_owner_);
auto* old_windows_layer = old_windows_layer_tree_owner_->root();
DCHECK(old_windows_layer);
root_layer->StackBelow(animation_layer, old_windows_layer);
// Translate the old layers of the removed desk's windows up by
// `kRemovedDeskWindowYTranslation`.
gfx::Transform transform = old_windows_layer->GetTargetTransform();
ui::ScopedLayerAnimationSettings settings(old_windows_layer->GetAnimator());
settings.SetPreemptionStrategy(
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
settings.SetTransitionDuration(kRemovedDeskWindowTranslationDuration);
settings.SetTweenType(gfx::Tween::EASE_OUT);
transform.Translate(0, -kRemovedDeskWindowYTranslation);
old_windows_layer->SetTransform(transform);
} else {
root_layer->StackAtTop(animation_layer);
}
starting_desk_screenshot_taken_ = true; starting_desk_screenshot_taken_ = true;
delegate_->OnStartingDeskScreenshotTaken(ending_desk_); delegate_->OnStartingDeskScreenshotTaken(ending_desk_);
} }
void RootWindowDeskSwitchAnimator::OnStartingDeskScreenshotTaken(
std::unique_ptr<viz::CopyOutputResult> copy_result) {
if (!copy_result || copy_result->IsEmpty()) {
// A frame may be activated before the screenshot requests are satisfied,
// leading to us getting an empty |result|. Rerequest the screenshot.
// (See viz::Surface::ActivateFrame()).
if (++starting_desk_screenshot_retries_ <= kMaxScreenshotRetries) {
TakeStartingDeskScreenshot();
} else {
LOG(ERROR) << "Received multiple empty screenshots of the starting desk.";
NOTREACHED();
starting_desk_screenshot_taken_ = true;
delegate_->OnStartingDeskScreenshotTaken(ending_desk_);
}
return;
}
CompleteAnimationPhase1WithLayer(
CreateLayerFromScreenshotResult(std::move(copy_result)));
}
void RootWindowDeskSwitchAnimator::OnEndingDeskScreenshotTaken( void RootWindowDeskSwitchAnimator::OnEndingDeskScreenshotTaken(
std::unique_ptr<viz::CopyOutputResult> copy_result) { std::unique_ptr<viz::CopyOutputResult> copy_result) {
if (!copy_result || copy_result->IsEmpty()) { if (!copy_result || copy_result->IsEmpty()) {
......
...@@ -17,6 +17,7 @@ class Window; ...@@ -17,6 +17,7 @@ class Window;
namespace ui { namespace ui {
class LayerTreeOwner; class LayerTreeOwner;
class Layer;
} // namespace ui } // namespace ui
namespace viz { namespace viz {
...@@ -129,7 +130,8 @@ class Desk; ...@@ -129,7 +130,8 @@ class Desk;
// be visible again. // be visible again.
// //
// This cooperative interaction between the animators and their owner // This cooperative interaction between the animators and their owner
// (DesksController) is needed for the following reasons: // (DesksController::AbstractDeskSwitchAnimation) is needed for the following
// reasons:
// 1- The new desk is only activated after all starting desk screenshots on all // 1- The new desk is only activated after all starting desk screenshots on all
// roots have been taken and placed on top of everything (between phase (1) // roots have been taken and placed on top of everything (between phase (1)
// and (2)), so that the effects of desk activation (windows hiding and // and (2)), so that the effects of desk activation (windows hiding and
...@@ -138,6 +140,20 @@ class Desk; ...@@ -138,6 +140,20 @@ class Desk;
// root windows are ready (between phase (2) and (3)). This is needed to // root windows are ready (between phase (2) and (3)). This is needed to
// synchronize the animations on all displays together (otherwise the // synchronize the animations on all displays together (otherwise the
// animations will lag behind each other). // animations will lag behind each other).
//
// When this animator is used to implement the remove-active-desk animation
// (which also involves switching desks; from the to-be-removed desk to another
// desk), `for_remove` is set to true in the constructor. The animation is
// slightly tweaked to do the following:
// - Instead of taking a screenshot of the starting desk, we replace it by a
// black solid color layer, to indicate the desk is being removed.
// - The layer tree of the active-desk container is recreated, and the old
// layers are detached and animated vertically by
// `kRemovedDeskWindowYTranslation`.
// - That old layer tree is then translated back down by the same amount while
// the desks screenshots are animating horizontally.
// This gives the effect that the removed desk windows are jumping from their
// desk to the target desk.
class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver { class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver {
public: public:
class Delegate { class Delegate {
...@@ -162,7 +178,8 @@ class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver { ...@@ -162,7 +178,8 @@ class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver {
RootWindowDeskSwitchAnimator(aura::Window* root, RootWindowDeskSwitchAnimator(aura::Window* root,
const Desk* ending_desk, const Desk* ending_desk,
Delegate* delegate, Delegate* delegate,
bool move_left); bool move_left,
bool for_remove);
~RootWindowDeskSwitchAnimator() override; ~RootWindowDeskSwitchAnimator() override;
...@@ -174,7 +191,7 @@ class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver { ...@@ -174,7 +191,7 @@ class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver {
} }
bool animation_finished() const { return animation_finished_; } bool animation_finished() const { return animation_finished_; }
// Begins pahse (1) of the animation by taking a screenshot of the starting // Begins phase (1) of the animation by taking a screenshot of the starting
// desk content. Delegate::OnStartingDeskScreenshotTaken() will be called once // desk content. Delegate::OnStartingDeskScreenshotTaken() will be called once
// the screenshot is taken and placed on top of everything on the screen. // the screenshot is taken and placed on top of everything on the screen.
void TakeStartingDeskScreenshot(); void TakeStartingDeskScreenshot();
...@@ -195,6 +212,15 @@ class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver { ...@@ -195,6 +212,15 @@ class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver {
void OnImplicitAnimationsCompleted() override; void OnImplicitAnimationsCompleted() override;
private: private:
// Completes the first phase of the animation using the given |layer| as the
// screenshot layer of the starting desk. This layer will be parented to the
// animation layer, which will be setup with its initial transform according
// to |move_left|. If |for_remove_| is true, the detached old layer tree of
// the soon-to-be-removed-desk's windows will be translated up vertically to
// simulate a jump from the removed desk to the target desk.
// |Delegate::OnStartingDeskScreenshotTaken()| will be called at the end.
void CompleteAnimationPhase1WithLayer(std::unique_ptr<ui::Layer> layer);
void OnStartingDeskScreenshotTaken( void OnStartingDeskScreenshotTaken(
std::unique_ptr<viz::CopyOutputResult> copy_result); std::unique_ptr<viz::CopyOutputResult> copy_result);
void OnEndingDeskScreenshotTaken( void OnEndingDeskScreenshotTaken(
...@@ -203,11 +229,20 @@ class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver { ...@@ -203,11 +229,20 @@ class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver {
// The root window that this animator is associated with. // The root window that this animator is associated with.
aura::Window* const root_window_; aura::Window* const root_window_;
// The active desk at the start of the animation.
const Desk* const starting_desk_;
// The desk to activate and animate to with this animator. // The desk to activate and animate to with this animator.
const Desk* const ending_desk_; const Desk* const ending_desk_;
Delegate* const delegate_; Delegate* const delegate_;
// The owner of the layer tree of the old detached layers of the removed
// desk's windows. This is only valid if |for_remove_| is true. This layer
// tree is animated to simulate that the windows are jumping from the removed
// desk to the target desk.
std::unique_ptr<ui::LayerTreeOwner> old_windows_layer_tree_owner_;
// The owner of the layer tree that contains the parent "animation layer" and // The owner of the layer tree that contains the parent "animation layer" and
// both its child starting and ending desks "screenshot layers". // both its child starting and ending desks "screenshot layers".
std::unique_ptr<ui::LayerTreeOwner> animation_layer_owner_; std::unique_ptr<ui::LayerTreeOwner> animation_layer_owner_;
...@@ -226,6 +261,9 @@ class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver { ...@@ -226,6 +261,9 @@ class RootWindowDeskSwitchAnimator : public ui::ImplicitAnimationObserver {
// means the starting desk is on the left of the ending desk. // means the starting desk is on the left of the ending desk.
const bool move_left_; const bool move_left_;
// True if this animator is handling the remove-active-desk animation.
const bool for_remove_;
// True when phase (1) finishes. // True when phase (1) finishes.
bool starting_desk_screenshot_taken_ = false; bool starting_desk_screenshot_taken_ = false;
......
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