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

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

Issue 11417150: Implement workspace scrubbing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years 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
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_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
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
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::CycleToNextVisibleWorkspace() {
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
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_visible = 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_visible = 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_visible) {
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698