Commit 227ea3c2 authored by Ahmed Fakhry's avatar Ahmed Fakhry Committed by Commit Bot

Virtual Desks: Implement move-window-to-desk animation

When the keyboard shortcut is used to move the active window
from current desk to desk on left/right, we animate it towards
the direction of the target desk until it goes offscreen.

Demo: https://bugs.chromium.org/p/chromium/issues/detail?id=977434#c4

BUG=977434, 866622
TEST=Manually

Change-Id: Ia86f493afe997ca640f923acc24fcb5bc3b3027c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1705516
Commit-Queue: Ahmed Fakhry <afakhry@chromium.org>
Reviewed-by: default avatarJames Cook <jamescook@chromium.org>
Cr-Commit-Position: refs/heads/master@{#678476}
parent c5fece63
...@@ -1080,14 +1080,14 @@ component("ash") { ...@@ -1080,14 +1080,14 @@ component("ash") {
"wm/desks/desk_mini_view_animations.h", "wm/desks/desk_mini_view_animations.h",
"wm/desks/desk_preview_view.cc", "wm/desks/desk_preview_view.cc",
"wm/desks/desk_preview_view.h", "wm/desks/desk_preview_view.h",
"wm/desks/desks_animations.cc",
"wm/desks/desks_animations.h",
"wm/desks/desks_bar_view.cc", "wm/desks/desks_bar_view.cc",
"wm/desks/desks_bar_view.h", "wm/desks/desks_bar_view.h",
"wm/desks/desks_controller.cc", "wm/desks/desks_controller.cc",
"wm/desks/desks_controller.h", "wm/desks/desks_controller.h",
"wm/desks/desks_util.cc", "wm/desks/desks_util.cc",
"wm/desks/desks_util.h", "wm/desks/desks_util.h",
"wm/desks/hit_the_wall_desk_switch_animation.cc",
"wm/desks/hit_the_wall_desk_switch_animation.h",
"wm/desks/new_desk_button.cc", "wm/desks/new_desk_button.cc",
"wm/desks/new_desk_button.h", "wm/desks/new_desk_button.h",
"wm/desks/root_window_desk_switch_animator.cc", "wm/desks/root_window_desk_switch_animator.cc",
......
...@@ -60,8 +60,8 @@ ...@@ -60,8 +60,8 @@
#include "ash/system/unified/unified_system_tray.h" #include "ash/system/unified/unified_system_tray.h"
#include "ash/touch/touch_hud_debug.h" #include "ash/touch/touch_hud_debug.h"
#include "ash/utility/screenshot_controller.h" #include "ash/utility/screenshot_controller.h"
#include "ash/wm/desks/desks_animations.h"
#include "ash/wm/desks/desks_controller.h" #include "ash/wm/desks/desks_controller.h"
#include "ash/wm/desks/hit_the_wall_desk_switch_animation.h"
#include "ash/wm/mru_window_tracker.h" #include "ash/wm/mru_window_tracker.h"
#include "ash/wm/overview/overview_controller.h" #include "ash/wm/overview/overview_controller.h"
#include "ash/wm/screen_pinning_controller.h" #include "ash/wm/screen_pinning_controller.h"
...@@ -281,7 +281,7 @@ void HandleActivateDesk(const ui::Accelerator& accelerator) { ...@@ -281,7 +281,7 @@ void HandleActivateDesk(const ui::Accelerator& accelerator) {
} else { } else {
const bool going_left = accelerator.key_code() == ui::VKEY_OEM_4; const bool going_left = accelerator.key_code() == ui::VKEY_OEM_4;
for (auto* root : Shell::GetAllRootWindows()) for (auto* root : Shell::GetAllRootWindows())
PerformHitTheWallDeskSwitchAnimation(root, going_left); desks_animations::PerformHitTheWallAnimation(root, going_left);
} }
} }
...@@ -323,9 +323,14 @@ void HandleMoveActiveItem(const ui::Accelerator& accelerator) { ...@@ -323,9 +323,14 @@ void HandleMoveActiveItem(const ui::Accelerator& accelerator) {
if (!target_desk) if (!target_desk)
return; return;
// TODO(afakhry): Finalize window movement animation to another desk outside if (!in_overview) {
// of overview with UX. https://crbug.com/977434. desks_animations::PerformWindowMoveToDeskAnimation(
window_to_move,
/*going_left=*/accelerator.key_code() == ui::VKEY_OEM_4);
}
desks_controller->MoveWindowFromActiveDeskTo(window_to_move, target_desk); desks_controller->MoveWindowFromActiveDeskTo(window_to_move, target_desk);
if (in_overview) { if (in_overview) {
// We should not exit overview as a result of this shortcut. // We should not exit overview as a result of this shortcut.
DCHECK(overview_controller->InOverviewSession()); DCHECK(overview_controller->InOverviewSession());
......
...@@ -2,21 +2,76 @@ ...@@ -2,21 +2,76 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "ash/wm/desks/hit_the_wall_desk_switch_animation.h" #include "ash/wm/desks/desks_animations.h"
#include <memory> #include <memory>
#include <utility> #include <utility>
#include "ash/shell.h"
#include "ash/wm/overview/overview_controller.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/compositor/layer.h" #include "ui/compositor/layer.h"
#include "ui/compositor/layer_animation_sequence.h" #include "ui/compositor/layer_animation_sequence.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/gfx/transform.h" #include "ui/gfx/transform.h"
#include "ui/wm/core/window_util.h"
namespace ash { namespace ash {
void PerformHitTheWallDeskSwitchAnimation(aura::Window* root, bool going_left) { namespace desks_animations {
namespace {
// Returns the transform that can translate |window| offscreen in the direction
// indicated by |going_left|.
gfx::Transform GetWindowEndTransform(aura::Window* window, bool going_left) {
gfx::Transform transform;
auto* root = window->GetRootWindow();
const auto root_bounds = root->bounds();
const auto window_bounds = window->GetBoundsInRootWindow();
const int x_translation = going_left
? -window_bounds.right()
: (root_bounds.right() - window_bounds.x());
transform.Translate(x_translation, 0);
return transform;
}
// A self-deleting object, which recreates the layer tree of the given |window|,
// and animates the old layer tree offscreen towards the direction of the
// target desk indicated by |going_left|. When the animation is over, this
// object deletes itself and the window's old layer tree.
class WindowMoveToDeskAnimation : public ui::ImplicitAnimationObserver {
public:
WindowMoveToDeskAnimation(aura::Window* window, bool going_left)
: old_window_layer_tree_(wm::RecreateLayers(window)) {
ui::Layer* layer = old_window_layer_tree_->root();
ui::ScopedLayerAnimationSettings settings{layer->GetAnimator()};
constexpr base::TimeDelta kDuration =
base::TimeDelta::FromMilliseconds(250);
settings.SetTransitionDuration(kDuration);
settings.SetTweenType(gfx::Tween::EASE_IN);
settings.SetPreemptionStrategy(
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
settings.AddObserver(this);
layer->SetTransform(GetWindowEndTransform(window, going_left));
}
~WindowMoveToDeskAnimation() override = default;
// ui::ImplicitAnimationObserver:
void OnImplicitAnimationsCompleted() override { delete this; }
private:
std::unique_ptr<ui::LayerTreeOwner> old_window_layer_tree_;
DISALLOW_COPY_AND_ASSIGN(WindowMoveToDeskAnimation);
};
} // namespace
void PerformHitTheWallAnimation(aura::Window* root, bool going_left) {
DCHECK(root->IsRootWindow()); DCHECK(root->IsRootWindow());
// Start and end the animation using the root layer's target transform, since // Start and end the animation using the root layer's target transform, since
...@@ -57,4 +112,13 @@ void PerformHitTheWallDeskSwitchAnimation(aura::Window* root, bool going_left) { ...@@ -57,4 +112,13 @@ void PerformHitTheWallDeskSwitchAnimation(aura::Window* root, bool going_left) {
layer->GetAnimator()->StartAnimation(sequence.release()); layer->GetAnimator()->StartAnimation(sequence.release());
} }
void PerformWindowMoveToDeskAnimation(aura::Window* window, bool going_left) {
DCHECK(!Shell::Get()->overview_controller()->InOverviewSession());
// This is a self-deleting object.
new WindowMoveToDeskAnimation(window, going_left);
}
} // namespace desks_animations
} // namespace ash } // namespace ash
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef ASH_WM_DESKS_HIT_THE_WALL_DESK_SWITCH_ANIMATION_H_ #ifndef ASH_WM_DESKS_DESKS_ANIMATIONS_H_
#define ASH_WM_DESKS_HIT_THE_WALL_DESK_SWITCH_ANIMATION_H_ #define ASH_WM_DESKS_DESKS_ANIMATIONS_H_
namespace aura { namespace aura {
class Window; class Window;
...@@ -11,12 +11,24 @@ class Window; ...@@ -11,12 +11,24 @@ class Window;
namespace ash { namespace ash {
namespace desks_animations {
// Animates the given |root| using a bounce-like animation to indicate that // Animates the given |root| using a bounce-like animation to indicate that
// there are no more desks in the direction the user is trying to go to. // there are no more desks in the direction the user is trying to go to.
// |going_left| is true when the user requests to switch to a desk on the left // |going_left| is true when the user requests to switch to a desk on the left
// of the currently active one. // of the currently active one.
void PerformHitTheWallDeskSwitchAnimation(aura::Window* root, bool going_left); void PerformHitTheWallAnimation(aura::Window* root, bool going_left);
// Recreates the layer tree of the given |window| and animates its old layer
// tree offscreen in the direction of the target desk indicated by |going_left|.
// After this function, |window| can be moved safely immediately to the target
// desk without having to wait for the animation to finish, since we're
// animating a completely separate layer tree.
// Note: This animation should not be performed on windows in overview.
void PerformWindowMoveToDeskAnimation(aura::Window* window, bool going_left);
} // namespace desks_animations
} // namespace ash } // namespace ash
#endif // ASH_WM_DESKS_HIT_THE_WALL_DESK_SWITCH_ANIMATION_H_ #endif // ASH_WM_DESKS_DESKS_ANIMATIONS_H_
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