Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <set> | |
| 10 #include <vector> | 11 #include <vector> |
| 11 | 12 |
| 12 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 13 #include "base/compiler_specific.h" | 14 #include "base/compiler_specific.h" |
| 14 #include "base/logging.h" | 15 #include "base/logging.h" |
| 15 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
| 16 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
| 17 #include "base/time/time.h" | 18 #include "base/time/time.h" |
| 18 #include "ui/aura/client/animation_host.h" | 19 #include "ui/aura/client/animation_host.h" |
| 19 #include "ui/aura/client/aura_constants.h" | 20 #include "ui/aura/client/aura_constants.h" |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 118 // destroyed when the stack unwinds. To handle this case, we start the hide | 119 // destroyed when the stack unwinds. To handle this case, we start the hide |
| 119 // animation immediately when the window is hidden, then when the window is | 120 // animation immediately when the window is hidden, then when the window is |
| 120 // subsequently destroyed this object acquires ownership of the window's layer, | 121 // subsequently destroyed this object acquires ownership of the window's layer, |
| 121 // so that it can continue animating it until the animation completes. | 122 // so that it can continue animating it until the animation completes. |
| 122 // Regardless of whether or not the window is destroyed, this object deletes | 123 // Regardless of whether or not the window is destroyed, this object deletes |
| 123 // itself when the animation completes. | 124 // itself when the animation completes. |
| 124 class HidingWindowAnimationObserver : public ui::ImplicitAnimationObserver, | 125 class HidingWindowAnimationObserver : public ui::ImplicitAnimationObserver, |
| 125 public aura::WindowObserver { | 126 public aura::WindowObserver { |
| 126 public: | 127 public: |
| 127 explicit HidingWindowAnimationObserver(aura::Window* window) | 128 explicit HidingWindowAnimationObserver(aura::Window* window) |
| 128 : window_(window) { | 129 : topmost_window_(window) { |
| 129 window_->AddObserver(this); | 130 topmost_window_->AddObserver(this); |
| 131 observed_.insert(topmost_window_); | |
| 130 } | 132 } |
| 131 virtual ~HidingWindowAnimationObserver() { | 133 virtual ~HidingWindowAnimationObserver() { |
| 132 STLDeleteElements(&layers_); | 134 STLDeleteElements(&layers_); |
| 135 | |
| 136 // |topmost_window_| should either be not destroyed or |topmost_window_| | |
| 137 // and all of its children should be destroyed. | |
| 138 // TODO(pkotwicz): Remove CHECK once it has been determined whether a child | |
| 139 // window outliving the end of |topmost_window_|'s animation is the source | |
| 140 // of the crash in crbug.com/338788 | |
| 141 CHECK(topmost_window_ || observed_.empty()); | |
|
sky
2014/02/05 21:38:15
If observed_ is not empty, is it possible to embed
| |
| 142 | |
| 143 for (std::set<aura::Window*>::const_iterator it = observed_.begin(); | |
| 144 it != observed_.end(); | |
| 145 ++it) { | |
| 146 (*it)->RemoveObserver(this); | |
| 147 } | |
| 133 } | 148 } |
| 134 | 149 |
| 135 private: | 150 private: |
| 136 // Overridden from ui::ImplicitAnimationObserver: | 151 // Overridden from ui::ImplicitAnimationObserver: |
| 137 virtual void OnImplicitAnimationsCompleted() OVERRIDE { | 152 virtual void OnImplicitAnimationsCompleted() OVERRIDE { |
| 138 // Window may have been destroyed by this point. | 153 // Window may have been destroyed by this point. |
| 139 if (window_) { | 154 if (topmost_window_) { |
| 140 aura::client::AnimationHost* animation_host = | 155 aura::client::AnimationHost* animation_host = |
| 141 aura::client::GetAnimationHost(window_); | 156 aura::client::GetAnimationHost(topmost_window_); |
| 142 if (animation_host) | 157 if (animation_host) |
| 143 animation_host->OnWindowHidingAnimationCompleted(); | 158 animation_host->OnWindowHidingAnimationCompleted(); |
| 144 window_->RemoveObserver(this); | |
| 145 } | 159 } |
| 146 delete this; | 160 delete this; |
| 147 } | 161 } |
| 148 | 162 |
| 149 // Overridden from aura::WindowObserver: | 163 // Overridden from aura::WindowObserver: |
| 150 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { | 164 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { |
| 151 DCHECK_EQ(window, window_); | 165 window->RemoveObserver(this); |
| 166 observed_.erase(window); | |
| 167 | |
| 168 if (window != topmost_window_) | |
| 169 return; | |
| 170 | |
| 171 // We acquire the layers of all of |topmost_window_|'s children with the | |
| 172 // assumption that they will be destroyed by the time that the animation | |
| 173 // terminates. Observe |topmost_window_|'s children to verify the | |
| 174 // assumption. | |
| 175 ObserveAllChildren(topmost_window_); | |
| 176 | |
| 152 DCHECK(layers_.empty()); | 177 DCHECK(layers_.empty()); |
| 153 AcquireAllLayers(window_); | 178 AcquireAllLayers(topmost_window_); |
| 154 | 179 |
| 155 // If the Widget has views with layers, then it is necessary to take | 180 // If the Widget has views with layers, then it is necessary to take |
| 156 // ownership of those layers too. | 181 // ownership of those layers too. |
| 157 views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window_); | 182 views::Widget* widget = views::Widget::GetWidgetForNativeWindow( |
| 183 topmost_window_); | |
| 158 const views::Widget* const_widget = widget; | 184 const views::Widget* const_widget = widget; |
| 159 if (widget && const_widget->GetRootView() && widget->GetContentsView()) | 185 if (widget && const_widget->GetRootView() && widget->GetContentsView()) |
| 160 AcquireAllViewLayers(widget->GetContentsView()); | 186 AcquireAllViewLayers(widget->GetContentsView()); |
| 161 window_->RemoveObserver(this); | 187 topmost_window_ = NULL; |
| 162 window_ = NULL; | 188 } |
| 189 | |
| 190 // Starts observing all of the windows in a subtree rooted at |window| | |
| 191 // excluding |window|. | |
| 192 void ObserveAllChildren(aura::Window* window) { | |
| 193 for (aura::Window::Windows::const_iterator it = window->children().begin(); | |
| 194 it != window->children().end(); | |
| 195 ++it) { | |
| 196 aura::Window* child = *it; | |
| 197 child->AddObserver(this); | |
| 198 observed_.insert(child); | |
| 199 ObserveAllChildren(child); | |
| 200 } | |
| 163 } | 201 } |
| 164 | 202 |
| 165 void AcquireAllLayers(aura::Window* window) { | 203 void AcquireAllLayers(aura::Window* window) { |
| 166 ui::Layer* layer = window->AcquireLayer(); | 204 ui::Layer* layer = window->AcquireLayer(); |
| 167 DCHECK(layer); | 205 DCHECK(layer); |
| 168 layers_.push_back(layer); | 206 layers_.push_back(layer); |
| 169 for (aura::Window::Windows::const_iterator it = window->children().begin(); | 207 for (aura::Window::Windows::const_iterator it = window->children().begin(); |
| 170 it != window->children().end(); | 208 it != window->children().end(); |
| 171 ++it) | 209 ++it) |
| 172 AcquireAllLayers(*it); | 210 AcquireAllLayers(*it); |
| 173 } | 211 } |
| 174 | 212 |
| 175 void AcquireAllViewLayers(views::View* view) { | 213 void AcquireAllViewLayers(views::View* view) { |
| 176 for (int i = 0; i < view->child_count(); ++i) | 214 for (int i = 0; i < view->child_count(); ++i) |
| 177 AcquireAllViewLayers(view->child_at(i)); | 215 AcquireAllViewLayers(view->child_at(i)); |
| 178 if (view->layer()) { | 216 if (view->layer()) { |
| 179 ui::Layer* layer = view->RecreateLayer(); | 217 ui::Layer* layer = view->RecreateLayer(); |
| 180 if (layer) { | 218 if (layer) { |
| 181 layer->SuppressPaint(); | 219 layer->SuppressPaint(); |
| 182 layers_.push_back(layer); | 220 layers_.push_back(layer); |
| 183 } | 221 } |
| 184 } | 222 } |
| 185 } | 223 } |
| 186 | 224 |
| 187 aura::Window* window_; | 225 aura::Window* topmost_window_; |
| 226 | |
| 227 // The set of windows observed by this class. | |
| 228 std::set<aura::Window*> observed_; | |
| 229 | |
| 188 std::vector<ui::Layer*> layers_; | 230 std::vector<ui::Layer*> layers_; |
| 189 | 231 |
| 190 DISALLOW_COPY_AND_ASSIGN(HidingWindowAnimationObserver); | 232 DISALLOW_COPY_AND_ASSIGN(HidingWindowAnimationObserver); |
| 191 }; | 233 }; |
| 192 | 234 |
| 193 void GetTransformRelativeToRoot(ui::Layer* layer, gfx::Transform* transform) { | 235 void GetTransformRelativeToRoot(ui::Layer* layer, gfx::Transform* transform) { |
| 194 const Layer* root = layer; | 236 const Layer* root = layer; |
| 195 while (root->parent()) | 237 while (root->parent()) |
| 196 root = root->parent(); | 238 root = root->parent(); |
| 197 layer->GetTargetTransformRelativeTo(root, transform); | 239 layer->GetTargetTransformRelativeTo(root, transform); |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 569 | 611 |
| 570 bool WindowAnimationsDisabled(aura::Window* window) { | 612 bool WindowAnimationsDisabled(aura::Window* window) { |
| 571 return (!gfx::Animation::ShouldRenderRichAnimation() || (window && | 613 return (!gfx::Animation::ShouldRenderRichAnimation() || (window && |
| 572 window->GetProperty(aura::client::kAnimationsDisabledKey)) || | 614 window->GetProperty(aura::client::kAnimationsDisabledKey)) || |
| 573 CommandLine::ForCurrentProcess()->HasSwitch( | 615 CommandLine::ForCurrentProcess()->HasSwitch( |
| 574 switches::kWindowAnimationsDisabled)); | 616 switches::kWindowAnimationsDisabled)); |
| 575 } | 617 } |
| 576 | 618 |
| 577 } // namespace corewm | 619 } // namespace corewm |
| 578 } // namespace views | 620 } // namespace views |
| OLD | NEW |