summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvarkha@chromium.org <varkha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-02 22:35:50 +0000
committervarkha@chromium.org <varkha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-02 22:35:50 +0000
commitfbc94488149d051eb37f09e9e5ba546f9d18880e (patch)
tree04208ff6f3b8d8f34f05a6a2a2114774aeccd5ca
parentdd3e22f4d33b083713620f00a9f0b19bab06e20a (diff)
downloadchromium_src-fbc94488149d051eb37f09e9e5ba546f9d18880e.zip
chromium_src-fbc94488149d051eb37f09e9e5ba546f9d18880e.tar.gz
chromium_src-fbc94488149d051eb37f09e9e5ba546f9d18880e.tar.bz2
Changes sequence of docked animations when evicting windows from dock. Windows that are restored into docked area are slid from below rather than from above as before. Additionally minimizing animation for the windows that no longer fit in the dock is slowed down in hopes of making it less confusing.
To allow this a new ScopedLayerAnimationSettings::LockTransitionDuration method is introduced which locks the current animation transition duration until the ScopedLayerAnimationSettings object that invoked it goes out of scope. BUG=323188 TEST=ash_unittests --gtest_filter=WindowAnimationsTest.LockAnimationDuration Review URL: https://codereview.chromium.org/82573002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@238212 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ash/wm/dock/docked_window_layout_manager.cc18
-rw-r--r--ash/wm/window_animations.cc8
-rw-r--r--ash/wm/window_animations_unittest.cc106
-rw-r--r--ui/compositor/layer_animator.cc11
-rw-r--r--ui/compositor/layer_animator.h13
-rw-r--r--ui/compositor/scoped_layer_animation_settings.cc16
-rw-r--r--ui/compositor/scoped_layer_animation_settings.h7
7 files changed, 163 insertions, 16 deletions
diff --git a/ash/wm/dock/docked_window_layout_manager.cc b/ash/wm/dock/docked_window_layout_manager.cc
index 9126351..b3c9ebe 100644
--- a/ash/wm/dock/docked_window_layout_manager.cc
+++ b/ash/wm/dock/docked_window_layout_manager.cc
@@ -45,7 +45,8 @@ const int DockedWindowLayoutManager::kMinDockGap = 2;
const int DockedWindowLayoutManager::kIdealWidth = 250;
const int kMinimumHeight = 250;
const int kSlideDurationMs = 120;
-const int kFadeDurationMs = 720;
+const int kFadeDurationMs = 60;
+const int kMinimizeDurationMs = 720;
namespace {
@@ -654,10 +655,17 @@ void DockedWindowLayoutManager::MaybeMinimizeChildrenExcept(
if (window == child || !IsUsedByLayout(window))
continue;
int room_needed = GetWindowHeightCloseTo(window, 0) + kMinDockGap;
- if (available_room > room_needed)
+ if (available_room > room_needed) {
available_room -= room_needed;
- else
+ } else {
+ // Slow down minimizing animations. Lock duration so that it is not
+ // overridden by other ScopedLayerAnimationSettings down the stack.
+ ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
+ settings.SetTransitionDuration(
+ base::TimeDelta::FromMilliseconds(kMinimizeDurationMs));
+ settings.LockTransitionDuration();
wm::GetWindowState(window)->Minimize();
+ }
}
}
@@ -674,7 +682,7 @@ void DockedWindowLayoutManager::RestoreDockedWindow(
wm::WindowState* window_state) {
aura::Window* window = window_state->window();
DCHECK(!IsPopupOrTransient(window));
- // Always place restored window at the top shuffling the other windows down.
+ // Always place restored window at the bottom shuffling the other windows up.
// TODO(varkha): add a separate container for docked windows to keep track
// of ordering.
gfx::Display display = Shell::GetScreen()->GetDisplayNearestWindow(
@@ -688,7 +696,7 @@ void DockedWindowLayoutManager::RestoreDockedWindow(
return;
}
gfx::Rect bounds(window->bounds());
- bounds.set_y(work_area.y() - bounds.height());
+ bounds.set_y(work_area.bottom());
window->SetBounds(bounds);
window->Show();
MaybeMinimizeChildrenExcept(window);
diff --git a/ash/wm/window_animations.cc b/ash/wm/window_animations.cc
index 5d02758..0daa4f3 100644
--- a/ash/wm/window_animations.cc
+++ b/ash/wm/window_animations.cc
@@ -105,8 +105,8 @@ void AddLayerAnimationsForMinimize(aura::Window* window, bool show) {
rotation_about_pivot->SetReversed(show);
- base::TimeDelta duration = base::TimeDelta::FromMilliseconds(
- kLayerAnimationsForMinimizeDurationMS);
+ base::TimeDelta duration = window->layer()->GetAnimator()->
+ GetTransitionDuration();
scoped_ptr<ui::LayerAnimationElement> transition(
ui::LayerAnimationElement::CreateInterpolatedTransformElement(
@@ -136,6 +136,10 @@ void AddLayerAnimationsForMinimize(aura::Window* window, bool show) {
void AnimateShowWindow_Minimize(aura::Window* window) {
window->layer()->set_delegate(window);
window->layer()->SetOpacity(kWindowAnimation_HideOpacity);
+ ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
+ base::TimeDelta duration = base::TimeDelta::FromMilliseconds(
+ kLayerAnimationsForMinimizeDurationMS);
+ settings.SetTransitionDuration(duration);
AddLayerAnimationsForMinimize(window, true);
// Now that the window has been restored, we need to clear its animation style
diff --git a/ash/wm/window_animations_unittest.cc b/ash/wm/window_animations_unittest.cc
index c2ea1f6..eeeb120 100644
--- a/ash/wm/window_animations_unittest.cc
+++ b/ash/wm/window_animations_unittest.cc
@@ -6,13 +6,16 @@
#include "ash/shell_window_ids.h"
#include "ash/test/ash_test_base.h"
+#include "ash/wm/window_state.h"
#include "ash/wm/workspace_controller.h"
#include "base/time/time.h"
#include "ui/aura/test/test_windows.h"
#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
+#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/layer_animator.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
+#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/animation/animation_container_element.h"
using aura::Window;
@@ -33,6 +36,37 @@ class WindowAnimationsTest : public ash::test::AshTestBase {
DISALLOW_COPY_AND_ASSIGN(WindowAnimationsTest);
};
+// Listens to animation scheduled notifications. Remembers the transition
+// duration of the first sequence.
+class MinimizeAnimationObserver : public ui::LayerAnimationObserver {
+ public:
+ explicit MinimizeAnimationObserver(ui::LayerAnimator* animator)
+ : animator_(animator) {
+ animator_->AddObserver(this);
+ // RemoveObserver is called when the first animation is scheduled and so
+ // there should be no need for now to remove it in destructor.
+ };
+ base::TimeDelta duration() { return duration_; }
+
+ protected:
+ // ui::LayerAnimationObserver:
+ virtual void OnLayerAnimationScheduled(
+ ui::LayerAnimationSequence* sequence) OVERRIDE {
+ duration_ = animator_->GetTransitionDuration();
+ animator_->RemoveObserver(this);
+ }
+ virtual void OnLayerAnimationEnded(
+ ui::LayerAnimationSequence* sequence) OVERRIDE {}
+ virtual void OnLayerAnimationAborted(
+ ui::LayerAnimationSequence* sequence) OVERRIDE {}
+
+ private:
+ ui::LayerAnimator* animator_;
+ base::TimeDelta duration_;
+
+ DISALLOW_COPY_AND_ASSIGN(MinimizeAnimationObserver);
+};
+
TEST_F(WindowAnimationsTest, HideShowBrightnessGrayscaleAnimation) {
scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
window->Show();
@@ -133,5 +167,77 @@ TEST_F(WindowAnimationsTest, CrossFadeToBounds) {
Step(base::TimeTicks::Now() + base::TimeDelta::FromSeconds(1));
}
+TEST_F(WindowAnimationsTest, LockAnimationDuration) {
+ ui::ScopedAnimationDurationScaleMode normal_duration_mode(
+ ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
+
+ scoped_ptr<Window> window(CreateTestWindowInShellWithId(0));
+ Layer* layer = window->layer();
+ window->SetBounds(gfx::Rect(5, 10, 320, 240));
+ window->Show();
+
+ // Test that it is possible to override transition duration when it is not
+ // locked.
+ {
+ ui::ScopedLayerAnimationSettings settings1(layer->GetAnimator());
+ settings1.SetTransitionDuration(base::TimeDelta::FromMilliseconds(1000));
+ {
+ ui::ScopedLayerAnimationSettings settings2(layer->GetAnimator());
+ // Duration is not locked so it gets overridden.
+ settings2.SetTransitionDuration(base::TimeDelta::FromMilliseconds(50));
+ wm::GetWindowState(window.get())->Minimize();
+ EXPECT_TRUE(layer->GetAnimator()->is_animating());
+ // Expect duration from the inner scope
+ EXPECT_EQ(50,
+ layer->GetAnimator()->GetTransitionDuration().InMilliseconds());
+ }
+ window->Show();
+ layer->GetAnimator()->StopAnimating();
+ }
+
+ // Test that it is possible to lock transition duration
+ {
+ ui::ScopedLayerAnimationSettings settings1(layer->GetAnimator());
+ settings1.SetTransitionDuration(base::TimeDelta::FromMilliseconds(1000));
+ // Duration is locked in outer scope.
+ settings1.LockTransitionDuration();
+ {
+ ui::ScopedLayerAnimationSettings settings2(layer->GetAnimator());
+ // Transition duration setting is ignored.
+ settings2.SetTransitionDuration(base::TimeDelta::FromMilliseconds(50));
+ wm::GetWindowState(window.get())->Minimize();
+ EXPECT_TRUE(layer->GetAnimator()->is_animating());
+ // Expect duration from the outer scope
+ EXPECT_EQ(1000,
+ layer->GetAnimator()->GetTransitionDuration().InMilliseconds());
+ }
+ window->Show();
+ layer->GetAnimator()->StopAnimating();
+ }
+
+ // Test that duration respects default.
+ {
+ // Query default duration.
+ MinimizeAnimationObserver observer(layer->GetAnimator());
+ wm::GetWindowState(window.get())->Minimize();
+ EXPECT_TRUE(layer->GetAnimator()->is_animating());
+ base::TimeDelta default_duration(observer.duration());
+ window->Show();
+ layer->GetAnimator()->StopAnimating();
+
+ ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
+ settings.LockTransitionDuration();
+ // Setting transition duration is ignored since duration is locked
+ settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(1000));
+ wm::GetWindowState(window.get())->Minimize();
+ EXPECT_TRUE(layer->GetAnimator()->is_animating());
+ // Expect default duration (200ms for stock ash minimizing animation).
+ EXPECT_EQ(default_duration.InMilliseconds(),
+ layer->GetAnimator()->GetTransitionDuration().InMilliseconds());
+ window->Show();
+ layer->GetAnimator()->StopAnimating();
+ }
+}
+
} // namespace internal
} // namespace ash
diff --git a/ui/compositor/layer_animator.cc b/ui/compositor/layer_animator.cc
index dd727a6..0fad04a 100644
--- a/ui/compositor/layer_animator.cc
+++ b/ui/compositor/layer_animator.cc
@@ -55,6 +55,7 @@ gfx::AnimationContainer* GetAnimationContainer() {
LayerAnimator::LayerAnimator(base::TimeDelta transition_duration)
: delegate_(NULL),
preemption_strategy_(IMMEDIATELY_SET_NEW_TARGET),
+ is_transition_duration_locked_(false),
transition_duration_(transition_duration),
tween_type_(gfx::Tween::LINEAR),
is_started_(false),
@@ -118,6 +119,10 @@ ANIMATED_PROPERTY(float, BRIGHTNESS, Brightness, float, brightness);
ANIMATED_PROPERTY(float, GRAYSCALE, Grayscale, float, grayscale);
ANIMATED_PROPERTY(SkColor, COLOR, Color, SkColor, color);
+base::TimeDelta LayerAnimator::GetTransitionDuration() const {
+ return transition_duration_;
+}
+
void LayerAnimator::SetDelegate(LayerAnimationDelegate* delegate) {
delegate_ = delegate;
}
@@ -810,8 +815,10 @@ void LayerAnimator::OnScheduled(LayerAnimationSequence* sequence) {
sequence->OnScheduled();
}
-base::TimeDelta LayerAnimator::GetTransitionDuration() const {
- return transition_duration_;
+void LayerAnimator::SetTransitionDuration(base::TimeDelta duration) {
+ if (is_transition_duration_locked_)
+ return;
+ transition_duration_ = duration;
}
void LayerAnimator::ClearAnimationsInternal() {
diff --git a/ui/compositor/layer_animator.h b/ui/compositor/layer_animator.h
index 5fe0d5c..ad3754d 100644
--- a/ui/compositor/layer_animator.h
+++ b/ui/compositor/layer_animator.h
@@ -88,6 +88,10 @@ class COMPOSITOR_EXPORT LayerAnimator
virtual void SetColor(SkColor color);
SkColor GetTargetColor() const;
+ // Returns the default length of animations, including adjustment for slow
+ // animation mode if set.
+ base::TimeDelta GetTransitionDuration() const;
+
// Sets the layer animation delegate the animator is associated with. The
// animator does not own the delegate. The layer animator expects a non-NULL
// delegate for most of its operations, so do not call any methods without
@@ -294,9 +298,8 @@ class COMPOSITOR_EXPORT LayerAnimator
// starting the animation or adding to the queue.
void OnScheduled(LayerAnimationSequence* sequence);
- // Returns the default length of animations, including adjustment for slow
- // animation mode if set.
- base::TimeDelta GetTransitionDuration() const;
+ // Sets |transition_duration_| unless |is_transition_duration_locked_| is set.
+ void SetTransitionDuration(base::TimeDelta duration);
// Clears the animation queues and notifies any running animations that they
// have been aborted.
@@ -317,6 +320,10 @@ class COMPOSITOR_EXPORT LayerAnimator
// Determines how animations are replaced.
PreemptionStrategy preemption_strategy_;
+ // Whether the length of animations is locked. While it is locked
+ // SetTransitionDuration does not set |transition_duration_|.
+ bool is_transition_duration_locked_;
+
// The default length of animations.
base::TimeDelta transition_duration_;
diff --git a/ui/compositor/scoped_layer_animation_settings.cc b/ui/compositor/scoped_layer_animation_settings.cc
index b5bad67..84456ee 100644
--- a/ui/compositor/scoped_layer_animation_settings.cc
+++ b/ui/compositor/scoped_layer_animation_settings.cc
@@ -81,7 +81,9 @@ class InvertingObserver : public ImplicitAnimationObserver {
ScopedLayerAnimationSettings::ScopedLayerAnimationSettings(
LayerAnimator* animator)
: animator_(animator),
- old_transition_duration_(animator->transition_duration_),
+ old_is_transition_duration_locked_(
+ animator->is_transition_duration_locked_),
+ old_transition_duration_(animator->GetTransitionDuration()),
old_tween_type_(animator->tween_type()),
old_preemption_strategy_(animator->preemption_strategy()),
inverse_observer_(new InvertingObserver()) {
@@ -90,7 +92,9 @@ ScopedLayerAnimationSettings::ScopedLayerAnimationSettings(
}
ScopedLayerAnimationSettings::~ScopedLayerAnimationSettings() {
- animator_->transition_duration_ = old_transition_duration_;
+ animator_->is_transition_duration_locked_ =
+ old_is_transition_duration_locked_;
+ animator_->SetTransitionDuration(old_transition_duration_);
animator_->set_tween_type(old_tween_type_);
animator_->set_preemption_strategy(old_preemption_strategy_);
@@ -113,11 +117,15 @@ void ScopedLayerAnimationSettings::AddObserver(
void ScopedLayerAnimationSettings::SetTransitionDuration(
base::TimeDelta duration) {
- animator_->transition_duration_ = duration;
+ animator_->SetTransitionDuration(duration);
+}
+
+void ScopedLayerAnimationSettings::LockTransitionDuration() {
+ animator_->is_transition_duration_locked_ = true;
}
base::TimeDelta ScopedLayerAnimationSettings::GetTransitionDuration() const {
- return animator_->transition_duration_;
+ return animator_->GetTransitionDuration();
}
void ScopedLayerAnimationSettings::SetTweenType(gfx::Tween::Type tween_type) {
diff --git a/ui/compositor/scoped_layer_animation_settings.h b/ui/compositor/scoped_layer_animation_settings.h
index e36b853..e8a1b46 100644
--- a/ui/compositor/scoped_layer_animation_settings.h
+++ b/ui/compositor/scoped_layer_animation_settings.h
@@ -34,6 +34,12 @@ class COMPOSITOR_EXPORT ScopedLayerAnimationSettings {
void SetTransitionDuration(base::TimeDelta duration);
base::TimeDelta GetTransitionDuration() const;
+ // Locks transition duration in |animator_|. When transition duration
+ // is locked any subsequent changes to it are ignored until the
+ // ScopedLayerAnimationSettings object that has locked the duration goes out
+ // of scope.
+ void LockTransitionDuration();
+
void SetTweenType(gfx::Tween::Type tween_type);
gfx::Tween::Type GetTweenType() const;
@@ -50,6 +56,7 @@ class COMPOSITOR_EXPORT ScopedLayerAnimationSettings {
private:
LayerAnimator* animator_;
+ bool old_is_transition_duration_locked_;
base::TimeDelta old_transition_duration_;
gfx::Tween::Type old_tween_type_;
LayerAnimator::PreemptionStrategy old_preemption_strategy_;