| 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 "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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |