| 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_manager.h" | 5 #include "ash/wm/workspace/workspace_manager.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/ash_switches.h" |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 active_workspace_->window()->Show(); | 124 active_workspace_->window()->Show(); |
| 125 Shell::GetInstance()->AddShellObserver(this); | 125 Shell::GetInstance()->AddShellObserver(this); |
| 126 } | 126 } |
| 127 | 127 |
| 128 WorkspaceManager::~WorkspaceManager() { | 128 WorkspaceManager::~WorkspaceManager() { |
| 129 Shell::GetInstance()->RemoveShellObserver(this); | 129 Shell::GetInstance()->RemoveShellObserver(this); |
| 130 // Release the windows, they'll be destroyed when |contents_view_| is | 130 // Release the windows, they'll be destroyed when |contents_view_| is |
| 131 // destroyed. | 131 // destroyed. |
| 132 std::for_each(workspaces_.begin(), workspaces_.end(), | 132 std::for_each(workspaces_.begin(), workspaces_.end(), |
| 133 std::mem_fun(&Workspace::ReleaseWindow)); | 133 std::mem_fun(&Workspace::ReleaseWindow)); |
| 134 std::for_each(hidden_workspaces_.begin(), hidden_workspaces_.end(), |
| 135 std::mem_fun(&Workspace::ReleaseWindow)); |
| 134 std::for_each(pending_workspaces_.begin(), pending_workspaces_.end(), | 136 std::for_each(pending_workspaces_.begin(), pending_workspaces_.end(), |
| 135 std::mem_fun(&Workspace::ReleaseWindow)); | 137 std::mem_fun(&Workspace::ReleaseWindow)); |
| 136 std::for_each(to_delete_.begin(), to_delete_.end(), | 138 std::for_each(to_delete_.begin(), to_delete_.end(), |
| 137 std::mem_fun(&Workspace::ReleaseWindow)); | 139 std::mem_fun(&Workspace::ReleaseWindow)); |
| 138 STLDeleteElements(&workspaces_); | 140 STLDeleteElements(&workspaces_); |
| 141 STLDeleteElements(&hidden_workspaces_); |
| 139 STLDeleteElements(&pending_workspaces_); | 142 STLDeleteElements(&pending_workspaces_); |
| 140 STLDeleteElements(&to_delete_); | 143 STLDeleteElements(&to_delete_); |
| 141 } | 144 } |
| 142 | 145 |
| 143 // static | 146 // static |
| 144 bool WorkspaceManager::IsMaximized(Window* window) { | 147 bool WorkspaceManager::IsMaximized(Window* window) { |
| 145 return IsMaximizedState(window->GetProperty(aura::client::kShowStateKey)); | 148 return IsMaximizedState(window->GetProperty(aura::client::kShowStateKey)); |
| 146 } | 149 } |
| 147 | 150 |
| 148 // static | 151 // static |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 pending_workspaces_.insert(workspace); | 260 pending_workspaces_.insert(workspace); |
| 258 return workspace->window(); | 261 return workspace->window(); |
| 259 } | 262 } |
| 260 | 263 |
| 261 if (!GetTrackedByWorkspace(window) || GetPersistsAcrossAllWorkspaces(window)) | 264 if (!GetTrackedByWorkspace(window) || GetPersistsAcrossAllWorkspaces(window)) |
| 262 return active_workspace_->window(); | 265 return active_workspace_->window(); |
| 263 | 266 |
| 264 return desktop_workspace()->window(); | 267 return desktop_workspace()->window(); |
| 265 } | 268 } |
| 266 | 269 |
| 270 bool WorkspaceManager::CycleAwayFromCurrentlyActiveWorkspace() { |
| 271 if (active_workspace_ == desktop_workspace()) |
| 272 return false; |
| 273 |
| 274 aura::Window* active_window = active_workspace_->GetActiveWindow(); |
| 275 MoveWorkspaceToHiddenOrDelete(active_workspace_, NULL, SWITCH_OTHER); |
| 276 |
| 277 // The activation controller will pick a window from the just activated |
| 278 // workspace to activate as a result of DeactivateWindow(). |
| 279 if (active_window) |
| 280 wm::DeactivateWindow(active_window); |
| 281 return true; |
| 282 } |
| 283 |
| 284 bool WorkspaceManager::CycleToNextHiddenWorkspace() { |
| 285 if (hidden_workspaces_.empty()) |
| 286 return false; |
| 287 |
| 288 aura::Window* active_window = active_workspace_->GetActiveWindow(); |
| 289 SetActiveWorkspace(hidden_workspaces_.back(), SWITCH_OTHER, |
| 290 base::TimeDelta()); |
| 291 |
| 292 // The activation controller will pick a window from the just activated |
| 293 // workspace to activate as a result of DeactivateWindow(). |
| 294 if (active_window) |
| 295 wm::DeactivateWindow(active_window); |
| 296 return true; |
| 297 } |
| 298 |
| 267 void WorkspaceManager::DoInitialAnimation() { | 299 void WorkspaceManager::DoInitialAnimation() { |
| 268 if (active_workspace_->is_maximized()) { | 300 if (active_workspace_->is_maximized()) { |
| 269 RootWindowController* root_controller = GetRootWindowController( | 301 RootWindowController* root_controller = GetRootWindowController( |
| 270 contents_view_->GetRootWindow()); | 302 contents_view_->GetRootWindow()); |
| 271 if (root_controller) { | 303 if (root_controller) { |
| 272 aura::Window* background = root_controller->GetContainer( | 304 aura::Window* background = root_controller->GetContainer( |
| 273 kShellWindowId_DesktopBackgroundContainer); | 305 kShellWindowId_DesktopBackgroundContainer); |
| 274 background->Show(); | 306 background->Show(); |
| 275 ShowOrHideDesktopBackground(background, SWITCH_INITIAL, | 307 ShowOrHideDesktopBackground(background, SWITCH_INITIAL, |
| 276 base::TimeDelta(), false); | 308 base::TimeDelta(), false); |
| 277 } | 309 } |
| 278 } | 310 } |
| 279 ShowWorkspace(active_workspace_, active_workspace_, SWITCH_INITIAL); | 311 ShowWorkspace(active_workspace_, active_workspace_, SWITCH_INITIAL); |
| 280 } | 312 } |
| 281 | 313 |
| 314 aura::Window* WorkspaceManager::GetActiveWorkspaceWindow() const { |
| 315 return active_workspace_->window(); |
| 316 } |
| 317 |
| 282 void WorkspaceManager::OnAppTerminating() { | 318 void WorkspaceManager::OnAppTerminating() { |
| 283 app_terminating_ = true; | 319 app_terminating_ = true; |
| 284 } | 320 } |
| 285 | 321 |
| 286 void WorkspaceManager::UpdateShelfVisibility() { | 322 void WorkspaceManager::UpdateShelfVisibility() { |
| 287 if (shelf_) | 323 if (shelf_) |
| 288 shelf_->UpdateVisibilityState(); | 324 shelf_->UpdateVisibilityState(); |
| 289 } | 325 } |
| 290 | 326 |
| 291 Workspace* WorkspaceManager::FindBy(Window* window) const { | 327 Workspace* WorkspaceManager::FindBy(Window* window) const { |
| 292 while (window) { | 328 while (window) { |
| 293 Workspace* workspace = window->GetProperty(kWorkspaceKey); | 329 Workspace* workspace = window->GetProperty(kWorkspaceKey); |
| 294 if (workspace) | 330 if (workspace) |
| 295 return workspace; | 331 return workspace; |
| 296 window = window->parent(); | 332 window = window->parent(); |
| 297 } | 333 } |
| 298 return NULL; | 334 return NULL; |
| 299 } | 335 } |
| 300 | 336 |
| 301 void WorkspaceManager::SetActiveWorkspace(Workspace* workspace, | 337 void WorkspaceManager::SetActiveWorkspace(Workspace* workspace, |
| 302 SwitchReason reason, | 338 SwitchReason reason, |
| 303 base::TimeDelta duration) { | 339 base::TimeDelta duration) { |
| 304 DCHECK(workspace); | 340 DCHECK(workspace); |
| 305 if (active_workspace_ == workspace) | 341 if (active_workspace_ == workspace) |
| 306 return; | 342 return; |
| 307 | 343 |
| 344 Workspaces::iterator it = std::find( |
| 345 hidden_workspaces_.begin(), hidden_workspaces_.end(), workspace); |
| 346 if (it != hidden_workspaces_.end()) |
| 347 hidden_workspaces_.erase(it); |
| 308 pending_workspaces_.erase(workspace); | 348 pending_workspaces_.erase(workspace); |
| 309 | 349 |
| 310 // Adjust the z-order. No need to adjust the z-order for the desktop since | 350 // Adjust the z-order. No need to adjust the z-order for the desktop since |
| 311 // it always stays at the bottom. | 351 // it always stays at the bottom. |
| 312 if (workspace != desktop_workspace() && | 352 if (workspace != desktop_workspace() && |
| 313 FindWorkspace(workspace) == workspaces_.end()) { | 353 FindWorkspace(workspace) == workspaces_.end()) { |
| 314 contents_view_->StackChildAbove(workspace->window(), | 354 contents_view_->StackChildAbove(workspace->window(), |
| 315 workspaces_.back()->window()); | 355 workspaces_.back()->window()); |
| 316 workspaces_.push_back(workspace); | 356 workspaces_.push_back(workspace); |
| 317 } | 357 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 | 404 |
| 365 WorkspaceManager::Workspaces::iterator | 405 WorkspaceManager::Workspaces::iterator |
| 366 WorkspaceManager::FindWorkspace(Workspace* workspace) { | 406 WorkspaceManager::FindWorkspace(Workspace* workspace) { |
| 367 return std::find(workspaces_.begin(), workspaces_.end(), workspace); | 407 return std::find(workspaces_.begin(), workspaces_.end(), workspace); |
| 368 } | 408 } |
| 369 | 409 |
| 370 Workspace* WorkspaceManager::CreateWorkspace(bool maximized) { | 410 Workspace* WorkspaceManager::CreateWorkspace(bool maximized) { |
| 371 return new Workspace(this, contents_view_, maximized); | 411 return new Workspace(this, contents_view_, maximized); |
| 372 } | 412 } |
| 373 | 413 |
| 374 void WorkspaceManager::MoveWorkspaceToPendingOrDelete( | 414 void WorkspaceManager::MoveWorkspaceToHiddenOrDelete( |
| 375 Workspace* workspace, | 415 Workspace* workspace, |
| 376 Window* stack_beneath, | 416 Window* stack_beneath, |
| 377 SwitchReason reason) { | 417 SwitchReason reason) { |
| 378 // We're all ready moving windows. | 418 // We're all ready moving windows. |
| 379 if (in_move_) | 419 if (in_move_) |
| 380 return; | 420 return; |
| 381 | 421 |
| 382 DCHECK_NE(desktop_workspace(), workspace); | 422 DCHECK_NE(desktop_workspace(), workspace); |
| 383 | 423 |
| 384 if (workspace == active_workspace_) | 424 if (workspace == active_workspace_) |
| 385 SelectNextWorkspace(reason); | 425 SelectNextWorkspace(reason); |
| 386 | 426 |
| 387 base::AutoReset<bool> setter(&in_move_, true); | 427 base::AutoReset<bool> setter(&in_move_, true); |
| 388 | 428 |
| 389 MoveChildrenToDesktop(workspace->window(), stack_beneath); | 429 MoveChildrenToDesktop(workspace->window(), stack_beneath); |
| 390 | 430 |
| 431 bool workspace_previously_active = false; |
| 391 { | 432 { |
| 392 Workspaces::iterator workspace_i(FindWorkspace(workspace)); | 433 Workspaces::iterator workspace_i(FindWorkspace(workspace)); |
| 393 if (workspace_i != workspaces_.end()) | 434 if (workspace_i != workspaces_.end()) { |
| 394 workspaces_.erase(workspace_i); | 435 workspaces_.erase(workspace_i); |
| 436 workspace_previously_active = true; |
| 437 } |
| 395 } | 438 } |
| 396 | 439 |
| 397 if (workspace->window()->children().empty()) { | 440 if (workspace->window()->children().empty()) { |
| 398 if (workspace == unminimizing_workspace_) | 441 if (workspace == unminimizing_workspace_) |
| 399 unminimizing_workspace_ = NULL; | 442 unminimizing_workspace_ = NULL; |
| 443 Workspaces::iterator hidden_i = std::find( |
| 444 hidden_workspaces_.begin(), hidden_workspaces_.end(), workspace); |
| 445 if (hidden_i != hidden_workspaces_.end()) |
| 446 hidden_workspaces_.erase(hidden_i); |
| 400 pending_workspaces_.erase(workspace); | 447 pending_workspaces_.erase(workspace); |
| 401 ScheduleDelete(workspace); | 448 ScheduleDelete(workspace); |
| 402 } else { | 449 } else if (workspace_previously_active) { |
| 403 pending_workspaces_.insert(workspace); | 450 hidden_workspaces_.push_back(workspace); |
| 404 } | 451 } |
| 405 } | 452 } |
| 406 | 453 |
| 407 void WorkspaceManager::MoveChildrenToDesktop(aura::Window* window, | 454 void WorkspaceManager::MoveChildrenToDesktop(aura::Window* window, |
| 408 aura::Window* stack_beneath) { | 455 aura::Window* stack_beneath) { |
| 409 // Build the list of windows to move. Exclude maximized/fullscreen and windows | 456 // Build the list of windows to move. Exclude maximized/fullscreen and windows |
| 410 // with transient parents. | 457 // with transient parents. |
| 411 Window::Windows to_move; | 458 Window::Windows to_move; |
| 412 for (size_t i = 0; i < window->children().size(); ++i) { | 459 for (size_t i = 0; i < window->children().size(); ++i) { |
| 413 Window* child = window->children()[i]; | 460 Window* child = window->children()[i]; |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 | 660 |
| 614 void WorkspaceManager::OnWillRemoveWindowFromWorkspace(Workspace* workspace, | 661 void WorkspaceManager::OnWillRemoveWindowFromWorkspace(Workspace* workspace, |
| 615 Window* child) { | 662 Window* child) { |
| 616 if (child->TargetVisibility()) | 663 if (child->TargetVisibility()) |
| 617 RearrangeVisibleWindowOnHideOrRemove(child); | 664 RearrangeVisibleWindowOnHideOrRemove(child); |
| 618 child->ClearProperty(kWorkspaceKey); | 665 child->ClearProperty(kWorkspaceKey); |
| 619 } | 666 } |
| 620 | 667 |
| 621 void WorkspaceManager::OnWindowRemovedFromWorkspace(Workspace* workspace, | 668 void WorkspaceManager::OnWindowRemovedFromWorkspace(Workspace* workspace, |
| 622 Window* child) { | 669 Window* child) { |
| 623 if (workspace->ShouldMoveToPending()) | 670 if (workspace->ShouldMoveToHidden()) |
| 624 MoveWorkspaceToPendingOrDelete(workspace, NULL, SWITCH_WINDOW_REMOVED); | 671 MoveWorkspaceToHiddenOrDelete(workspace, NULL, SWITCH_WINDOW_REMOVED); |
| 625 } | 672 } |
| 626 | 673 |
| 627 void WorkspaceManager::OnWorkspaceChildWindowVisibilityChanged( | 674 void WorkspaceManager::OnWorkspaceChildWindowVisibilityChanged( |
| 628 Workspace* workspace, | 675 Workspace* workspace, |
| 629 Window* child) { | 676 Window* child) { |
| 630 if (workspace->ShouldMoveToPending()) { | 677 if (workspace->ShouldMoveToHidden()) { |
| 631 MoveWorkspaceToPendingOrDelete(workspace, NULL, SWITCH_VISIBILITY_CHANGED); | 678 MoveWorkspaceToHiddenOrDelete(workspace, NULL, SWITCH_VISIBILITY_CHANGED); |
| 632 } else { | 679 } else { |
| 633 if (child->TargetVisibility()) | 680 if (child->TargetVisibility()) |
| 634 RearrangeVisibleWindowOnShow(child); | 681 RearrangeVisibleWindowOnShow(child); |
| 635 else | 682 else |
| 636 RearrangeVisibleWindowOnHideOrRemove(child); | 683 RearrangeVisibleWindowOnHideOrRemove(child); |
| 637 if (workspace == active_workspace_) | 684 if (workspace == active_workspace_) |
| 638 UpdateShelfVisibility(); | 685 UpdateShelfVisibility(); |
| 639 } | 686 } |
| 640 } | 687 } |
| 641 | 688 |
| 642 void WorkspaceManager::OnWorkspaceWindowChildBoundsChanged( | 689 void WorkspaceManager::OnWorkspaceWindowChildBoundsChanged( |
| 643 Workspace* workspace, | 690 Workspace* workspace, |
| 644 Window* child) { | 691 Window* child) { |
| 645 if (workspace == active_workspace_) | 692 if (workspace == active_workspace_) |
| 646 UpdateShelfVisibility(); | 693 UpdateShelfVisibility(); |
| 647 } | 694 } |
| 648 | 695 |
| 649 void WorkspaceManager::OnWorkspaceWindowShowStateChanged( | 696 void WorkspaceManager::OnWorkspaceWindowShowStateChanged( |
| 650 Workspace* workspace, | 697 Workspace* workspace, |
| 651 Window* child, | 698 Window* child, |
| 652 ui::WindowShowState last_show_state, | 699 ui::WindowShowState last_show_state, |
| 653 ui::Layer* old_layer) { | 700 ui::Layer* old_layer) { |
| 654 // |child| better still be in |workspace| else things have gone wrong. | 701 // |child| better still be in |workspace| else things have gone wrong. |
| 655 DCHECK_EQ(workspace, child->GetProperty(kWorkspaceKey)); | 702 DCHECK_EQ(workspace, child->GetProperty(kWorkspaceKey)); |
| 656 if (wm::IsWindowMinimized(child)) { | 703 if (wm::IsWindowMinimized(child)) { |
| 657 if (workspace->ShouldMoveToPending()) | 704 if (workspace->ShouldMoveToHidden()) |
| 658 MoveWorkspaceToPendingOrDelete(workspace, NULL, SWITCH_MINIMIZED); | 705 MoveWorkspaceToHiddenOrDelete(workspace, NULL, SWITCH_MINIMIZED); |
| 659 DCHECK(!old_layer); | 706 DCHECK(!old_layer); |
| 660 } else { | 707 } else { |
| 661 // Set of cases to deal with: | 708 // Set of cases to deal with: |
| 662 // . More than one maximized window: move newly maximized window into | 709 // . More than one maximized window: move newly maximized window into |
| 663 // own workspace. | 710 // own workspace. |
| 664 // . One maximized window and not in a maximized workspace: move window | 711 // . One maximized window and not in a maximized workspace: move window |
| 665 // into own workspace. | 712 // into own workspace. |
| 666 // . No maximized window and not in desktop: move to desktop and further | 713 // . No maximized window and not in desktop: move to desktop and further |
| 667 // any existing windows are stacked beneath |child|. | 714 // any existing windows are stacked beneath |child|. |
| 668 const bool is_active = wm::IsActiveWindow(child); | 715 const bool is_active = wm::IsActiveWindow(child); |
| 669 Workspace* new_workspace = NULL; | 716 Workspace* new_workspace = NULL; |
| 670 const int max_count = workspace->GetNumMaximizedWindows(); | 717 const int max_count = workspace->GetNumMaximizedWindows(); |
| 671 base::TimeDelta duration = old_layer && !IsMaximized(child) ? | 718 base::TimeDelta duration = old_layer && !IsMaximized(child) ? |
| 672 GetCrossFadeDuration(old_layer->bounds(), child->bounds()) : | 719 GetCrossFadeDuration(old_layer->bounds(), child->bounds()) : |
| 673 base::TimeDelta::FromMilliseconds(kCrossFadeSwitchTimeMS); | 720 base::TimeDelta::FromMilliseconds(kCrossFadeSwitchTimeMS); |
| 674 if (max_count == 0) { | 721 if (max_count == 0) { |
| 675 if (workspace != desktop_workspace()) { | 722 if (workspace != desktop_workspace()) { |
| 676 { | 723 { |
| 677 base::AutoReset<bool> setter(&in_move_, true); | 724 base::AutoReset<bool> setter(&in_move_, true); |
| 678 ReparentWindow(child, desktop_workspace()->window(), NULL); | 725 ReparentWindow(child, desktop_workspace()->window(), NULL); |
| 679 } | 726 } |
| 680 DCHECK(!is_active || old_layer); | 727 DCHECK(!is_active || old_layer); |
| 681 new_workspace = desktop_workspace(); | 728 new_workspace = desktop_workspace(); |
| 682 SetActiveWorkspace(new_workspace, SWITCH_MAXIMIZED_OR_RESTORED, | 729 SetActiveWorkspace(new_workspace, SWITCH_MAXIMIZED_OR_RESTORED, |
| 683 duration); | 730 duration); |
| 684 MoveWorkspaceToPendingOrDelete(workspace, child, | 731 MoveWorkspaceToHiddenOrDelete(workspace, child, |
| 685 SWITCH_MAXIMIZED_OR_RESTORED); | 732 SWITCH_MAXIMIZED_OR_RESTORED); |
| 686 if (FindWorkspace(workspace) == workspaces_.end()) | 733 if (FindWorkspace(workspace) == workspaces_.end()) |
| 687 workspace = NULL; | 734 workspace = NULL; |
| 688 } | 735 } |
| 689 } else if ((max_count == 1 && workspace == desktop_workspace()) || | 736 } else if ((max_count == 1 && workspace == desktop_workspace()) || |
| 690 max_count > 1) { | 737 max_count > 1) { |
| 691 new_workspace = CreateWorkspace(true); | 738 new_workspace = CreateWorkspace(true); |
| 692 pending_workspaces_.insert(new_workspace); | 739 pending_workspaces_.insert(new_workspace); |
| 693 ReparentWindow(child, new_workspace->window(), NULL); | 740 ReparentWindow(child, new_workspace->window(), NULL); |
| 694 } | 741 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 736 new_workspace->window()->Show(); | 783 new_workspace->window()->Show(); |
| 737 ReparentWindow(window, new_workspace->window(), NULL); | 784 ReparentWindow(window, new_workspace->window(), NULL); |
| 738 if (is_active) { | 785 if (is_active) { |
| 739 SetActiveWorkspace(new_workspace, SWITCH_TRACKED_BY_WORKSPACE_CHANGED, | 786 SetActiveWorkspace(new_workspace, SWITCH_TRACKED_BY_WORKSPACE_CHANGED, |
| 740 base::TimeDelta()); | 787 base::TimeDelta()); |
| 741 } | 788 } |
| 742 } | 789 } |
| 743 | 790 |
| 744 } // namespace internal | 791 } // namespace internal |
| 745 } // namespace ash | 792 } // namespace ash |
| OLD | NEW |