| 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
|
|
|