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

Side by Side Diff: ash/wm/compact_layout_manager.cc

Issue 9388018: Compact layout mananger animates windows rather than the default container layer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 10 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
« no previous file with comments | « ash/wm/compact_layout_manager.h ('k') | ash/wm/compact_layout_manager_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "ash/wm/compact_layout_manager.h" 5 #include "ash/wm/compact_layout_manager.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "ash/shell.h" 9 #include "ash/shell.h"
10 #include "ash/shell_delegate.h" 10 #include "ash/shell_delegate.h"
11 #include "ash/shell_window_ids.h" 11 #include "ash/shell_window_ids.h"
12 #include "ash/wm/window_util.h" 12 #include "ash/wm/window_util.h"
13 #include "base/memory/scoped_vector.h"
13 #include "ui/aura/client/aura_constants.h" 14 #include "ui/aura/client/aura_constants.h"
14 #include "ui/aura/window.h" 15 #include "ui/aura/window.h"
15 #include "ui/gfx/compositor/scoped_layer_animation_settings.h" 16 #include "ui/gfx/compositor/scoped_layer_animation_settings.h"
16 #include "ui/gfx/compositor/layer.h" 17 #include "ui/gfx/compositor/layer.h"
17 #include "ui/gfx/compositor/layer_animation_sequence.h" 18 #include "ui/gfx/compositor/layer_animation_sequence.h"
18 #include "ui/gfx/screen.h" 19 #include "ui/gfx/screen.h"
19 #include "ui/views/widget/widget.h" 20 #include "ui/views/widget/widget.h"
20 21
21 namespace ash { 22 namespace ash {
22 namespace internal { 23 namespace internal {
23 24
24 namespace { 25 namespace {
25 26
26 typedef std::vector<aura::Window*> WindowList; 27 typedef std::vector<aura::Window*> WindowList;
27 typedef std::vector<aura::Window*>::const_iterator WindowListConstIter; 28 typedef std::vector<aura::Window*>::const_iterator WindowListConstIter;
28 29
29 // Convenience method to get the layer of this container. 30 // Convenience method to get the layer of this container.
30 ui::Layer* GetDefaultContainerLayer() { 31 ui::Layer* GetDefaultContainerLayer() {
31 return Shell::GetInstance()->GetContainer( 32 return Shell::GetInstance()->GetContainer(
32 internal::kShellWindowId_DefaultContainer)->layer(); 33 internal::kShellWindowId_DefaultContainer)->layer();
33 } 34 }
34 35
35 // Whether it is a window that should be animated on entrance. 36 // Whether it is a window that should be animated on entrance.
36 bool ShouldAnimateOnEntrance(aura::Window* window) { 37 bool ShouldAnimateOnEntrance(aura::Window* window) {
37 return window && 38 return window &&
38 window->type() == aura::client::WINDOW_TYPE_NORMAL && 39 window->type() == aura::client::WINDOW_TYPE_NORMAL &&
39 window_util::IsWindowMaximized(window); 40 window_util::IsWindowMaximized(window);
40 } 41 }
41 42
42 // Adjust layer bounds to grow or shrink in |delta_width|.
43 void AdjustContainerLayerWidth(int delta_width) {
44 gfx::Rect bounds(GetDefaultContainerLayer()->bounds());
45 bounds.set_width(bounds.width() + delta_width);
46 GetDefaultContainerLayer()->SetBounds(bounds);
47 GetDefaultContainerLayer()->GetCompositor()->WidgetSizeChanged(
48 GetDefaultContainerLayer()->bounds().size());
49 }
50 } // namespace 43 } // namespace
51 44
52 ///////////////////////////////////////////////////////////////////////////// 45 /////////////////////////////////////////////////////////////////////////////
53 // CompactLayoutManager, public: 46 // CompactLayoutManager, public:
54 47
55 CompactLayoutManager::CompactLayoutManager() 48 CompactLayoutManager::CompactLayoutManager()
56 : status_area_widget_(NULL), 49 : status_area_widget_(NULL),
57 current_window_(NULL) { 50 current_window_(NULL) {
58 } 51 }
59 52
60 CompactLayoutManager::~CompactLayoutManager() { 53 CompactLayoutManager::~CompactLayoutManager() {
61 } 54 }
62 55
63 ///////////////////////////////////////////////////////////////////////////// 56 /////////////////////////////////////////////////////////////////////////////
64 // CompactLayoutManager, LayoutManager overrides: 57 // CompactLayoutManager, LayoutManager overrides:
65 58
66 void CompactLayoutManager::OnWindowAddedToLayout(aura::Window* child) { 59 void CompactLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
67 // Windows added to this container does not need extra animation. 60 // Windows added to this container does not need extra animation.
68 if (child->type() == aura::client::WINDOW_TYPE_NORMAL) 61 if (child->type() == aura::client::WINDOW_TYPE_NORMAL)
69 child->SetProperty(aura::client::kAnimationsDisabledKey, true); 62 child->SetProperty(aura::client::kAnimationsDisabledKey, true);
70 BaseLayoutManager::OnWindowAddedToLayout(child); 63 BaseLayoutManager::OnWindowAddedToLayout(child);
71 UpdateStatusAreaVisibility(); 64 UpdateStatusAreaVisibility();
72 if (windows().size() > 1 &&
73 child->type() == aura::client::WINDOW_TYPE_NORMAL) {
74 // The first window is already contained in the current layer,
75 // add subsequent windows to layer bounds calculation.
76 AdjustContainerLayerWidth(child->bounds().width());
77 }
78 } 65 }
79 66
80 void CompactLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) { 67 void CompactLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) {
81 BaseLayoutManager::OnWillRemoveWindowFromLayout(child); 68 BaseLayoutManager::OnWillRemoveWindowFromLayout(child);
82 UpdateStatusAreaVisibility(); 69 UpdateStatusAreaVisibility();
83 if (windows().size() > 1 && ShouldAnimateOnEntrance(child))
84 AdjustContainerLayerWidth(-child->bounds().width());
85
86 if (child == current_window_) { 70 if (child == current_window_) {
87 LayoutWindows(current_window_); 71 LayoutWindows(current_window_);
88 SwitchToReplacementWindow(); 72 SwitchToReplacementWindow();
89 } 73 }
90 // Allow window to be animated by others. 74 // Allow window to be animated by others.
91 if (child->type() == aura::client::WINDOW_TYPE_NORMAL) 75 if (child->type() == aura::client::WINDOW_TYPE_NORMAL)
92 child->SetProperty(aura::client::kAnimationsDisabledKey, false); 76 child->SetProperty(aura::client::kAnimationsDisabledKey, false);
93 } 77 }
94 78
95 void CompactLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child, 79 void CompactLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 } 131 }
148 // Animate to |window| when there is a stacking change. 132 // Animate to |window| when there is a stacking change.
149 AnimateSlideTo(window->bounds().x()); 133 AnimateSlideTo(window->bounds().x());
150 } 134 }
151 } 135 }
152 136
153 ///////////////////////////////////////////////////////////////////////////// 137 /////////////////////////////////////////////////////////////////////////////
154 // CompactLayoutManager, AnimationDelegate overrides: 138 // CompactLayoutManager, AnimationDelegate overrides:
155 139
156 void CompactLayoutManager::OnImplicitAnimationsCompleted() { 140 void CompactLayoutManager::OnImplicitAnimationsCompleted() {
157 if (!GetDefaultContainerLayer()->GetAnimator()->is_animating()) 141 if (AreWindowsAnimating())
158 HideWindows(); 142 return;
143 HideWindows();
159 } 144 }
160 145
161 ////////////////////////////////////////////////////////////////////////////// 146 //////////////////////////////////////////////////////////////////////////////
162 // CompactLayoutManager, private: 147 // CompactLayoutManager, private:
163 148
164 void CompactLayoutManager::UpdateStatusAreaVisibility() { 149 void CompactLayoutManager::UpdateStatusAreaVisibility() {
165 if (!status_area_widget_) 150 if (!status_area_widget_)
166 return; 151 return;
167 // Full screen windows should hide the status area widget. 152 // Full screen windows should hide the status area widget.
168 bool has_fullscreen = window_util::HasFullscreenWindow(windows()); 153 bool has_fullscreen = window_util::HasFullscreenWindow(windows());
169 bool widget_visible = status_area_widget_->IsVisible(); 154 bool widget_visible = status_area_widget_->IsVisible();
170 if (has_fullscreen && widget_visible) 155 if (has_fullscreen && widget_visible)
171 status_area_widget_->Hide(); 156 status_area_widget_->Hide();
172 else if (!has_fullscreen && !widget_visible) 157 else if (!has_fullscreen && !widget_visible)
173 status_area_widget_->Show(); 158 status_area_widget_->Show();
174 } 159 }
175 160
176 void CompactLayoutManager::AnimateSlideTo(int offset_x) { 161 void CompactLayoutManager::AnimateSlideTo(int offset_x) {
177 GetDefaultContainerLayer()->GetAnimator()->RemoveObserver(this); 162 // If we were waiting for another implicit animation to complete, forget
178 ui::ScopedLayerAnimationSettings settings( 163 // about it since we're about to start observing a new animation.
179 GetDefaultContainerLayer()->GetAnimator()); 164 StopObservingImplicitAnimations();
180 settings.AddObserver(this); 165 ScopedVector<ui::ScopedLayerAnimationSettings> settings;
181 ui::Transform transform; 166 ShellDelegate* shell_delegate = ash::Shell::GetInstance()->delegate();
182 transform.ConcatTranslate(-offset_x, 0); 167 const WindowList& windows_list = shell_delegate->GetCycleWindowList(
183 GetDefaultContainerLayer()->SetTransform(transform); // Will be animated! 168 ShellDelegate::SOURCE_KEYBOARD,
169 ShellDelegate::ORDER_LINEAR);
170 for (WindowListConstIter const_it = windows_list.begin();
171 const_it != windows_list.end();
172 ++const_it) {
173 settings.push_back(new ui::ScopedLayerAnimationSettings(
174 (*const_it)->layer()->GetAnimator()));
175 settings[settings.size() - 1]->AddObserver(this);
alicet1 2012/02/14 16:04:39 settings.back()?
176 settings[settings.size() - 1]->SetPreemptionStrategy(
177 ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
178 gfx::Rect bounds = (*const_it)->layer()->bounds();
alicet1 2012/02/14 16:04:39 should this be GetTargetBounds() ?
179 bounds.Offset(-offset_x, 0);
180 (*const_it)->layer()->SetBounds(bounds);
181 }
182 }
183
184 bool CompactLayoutManager::AreWindowsAnimating() const {
185 ShellDelegate* shell_delegate = ash::Shell::GetInstance()->delegate();
186 const WindowList& windows_list = shell_delegate->GetCycleWindowList(
187 ShellDelegate::SOURCE_KEYBOARD,
188 ShellDelegate::ORDER_LINEAR);
189 for (WindowListConstIter const_it = windows_list.begin();
190 const_it != windows_list.end();
191 ++const_it) {
192 if ((*const_it)->layer()->GetAnimator()->is_animating())
193 return true;
194 }
195 return false;
184 } 196 }
185 197
186 void CompactLayoutManager::LayoutWindows(aura::Window* skip) { 198 void CompactLayoutManager::LayoutWindows(aura::Window* skip) {
187 ShellDelegate* shell_delegate = ash::Shell::GetInstance()->delegate(); 199 ShellDelegate* shell_delegate = ash::Shell::GetInstance()->delegate();
188 const WindowList& windows_list = shell_delegate->GetCycleWindowList( 200 const WindowList& windows_list = shell_delegate->GetCycleWindowList(
189 ShellDelegate::SOURCE_KEYBOARD, 201 ShellDelegate::SOURCE_KEYBOARD,
190 ShellDelegate::ORDER_LINEAR); 202 ShellDelegate::ORDER_LINEAR);
203 bool first_window = true;
191 int new_x = 0; 204 int new_x = 0;
192 for (WindowListConstIter const_it = windows_list.begin(); 205 for (WindowListConstIter const_it = windows_list.begin();
193 const_it != windows_list.end(); 206 const_it != windows_list.end();
194 ++const_it) { 207 ++const_it) {
195 if (*const_it != skip) { 208 if (*const_it != skip) {
196 gfx::Rect new_bounds((*const_it)->bounds()); 209 gfx::Rect new_bounds((*const_it)->bounds());
197 new_bounds.set_x(new_x); 210 if (first_window) {
211 new_x = new_bounds.x();
212 first_window = false;
213 } else
214 new_bounds.set_x(new_x);
198 SetChildBoundsDirect(*const_it, new_bounds); 215 SetChildBoundsDirect(*const_it, new_bounds);
199 (*const_it)->layer()->SetVisible(true); 216 (*const_it)->layer()->SetVisible(true);
200 new_x += (*const_it)->bounds().width(); 217 new_x += (*const_it)->bounds().width();
201 } 218 }
202 } 219 }
203 } 220 }
204 221
205 void CompactLayoutManager::HideWindows() { 222 void CompactLayoutManager::HideWindows() {
206 // If we do not know which one is the current window, or if the current 223 // If we do not know which one is the current window, or if the current
207 // window is not visible, do not attempt to hide the windows. 224 // window is not visible, do not attempt to hide the windows.
208 if (current_window_ == NULL) 225 if (current_window_ == NULL)
209 return; 226 return;
210 // Current window should be visible, if not it is an error and we shouldn't 227 // Current window should be visible, if not it is an error and we shouldn't
211 // proceed. 228 // proceed.
212 if (!current_window_->layer()->visible()) 229 if (!current_window_->layer()->visible())
213 NOTREACHED() << "Current window is invisible"; 230 NOTREACHED() << "Current window is invisible";
214 231
215 ShellDelegate* shell_delegate = ash::Shell::GetInstance()->delegate(); 232 ShellDelegate* shell_delegate = ash::Shell::GetInstance()->delegate();
216 const WindowList& windows_list = shell_delegate->GetCycleWindowList( 233 const WindowList& windows_list = shell_delegate->GetCycleWindowList(
217 ShellDelegate::SOURCE_KEYBOARD, 234 ShellDelegate::SOURCE_KEYBOARD,
218 ShellDelegate::ORDER_LINEAR); 235 ShellDelegate::ORDER_LINEAR);
219 for (WindowListConstIter const_it = windows_list.begin(); 236 for (WindowListConstIter const_it = windows_list.begin();
220 const_it != windows_list.end(); 237 const_it != windows_list.end();
221 ++const_it) { 238 ++const_it) {
222 if (*const_it != current_window_) 239 if (*const_it != current_window_ &&
240 (*const_it)->layer()->GetTargetVisibility())
223 (*const_it)->layer()->SetVisible(false); 241 (*const_it)->layer()->SetVisible(false);
224 } 242 }
225 } 243 }
226 244
227 aura::Window* CompactLayoutManager::FindReplacementWindow( 245 aura::Window* CompactLayoutManager::FindReplacementWindow(
228 aura::Window* window) { 246 aura::Window* window) {
229 ShellDelegate* shell_delegate = ash::Shell::GetInstance()->delegate(); 247 ShellDelegate* shell_delegate = ash::Shell::GetInstance()->delegate();
230 const WindowList& windows_list = shell_delegate->GetCycleWindowList( 248 const WindowList& windows_list = shell_delegate->GetCycleWindowList(
231 ShellDelegate::SOURCE_KEYBOARD, 249 ShellDelegate::SOURCE_KEYBOARD,
232 ShellDelegate::ORDER_LINEAR); 250 ShellDelegate::ORDER_LINEAR);
(...skipping 15 matching lines...) Expand all
248 void CompactLayoutManager::SwitchToReplacementWindow() { 266 void CompactLayoutManager::SwitchToReplacementWindow() {
249 current_window_ = FindReplacementWindow(current_window_); 267 current_window_ = FindReplacementWindow(current_window_);
250 if (current_window_) { 268 if (current_window_) {
251 ActivateWindow(current_window_); 269 ActivateWindow(current_window_);
252 AnimateSlideTo(current_window_->bounds().x()); 270 AnimateSlideTo(current_window_->bounds().x());
253 } 271 }
254 } 272 }
255 273
256 } // namespace internal 274 } // namespace internal
257 } // namespace ash 275 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/compact_layout_manager.h ('k') | ash/wm/compact_layout_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698