Index: ash/wm/workspace/workspace_manager2.cc |
=================================================================== |
--- ash/wm/workspace/workspace_manager2.cc (revision 165163) |
+++ ash/wm/workspace/workspace_manager2.cc (working copy) |
@@ -1,733 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "ash/wm/workspace/workspace_manager2.h" |
- |
-#include <algorithm> |
-#include <functional> |
- |
-#include "ash/ash_switches.h" |
-#include "ash/root_window_controller.h" |
-#include "ash/shell.h" |
-#include "ash/shell_window_ids.h" |
-#include "ash/wm/base_layout_manager.h" |
-#include "ash/wm/property_util.h" |
-#include "ash/wm/shelf_layout_manager.h" |
-#include "ash/wm/window_animations.h" |
-#include "ash/wm/window_properties.h" |
-#include "ash/wm/window_util.h" |
-#include "ash/wm/workspace/auto_window_management.h" |
-#include "ash/wm/workspace/desktop_background_fade_controller.h" |
-#include "ash/wm/workspace/workspace_animations.h" |
-#include "ash/wm/workspace/workspace_layout_manager2.h" |
-#include "ash/wm/workspace/workspace2.h" |
-#include "base/auto_reset.h" |
-#include "base/command_line.h" |
-#include "base/logging.h" |
-#include "base/stl_util.h" |
-#include "ui/aura/client/aura_constants.h" |
-#include "ui/aura/root_window.h" |
-#include "ui/aura/window.h" |
-#include "ui/aura/window_property.h" |
-#include "ui/base/ui_base_types.h" |
-#include "ui/compositor/layer.h" |
-#include "ui/compositor/layer_animator.h" |
-#include "ui/compositor/scoped_layer_animation_settings.h" |
-#include "ui/views/widget/widget.h" |
- |
-DECLARE_WINDOW_PROPERTY_TYPE(ash::internal::Workspace2*); |
-DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(ASH_EXPORT, ui::WindowShowState); |
- |
-using aura::Window; |
- |
-namespace ash { |
-namespace internal { |
- |
-DEFINE_WINDOW_PROPERTY_KEY(Workspace2*, kWorkspaceKey, NULL); |
- |
-namespace { |
- |
-// Duration for fading out the desktop background when maximizing. |
-const int kCrossFadeSwitchTimeMS = 700; |
- |
-// Amount of time to pause before animating anything. Only used during initial |
-// animation (when logging in). |
-const int kInitialPauseTimeMS = 750; |
- |
-// Changes the parent of |window| and all its transient children to |
-// |new_parent|. If |stack_beneach| is non-NULL all the windows are stacked |
-// beneath it. |
-void ReparentWindow(Window* window, |
- Window* new_parent, |
- Window* stack_beneath) { |
- window->SetParent(new_parent); |
- if (stack_beneath) |
- new_parent->StackChildBelow(window, stack_beneath); |
- for (size_t i = 0; i < window->transient_children().size(); ++i) |
- ReparentWindow(window->transient_children()[i], new_parent, stack_beneath); |
-} |
- |
-} // namespace |
- |
-// Workspace ------------------------------------------------------------------- |
- |
-// LayoutManager installed on the parent window of all the Workspace window (eg |
-// |WorkspaceManager2::contents_view_|). |
-class WorkspaceManager2::LayoutManagerImpl : public BaseLayoutManager { |
- public: |
- explicit LayoutManagerImpl(WorkspaceManager2* workspace_manager) |
- : BaseLayoutManager(workspace_manager->contents_view_->GetRootWindow()), |
- workspace_manager_(workspace_manager) { |
- } |
- virtual ~LayoutManagerImpl() {} |
- |
- // Overridden from BaseWorkspaceLayoutManager: |
- virtual void OnWindowResized() OVERRIDE { |
- for (size_t i = 0; i < window()->children().size(); ++i) |
- window()->children()[i]->SetBounds(gfx::Rect(window()->bounds().size())); |
- } |
- virtual void OnWindowAddedToLayout(Window* child) OVERRIDE { |
- // Only workspaces should be added as children. |
- DCHECK((child->id() == kShellWindowId_WorkspaceContainer) || |
- workspace_manager_->creating_fade_); |
- child->SetBounds(gfx::Rect(window()->bounds().size())); |
- } |
- |
- private: |
- aura::Window* window() { return workspace_manager_->contents_view_; } |
- |
- WorkspaceManager2* workspace_manager_; |
- |
- DISALLOW_COPY_AND_ASSIGN(LayoutManagerImpl); |
-}; |
- |
-// WorkspaceManager2 ----------------------------------------------------------- |
- |
-WorkspaceManager2::WorkspaceManager2(Window* contents_view) |
- : contents_view_(contents_view), |
- active_workspace_(NULL), |
- shelf_(NULL), |
- in_move_(false), |
- ALLOW_THIS_IN_INITIALIZER_LIST( |
- clear_unminimizing_workspace_factory_(this)), |
- unminimizing_workspace_(NULL), |
- app_terminating_(false), |
- creating_fade_(false) { |
- // Clobber any existing event filter. |
- contents_view->SetEventFilter(NULL); |
- // |contents_view| takes ownership of LayoutManagerImpl. |
- contents_view->SetLayoutManager(new LayoutManagerImpl(this)); |
- active_workspace_ = CreateWorkspace(false); |
- workspaces_.push_back(active_workspace_); |
- active_workspace_->window()->Show(); |
- Shell::GetInstance()->AddShellObserver(this); |
-} |
- |
-WorkspaceManager2::~WorkspaceManager2() { |
- Shell::GetInstance()->RemoveShellObserver(this); |
- // Release the windows, they'll be destroyed when |contents_view_| is |
- // destroyed. |
- std::for_each(workspaces_.begin(), workspaces_.end(), |
- std::mem_fun(&Workspace2::ReleaseWindow)); |
- std::for_each(pending_workspaces_.begin(), pending_workspaces_.end(), |
- std::mem_fun(&Workspace2::ReleaseWindow)); |
- std::for_each(to_delete_.begin(), to_delete_.end(), |
- std::mem_fun(&Workspace2::ReleaseWindow)); |
- STLDeleteElements(&workspaces_); |
- STLDeleteElements(&pending_workspaces_); |
- STLDeleteElements(&to_delete_); |
-} |
- |
-// static |
-bool WorkspaceManager2::IsMaximized(Window* window) { |
- return IsMaximizedState(window->GetProperty(aura::client::kShowStateKey)); |
-} |
- |
-// static |
-bool WorkspaceManager2::IsMaximizedState(ui::WindowShowState state) { |
- return state == ui::SHOW_STATE_MAXIMIZED || |
- state == ui::SHOW_STATE_FULLSCREEN; |
-} |
- |
-// static |
-bool WorkspaceManager2::WillRestoreMaximized(Window* window) { |
- return wm::IsWindowMinimized(window) && |
- IsMaximizedState(window->GetProperty(internal::kRestoreShowStateKey)); |
-} |
- |
-WorkspaceWindowState WorkspaceManager2::GetWindowState() const { |
- if (!shelf_) |
- return WORKSPACE_WINDOW_STATE_DEFAULT; |
- |
- const bool is_active_maximized = active_workspace_->is_maximized(); |
- const gfx::Rect shelf_bounds(shelf_->GetIdealBounds()); |
- const Window::Windows& windows(active_workspace_->window()->children()); |
- bool window_overlaps_launcher = false; |
- bool has_maximized_window = false; |
- for (Window::Windows::const_iterator i = windows.begin(); |
- i != windows.end(); ++i) { |
- if (GetIgnoredByShelf(*i)) |
- continue; |
- ui::Layer* layer = (*i)->layer(); |
- if (!layer->GetTargetVisibility() || layer->GetTargetOpacity() == 0.0f) |
- continue; |
- // Ignore maximized/fullscreen windows if we're in the desktop. Such a state |
- // is transitory and means we haven't yet switched. If we did consider such |
- // windows we'll return the wrong thing, which can lead to prematurely |
- // changing the launcher state and clobbering restore bounds. |
- if (is_active_maximized) { |
- if (wm::IsWindowMaximized(*i)) { |
- // An untracked window may still be fullscreen so we keep iterating when |
- // we hit a maximized window. |
- has_maximized_window = true; |
- } else if (wm::IsWindowFullscreen(*i)) { |
- return WORKSPACE_WINDOW_STATE_FULL_SCREEN; |
- } |
- } |
- if (!window_overlaps_launcher && (*i)->bounds().Intersects(shelf_bounds)) |
- window_overlaps_launcher = true; |
- } |
- if (has_maximized_window) |
- return WORKSPACE_WINDOW_STATE_MAXIMIZED; |
- |
- return window_overlaps_launcher ? |
- WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF : |
- WORKSPACE_WINDOW_STATE_DEFAULT; |
-} |
- |
-void WorkspaceManager2::SetShelf(ShelfLayoutManager* shelf) { |
- shelf_ = shelf; |
-} |
- |
-void WorkspaceManager2::SetActiveWorkspaceByWindow(Window* window) { |
- Workspace2* workspace = FindBy(window); |
- if (!workspace) |
- return; |
- |
- if (workspace != active_workspace_) { |
- // A window is being made active. In the following cases we reparent to |
- // the active desktop: |
- // . The window is not tracked by workspace code. This is used for tab |
- // dragging. Since tab dragging needs to happen in the active workspace we |
- // have to reparent the window (otherwise the window you dragged the tab |
- // out of would disappear since the workspace changed). Since this case is |
- // only transiently used (property reset on input release) we don't worry |
- // about window state. In fact we can't consider window state here as we |
- // have to allow dragging of a maximized window to work in this case. |
- // . The window persists across all workspaces. For example, the task |
- // manager is in the desktop worskpace and the current workspace is |
- // maximized. If we swapped to the desktop you would lose context. Instead |
- // we reparent. The exception to this is if the window is maximized (it |
- // needs its own workspace then) or we're in the process of maximizing. If |
- // we're in the process of maximizing the window needs its own workspace. |
- if (!GetTrackedByWorkspace(window) || |
- (GetPersistsAcrossAllWorkspaces(window) && !IsMaximized(window) && |
- !(wm::IsWindowMinimized(window) && WillRestoreMaximized(window)))) { |
- ReparentWindow(window, active_workspace_->window(), NULL); |
- } else { |
- SetActiveWorkspace(workspace, SWITCH_WINDOW_MADE_ACTIVE, |
- base::TimeDelta()); |
- } |
- } |
- if (workspace->is_maximized() && IsMaximized(window)) { |
- // Clicking on the maximized window in a maximized workspace. Force all |
- // other windows to drop to the desktop. |
- MoveChildrenToDesktop(workspace->window(), NULL); |
- } |
-} |
- |
-Window* WorkspaceManager2::GetParentForNewWindow(Window* window) { |
- // Try to put windows with transient parents in the same workspace as their |
- // transient parent. |
- if (window->transient_parent() && !IsMaximized(window)) { |
- Workspace2* workspace = FindBy(window->transient_parent()); |
- if (workspace) |
- return workspace->window(); |
- // Fall through to normal logic. |
- } |
- |
- if (!GetTrackedByWorkspace(window)) |
- return active_workspace_->window(); |
- |
- if (IsMaximized(window)) { |
- // Wait for the window to be made active before showing the workspace. |
- Workspace2* workspace = CreateWorkspace(true); |
- pending_workspaces_.insert(workspace); |
- return workspace->window(); |
- } |
- |
- if (!GetTrackedByWorkspace(window) || GetPersistsAcrossAllWorkspaces(window)) |
- return active_workspace_->window(); |
- |
- return desktop_workspace()->window(); |
-} |
- |
-void WorkspaceManager2::DoInitialAnimation() { |
- if (active_workspace_->is_maximized()) { |
- RootWindowController* root_controller = GetRootWindowController( |
- contents_view_->GetRootWindow()); |
- if (root_controller) { |
- aura::Window* background = root_controller->GetContainer( |
- kShellWindowId_DesktopBackgroundContainer); |
- background->Show(); |
- ShowOrHideDesktopBackground(background, SWITCH_INITIAL, |
- base::TimeDelta(), false); |
- } |
- } |
- ShowWorkspace(active_workspace_, active_workspace_, SWITCH_INITIAL); |
-} |
- |
-void WorkspaceManager2::OnAppTerminating() { |
- app_terminating_ = true; |
-} |
- |
-void WorkspaceManager2::UpdateShelfVisibility() { |
- if (shelf_) |
- shelf_->UpdateVisibilityState(); |
-} |
- |
-Workspace2* WorkspaceManager2::FindBy(Window* window) const { |
- while (window) { |
- Workspace2* workspace = window->GetProperty(kWorkspaceKey); |
- if (workspace) |
- return workspace; |
- window = window->parent(); |
- } |
- return NULL; |
-} |
- |
-void WorkspaceManager2::SetActiveWorkspace(Workspace2* workspace, |
- SwitchReason reason, |
- base::TimeDelta duration) { |
- DCHECK(workspace); |
- if (active_workspace_ == workspace) |
- return; |
- |
- pending_workspaces_.erase(workspace); |
- |
- // Adjust the z-order. No need to adjust the z-order for the desktop since |
- // it always stays at the bottom. |
- if (workspace != desktop_workspace() && |
- FindWorkspace(workspace) == workspaces_.end()) { |
- contents_view_->StackChildAbove(workspace->window(), |
- workspaces_.back()->window()); |
- workspaces_.push_back(workspace); |
- } |
- |
- Workspace2* last_active = active_workspace_; |
- active_workspace_ = workspace; |
- |
- // The display work-area may have changed while |workspace| was not the active |
- // workspace. Give it a chance to adjust its state for the new work-area. |
- active_workspace_->workspace_layout_manager()-> |
- OnDisplayWorkAreaInsetsChanged(); |
- |
- const bool is_unminimizing_maximized_window = |
- unminimizing_workspace_ && unminimizing_workspace_ == active_workspace_ && |
- active_workspace_->is_maximized(); |
- if (is_unminimizing_maximized_window) { |
- // If we're unminimizing a window it needs to be on the top, otherwise you |
- // won't see the animation. |
- contents_view_->StackChildAtTop(active_workspace_->window()); |
- } else if (active_workspace_->is_maximized() && last_active->is_maximized()) { |
- // When switching between maximized windows we need the last active |
- // workspace on top of the new, otherwise the animations won't look |
- // right. Since only one workspace is visible at a time stacking order of |
- // the workspace windows ultimately doesn't matter. |
- contents_view_->StackChildAtTop(last_active->window()); |
- } |
- |
- UpdateShelfVisibility(); |
- |
- // NOTE: duration supplied to this method is only used for desktop background. |
- HideWorkspace(last_active, reason, is_unminimizing_maximized_window); |
- ShowWorkspace(workspace, last_active, reason); |
- |
- RootWindowController* root_controller = GetRootWindowController( |
- contents_view_->GetRootWindow()); |
- if (root_controller) { |
- aura::Window* background = root_controller->GetContainer( |
- kShellWindowId_DesktopBackgroundContainer); |
- if (last_active == desktop_workspace()) { |
- ShowOrHideDesktopBackground(background, reason, duration, false); |
- } else if (active_workspace_ == desktop_workspace() && !app_terminating_) { |
- ShowOrHideDesktopBackground(background, reason, duration, true); |
- } |
- } |
-} |
- |
-WorkspaceManager2::Workspaces::iterator |
-WorkspaceManager2::FindWorkspace(Workspace2* workspace) { |
- return std::find(workspaces_.begin(), workspaces_.end(), workspace); |
-} |
- |
-Workspace2* WorkspaceManager2::CreateWorkspace(bool maximized) { |
- return new Workspace2(this, contents_view_, maximized); |
-} |
- |
-void WorkspaceManager2::MoveWorkspaceToPendingOrDelete( |
- Workspace2* workspace, |
- Window* stack_beneath, |
- SwitchReason reason) { |
- // We're all ready moving windows. |
- if (in_move_) |
- return; |
- |
- DCHECK_NE(desktop_workspace(), workspace); |
- |
- if (workspace == active_workspace_) |
- SelectNextWorkspace(reason); |
- |
- AutoReset<bool> setter(&in_move_, true); |
- |
- MoveChildrenToDesktop(workspace->window(), stack_beneath); |
- |
- { |
- Workspaces::iterator workspace_i(FindWorkspace(workspace)); |
- if (workspace_i != workspaces_.end()) |
- workspaces_.erase(workspace_i); |
- } |
- |
- if (workspace->window()->children().empty()) { |
- if (workspace == unminimizing_workspace_) |
- unminimizing_workspace_ = NULL; |
- pending_workspaces_.erase(workspace); |
- ScheduleDelete(workspace); |
- } else { |
- pending_workspaces_.insert(workspace); |
- } |
-} |
- |
-void WorkspaceManager2::MoveChildrenToDesktop(aura::Window* window, |
- aura::Window* stack_beneath) { |
- // Build the list of windows to move. Exclude maximized/fullscreen and windows |
- // with transient parents. |
- Window::Windows to_move; |
- for (size_t i = 0; i < window->children().size(); ++i) { |
- Window* child = window->children()[i]; |
- if (!child->transient_parent() && !IsMaximized(child) && |
- !WillRestoreMaximized(child)) { |
- to_move.push_back(child); |
- } |
- } |
- // Move the windows, but make sure the window is still a child of |window| |
- // (moving may cascade and cause other windows to move). |
- for (size_t i = 0; i < to_move.size(); ++i) { |
- if (std::find(window->children().begin(), window->children().end(), |
- to_move[i]) != window->children().end()) { |
- ReparentWindow(to_move[i], desktop_workspace()->window(), |
- stack_beneath); |
- } |
- } |
-} |
- |
-void WorkspaceManager2::SelectNextWorkspace(SwitchReason reason) { |
- DCHECK_NE(active_workspace_, desktop_workspace()); |
- |
- Workspaces::const_iterator workspace_i(FindWorkspace(active_workspace_)); |
- Workspaces::const_iterator next_workspace_i(workspace_i + 1); |
- if (next_workspace_i != workspaces_.end()) |
- SetActiveWorkspace(*next_workspace_i, reason, base::TimeDelta()); |
- else |
- SetActiveWorkspace(*(workspace_i - 1), reason, base::TimeDelta()); |
-} |
- |
-void WorkspaceManager2::ScheduleDelete(Workspace2* workspace) { |
- to_delete_.insert(workspace); |
- delete_timer_.Stop(); |
- delete_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(1), this, |
- &WorkspaceManager2::ProcessDeletion); |
-} |
- |
-void WorkspaceManager2::SetUnminimizingWorkspace(Workspace2* workspace) { |
- // The normal sequence of unminimizing a window is: Show() the window, which |
- // triggers changing the kShowStateKey to NORMAL and lastly the window is made |
- // active. This means at the time the window is unminimized we don't know if |
- // the workspace it is in is going to become active. To track this |
- // |unminimizing_workspace_| is set at the time we unminimize and a task is |
- // schedule to reset it. This way when we get the activate we know we're in |
- // the process unminimizing and can do the right animation. |
- unminimizing_workspace_ = workspace; |
- if (unminimizing_workspace_) { |
- MessageLoop::current()->PostTask( |
- FROM_HERE, |
- base::Bind(&WorkspaceManager2::SetUnminimizingWorkspace, |
- clear_unminimizing_workspace_factory_.GetWeakPtr(), |
- static_cast<Workspace2*>(NULL))); |
- } |
-} |
- |
-void WorkspaceManager2::FadeDesktop(aura::Window* window, |
- base::TimeDelta duration) { |
- if (CommandLine::ForCurrentProcess()->HasSwitch( |
- ash::switches::kAshWindowAnimationsDisabled) || |
- ui::LayerAnimator::disable_animations_for_test()) |
- return; |
- |
- AutoReset<bool> reseter(&creating_fade_, true); |
- DesktopBackgroundFadeController::Direction direction; |
- aura::Window* parent = NULL; |
- aura::Window* stack_above = NULL; |
- if (active_workspace_ == desktop_workspace()) { |
- direction = DesktopBackgroundFadeController::FADE_IN; |
- parent = desktop_workspace()->window(); |
- stack_above = window; |
- } else { |
- direction = DesktopBackgroundFadeController::FADE_OUT; |
- parent = contents_view_; |
- stack_above = desktop_workspace()->window(); |
- DCHECK_EQ(kCrossFadeSwitchTimeMS, (int)duration.InMilliseconds()); |
- duration = base::TimeDelta::FromMilliseconds(kCrossFadeSwitchTimeMS); |
- } |
- desktop_fade_controller_.reset( |
- new DesktopBackgroundFadeController( |
- parent, stack_above, duration, direction)); |
-} |
- |
-void WorkspaceManager2::ShowOrHideDesktopBackground( |
- aura::Window* window, |
- SwitchReason reason, |
- base::TimeDelta duration, |
- bool show) const { |
- WorkspaceAnimationDetails details; |
- details.animate = true; |
- details.direction = show ? WORKSPACE_ANIMATE_UP : WORKSPACE_ANIMATE_DOWN; |
- details.animate_scale = reason != SWITCH_MAXIMIZED_OR_RESTORED; |
- details.duration = duration; |
- if (reason == SWITCH_INITIAL) |
- details.pause_time_ms = kInitialPauseTimeMS; |
- if (show) |
- ash::internal::ShowWorkspace(window, details); |
- else |
- ash::internal::HideWorkspace(window, details); |
-} |
- |
-void WorkspaceManager2::ShowWorkspace( |
- Workspace2* workspace, |
- Workspace2* last_active, |
- SwitchReason reason) const { |
- WorkspaceAnimationDetails details; |
- details.direction = |
- (last_active == desktop_workspace() || reason == SWITCH_INITIAL) ? |
- WORKSPACE_ANIMATE_DOWN : WORKSPACE_ANIMATE_UP; |
- |
- switch (reason) { |
- case SWITCH_WINDOW_MADE_ACTIVE: |
- case SWITCH_TRACKED_BY_WORKSPACE_CHANGED: |
- case SWITCH_WINDOW_REMOVED: |
- case SWITCH_VISIBILITY_CHANGED: |
- case SWITCH_MINIMIZED: |
- details.animate = details.animate_scale = true; |
- details.animate_opacity = last_active == desktop_workspace(); |
- break; |
- |
- case SWITCH_INITIAL: |
- details.animate = details.animate_opacity = details.animate_scale = true; |
- details.pause_time_ms = kInitialPauseTimeMS; |
- break; |
- |
- // Remaining cases require no animation. |
- default: |
- break; |
- } |
- ash::internal::ShowWorkspace(workspace->window(), details); |
-} |
- |
-void WorkspaceManager2::HideWorkspace( |
- Workspace2* workspace, |
- SwitchReason reason, |
- bool is_unminimizing_maximized_window) const { |
- WorkspaceAnimationDetails details; |
- details.direction = active_workspace_ == desktop_workspace() ? |
- WORKSPACE_ANIMATE_UP : WORKSPACE_ANIMATE_DOWN; |
- switch (reason) { |
- case SWITCH_WINDOW_MADE_ACTIVE: |
- case SWITCH_TRACKED_BY_WORKSPACE_CHANGED: |
- details.animate_opacity = |
- ((active_workspace_ == desktop_workspace() || |
- workspace != desktop_workspace()) && |
- !is_unminimizing_maximized_window); |
- details.animate_scale = true; |
- details.animate = true; |
- break; |
- |
- case SWITCH_MAXIMIZED_OR_RESTORED: |
- if (active_workspace_->is_maximized()) { |
- // Delay the hide until the animation is done. |
- details.duration = |
- base::TimeDelta::FromMilliseconds(kCrossFadeSwitchTimeMS); |
- details.animate = true; |
- } |
- break; |
- |
- // Remaining cases require no animation. |
- default: |
- break; |
- } |
- ash::internal::HideWorkspace(workspace->window(), details); |
-} |
- |
-void WorkspaceManager2::ProcessDeletion() { |
- std::set<Workspace2*> to_delete; |
- to_delete.swap(to_delete_); |
- for (std::set<Workspace2*>::iterator i = to_delete.begin(); |
- i != to_delete.end(); ++i) { |
- Workspace2* workspace = *i; |
- if (workspace->window()->layer()->children().empty()) { |
- delete workspace->ReleaseWindow(); |
- delete workspace; |
- } else { |
- to_delete_.insert(workspace); |
- } |
- } |
- if (!to_delete_.empty()) { |
- delete_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(1), this, |
- &WorkspaceManager2::ProcessDeletion); |
- } |
-} |
- |
-void WorkspaceManager2::OnWindowAddedToWorkspace(Workspace2* workspace, |
- Window* child) { |
- child->SetProperty(kWorkspaceKey, workspace); |
- // Do nothing (other than updating shelf visibility) as the right parent was |
- // chosen by way of GetParentForNewWindow() or we explicitly moved the window |
- // to the workspace. |
- if (workspace == active_workspace_) |
- UpdateShelfVisibility(); |
- |
- RearrangeVisibleWindowOnShow(child); |
-} |
- |
-void WorkspaceManager2::OnWillRemoveWindowFromWorkspace(Workspace2* workspace, |
- Window* child) { |
- if (child->TargetVisibility()) |
- RearrangeVisibleWindowOnHideOrRemove(child); |
- child->ClearProperty(kWorkspaceKey); |
-} |
- |
-void WorkspaceManager2::OnWindowRemovedFromWorkspace(Workspace2* workspace, |
- Window* child) { |
- if (workspace->ShouldMoveToPending()) |
- MoveWorkspaceToPendingOrDelete(workspace, NULL, SWITCH_WINDOW_REMOVED); |
-} |
- |
-void WorkspaceManager2::OnWorkspaceChildWindowVisibilityChanged( |
- Workspace2* workspace, |
- Window* child) { |
- if (workspace->ShouldMoveToPending()) { |
- MoveWorkspaceToPendingOrDelete(workspace, NULL, SWITCH_VISIBILITY_CHANGED); |
- } else { |
- if (child->TargetVisibility()) |
- RearrangeVisibleWindowOnShow(child); |
- else |
- RearrangeVisibleWindowOnHideOrRemove(child); |
- if (workspace == active_workspace_) |
- UpdateShelfVisibility(); |
- } |
-} |
- |
-void WorkspaceManager2::OnWorkspaceWindowChildBoundsChanged( |
- Workspace2* workspace, |
- Window* child) { |
- if (workspace == active_workspace_) |
- UpdateShelfVisibility(); |
-} |
- |
-void WorkspaceManager2::OnWorkspaceWindowShowStateChanged( |
- Workspace2* workspace, |
- Window* child, |
- ui::WindowShowState last_show_state, |
- ui::Layer* old_layer) { |
- // |child| better still be in |workspace| else things have gone wrong. |
- DCHECK_EQ(workspace, child->GetProperty(kWorkspaceKey)); |
- if (wm::IsWindowMinimized(child)) { |
- if (workspace->ShouldMoveToPending()) |
- MoveWorkspaceToPendingOrDelete(workspace, NULL, SWITCH_MINIMIZED); |
- DCHECK(!old_layer); |
- } else { |
- // Set of cases to deal with: |
- // . More than one maximized window: move newly maximized window into |
- // own workspace. |
- // . One maximized window and not in a maximized workspace: move window |
- // into own workspace. |
- // . No maximized window and not in desktop: move to desktop and further |
- // any existing windows are stacked beneath |child|. |
- const bool is_active = wm::IsActiveWindow(child); |
- Workspace2* new_workspace = NULL; |
- const int max_count = workspace->GetNumMaximizedWindows(); |
- base::TimeDelta duration = old_layer && !IsMaximized(child) ? |
- GetCrossFadeDuration(old_layer->bounds(), child->bounds()) : |
- base::TimeDelta::FromMilliseconds(kCrossFadeSwitchTimeMS); |
- if (max_count == 0) { |
- if (workspace != desktop_workspace()) { |
- { |
- AutoReset<bool> setter(&in_move_, true); |
- ReparentWindow(child, desktop_workspace()->window(), NULL); |
- } |
- DCHECK(!is_active || old_layer); |
- new_workspace = desktop_workspace(); |
- SetActiveWorkspace(new_workspace, SWITCH_MAXIMIZED_OR_RESTORED, |
- duration); |
- MoveWorkspaceToPendingOrDelete(workspace, child, |
- SWITCH_MAXIMIZED_OR_RESTORED); |
- if (FindWorkspace(workspace) == workspaces_.end()) |
- workspace = NULL; |
- } |
- } else if ((max_count == 1 && workspace == desktop_workspace()) || |
- max_count > 1) { |
- new_workspace = CreateWorkspace(true); |
- pending_workspaces_.insert(new_workspace); |
- ReparentWindow(child, new_workspace->window(), NULL); |
- } |
- if (is_active && new_workspace) { |
- // |old_layer| may be NULL if as part of processing |
- // WorkspaceLayoutManager2::OnWindowPropertyChanged() the window is made |
- // active. |
- if (old_layer) { |
- SetActiveWorkspace(new_workspace, SWITCH_MAXIMIZED_OR_RESTORED, |
- duration); |
- CrossFadeWindowBetweenWorkspaces(new_workspace->window(), child, |
- old_layer); |
- if (workspace == desktop_workspace() || |
- new_workspace == desktop_workspace()) { |
- FadeDesktop(child, duration); |
- } |
- } else { |
- SetActiveWorkspace(new_workspace, SWITCH_OTHER, base::TimeDelta()); |
- } |
- } else { |
- if (last_show_state == ui::SHOW_STATE_MINIMIZED) |
- SetUnminimizingWorkspace(new_workspace ? new_workspace : workspace); |
- DCHECK(!old_layer); |
- } |
- } |
- UpdateShelfVisibility(); |
-} |
- |
-void WorkspaceManager2::OnTrackedByWorkspaceChanged(Workspace2* workspace, |
- aura::Window* window) { |
- Workspace2* new_workspace = NULL; |
- if (IsMaximized(window)) { |
- new_workspace = CreateWorkspace(true); |
- pending_workspaces_.insert(new_workspace); |
- } else if (workspace->is_maximized()) { |
- new_workspace = desktop_workspace(); |
- } else { |
- return; |
- } |
- // If the window is active we need to make sure the destination Workspace |
- // window is showing. Otherwise the window will be parented to a hidden window |
- // and lose activation. |
- const bool is_active = wm::IsActiveWindow(window); |
- if (is_active) |
- new_workspace->window()->Show(); |
- ReparentWindow(window, new_workspace->window(), NULL); |
- if (is_active) { |
- SetActiveWorkspace(new_workspace, SWITCH_TRACKED_BY_WORKSPACE_CHANGED, |
- base::TimeDelta()); |
- } |
-} |
- |
-} // namespace internal |
-} // namespace ash |