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