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/shelf/shelf_layout_manager.h"
      8 #include "ash/shell.h"
      9 #include "ash/shell_window_ids.h"
     10 #include "ash/wm/base_layout_manager.h"
     11 #include "ash/wm/property_util.h"
     12 #include "ash/wm/window_animations.h"
     13 #include "ash/wm/window_properties.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 }  // namespace
     35 
     36 WorkspaceController::WorkspaceController(aura::Window* viewport)
     37     : viewport_(viewport),
     38       shelf_(NULL),
     39       event_handler_(new WorkspaceEventHandler(viewport_)) {
     40   SetWindowVisibilityAnimationTransition(
     41       viewport_, views::corewm::ANIMATE_NONE);
     42   // Do this so when animating out windows don't extend beyond the bounds.
     43   viewport_->layer()->SetMasksToBounds(true);
     44 
     45   // The layout-manager cannot be created in the initializer list since it
     46   // depends on the window to have been initialized.
     47   layout_manager_ = new WorkspaceLayoutManager(viewport_);
     48   viewport_->SetLayoutManager(layout_manager_);
     49 
     50   viewport_->Show();
     51 }
     52 
     53 WorkspaceController::~WorkspaceController() {
     54   viewport_->SetLayoutManager(NULL);
     55   viewport_->SetEventFilter(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 
     64   const gfx::Rect shelf_bounds(shelf_->GetIdealBounds());
     65   const aura::Window::Windows& windows(viewport_->children());
     66   bool window_overlaps_launcher = false;
     67   bool has_maximized_window = false;
     68   for (aura::Window::Windows::const_iterator i = windows.begin();
     69        i != windows.end(); ++i) {
     70     if (GetIgnoredByShelf(*i))
     71       continue;
     72     ui::Layer* layer = (*i)->layer();
     73     if (!layer->GetTargetVisibility() || layer->GetTargetOpacity() == 0.0f)
     74       continue;
     75     if (wm::IsWindowMaximized(*i)) {
     76       // An untracked window may still be fullscreen so we keep iterating when
     77       // we hit a maximized window.
     78       has_maximized_window = true;
     79     } else if (wm::IsWindowFullscreen(*i)) {
     80       return WORKSPACE_WINDOW_STATE_FULL_SCREEN;
     81     }
     82     if (!window_overlaps_launcher && (*i)->bounds().Intersects(shelf_bounds))
     83       window_overlaps_launcher = true;
     84   }
     85   if (has_maximized_window)
     86     return WORKSPACE_WINDOW_STATE_MAXIMIZED;
     87 
     88   return window_overlaps_launcher ?
     89       WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF :
     90       WORKSPACE_WINDOW_STATE_DEFAULT;
     91 }
     92 
     93 void WorkspaceController::SetShelf(ShelfLayoutManager* shelf) {
     94   shelf_ = shelf;
     95   layout_manager_->SetShelf(shelf);
     96 }
     97 
     98 void WorkspaceController::DoInitialAnimation() {
     99   viewport_->Show();
    100 
    101   viewport_->layer()->SetOpacity(0.0f);
    102   SetTransformForScaleAnimation(
    103       viewport_->layer(), LAYER_SCALE_ANIMATION_ABOVE);
    104 
    105   // In order for pause to work we need to stop animations.
    106   viewport_->layer()->GetAnimator()->StopAnimating();
    107 
    108   {
    109     ui::ScopedLayerAnimationSettings settings(
    110         viewport_->layer()->GetAnimator());
    111 
    112     settings.SetPreemptionStrategy(ui::LayerAnimator::ENQUEUE_NEW_ANIMATION);
    113     viewport_->layer()->GetAnimator()->SchedulePauseForProperties(
    114         base::TimeDelta::FromMilliseconds(kInitialPauseTimeMS),
    115         ui::LayerAnimationElement::TRANSFORM,
    116         ui::LayerAnimationElement::OPACITY,
    117         ui::LayerAnimationElement::BRIGHTNESS,
    118         ui::LayerAnimationElement::VISIBILITY,
    119         -1);
    120 
    121     settings.SetTweenType(ui::Tween::EASE_OUT);
    122     settings.SetTransitionDuration(
    123         base::TimeDelta::FromMilliseconds(kCrossFadeDurationMS));
    124     viewport_->layer()->SetTransform(gfx::Transform());
    125     viewport_->layer()->SetOpacity(1.0f);
    126   }
    127 }
    128 
    129 }  // namespace internal
    130 }  // namespace ash
    131