• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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|.
IsDockedAreaVisible(const ShelfLayoutManager * shelf)36 bool IsDockedAreaVisible(const ShelfLayoutManager* shelf) {
37   return shelf->dock_bounds().width() > 0;
38 }
39 
40 }  // namespace
41 
WorkspaceController(aura::Window * viewport)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 
~WorkspaceController()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 
GetWindowState() const64 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 
SetShelf(ShelfLayoutManager * shelf)108 void WorkspaceController::SetShelf(ShelfLayoutManager* shelf) {
109   shelf_ = shelf;
110   layout_manager_->SetShelf(shelf);
111 }
112 
DoInitialAnimation()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