Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(209)

Side by Side Diff: ui/views/corewm/window_animations.cc

Issue 180273025: Keep dedicated layers for hiding animation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/corewm/window_animations.h" 5 #include "ui/views/corewm/window_animations.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <vector> 10 #include <vector>
(...skipping 16 matching lines...) Expand all
27 #include "ui/compositor/layer_animation_sequence.h" 27 #include "ui/compositor/layer_animation_sequence.h"
28 #include "ui/compositor/layer_animator.h" 28 #include "ui/compositor/layer_animator.h"
29 #include "ui/compositor/scoped_layer_animation_settings.h" 29 #include "ui/compositor/scoped_layer_animation_settings.h"
30 #include "ui/gfx/animation/animation.h" 30 #include "ui/gfx/animation/animation.h"
31 #include "ui/gfx/interpolated_transform.h" 31 #include "ui/gfx/interpolated_transform.h"
32 #include "ui/gfx/rect_conversions.h" 32 #include "ui/gfx/rect_conversions.h"
33 #include "ui/gfx/screen.h" 33 #include "ui/gfx/screen.h"
34 #include "ui/gfx/vector2d.h" 34 #include "ui/gfx/vector2d.h"
35 #include "ui/gfx/vector3d_f.h" 35 #include "ui/gfx/vector3d_f.h"
36 #include "ui/views/corewm/corewm_switches.h" 36 #include "ui/views/corewm/corewm_switches.h"
37 #include "ui/views/corewm/transient_window_manager.h"
37 #include "ui/views/corewm/window_util.h" 38 #include "ui/views/corewm/window_util.h"
38 39
39 DECLARE_WINDOW_PROPERTY_TYPE(int) 40 DECLARE_WINDOW_PROPERTY_TYPE(int)
40 DECLARE_WINDOW_PROPERTY_TYPE(views::corewm::WindowVisibilityAnimationType) 41 DECLARE_WINDOW_PROPERTY_TYPE(views::corewm::WindowVisibilityAnimationType)
41 DECLARE_WINDOW_PROPERTY_TYPE(views::corewm::WindowVisibilityAnimationTransition) 42 DECLARE_WINDOW_PROPERTY_TYPE(views::corewm::WindowVisibilityAnimationTransition)
42 DECLARE_WINDOW_PROPERTY_TYPE(float) 43 DECLARE_WINDOW_PROPERTY_TYPE(float)
43 DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(VIEWS_EXPORT, bool) 44 DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(VIEWS_EXPORT, bool)
44 45
45 using aura::Window; 46 using aura::Window;
46 using base::TimeDelta; 47 using base::TimeDelta;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 // animation immediately when the window is hidden, then when the window is 118 // animation immediately when the window is hidden, then when the window is
118 // subsequently destroyed this object acquires ownership of the window's layer, 119 // subsequently destroyed this object acquires ownership of the window's layer,
119 // so that it can continue animating it until the animation completes. 120 // so that it can continue animating it until the animation completes.
120 // Regardless of whether or not the window is destroyed, this object deletes 121 // Regardless of whether or not the window is destroyed, this object deletes
121 // itself when the animation completes. 122 // itself when the animation completes.
122 class HidingWindowAnimationObserver : public ui::ImplicitAnimationObserver, 123 class HidingWindowAnimationObserver : public ui::ImplicitAnimationObserver,
123 public aura::WindowObserver { 124 public aura::WindowObserver {
124 public: 125 public:
125 explicit HidingWindowAnimationObserver(aura::Window* window) 126 explicit HidingWindowAnimationObserver(aura::Window* window)
126 : window_(window) { 127 : window_(window) {
127 window_->AddObserver(this); 128 window_->AddObserver(this);
sky 2014/03/07 15:14:54 This code previously cared about the window so tha
oshima 2014/03/08 00:14:30 I tried that but it broke the test due to the Anim
128 } 129 }
130
129 virtual ~HidingWindowAnimationObserver() { 131 virtual ~HidingWindowAnimationObserver() {
130 STLDeleteElements(&layers_); 132 }
133
134 void DetachAndRecreateLayers() {
135 layer_.reset(views::corewm::RecreateWindowLayers(window_, true));
sky 2014/03/07 15:14:54 nit: don't need views::corem here as you're in tha
sky 2014/03/07 15:14:54 Layer does not own its children. So, the way you h
Ben Goodger (Google) 2014/03/07 15:51:54 Yeah RecreateWindowLayers seems like a weird API.
sky 2014/03/07 16:34:57 I'm going to change the return value of RecreateWi
oshima 2014/03/08 00:14:30 Fixed to use DeepDeleteLayers for now. I'll update
136 // Use const window to avoid creating a TransientWindowManager
137 // if the window doesn't have one.
138 const aura::Window* const_window = window_;
sky 2014/03/07 15:14:54 If you use the function in window_util it'll do th
oshima 2014/03/08 00:14:30 Ah, I didn't see that. Fixed
139 const TransientWindowManager* transient_window_manager =
140 TransientWindowManager::Get(const_window);
141 // If the window has transient children, move above the top most
sky 2014/03/07 15:14:54 Document why you need to do this.
oshima 2014/03/08 00:14:30 Done.
142 // transient child.
143 if (transient_window_manager) {
144 const aura::Window::Windows& transient_children =
145 transient_window_manager->transient_children();
146 aura::Window::Windows::const_iterator iter =
147 std::find(window_->parent()->children().begin(),
148 window_->parent()->children().end(),
149 window_);
150 aura::Window* topmost_transient_child = NULL;
151 DCHECK(iter != window_->parent()->children().end());
152 for (++iter; iter != window_->parent()->children().end(); ++iter) {
153 if (std::find(transient_children.begin(),
154 transient_children.end(),
155 *iter) !=
156 transient_children.end()) {
157 topmost_transient_child = *iter;
158 }
159 }
160 if (topmost_transient_child) {
161 window_->parent()->layer()->StackAbove(
162 layer_.get(), topmost_transient_child->layer());
163 }
164 }
165 // Make the new layer unvisible immediately.
Ben Goodger (Google) 2014/03/07 15:51:54 invisible
oshima 2014/03/08 00:14:30 Done.
166 window_->layer()->SetVisible(false);
167 window_->layer()->SetOpacity(0);
131 } 168 }
132 169
133 private: 170 private:
134 // Overridden from ui::ImplicitAnimationObserver: 171 // Overridden from ui::ImplicitAnimationObserver:
135 virtual void OnImplicitAnimationsCompleted() OVERRIDE { 172 virtual void OnImplicitAnimationsCompleted() OVERRIDE {
136 // Window may have been destroyed by this point. 173 // Window may have been destroyed by this point.
137 if (window_) { 174 if (window_) {
138 aura::client::AnimationHost* animation_host = 175 aura::client::AnimationHost* animation_host =
139 aura::client::GetAnimationHost(window_); 176 aura::client::GetAnimationHost(window_);
140 if (animation_host) 177 if (animation_host)
141 animation_host->OnWindowHidingAnimationCompleted(); 178 animation_host->OnWindowHidingAnimationCompleted();
142 window_->RemoveObserver(this); 179 window_->RemoveObserver(this);
143 } 180 }
144 delete this; 181 delete this;
145 } 182 }
146 183
147 // Overridden from aura::WindowObserver: 184 // Overridden from aura::WindowObserver:
148 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { 185 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
149 DCHECK_EQ(window, window_); 186 DCHECK_EQ(window, window_);
150 DCHECK(layers_.empty());
151 AcquireAllLayers(window_->layer());
152 window_->RemoveObserver(this); 187 window_->RemoveObserver(this);
153 window_ = NULL; 188 window_ = NULL;
154 } 189 }
155 190
156 void AcquireAllLayers(ui::Layer* layer) { 191 aura::Window* window_;
157 if (layer->owner()) { 192 scoped_ptr<ui::Layer> layer_;
158 ui::Layer* released = layer->owner()->AcquireLayer(); 193
159 DCHECK_EQ(layer, released); 194 DISALLOW_COPY_AND_ASSIGN(HidingWindowAnimationObserver);
160 layers_.push_back(released); 195 };
161 } 196
162 std::vector<Layer*>::const_iterator it = layer->children().begin(); 197 class ScopedLayerDetacher {
sky 2014/03/07 15:14:54 Description?
oshima 2014/03/08 00:14:30 Moved to header and added comment.
163 for (; it != layer->children().end(); ++it) 198 public:
164 AcquireAllLayers(*it); 199 explicit ScopedLayerDetacher(HidingWindowAnimationObserver* observer)
200 : observer_(observer) {}
201 ~ScopedLayerDetacher() {
202 observer_->DetachAndRecreateLayers();
165 } 203 }
166 204
167 aura::Window* window_; 205 HidingWindowAnimationObserver* observer() { return observer_; }
168 std::vector<ui::Layer*> layers_;
169 206
170 DISALLOW_COPY_AND_ASSIGN(HidingWindowAnimationObserver); 207 private:
208 HidingWindowAnimationObserver* observer_ ; // not owned.
209
210 DISALLOW_COPY_AND_ASSIGN(ScopedLayerDetacher);
171 }; 211 };
172 212
173 void GetTransformRelativeToRoot(ui::Layer* layer, gfx::Transform* transform) { 213 void GetTransformRelativeToRoot(ui::Layer* layer, gfx::Transform* transform) {
174 const Layer* root = layer; 214 const Layer* root = layer;
175 while (root->parent()) 215 while (root->parent())
176 root = root->parent(); 216 root = root->parent();
177 layer->GetTargetTransformRelativeTo(root, transform); 217 layer->GetTargetTransformRelativeTo(root, transform);
178 } 218 }
179 219
180 gfx::Rect GetLayerWorldBoundsAfterTransform(ui::Layer* layer, 220 gfx::Rect GetLayerWorldBoundsAfterTransform(ui::Layer* layer,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 288
249 // Hides a window using an animation, animating its opacity from 1.f to 0.f, 289 // Hides a window using an animation, animating its opacity from 1.f to 0.f,
250 // its visibility to false, and its transform to |end_transform|. 290 // its visibility to false, and its transform to |end_transform|.
251 void AnimateHideWindowCommon(aura::Window* window, 291 void AnimateHideWindowCommon(aura::Window* window,
252 const gfx::Transform& end_transform) { 292 const gfx::Transform& end_transform) {
253 AugmentWindowSize(window, end_transform); 293 AugmentWindowSize(window, end_transform);
254 window->layer()->set_delegate(NULL); 294 window->layer()->set_delegate(NULL);
255 295
256 // Property sets within this scope will be implicitly animated. 296 // Property sets within this scope will be implicitly animated.
257 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); 297 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
258 settings.AddObserver(new HidingWindowAnimationObserver(window)); 298 ScopedLayerDetacher detacher(new HidingWindowAnimationObserver(window));
299 settings.AddObserver(detacher.observer());
259 300
260 base::TimeDelta duration = GetWindowVisibilityAnimationDuration(*window); 301 base::TimeDelta duration = GetWindowVisibilityAnimationDuration(*window);
261 if (duration.ToInternalValue() > 0) 302 if (duration.ToInternalValue() > 0)
262 settings.SetTransitionDuration(duration); 303 settings.SetTransitionDuration(duration);
263 304
264 window->layer()->SetOpacity(kWindowAnimation_HideOpacity); 305 window->layer()->SetOpacity(kWindowAnimation_HideOpacity);
265 window->layer()->SetTransform(end_transform); 306 window->layer()->SetTransform(end_transform);
266 window->layer()->SetVisible(false); 307 window->layer()->SetVisible(false);
267 } 308 }
268 309
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 window->layer()->GetAnimator()->StartAnimation(sequence.release()); 391 window->layer()->GetAnimator()->StartAnimation(sequence.release());
351 } 392 }
352 393
353 void AddLayerAnimationsForRotate(aura::Window* window, bool show) { 394 void AddLayerAnimationsForRotate(aura::Window* window, bool show) {
354 window->layer()->set_delegate(window); 395 window->layer()->set_delegate(window);
355 if (show) 396 if (show)
356 window->layer()->SetOpacity(kWindowAnimation_HideOpacity); 397 window->layer()->SetOpacity(kWindowAnimation_HideOpacity);
357 398
358 base::TimeDelta duration = base::TimeDelta::FromMilliseconds( 399 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(
359 kWindowAnimation_Rotate_DurationMS); 400 kWindowAnimation_Rotate_DurationMS);
401 scoped_ptr<ScopedLayerDetacher> layer_detacher;
360 402
361 if (!show) { 403 if (!show) {
362 new HidingWindowAnimationObserver(window); 404 layer_detacher.reset(new ScopedLayerDetacher(
405 new HidingWindowAnimationObserver(window)));
363 window->layer()->GetAnimator()->SchedulePauseForProperties( 406 window->layer()->GetAnimator()->SchedulePauseForProperties(
364 duration * (100 - kWindowAnimation_Rotate_OpacityDurationPercent) / 100, 407 duration * (100 - kWindowAnimation_Rotate_OpacityDurationPercent) / 100,
365 ui::LayerAnimationElement::OPACITY); 408 ui::LayerAnimationElement::OPACITY);
366 } 409 }
367 scoped_ptr<ui::LayerAnimationElement> opacity( 410 scoped_ptr<ui::LayerAnimationElement> opacity(
368 ui::LayerAnimationElement::CreateOpacityElement( 411 ui::LayerAnimationElement::CreateOpacityElement(
369 show ? kWindowAnimation_ShowOpacity : kWindowAnimation_HideOpacity, 412 show ? kWindowAnimation_ShowOpacity : kWindowAnimation_HideOpacity,
370 duration * kWindowAnimation_Rotate_OpacityDurationPercent / 100)); 413 duration * kWindowAnimation_Rotate_OpacityDurationPercent / 100));
371 opacity->set_tween_type(gfx::Tween::EASE_IN_OUT); 414 opacity->set_tween_type(gfx::Tween::EASE_IN_OUT);
372 window->layer()->GetAnimator()->ScheduleAnimation( 415 window->layer()->GetAnimator()->ScheduleAnimation(
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 window.GetProperty(kWindowVisibilityAnimationDurationKey)); 559 window.GetProperty(kWindowVisibilityAnimationDurationKey));
517 } 560 }
518 561
519 void SetWindowVisibilityAnimationVerticalPosition(aura::Window* window, 562 void SetWindowVisibilityAnimationVerticalPosition(aura::Window* window,
520 float position) { 563 float position) {
521 window->SetProperty(kWindowVisibilityAnimationVerticalPositionKey, position); 564 window->SetProperty(kWindowVisibilityAnimationVerticalPositionKey, position);
522 } 565 }
523 566
524 ui::ImplicitAnimationObserver* CreateHidingWindowAnimationObserver( 567 ui::ImplicitAnimationObserver* CreateHidingWindowAnimationObserver(
525 aura::Window* window) { 568 aura::Window* window) {
526 return new HidingWindowAnimationObserver(window); 569 return new HidingWindowAnimationObserver(window);
Ben Goodger (Google) 2014/03/07 15:51:54 do you run into the same problem when this method
oshima 2014/03/08 00:14:30 Thanks. I looked at usages and looks like I should
527 } 570 }
528 571
529 bool AnimateOnChildWindowVisibilityChanged(aura::Window* window, bool visible) { 572 bool AnimateOnChildWindowVisibilityChanged(aura::Window* window, bool visible) {
530 if (WindowAnimationsDisabled(window)) 573 if (WindowAnimationsDisabled(window))
531 return false; 574 return false;
532 if (visible) 575 if (visible)
533 return AnimateShowWindow(window); 576 return AnimateShowWindow(window);
534 // Don't start hiding the window again if it's already being hidden. 577 // Don't start hiding the window again if it's already being hidden.
535 return window->layer()->GetTargetOpacity() != 0.0f && 578 return window->layer()->GetTargetOpacity() != 0.0f &&
536 AnimateHideWindow(window); 579 AnimateHideWindow(window);
(...skipping 12 matching lines...) Expand all
549 592
550 bool WindowAnimationsDisabled(aura::Window* window) { 593 bool WindowAnimationsDisabled(aura::Window* window) {
551 return (!gfx::Animation::ShouldRenderRichAnimation() || (window && 594 return (!gfx::Animation::ShouldRenderRichAnimation() || (window &&
552 window->GetProperty(aura::client::kAnimationsDisabledKey)) || 595 window->GetProperty(aura::client::kAnimationsDisabledKey)) ||
553 CommandLine::ForCurrentProcess()->HasSwitch( 596 CommandLine::ForCurrentProcess()->HasSwitch(
554 switches::kWindowAnimationsDisabled)); 597 switches::kWindowAnimationsDisabled));
555 } 598 }
556 599
557 } // namespace corewm 600 } // namespace corewm
558 } // namespace views 601 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/corewm/visibility_controller_unittest.cc ('k') | ui/views/corewm/window_animations_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698