OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/wm/shelf_layout_manager.h" | 5 #include "ash/wm/shelf_layout_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
10 #include "ash/launcher/launcher.h" | 10 #include "ash/launcher/launcher.h" |
11 #include "ash/screen_ash.h" | 11 #include "ash/screen_ash.h" |
12 #include "ash/shell.h" | 12 #include "ash/shell.h" |
13 #include "ash/shell_delegate.h" | 13 #include "ash/shell_delegate.h" |
14 #include "ash/shell_window_ids.h" | 14 #include "ash/shell_window_ids.h" |
15 #include "ash/system/status_area_widget.h" | 15 #include "ash/system/status_area_widget.h" |
| 16 #include "ash/wm/window_animations.h" |
16 #include "ash/wm/workspace_controller.h" | 17 #include "ash/wm/workspace_controller.h" |
17 #include "base/auto_reset.h" | 18 #include "base/auto_reset.h" |
18 #include "base/i18n/rtl.h" | 19 #include "base/i18n/rtl.h" |
19 #include "ui/aura/client/activation_client.h" | 20 #include "ui/aura/client/activation_client.h" |
20 #include "ui/aura/event_filter.h" | 21 #include "ui/aura/event_filter.h" |
21 #include "ui/aura/root_window.h" | 22 #include "ui/aura/root_window.h" |
22 #include "ui/base/events/event.h" | 23 #include "ui/base/events/event.h" |
23 #include "ui/compositor/layer.h" | 24 #include "ui/compositor/layer.h" |
24 #include "ui/compositor/layer_animation_observer.h" | 25 #include "ui/compositor/layer_animation_observer.h" |
25 #include "ui/compositor/layer_animator.h" | 26 #include "ui/compositor/layer_animator.h" |
(...skipping 14 matching lines...) Expand all Loading... |
40 } | 41 } |
41 | 42 |
42 } // namespace | 43 } // namespace |
43 | 44 |
44 // static | 45 // static |
45 const int ShelfLayoutManager::kWorkspaceAreaBottomInset = 2; | 46 const int ShelfLayoutManager::kWorkspaceAreaBottomInset = 2; |
46 | 47 |
47 // static | 48 // static |
48 const int ShelfLayoutManager::kAutoHideSize = 2; | 49 const int ShelfLayoutManager::kAutoHideSize = 2; |
49 | 50 |
| 51 // ShelfLayoutManager::AutoHideEventFilter ------------------------------------- |
| 52 |
50 // Notifies ShelfLayoutManager any time the mouse moves. | 53 // Notifies ShelfLayoutManager any time the mouse moves. |
51 class ShelfLayoutManager::AutoHideEventFilter : public aura::EventFilter { | 54 class ShelfLayoutManager::AutoHideEventFilter : public aura::EventFilter { |
52 public: | 55 public: |
53 explicit AutoHideEventFilter(ShelfLayoutManager* shelf); | 56 explicit AutoHideEventFilter(ShelfLayoutManager* shelf); |
54 virtual ~AutoHideEventFilter(); | 57 virtual ~AutoHideEventFilter(); |
55 | 58 |
56 // Returns true if the last mouse event was a mouse drag. | 59 // Returns true if the last mouse event was a mouse drag. |
57 bool in_mouse_drag() const { return in_mouse_drag_; } | 60 bool in_mouse_drag() const { return in_mouse_drag_; } |
58 | 61 |
59 // Overridden from aura::EventFilter: | 62 // Overridden from aura::EventFilter: |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 return ui::TOUCH_STATUS_UNKNOWN; // Not handled. | 115 return ui::TOUCH_STATUS_UNKNOWN; // Not handled. |
113 } | 116 } |
114 | 117 |
115 ui::EventResult | 118 ui::EventResult |
116 ShelfLayoutManager::AutoHideEventFilter::PreHandleGestureEvent( | 119 ShelfLayoutManager::AutoHideEventFilter::PreHandleGestureEvent( |
117 aura::Window* target, | 120 aura::Window* target, |
118 ui::GestureEvent* event) { | 121 ui::GestureEvent* event) { |
119 return ui::ER_UNHANDLED; // Not handled. | 122 return ui::ER_UNHANDLED; // Not handled. |
120 } | 123 } |
121 | 124 |
122 //////////////////////////////////////////////////////////////////////////////// | 125 // ShelfLayoutManager:UpdateShelfObserver -------------------------------------- |
123 // ShelfLayoutManager, public: | 126 |
| 127 // UpdateShelfObserver is used to delay updating the background until the |
| 128 // animation completes. |
| 129 class ShelfLayoutManager::UpdateShelfObserver |
| 130 : public ui::ImplicitAnimationObserver { |
| 131 public: |
| 132 explicit UpdateShelfObserver(ShelfLayoutManager* shelf) : shelf_(shelf) { |
| 133 shelf_->update_shelf_observer_ = this; |
| 134 } |
| 135 |
| 136 void Detach() { |
| 137 shelf_ = NULL; |
| 138 } |
| 139 |
| 140 virtual void OnImplicitAnimationsCompleted() OVERRIDE { |
| 141 if (shelf_) { |
| 142 shelf_->UpdateShelfBackground( |
| 143 internal::BackgroundAnimator::CHANGE_ANIMATE); |
| 144 } |
| 145 delete this; |
| 146 } |
| 147 |
| 148 private: |
| 149 virtual ~UpdateShelfObserver() { |
| 150 if (shelf_) |
| 151 shelf_->update_shelf_observer_ = NULL; |
| 152 } |
| 153 |
| 154 // Shelf we're in. NULL if deleted before we're deleted. |
| 155 ShelfLayoutManager* shelf_; |
| 156 |
| 157 DISALLOW_COPY_AND_ASSIGN(UpdateShelfObserver); |
| 158 }; |
| 159 |
| 160 // ShelfLayoutManager ---------------------------------------------------------- |
124 | 161 |
125 ShelfLayoutManager::ShelfLayoutManager(views::Widget* status) | 162 ShelfLayoutManager::ShelfLayoutManager(views::Widget* status) |
126 : root_window_(Shell::GetPrimaryRootWindow()), | 163 : root_window_(Shell::GetPrimaryRootWindow()), |
127 in_layout_(false), | 164 in_layout_(false), |
128 auto_hide_behavior_(SHELF_AUTO_HIDE_BEHAVIOR_DEFAULT), | 165 auto_hide_behavior_(SHELF_AUTO_HIDE_BEHAVIOR_DEFAULT), |
129 alignment_(SHELF_ALIGNMENT_BOTTOM), | 166 alignment_(SHELF_ALIGNMENT_BOTTOM), |
130 launcher_(NULL), | 167 launcher_(NULL), |
131 status_(status), | 168 status_(status), |
132 workspace_controller_(NULL), | 169 workspace_controller_(NULL), |
133 window_overlaps_shelf_(false), | 170 window_overlaps_shelf_(false), |
134 gesture_drag_status_(GESTURE_DRAG_NONE), | 171 gesture_drag_status_(GESTURE_DRAG_NONE), |
135 gesture_drag_amount_(0.f), | 172 gesture_drag_amount_(0.f), |
136 gesture_drag_auto_hide_state_(AUTO_HIDE_SHOWN) { | 173 gesture_drag_auto_hide_state_(AUTO_HIDE_SHOWN), |
| 174 update_shelf_observer_(NULL) { |
137 Shell::GetInstance()->AddShellObserver(this); | 175 Shell::GetInstance()->AddShellObserver(this); |
138 aura::client::GetActivationClient(root_window_)->AddObserver(this); | 176 aura::client::GetActivationClient(root_window_)->AddObserver(this); |
139 } | 177 } |
140 | 178 |
141 ShelfLayoutManager::~ShelfLayoutManager() { | 179 ShelfLayoutManager::~ShelfLayoutManager() { |
| 180 if (update_shelf_observer_) |
| 181 update_shelf_observer_->Detach(); |
| 182 |
142 FOR_EACH_OBSERVER(Observer, observers_, WillDeleteShelf()); | 183 FOR_EACH_OBSERVER(Observer, observers_, WillDeleteShelf()); |
143 Shell::GetInstance()->RemoveShellObserver(this); | 184 Shell::GetInstance()->RemoveShellObserver(this); |
144 aura::client::GetActivationClient(root_window_)->RemoveObserver(this); | 185 aura::client::GetActivationClient(root_window_)->RemoveObserver(this); |
145 } | 186 } |
146 | 187 |
147 void ShelfLayoutManager::SetAutoHideBehavior(ShelfAutoHideBehavior behavior) { | 188 void ShelfLayoutManager::SetAutoHideBehavior(ShelfAutoHideBehavior behavior) { |
148 if (auto_hide_behavior_ == behavior) | 189 if (auto_hide_behavior_ == behavior) |
149 return; | 190 return; |
150 auto_hide_behavior_ = behavior; | 191 auto_hide_behavior_ = behavior; |
151 UpdateVisibilityState(); | 192 UpdateVisibilityState(); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 SetState(auto_hide_behavior_ != SHELF_AUTO_HIDE_BEHAVIOR_NEVER ? | 287 SetState(auto_hide_behavior_ != SHELF_AUTO_HIDE_BEHAVIOR_NEVER ? |
247 AUTO_HIDE : VISIBLE); | 288 AUTO_HIDE : VISIBLE); |
248 break; | 289 break; |
249 | 290 |
250 case WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF: | 291 case WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF: |
251 case WORKSPACE_WINDOW_STATE_DEFAULT: | 292 case WORKSPACE_WINDOW_STATE_DEFAULT: |
252 SetState(auto_hide_behavior_ == SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS ? | 293 SetState(auto_hide_behavior_ == SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS ? |
253 AUTO_HIDE : VISIBLE); | 294 AUTO_HIDE : VISIBLE); |
254 SetWindowOverlapsShelf(window_state == | 295 SetWindowOverlapsShelf(window_state == |
255 WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF); | 296 WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF); |
| 297 break; |
256 } | 298 } |
257 } | 299 } |
258 } | 300 } |
259 | 301 |
260 void ShelfLayoutManager::UpdateAutoHideState() { | 302 void ShelfLayoutManager::UpdateAutoHideState() { |
261 AutoHideState auto_hide_state = | 303 AutoHideState auto_hide_state = |
262 CalculateAutoHideState(state_.visibility_state); | 304 CalculateAutoHideState(state_.visibility_state); |
263 if (auto_hide_state != state_.auto_hide_state) { | 305 if (auto_hide_state != state_.auto_hide_state) { |
264 if (auto_hide_state == AUTO_HIDE_HIDDEN) { | 306 if (auto_hide_state == AUTO_HIDE_HIDDEN) { |
265 // Hides happen immediately. | 307 // Hides happen immediately. |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 // launcher to unhide the shelf. AutoHideEventFilter does that for us. | 503 // launcher to unhide the shelf. AutoHideEventFilter does that for us. |
462 if (!event_filter_.get()) | 504 if (!event_filter_.get()) |
463 event_filter_.reset(new AutoHideEventFilter(this)); | 505 event_filter_.reset(new AutoHideEventFilter(this)); |
464 } else { | 506 } else { |
465 event_filter_.reset(NULL); | 507 event_filter_.reset(NULL); |
466 } | 508 } |
467 | 509 |
468 auto_hide_timer_.Stop(); | 510 auto_hide_timer_.Stop(); |
469 | 511 |
470 // Animating the background when transitioning from auto-hide & hidden to | 512 // Animating the background when transitioning from auto-hide & hidden to |
471 // visibile is janking. Update the background immediately in this case. | 513 // visible is janky. Update the background immediately in this case. |
472 internal::BackgroundAnimator::ChangeType change_type = | 514 internal::BackgroundAnimator::ChangeType change_type = |
473 (state_.visibility_state == AUTO_HIDE && | 515 (state_.visibility_state == AUTO_HIDE && |
474 state_.auto_hide_state == AUTO_HIDE_HIDDEN && | 516 state_.auto_hide_state == AUTO_HIDE_HIDDEN && |
475 state.visibility_state == VISIBLE) ? | 517 state.visibility_state == VISIBLE) ? |
476 internal::BackgroundAnimator::CHANGE_IMMEDIATE : | 518 internal::BackgroundAnimator::CHANGE_IMMEDIATE : |
477 internal::BackgroundAnimator::CHANGE_ANIMATE; | 519 internal::BackgroundAnimator::CHANGE_ANIMATE; |
478 StopAnimating(); | 520 StopAnimating(); |
479 state_ = state; | 521 state_ = state; |
480 TargetBounds target_bounds; | 522 TargetBounds target_bounds; |
481 CalculateTargetBounds(state_, &target_bounds); | 523 CalculateTargetBounds(state_, &target_bounds); |
| 524 const int animate_time_ms = |
| 525 WorkspaceController::IsWorkspace2Enabled() ? kWorkspaceSwitchTimeMS : |
| 526 130; |
482 if (launcher_widget()) { | 527 if (launcher_widget()) { |
483 ui::ScopedLayerAnimationSettings launcher_animation_setter( | 528 ui::ScopedLayerAnimationSettings launcher_animation_setter( |
484 GetLayer(launcher_widget())->GetAnimator()); | 529 GetLayer(launcher_widget())->GetAnimator()); |
485 launcher_animation_setter.SetTransitionDuration( | 530 launcher_animation_setter.SetTransitionDuration( |
486 base::TimeDelta::FromMilliseconds(130)); | 531 base::TimeDelta::FromMilliseconds(animate_time_ms)); |
487 launcher_animation_setter.SetTweenType(ui::Tween::EASE_OUT); | 532 launcher_animation_setter.SetTweenType(ui::Tween::EASE_OUT); |
488 GetLayer(launcher_widget())->SetBounds( | 533 GetLayer(launcher_widget())->SetBounds( |
489 target_bounds.launcher_bounds_in_root); | 534 target_bounds.launcher_bounds_in_root); |
490 GetLayer(launcher_widget())->SetOpacity(target_bounds.opacity); | 535 GetLayer(launcher_widget())->SetOpacity(target_bounds.opacity); |
491 } | 536 } |
492 ui::ScopedLayerAnimationSettings status_animation_setter( | 537 ui::ScopedLayerAnimationSettings status_animation_setter( |
493 GetLayer(status_)->GetAnimator()); | 538 GetLayer(status_)->GetAnimator()); |
494 status_animation_setter.SetTransitionDuration( | 539 status_animation_setter.SetTransitionDuration( |
495 base::TimeDelta::FromMilliseconds(130)); | 540 base::TimeDelta::FromMilliseconds(animate_time_ms)); |
496 status_animation_setter.SetTweenType(ui::Tween::EASE_OUT); | 541 status_animation_setter.SetTweenType(ui::Tween::EASE_OUT); |
| 542 // Delay updating the background when going from AUTO_HIDE_SHOWN to |
| 543 // AUTO_HIDE_HIDDEN until the shelf animates out. Otherwise during the |
| 544 // animation you see the background change. |
| 545 const bool delay_shelf_update = |
| 546 state.visibility_state && AUTO_HIDE && |
| 547 state.auto_hide_state == AUTO_HIDE_HIDDEN && |
| 548 state_.visibility_state == AUTO_HIDE; |
| 549 if (delay_shelf_update) { |
| 550 if (update_shelf_observer_) |
| 551 update_shelf_observer_->Detach(); |
| 552 // UpdateShelfBackground deletes itself when the animation is done. |
| 553 update_shelf_observer_ = new UpdateShelfObserver(this); |
| 554 status_animation_setter.AddObserver(update_shelf_observer_); |
| 555 } |
497 GetLayer(status_)->SetBounds(target_bounds.status_bounds_in_root); | 556 GetLayer(status_)->SetBounds(target_bounds.status_bounds_in_root); |
498 GetLayer(status_)->SetOpacity(target_bounds.opacity); | 557 GetLayer(status_)->SetOpacity(target_bounds.opacity); |
499 Shell::GetInstance()->SetDisplayWorkAreaInsets( | 558 Shell::GetInstance()->SetDisplayWorkAreaInsets( |
500 Shell::GetPrimaryRootWindow(), | 559 Shell::GetPrimaryRootWindow(), |
501 target_bounds.work_area_insets); | 560 target_bounds.work_area_insets); |
502 UpdateHitTestBounds(); | 561 UpdateHitTestBounds(); |
503 UpdateShelfBackground(change_type); | 562 if (!delay_shelf_update) |
| 563 UpdateShelfBackground(change_type); |
504 } | 564 } |
505 | 565 |
506 void ShelfLayoutManager::StopAnimating() { | 566 void ShelfLayoutManager::StopAnimating() { |
507 if (launcher_widget()) | 567 if (launcher_widget()) |
508 GetLayer(launcher_widget())->GetAnimator()->StopAnimating(); | 568 GetLayer(launcher_widget())->GetAnimator()->StopAnimating(); |
509 GetLayer(status_)->GetAnimator()->StopAnimating(); | 569 GetLayer(status_)->GetAnimator()->StopAnimating(); |
510 } | 570 } |
511 | 571 |
512 void ShelfLayoutManager::GetShelfSize(int* width, int* height) { | 572 void ShelfLayoutManager::GetShelfSize(int* width, int* height) { |
513 *width = *height = 0; | 573 *width = *height = 0; |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
786 int ShelfLayoutManager::GetWorkAreaSize(const State& state, int size) const { | 846 int ShelfLayoutManager::GetWorkAreaSize(const State& state, int size) const { |
787 if (state.visibility_state == VISIBLE) | 847 if (state.visibility_state == VISIBLE) |
788 return size; | 848 return size; |
789 if (state.visibility_state == AUTO_HIDE) | 849 if (state.visibility_state == AUTO_HIDE) |
790 return kAutoHideSize; | 850 return kAutoHideSize; |
791 return 0; | 851 return 0; |
792 } | 852 } |
793 | 853 |
794 } // namespace internal | 854 } // namespace internal |
795 } // namespace ash | 855 } // namespace ash |
OLD | NEW |