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

Side by Side Diff: ash/wm/workspace/workspace_manager2.cc

Issue 11106003: Tweaks workspace animation code per latest from Nicholas. Additionally (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge to trunk Created 8 years, 2 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/workspace/workspace_manager2.h ('k') | no next file » | 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/workspace/workspace_manager2.h" 5 #include "ash/wm/workspace/workspace_manager2.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <functional> 8 #include <functional>
9 9
10 #include "ash/ash_switches.h"
10 #include "ash/root_window_controller.h" 11 #include "ash/root_window_controller.h"
11 #include "ash/shell.h" 12 #include "ash/shell.h"
12 #include "ash/shell_window_ids.h" 13 #include "ash/shell_window_ids.h"
13 #include "ash/wm/base_layout_manager.h" 14 #include "ash/wm/base_layout_manager.h"
14 #include "ash/wm/property_util.h" 15 #include "ash/wm/property_util.h"
15 #include "ash/wm/shelf_layout_manager.h" 16 #include "ash/wm/shelf_layout_manager.h"
16 #include "ash/wm/window_animations.h" 17 #include "ash/wm/window_animations.h"
17 #include "ash/wm/window_properties.h" 18 #include "ash/wm/window_properties.h"
18 #include "ash/wm/window_util.h" 19 #include "ash/wm/window_util.h"
20 #include "ash/wm/workspace/desktop_background_fade_controller.h"
21 #include "ash/wm/workspace/workspace_animations.h"
19 #include "ash/wm/workspace/workspace_layout_manager2.h" 22 #include "ash/wm/workspace/workspace_layout_manager2.h"
20 #include "ash/wm/workspace/workspace2.h" 23 #include "ash/wm/workspace/workspace2.h"
21 #include "base/auto_reset.h" 24 #include "base/auto_reset.h"
22 #include "base/command_line.h" 25 #include "base/command_line.h"
23 #include "base/logging.h" 26 #include "base/logging.h"
24 #include "base/stl_util.h" 27 #include "base/stl_util.h"
25 #include "base/stringprintf.h"
26 #include "ui/aura/client/aura_constants.h" 28 #include "ui/aura/client/aura_constants.h"
27 #include "ui/aura/root_window.h" 29 #include "ui/aura/root_window.h"
28 #include "ui/aura/window.h" 30 #include "ui/aura/window.h"
29 #include "ui/aura/window_property.h" 31 #include "ui/aura/window_property.h"
30 #include "ui/base/ui_base_types.h" 32 #include "ui/base/ui_base_types.h"
31 #include "ui/compositor/layer.h" 33 #include "ui/compositor/layer.h"
32 #include "ui/compositor/layer_animator.h" 34 #include "ui/compositor/layer_animator.h"
35 #include "ui/compositor/scoped_layer_animation_settings.h"
36 #include "ui/views/widget/widget.h"
33 37
34 DECLARE_WINDOW_PROPERTY_TYPE(ash::internal::Workspace2*); 38 DECLARE_WINDOW_PROPERTY_TYPE(ash::internal::Workspace2*);
35 39
36 using aura::Window; 40 using aura::Window;
37 41
38 namespace ash { 42 namespace ash {
39 namespace internal { 43 namespace internal {
40 44
41 DEFINE_WINDOW_PROPERTY_KEY(Workspace2*, kWorkspaceKey, NULL); 45 DEFINE_WINDOW_PROPERTY_KEY(Workspace2*, kWorkspaceKey, NULL);
42 46
43 namespace { 47 namespace {
44 48
49 // Duration for fading out the desktop background when maximizing.
50 const int kCrossFadeSwitchTimeMS = 700;
51
52 // Amount of time to pause before animating anything. Only used during initial
53 // animation (when logging in).
54 const int kInitialPauseTimeMS = 750;
55
45 // Changes the parent of |window| and all its transient children to 56 // Changes the parent of |window| and all its transient children to
46 // |new_parent|. If |stack_beneach| is non-NULL all the windows are stacked 57 // |new_parent|. If |stack_beneach| is non-NULL all the windows are stacked
47 // beneath it. 58 // beneath it.
48 void ReparentWindow(Window* window, 59 void ReparentWindow(Window* window,
49 Window* new_parent, 60 Window* new_parent,
50 Window* stack_beneath) { 61 Window* stack_beneath) {
51 window->SetParent(new_parent); 62 window->SetParent(new_parent);
52 if (stack_beneath) 63 if (stack_beneath)
53 new_parent->StackChildBelow(window, stack_beneath); 64 new_parent->StackChildBelow(window, stack_beneath);
54 for (size_t i = 0; i < window->transient_children().size(); ++i) 65 for (size_t i = 0; i < window->transient_children().size(); ++i)
55 ReparentWindow(window->transient_children()[i], new_parent, stack_beneath); 66 ReparentWindow(window->transient_children()[i], new_parent, stack_beneath);
56 } 67 }
57 68
58 WorkspaceType WorkspaceType(Workspace2* workspace) { 69 } // namespace
59 return workspace->is_maximized() ? WORKSPACE_MAXIMIZED : WORKSPACE_DESKTOP;
60 }
61 70
62 // Workspace ------------------------------------------------------------------- 71 // Workspace -------------------------------------------------------------------
63 72
64 // LayoutManager installed on the parent window of all the Workspace windows (eg 73 // LayoutManager installed on the parent window of all the Workspace window (eg
65 // |WorkspaceManager2::contents_view_|). 74 // |WorkspaceManager2::contents_view_|).
66 class WorkspaceManagerLayoutManager2 : public BaseLayoutManager { 75 class WorkspaceManager2::LayoutManagerImpl : public BaseLayoutManager {
67 public: 76 public:
68 WorkspaceManagerLayoutManager2(Window* window) 77 explicit LayoutManagerImpl(WorkspaceManager2* workspace_manager)
69 : BaseLayoutManager(window->GetRootWindow()), 78 : BaseLayoutManager(workspace_manager->contents_view_->GetRootWindow()),
70 window_(window) { 79 workspace_manager_(workspace_manager) {
71 } 80 }
72 virtual ~WorkspaceManagerLayoutManager2() {} 81 virtual ~LayoutManagerImpl() {}
73 82
74 // Overridden from BaseWorkspaceLayoutManager: 83 // Overridden from BaseWorkspaceLayoutManager:
75 virtual void OnWindowResized() OVERRIDE { 84 virtual void OnWindowResized() OVERRIDE {
76 for (size_t i = 0; i < window_->children().size(); ++i) 85 for (size_t i = 0; i < window()->children().size(); ++i)
77 window_->children()[i]->SetBounds(gfx::Rect(window_->bounds().size())); 86 window()->children()[i]->SetBounds(gfx::Rect(window()->bounds().size()));
78 } 87 }
79 virtual void OnWindowAddedToLayout(Window* child) OVERRIDE { 88 virtual void OnWindowAddedToLayout(Window* child) OVERRIDE {
80 // Only workspaces should be added as children. 89 // Only workspaces should be added as children.
81 DCHECK_EQ(kShellWindowId_WorkspaceContainer, child->id()); 90 DCHECK((child->id() == kShellWindowId_WorkspaceContainer) ||
82 child->SetBounds(gfx::Rect(window_->bounds().size())); 91 workspace_manager_->creating_fade_);
92 child->SetBounds(gfx::Rect(window()->bounds().size()));
83 } 93 }
84 94
85 private: 95 private:
86 Window* window_; 96 aura::Window* window() { return workspace_manager_->contents_view_; }
87 97
88 DISALLOW_COPY_AND_ASSIGN(WorkspaceManagerLayoutManager2); 98 WorkspaceManager2* workspace_manager_;
99
100 DISALLOW_COPY_AND_ASSIGN(LayoutManagerImpl);
89 }; 101 };
90 102
91 } // namespace
92
93 // WorkspaceManager2 ----------------------------------------------------------- 103 // WorkspaceManager2 -----------------------------------------------------------
94 104
95 WorkspaceManager2::WorkspaceManager2(Window* contents_view) 105 WorkspaceManager2::WorkspaceManager2(Window* contents_view)
96 : contents_view_(contents_view), 106 : contents_view_(contents_view),
97 active_workspace_(NULL), 107 active_workspace_(NULL),
98 shelf_(NULL), 108 shelf_(NULL),
99 in_move_(false), 109 in_move_(false),
100 ALLOW_THIS_IN_INITIALIZER_LIST( 110 ALLOW_THIS_IN_INITIALIZER_LIST(
101 clear_unminimizing_workspace_factory_(this)), 111 clear_unminimizing_workspace_factory_(this)),
102 unminimizing_workspace_(NULL), 112 unminimizing_workspace_(NULL),
103 app_terminating_(false) { 113 app_terminating_(false),
114 creating_fade_(false) {
104 // Clobber any existing event filter. 115 // Clobber any existing event filter.
105 contents_view->SetEventFilter(NULL); 116 contents_view->SetEventFilter(NULL);
106 // |contents_view| takes ownership of WorkspaceManagerLayoutManager2. 117 // |contents_view| takes ownership of LayoutManagerImpl.
107 contents_view->SetLayoutManager( 118 contents_view->SetLayoutManager(new LayoutManagerImpl(this));
108 new WorkspaceManagerLayoutManager2(contents_view));
109 active_workspace_ = CreateWorkspace(false); 119 active_workspace_ = CreateWorkspace(false);
110 workspaces_.push_back(active_workspace_); 120 workspaces_.push_back(active_workspace_);
111 active_workspace_->window()->Show(); 121 active_workspace_->window()->Show();
112 Shell::GetInstance()->AddShellObserver(this); 122 Shell::GetInstance()->AddShellObserver(this);
113 } 123 }
114 124
115 WorkspaceManager2::~WorkspaceManager2() { 125 WorkspaceManager2::~WorkspaceManager2() {
116 Shell::GetInstance()->RemoveShellObserver(this); 126 Shell::GetInstance()->RemoveShellObserver(this);
117 // Release the windows, they'll be destroyed when |contents_view_| is 127 // Release the windows, they'll be destroyed when |contents_view_| is
118 // destroyed. 128 // destroyed.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 // manager is in the desktop worskpace and the current workspace is 221 // manager is in the desktop worskpace and the current workspace is
212 // maximized. If we swapped to the desktop you would lose context. Instead 222 // maximized. If we swapped to the desktop you would lose context. Instead
213 // we reparent. The exception to this is if the window is maximized (it 223 // we reparent. The exception to this is if the window is maximized (it
214 // needs its own workspace then) or we're in the process of maximizing. If 224 // needs its own workspace then) or we're in the process of maximizing. If
215 // we're in the process of maximizing the window needs its own workspace. 225 // we're in the process of maximizing the window needs its own workspace.
216 if (!GetTrackedByWorkspace(window) || 226 if (!GetTrackedByWorkspace(window) ||
217 (GetPersistsAcrossAllWorkspaces(window) && !IsMaximized(window) && 227 (GetPersistsAcrossAllWorkspaces(window) && !IsMaximized(window) &&
218 !(wm::IsWindowMinimized(window) && WillRestoreMaximized(window)))) { 228 !(wm::IsWindowMinimized(window) && WillRestoreMaximized(window)))) {
219 ReparentWindow(window, active_workspace_->window(), NULL); 229 ReparentWindow(window, active_workspace_->window(), NULL);
220 } else { 230 } else {
221 SetActiveWorkspace(workspace, ANIMATE_OLD_AND_NEW); 231 SetActiveWorkspace(workspace, SWITCH_WINDOW_MADE_ACTIVE,
232 base::TimeDelta());
222 } 233 }
223 } 234 }
224 if (workspace->is_maximized() && IsMaximized(window)) { 235 if (workspace->is_maximized() && IsMaximized(window)) {
225 // Clicking on the maximized window in a maximized workspace. Force all 236 // Clicking on the maximized window in a maximized workspace. Force all
226 // other windows to drop to the desktop. 237 // other windows to drop to the desktop.
227 MoveChildrenToDesktop(workspace->window(), NULL); 238 MoveChildrenToDesktop(workspace->window(), NULL);
228 } 239 }
229 } 240 }
230 241
231 Window* WorkspaceManager2::GetParentForNewWindow(Window* window) { 242 Window* WorkspaceManager2::GetParentForNewWindow(Window* window) {
(...skipping 23 matching lines...) Expand all
255 } 266 }
256 267
257 void WorkspaceManager2::DoInitialAnimation() { 268 void WorkspaceManager2::DoInitialAnimation() {
258 if (active_workspace_->is_maximized()) { 269 if (active_workspace_->is_maximized()) {
259 RootWindowController* root_controller = GetRootWindowController( 270 RootWindowController* root_controller = GetRootWindowController(
260 contents_view_->GetRootWindow()); 271 contents_view_->GetRootWindow());
261 if (root_controller) { 272 if (root_controller) {
262 aura::Window* background = root_controller->GetContainer( 273 aura::Window* background = root_controller->GetContainer(
263 kShellWindowId_DesktopBackgroundContainer); 274 kShellWindowId_DesktopBackgroundContainer);
264 background->Show(); 275 background->Show();
265 AnimateWorkspaceOut(background, WORKSPACE_ANIMATE_DOWN, 276 ShowOrHideDesktopBackground(background, SWITCH_INITIAL,
266 WORKSPACE_DESKTOP, true, base::TimeDelta()); 277 base::TimeDelta(), false);
267 } 278 }
268 } 279 }
269 AnimateWorkspaceIn(active_workspace_->window(), WORKSPACE_ANIMATE_DOWN, 280 ShowWorkspace(active_workspace_, active_workspace_, SWITCH_INITIAL);
270 true, base::TimeDelta());
271 } 281 }
272 282
273 void WorkspaceManager2::OnAppTerminating() { 283 void WorkspaceManager2::OnAppTerminating() {
274 app_terminating_ = true; 284 app_terminating_ = true;
275 } 285 }
276 286
277 void WorkspaceManager2::UpdateShelfVisibility() { 287 void WorkspaceManager2::UpdateShelfVisibility() {
278 if (shelf_) 288 if (shelf_)
279 shelf_->UpdateVisibilityState(); 289 shelf_->UpdateVisibilityState();
280 } 290 }
281 291
282 Workspace2* WorkspaceManager2::FindBy(Window* window) const { 292 Workspace2* WorkspaceManager2::FindBy(Window* window) const {
283 while (window) { 293 while (window) {
284 Workspace2* workspace = window->GetProperty(kWorkspaceKey); 294 Workspace2* workspace = window->GetProperty(kWorkspaceKey);
285 if (workspace) 295 if (workspace)
286 return workspace; 296 return workspace;
287 window = window->parent(); 297 window = window->parent();
288 } 298 }
289 return NULL; 299 return NULL;
290 } 300 }
291 301
292 void WorkspaceManager2::SetActiveWorkspace(Workspace2* workspace, 302 void WorkspaceManager2::SetActiveWorkspace(Workspace2* workspace,
293 AnimateType animate_type) { 303 SwitchReason reason,
304 base::TimeDelta duration) {
294 DCHECK(workspace); 305 DCHECK(workspace);
295 if (active_workspace_ == workspace) 306 if (active_workspace_ == workspace)
296 return; 307 return;
297 308
298 pending_workspaces_.erase(workspace); 309 pending_workspaces_.erase(workspace);
299 310
300 // Adjust the z-order. No need to adjust the z-order for the desktop since 311 // Adjust the z-order. No need to adjust the z-order for the desktop since
301 // it always stays at the bottom. 312 // it always stays at the bottom.
302 if (workspace != desktop_workspace()) { 313 if (workspace != desktop_workspace() &&
303 if (FindWorkspace(workspace) == workspaces_.end()) { 314 FindWorkspace(workspace) == workspaces_.end()) {
304 contents_view_->StackChildAbove(workspace->window(), 315 contents_view_->StackChildAbove(workspace->window(),
305 workspaces_.back()->window()); 316 workspaces_.back()->window());
306 workspaces_.push_back(workspace); 317 workspaces_.push_back(workspace);
307 }
308 } 318 }
309 319
310 Workspace2* last_active = active_workspace_; 320 Workspace2* last_active = active_workspace_;
311 active_workspace_ = workspace; 321 active_workspace_ = workspace;
312 322
313 // The display work-area may have changed while |workspace| was not the active 323 // The display work-area may have changed while |workspace| was not the active
314 // workspace. Give it a chance to adjust its state for the new work-area. 324 // workspace. Give it a chance to adjust its state for the new work-area.
315 active_workspace_->workspace_layout_manager()-> 325 active_workspace_->workspace_layout_manager()->
316 OnDisplayWorkAreaInsetsChanged(); 326 OnDisplayWorkAreaInsetsChanged();
317 327
318 const bool is_unminimizing_maximized_window = 328 const bool is_unminimizing_maximized_window =
319 unminimizing_workspace_ && unminimizing_workspace_ == active_workspace_ && 329 unminimizing_workspace_ && unminimizing_workspace_ == active_workspace_ &&
320 active_workspace_->is_maximized(); 330 active_workspace_->is_maximized();
321 if (is_unminimizing_maximized_window) { 331 if (is_unminimizing_maximized_window) {
322 // If we're unminimizing a window it needs to be on the top, otherwise you 332 // If we're unminimizing a window it needs to be on the top, otherwise you
323 // won't see the animation. 333 // won't see the animation.
324 contents_view_->StackChildAtTop(active_workspace_->window()); 334 contents_view_->StackChildAtTop(active_workspace_->window());
325 } else if (active_workspace_->is_maximized() && last_active->is_maximized()) { 335 } else if (active_workspace_->is_maximized() && last_active->is_maximized()) {
326 // When switching between maximized windows we need the last active 336 // When switching between maximized windows we need the last active
327 // workspace on top of the new, otherwise the animations won't look 337 // workspace on top of the new, otherwise the animations won't look
328 // right. Since only one workspace is visible at a time stacking order of 338 // right. Since only one workspace is visible at a time stacking order of
329 // the workspace windows ultimately doesn't matter. 339 // the workspace windows ultimately doesn't matter.
330 contents_view_->StackChildAtTop(last_active->window()); 340 contents_view_->StackChildAtTop(last_active->window());
331 } 341 }
332 342
333 UpdateShelfVisibility(); 343 UpdateShelfVisibility();
334 344
335 if (animate_type != ANIMATE_NONE) { 345 // NOTE: duration supplied to this method is only used for desktop background.
336 AnimateBetweenWorkspaces( 346 HideWorkspace(last_active, reason, is_unminimizing_maximized_window);
337 last_active->window(), 347 ShowWorkspace(workspace, last_active, reason);
338 WorkspaceType(last_active),
339 (animate_type == ANIMATE_OLD_AND_NEW),
340 workspace->window(),
341 WorkspaceType(workspace),
342 is_unminimizing_maximized_window);
343 }
344 348
345 RootWindowController* root_controller = GetRootWindowController( 349 RootWindowController* root_controller = GetRootWindowController(
346 contents_view_->GetRootWindow()); 350 contents_view_->GetRootWindow());
347 if (root_controller) { 351 if (root_controller) {
348 aura::Window* background = root_controller->GetContainer( 352 aura::Window* background = root_controller->GetContainer(
349 kShellWindowId_DesktopBackgroundContainer); 353 kShellWindowId_DesktopBackgroundContainer);
350 if (last_active == desktop_workspace()) { 354 if (last_active == desktop_workspace()) {
351 AnimateWorkspaceOut(background, WORKSPACE_ANIMATE_DOWN, 355 ShowOrHideDesktopBackground(background, reason, duration, false);
352 WORKSPACE_DESKTOP, false, switch_duration_);
353 } else if (active_workspace_ == desktop_workspace() && !app_terminating_) { 356 } else if (active_workspace_ == desktop_workspace() && !app_terminating_) {
354 AnimateWorkspaceIn(background, WORKSPACE_ANIMATE_UP, false, 357 ShowOrHideDesktopBackground(background, reason, duration, true);
355 switch_duration_);
356 } 358 }
357 } 359 }
358 } 360 }
359 361
360 WorkspaceManager2::Workspaces::iterator 362 WorkspaceManager2::Workspaces::iterator
361 WorkspaceManager2::FindWorkspace(Workspace2* workspace) { 363 WorkspaceManager2::FindWorkspace(Workspace2* workspace) {
362 return std::find(workspaces_.begin(), workspaces_.end(), workspace); 364 return std::find(workspaces_.begin(), workspaces_.end(), workspace);
363 } 365 }
364 366
365 Workspace2* WorkspaceManager2::CreateWorkspace(bool maximized) { 367 Workspace2* WorkspaceManager2::CreateWorkspace(bool maximized) {
366 return new Workspace2(this, contents_view_, maximized); 368 return new Workspace2(this, contents_view_, maximized);
367 } 369 }
368 370
369 void WorkspaceManager2::MoveWorkspaceToPendingOrDelete( 371 void WorkspaceManager2::MoveWorkspaceToPendingOrDelete(
370 Workspace2* workspace, 372 Workspace2* workspace,
371 Window* stack_beneath, 373 Window* stack_beneath,
372 AnimateType animate_type) { 374 SwitchReason reason) {
373 // We're all ready moving windows. 375 // We're all ready moving windows.
374 if (in_move_) 376 if (in_move_)
375 return; 377 return;
376 378
377 DCHECK_NE(desktop_workspace(), workspace); 379 DCHECK_NE(desktop_workspace(), workspace);
378 380
379 if (workspace == active_workspace_) 381 if (workspace == active_workspace_)
380 SelectNextWorkspace(animate_type); 382 SelectNextWorkspace(reason);
381 383
382 AutoReset<bool> setter(&in_move_, true); 384 AutoReset<bool> setter(&in_move_, true);
383 385
384 MoveChildrenToDesktop(workspace->window(), stack_beneath); 386 MoveChildrenToDesktop(workspace->window(), stack_beneath);
385 387
386 { 388 {
387 Workspaces::iterator workspace_i(FindWorkspace(workspace)); 389 Workspaces::iterator workspace_i(FindWorkspace(workspace));
388 if (workspace_i != workspaces_.end()) 390 if (workspace_i != workspaces_.end())
389 workspaces_.erase(workspace_i); 391 workspaces_.erase(workspace_i);
390 } 392 }
(...skipping 24 matching lines...) Expand all
415 // (moving may cascade and cause other windows to move). 417 // (moving may cascade and cause other windows to move).
416 for (size_t i = 0; i < to_move.size(); ++i) { 418 for (size_t i = 0; i < to_move.size(); ++i) {
417 if (std::find(window->children().begin(), window->children().end(), 419 if (std::find(window->children().begin(), window->children().end(),
418 to_move[i]) != window->children().end()) { 420 to_move[i]) != window->children().end()) {
419 ReparentWindow(to_move[i], desktop_workspace()->window(), 421 ReparentWindow(to_move[i], desktop_workspace()->window(),
420 stack_beneath); 422 stack_beneath);
421 } 423 }
422 } 424 }
423 } 425 }
424 426
425 void WorkspaceManager2::SelectNextWorkspace(AnimateType animate_type) { 427 void WorkspaceManager2::SelectNextWorkspace(SwitchReason reason) {
426 DCHECK_NE(active_workspace_, desktop_workspace()); 428 DCHECK_NE(active_workspace_, desktop_workspace());
427 429
428 Workspaces::const_iterator workspace_i(FindWorkspace(active_workspace_)); 430 Workspaces::const_iterator workspace_i(FindWorkspace(active_workspace_));
429 Workspaces::const_iterator next_workspace_i(workspace_i + 1); 431 Workspaces::const_iterator next_workspace_i(workspace_i + 1);
430 if (next_workspace_i != workspaces_.end()) 432 if (next_workspace_i != workspaces_.end())
431 SetActiveWorkspace(*next_workspace_i, animate_type); 433 SetActiveWorkspace(*next_workspace_i, reason, base::TimeDelta());
432 else 434 else
433 SetActiveWorkspace(*(workspace_i - 1), animate_type); 435 SetActiveWorkspace(*(workspace_i - 1), reason, base::TimeDelta());
434 } 436 }
435 437
436 void WorkspaceManager2::ScheduleDelete(Workspace2* workspace) { 438 void WorkspaceManager2::ScheduleDelete(Workspace2* workspace) {
437 to_delete_.insert(workspace); 439 to_delete_.insert(workspace);
438 delete_timer_.Stop(); 440 delete_timer_.Stop();
439 delete_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(1), this, 441 delete_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(1), this,
440 &WorkspaceManager2::ProcessDeletion); 442 &WorkspaceManager2::ProcessDeletion);
441 } 443 }
442 444
443 void WorkspaceManager2::SetUnminimizingWorkspace(Workspace2* workspace) { 445 void WorkspaceManager2::SetUnminimizingWorkspace(Workspace2* workspace) {
444 // The normal sequence of unminimizing a window is: Show() the window, which 446 // The normal sequence of unminimizing a window is: Show() the window, which
445 // triggers changing the kShowStateKey to NORMAL and lastly the window is made 447 // triggers changing the kShowStateKey to NORMAL and lastly the window is made
446 // active. This means at the time the window is unminimized we don't know if 448 // active. This means at the time the window is unminimized we don't know if
447 // the workspace it is in is going to become active. To track this 449 // the workspace it is in is going to become active. To track this
448 // |unminimizing_workspace_| is set at the time we unminimize and a task is 450 // |unminimizing_workspace_| is set at the time we unminimize and a task is
449 // schedule to reset it. This way when we get the activate we know we're in 451 // schedule to reset it. This way when we get the activate we know we're in
450 // the process unminimizing and can do the right animation. 452 // the process unminimizing and can do the right animation.
451 unminimizing_workspace_ = workspace; 453 unminimizing_workspace_ = workspace;
452 if (unminimizing_workspace_) { 454 if (unminimizing_workspace_) {
453 MessageLoop::current()->PostTask( 455 MessageLoop::current()->PostTask(
454 FROM_HERE, 456 FROM_HERE,
455 base::Bind(&WorkspaceManager2::SetUnminimizingWorkspace, 457 base::Bind(&WorkspaceManager2::SetUnminimizingWorkspace,
456 clear_unminimizing_workspace_factory_.GetWeakPtr(), 458 clear_unminimizing_workspace_factory_.GetWeakPtr(),
457 static_cast<Workspace2*>(NULL))); 459 static_cast<Workspace2*>(NULL)));
458 } 460 }
459 } 461 }
460 462
463 void WorkspaceManager2::FadeDesktop(aura::Window* window,
464 base::TimeDelta duration) {
465 if (CommandLine::ForCurrentProcess()->HasSwitch(
466 ash::switches::kAshWindowAnimationsDisabled) ||
467 ui::LayerAnimator::disable_animations_for_test())
468 return;
469
470 AutoReset<bool> reseter(&creating_fade_, true);
471 DesktopBackgroundFadeController::Direction direction;
472 aura::Window* parent = NULL;
473 aura::Window* stack_above = NULL;
474 if (active_workspace_ == desktop_workspace()) {
475 direction = DesktopBackgroundFadeController::FADE_IN;
476 parent = desktop_workspace()->window();
477 stack_above = window;
478 } else {
479 direction = DesktopBackgroundFadeController::FADE_OUT;
480 parent = contents_view_;
481 stack_above = desktop_workspace()->window();
482 DCHECK_EQ(kCrossFadeSwitchTimeMS, (int)duration.InMilliseconds());
483 duration = base::TimeDelta::FromMilliseconds(kCrossFadeSwitchTimeMS);
484 }
485 desktop_fade_controller_.reset(
486 new DesktopBackgroundFadeController(
487 parent, stack_above, duration, direction));
488 }
489
490 void WorkspaceManager2::ShowOrHideDesktopBackground(
491 aura::Window* window,
492 SwitchReason reason,
493 base::TimeDelta duration,
494 bool show) const {
495 WorkspaceAnimationDetails details;
496 details.animate = true;
497 details.direction = show ? WORKSPACE_ANIMATE_UP : WORKSPACE_ANIMATE_DOWN;
498 details.animate_scale = reason != SWITCH_MAXIMIZED_OR_RESTORED;
499 details.duration = duration;
500 if (reason == SWITCH_INITIAL)
501 details.pause_time_ms = kInitialPauseTimeMS;
502 if (show)
503 ash::internal::ShowWorkspace(window, details);
504 else
505 ash::internal::HideWorkspace(window, details);
506 }
507
508 void WorkspaceManager2::ShowWorkspace(
509 Workspace2* workspace,
510 Workspace2* last_active,
511 SwitchReason reason) const {
512 WorkspaceAnimationDetails details;
513 details.direction =
514 (last_active == desktop_workspace() || reason == SWITCH_INITIAL) ?
515 WORKSPACE_ANIMATE_DOWN : WORKSPACE_ANIMATE_UP;
516
517 switch (reason) {
518 case SWITCH_WINDOW_MADE_ACTIVE:
519 case SWITCH_TRACKED_BY_WORKSPACE_CHANGED:
520 case SWITCH_WINDOW_REMOVED:
521 case SWITCH_VISIBILITY_CHANGED:
522 case SWITCH_MINIMIZED:
523 details.animate = details.animate_scale = true;
524 details.animate_opacity = last_active == desktop_workspace();
525 break;
526
527 case SWITCH_INITIAL:
528 details.animate = details.animate_opacity = details.animate_scale = true;
529 details.pause_time_ms = kInitialPauseTimeMS;
530 break;
531
532 // Remaining cases require no animation.
533 default:
534 break;
535 }
536 ash::internal::ShowWorkspace(workspace->window(), details);
537 }
538
539 void WorkspaceManager2::HideWorkspace(
540 Workspace2* workspace,
541 SwitchReason reason,
542 bool is_unminimizing_maximized_window) const {
543 WorkspaceAnimationDetails details;
544 details.direction = active_workspace_ == desktop_workspace() ?
545 WORKSPACE_ANIMATE_UP : WORKSPACE_ANIMATE_DOWN;
546 switch (reason) {
547 case SWITCH_WINDOW_MADE_ACTIVE:
548 case SWITCH_TRACKED_BY_WORKSPACE_CHANGED:
549 details.animate_opacity =
550 ((active_workspace_ == desktop_workspace() ||
551 workspace != desktop_workspace()) &&
552 !is_unminimizing_maximized_window);
553 details.animate_scale = true;
554 details.animate = true;
555 break;
556
557 case SWITCH_MAXIMIZED_OR_RESTORED:
558 if (active_workspace_->is_maximized()) {
559 // Delay the hide until the animation is done.
560 details.duration =
561 base::TimeDelta::FromMilliseconds(kCrossFadeSwitchTimeMS);
562 details.animate = true;
563 }
564 break;
565
566 // Remaining cases require no animation.
567 default:
568 break;
569 }
570 ash::internal::HideWorkspace(workspace->window(), details);
571 }
572
461 void WorkspaceManager2::ProcessDeletion() { 573 void WorkspaceManager2::ProcessDeletion() {
462 std::set<Workspace2*> to_delete; 574 std::set<Workspace2*> to_delete;
463 to_delete.swap(to_delete_); 575 to_delete.swap(to_delete_);
464 for (std::set<Workspace2*>::iterator i = to_delete.begin(); 576 for (std::set<Workspace2*>::iterator i = to_delete.begin();
465 i != to_delete.end(); ++i) { 577 i != to_delete.end(); ++i) {
466 Workspace2* workspace = *i; 578 Workspace2* workspace = *i;
467 if (workspace->window()->layer()->children().empty()) { 579 if (workspace->window()->layer()->children().empty()) {
468 delete workspace->ReleaseWindow(); 580 delete workspace->ReleaseWindow();
469 delete workspace; 581 delete workspace;
470 } else { 582 } else {
(...skipping 17 matching lines...) Expand all
488 } 600 }
489 601
490 void WorkspaceManager2::OnWillRemoveWindowFromWorkspace(Workspace2* workspace, 602 void WorkspaceManager2::OnWillRemoveWindowFromWorkspace(Workspace2* workspace,
491 Window* child) { 603 Window* child) {
492 child->ClearProperty(kWorkspaceKey); 604 child->ClearProperty(kWorkspaceKey);
493 } 605 }
494 606
495 void WorkspaceManager2::OnWindowRemovedFromWorkspace(Workspace2* workspace, 607 void WorkspaceManager2::OnWindowRemovedFromWorkspace(Workspace2* workspace,
496 Window* child) { 608 Window* child) {
497 if (workspace->ShouldMoveToPending()) 609 if (workspace->ShouldMoveToPending())
498 MoveWorkspaceToPendingOrDelete(workspace, NULL, ANIMATE_NEW); 610 MoveWorkspaceToPendingOrDelete(workspace, NULL, SWITCH_WINDOW_REMOVED);
499 } 611 }
500 612
501 void WorkspaceManager2::OnWorkspaceChildWindowVisibilityChanged( 613 void WorkspaceManager2::OnWorkspaceChildWindowVisibilityChanged(
502 Workspace2* workspace, 614 Workspace2* workspace,
503 Window* child) { 615 Window* child) {
504 if (workspace->ShouldMoveToPending()) 616 if (workspace->ShouldMoveToPending())
505 MoveWorkspaceToPendingOrDelete(workspace, NULL, ANIMATE_NEW); 617 MoveWorkspaceToPendingOrDelete(workspace, NULL, SWITCH_VISIBILITY_CHANGED);
506 else if (workspace == active_workspace_) 618 else if (workspace == active_workspace_)
507 UpdateShelfVisibility(); 619 UpdateShelfVisibility();
508 } 620 }
509 621
510 void WorkspaceManager2::OnWorkspaceWindowChildBoundsChanged( 622 void WorkspaceManager2::OnWorkspaceWindowChildBoundsChanged(
511 Workspace2* workspace, 623 Workspace2* workspace,
512 Window* child) { 624 Window* child) {
513 if (workspace == active_workspace_) 625 if (workspace == active_workspace_)
514 UpdateShelfVisibility(); 626 UpdateShelfVisibility();
515 } 627 }
516 628
517 void WorkspaceManager2::OnWorkspaceWindowShowStateChanged( 629 void WorkspaceManager2::OnWorkspaceWindowShowStateChanged(
518 Workspace2* workspace, 630 Workspace2* workspace,
519 Window* child, 631 Window* child,
520 ui::WindowShowState last_show_state, 632 ui::WindowShowState last_show_state,
521 ui::Layer* old_layer) { 633 ui::Layer* old_layer) {
522 // |child| better still be in |workspace| else things have gone wrong. 634 // |child| better still be in |workspace| else things have gone wrong.
523 DCHECK_EQ(workspace, child->GetProperty(kWorkspaceKey)); 635 DCHECK_EQ(workspace, child->GetProperty(kWorkspaceKey));
524 if (wm::IsWindowMinimized(child)) { 636 if (wm::IsWindowMinimized(child)) {
525 if (workspace->ShouldMoveToPending()) 637 if (workspace->ShouldMoveToPending())
526 MoveWorkspaceToPendingOrDelete(workspace, NULL, ANIMATE_NEW); 638 MoveWorkspaceToPendingOrDelete(workspace, NULL, SWITCH_MINIMIZED);
527 DCHECK(!old_layer); 639 DCHECK(!old_layer);
528 } else { 640 } else {
529 // Set of cases to deal with: 641 // Set of cases to deal with:
530 // . More than one maximized window: move newly maximized window into 642 // . More than one maximized window: move newly maximized window into
531 // own workspace. 643 // own workspace.
532 // . One maximized window and not in a maximized workspace: move window 644 // . One maximized window and not in a maximized workspace: move window
533 // into own workspace. 645 // into own workspace.
534 // . No maximized window and not in desktop: move to desktop and further 646 // . No maximized window and not in desktop: move to desktop and further
535 // any existing windows are stacked beneath |child|. 647 // any existing windows are stacked beneath |child|.
536 const bool is_active = wm::IsActiveWindow(child); 648 const bool is_active = wm::IsActiveWindow(child);
537 Workspace2* new_workspace = NULL; 649 Workspace2* new_workspace = NULL;
538 const int max_count = workspace->GetNumMaximizedWindows(); 650 const int max_count = workspace->GetNumMaximizedWindows();
651 base::TimeDelta duration = old_layer && !IsMaximized(child) ?
652 GetCrossFadeDuration(old_layer->bounds(), child->bounds()) :
653 base::TimeDelta::FromMilliseconds(kCrossFadeSwitchTimeMS);
539 if (max_count == 0) { 654 if (max_count == 0) {
540 if (workspace != desktop_workspace()) { 655 if (workspace != desktop_workspace()) {
541 { 656 {
542 AutoReset<bool> setter(&in_move_, true); 657 AutoReset<bool> setter(&in_move_, true);
543 ReparentWindow(child, desktop_workspace()->window(), NULL); 658 ReparentWindow(child, desktop_workspace()->window(), NULL);
544 } 659 }
545 DCHECK(!is_active || old_layer); 660 DCHECK(!is_active || old_layer);
546 MoveWorkspaceToPendingOrDelete(workspace, child, ANIMATE_NONE); 661 new_workspace = desktop_workspace();
662 SetActiveWorkspace(new_workspace, SWITCH_MAXIMIZED_OR_RESTORED,
663 duration);
664 MoveWorkspaceToPendingOrDelete(workspace, child,
665 SWITCH_MAXIMIZED_OR_RESTORED);
547 if (FindWorkspace(workspace) == workspaces_.end()) 666 if (FindWorkspace(workspace) == workspaces_.end())
548 workspace = NULL; 667 workspace = NULL;
549 new_workspace = desktop_workspace();
550 } 668 }
551 } else if ((max_count == 1 && workspace == desktop_workspace()) || 669 } else if ((max_count == 1 && workspace == desktop_workspace()) ||
552 max_count > 1) { 670 max_count > 1) {
553 new_workspace = CreateWorkspace(true); 671 new_workspace = CreateWorkspace(true);
554 pending_workspaces_.insert(new_workspace); 672 pending_workspaces_.insert(new_workspace);
555 ReparentWindow(child, new_workspace->window(), NULL); 673 ReparentWindow(child, new_workspace->window(), NULL);
556 } 674 }
557 if (is_active && new_workspace) { 675 if (is_active && new_workspace) {
558 // |old_layer| may be NULL if as part of processing 676 // |old_layer| may be NULL if as part of processing
559 // WorkspaceLayoutManager2::OnWindowPropertyChanged() the window is made 677 // WorkspaceLayoutManager2::OnWindowPropertyChanged() the window is made
560 // active. 678 // active.
561 if (old_layer) { 679 if (old_layer) {
562 switch_duration_ = 680 SetActiveWorkspace(new_workspace, SWITCH_MAXIMIZED_OR_RESTORED,
563 GetCrossFadeDuration(old_layer->bounds(), child->bounds()); 681 duration);
564 SetActiveWorkspace(new_workspace, ANIMATE_NONE); 682 CrossFadeWindowBetweenWorkspaces(new_workspace->window(), child,
565 switch_duration_ = base::TimeDelta(); 683 old_layer);
566 CrossFadeWindowBetweenWorkspaces( 684 if (workspace == desktop_workspace() ||
567 workspace ? workspace->window() : NULL, new_workspace->window(), 685 new_workspace == desktop_workspace()) {
568 child, old_layer); 686 FadeDesktop(child, duration);
687 }
569 } else { 688 } else {
570 SetActiveWorkspace(new_workspace, ANIMATE_NONE); 689 SetActiveWorkspace(new_workspace, SWITCH_OTHER, base::TimeDelta());
571 } 690 }
572 } else { 691 } else {
573 if (last_show_state == ui::SHOW_STATE_MINIMIZED) 692 if (last_show_state == ui::SHOW_STATE_MINIMIZED)
574 SetUnminimizingWorkspace(new_workspace ? new_workspace : workspace); 693 SetUnminimizingWorkspace(new_workspace ? new_workspace : workspace);
575 DCHECK(!old_layer); 694 DCHECK(!old_layer);
576 } 695 }
577 } 696 }
578 UpdateShelfVisibility(); 697 UpdateShelfVisibility();
579 } 698 }
580 699
581 void WorkspaceManager2::OnTrackedByWorkspaceChanged(Workspace2* workspace, 700 void WorkspaceManager2::OnTrackedByWorkspaceChanged(Workspace2* workspace,
582 aura::Window* window) { 701 aura::Window* window) {
583 Workspace2* new_workspace = NULL; 702 Workspace2* new_workspace = NULL;
584 if (IsMaximized(window)) { 703 if (IsMaximized(window)) {
585 new_workspace = CreateWorkspace(true); 704 new_workspace = CreateWorkspace(true);
586 pending_workspaces_.insert(new_workspace); 705 pending_workspaces_.insert(new_workspace);
587 } else if (workspace->is_maximized()) { 706 } else if (workspace->is_maximized()) {
588 new_workspace = desktop_workspace(); 707 new_workspace = desktop_workspace();
589 } else { 708 } else {
590 return; 709 return;
591 } 710 }
592 // If the window is active we need to make sure the destination Workspace 711 // If the window is active we need to make sure the destination Workspace
593 // window is showing. Otherwise the window will be parented to a hidden window 712 // window is showing. Otherwise the window will be parented to a hidden window
594 // and lose activation. 713 // and lose activation.
595 const bool is_active = wm::IsActiveWindow(window); 714 const bool is_active = wm::IsActiveWindow(window);
596 if (is_active) 715 if (is_active)
597 new_workspace->window()->Show(); 716 new_workspace->window()->Show();
598 ReparentWindow(window, new_workspace->window(), NULL); 717 ReparentWindow(window, new_workspace->window(), NULL);
599 if (is_active) 718 if (is_active) {
600 SetActiveWorkspace(new_workspace, ANIMATE_OLD_AND_NEW); 719 SetActiveWorkspace(new_workspace, SWITCH_TRACKED_BY_WORKSPACE_CHANGED,
720 base::TimeDelta());
721 }
601 } 722 }
602 723
603 } // namespace internal 724 } // namespace internal
604 } // namespace ash 725 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/workspace/workspace_manager2.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698