Home | History | Annotate | Download | only in wm
      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
      3 // found in the LICENSE file.
      4 
      5 #include "ash/wm/workspace_controller.h"
      6 
      7 #include "ash/root_window_controller.h"
      8 #include "ash/shelf/shelf_layout_manager.h"
      9 #include "ash/shell.h"
     10 #include "ash/shell_window_ids.h"
     11 #include "ash/wm/window_animations.h"
     12 #include "ash/wm/window_state.h"
     13 #include "ash/wm/window_util.h"
     14 #include "ash/wm/workspace/workspace_event_handler.h"
     15 #include "ash/wm/workspace/workspace_layout_manager.h"
     16 #include "ash/wm/workspace/workspace_layout_manager_delegate.h"
     17 #include "ui/aura/client/aura_constants.h"
     18 #include "ui/aura/window.h"
     19 #include "ui/aura/window_event_dispatcher.h"
     20 #include "ui/compositor/layer.h"
     21 #include "ui/compositor/scoped_layer_animation_settings.h"
     22 #include "ui/wm/core/visibility_controller.h"
     23 #include "ui/wm/core/window_animations.h"
     24 #include "ui/wm/public/activation_client.h"
     25 
     26 namespace ash {
     27 namespace {
     28 
     29 // Amount of time to pause before animating anything. Only used during initial
     30 // animation (when logging in).
     31 const int kInitialPauseTimeMS = 750;
     32 
     33 // Returns true if there are visible docked windows in the same screen as the
     34 // |shelf|.
     35 bool IsDockedAreaVisible(const ShelfLayoutManager* shelf) {
     36   return shelf->dock_bounds().width() > 0;
     37 }
     38 
     39 }  // namespace
     40 
     41 WorkspaceController::WorkspaceController(aura::Window* viewport)
     42     : viewport_(viewport),
     43       shelf_(NULL),
     44       event_handler_(new WorkspaceEventHandler),
     45       layout_manager_(new WorkspaceLayoutManager(viewport)) {
     46   SetWindowVisibilityAnimationTransition(
     47       viewport_, ::wm::ANIMATE_NONE);
     48 
     49   viewport_->SetLayoutManager(layout_manager_);
     50   viewport_->AddPreTargetHandler(event_handler_.get());
     51   viewport_->AddPostTargetHandler(event_handler_.get());
     52 }
     53 
     54 WorkspaceController::~WorkspaceController() {
     55   viewport_->SetLayoutManager(NULL);
     56   viewport_->RemovePreTargetHandler(event_handler_.get());
     57   viewport_->RemovePostTargetHandler(event_handler_.get());
     58 }
     59 
     60 WorkspaceWindowState WorkspaceController::GetWindowState() const {
     61   if (!shelf_)
     62     return WORKSPACE_WINDOW_STATE_DEFAULT;
     63   const aura::Window* topmost_fullscreen_window = GetRootWindowController(
     64       viewport_->GetRootWindow())->GetWindowForFullscreenMode();
     65   if (topmost_fullscreen_window &&
     66       !wm::GetWindowState(topmost_fullscreen_window)->ignored_by_shelf()) {
     67     return WORKSPACE_WINDOW_STATE_FULL_SCREEN;
     68   }
     69 
     70   // These are the container ids of containers which may contain windows that
     71   // may overlap the launcher shelf and affect its transparency.
     72   const int kWindowContainerIds[] = {kShellWindowId_DefaultContainer,
     73                                      kShellWindowId_DockedContainer, };
     74   const gfx::Rect shelf_bounds(shelf_->GetIdealBounds());
     75   bool window_overlaps_launcher = false;
     76   for (size_t idx = 0; idx < arraysize(kWindowContainerIds); idx++) {
     77     const aura::Window* container = Shell::GetContainer(
     78         viewport_->GetRootWindow(), kWindowContainerIds[idx]);
     79     const aura::Window::Windows& windows(container->children());
     80     for (aura::Window::Windows::const_iterator i = windows.begin();
     81          i != windows.end(); ++i) {
     82       wm::WindowState* window_state = wm::GetWindowState(*i);
     83       if (window_state->ignored_by_shelf())
     84         continue;
     85       ui::Layer* layer = (*i)->layer();
     86       if (!layer->GetTargetVisibility())
     87         continue;
     88       if (window_state->IsMaximized())
     89         return WORKSPACE_WINDOW_STATE_MAXIMIZED;
     90       if (!window_overlaps_launcher &&
     91           ((*i)->bounds().Intersects(shelf_bounds))) {
     92         window_overlaps_launcher = true;
     93       }
     94     }
     95   }
     96 
     97   return (window_overlaps_launcher || IsDockedAreaVisible(shelf_)) ?
     98       WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF :
     99       WORKSPACE_WINDOW_STATE_DEFAULT;
    100 }
    101 
    102 void WorkspaceController::SetShelf(ShelfLayoutManager* shelf) {
    103   shelf_ = shelf;
    104   layout_manager_->SetShelf(shelf);
    105 }
    106 
    107 void WorkspaceController::DoInitialAnimation() {
    108   viewport_->Show();
    109 
    110   viewport_->layer()->SetOpacity(0.0f);
    111   SetTransformForScaleAnimation(
    112       viewport_->layer(), LAYER_SCALE_ANIMATION_ABOVE);
    113 
    114   // In order for pause to work we need to stop animations.
    115   viewport_->layer()->GetAnimator()->StopAnimating();
    116 
    117   {
    118     ui::ScopedLayerAnimationSettings settings(
    119         viewport_->layer()->GetAnimator());
    120 
    121     settings.SetPreemptionStrategy(ui::LayerAnimator::ENQUEUE_NEW_ANIMATION);
    122     viewport_->layer()->GetAnimator()->SchedulePauseForProperties(
    123         base::TimeDelta::FromMilliseconds(kInitialPauseTimeMS),
    124         ui::LayerAnimationElement::TRANSFORM |
    125             ui::LayerAnimationElement::OPACITY |
    126             ui::LayerAnimationElement::BRIGHTNESS |
    127             ui::LayerAnimationElement::VISIBILITY);
    128     settings.SetTweenType(gfx::Tween::EASE_OUT);
    129     settings.SetTransitionDuration(
    130         base::TimeDelta::FromMilliseconds(kCrossFadeDurationMS));
    131     viewport_->layer()->SetTransform(gfx::Transform());
    132     viewport_->layer()->SetOpacity(1.0f);
    133   }
    134 }
    135 
    136 void WorkspaceController::SetMaximizeBackdropDelegate(
    137     scoped_ptr<WorkspaceLayoutManagerDelegate> delegate) {
    138   layout_manager_->SetMaximizeBackdropDelegate(delegate.Pass());
    139 }
    140 
    141 }  // namespace ash
    142