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/shelf/shelf_layout_manager.h" | 5 #include "ash/shelf/shelf_layout_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 #include <cstring> | 9 #include <cstring> |
10 #include <string> | 10 #include <string> |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 if (auto_hide_behavior_ == behavior) | 209 if (auto_hide_behavior_ == behavior) |
210 return; | 210 return; |
211 auto_hide_behavior_ = behavior; | 211 auto_hide_behavior_ = behavior; |
212 UpdateVisibilityState(); | 212 UpdateVisibilityState(); |
213 FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_, | 213 FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_, |
214 OnAutoHideStateChanged(state_.auto_hide_state)); | 214 OnAutoHideStateChanged(state_.auto_hide_state)); |
215 FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_, | 215 FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_, |
216 OnAutoHideBehaviorChanged(auto_hide_behavior_)); | 216 OnAutoHideBehaviorChanged(auto_hide_behavior_)); |
217 } | 217 } |
218 | 218 |
| 219 void ShelfLayoutManager::PrepareForShutdown() { |
| 220 // Clear all event filters, otherwise sometimes those filters may catch |
| 221 // synthesized mouse event and cause crashes during the shutdown. |
| 222 set_workspace_controller(NULL); |
| 223 auto_hide_event_filter_.reset(); |
| 224 bezel_event_filter_.reset(); |
| 225 } |
| 226 |
219 bool ShelfLayoutManager::IsVisible() const { | 227 bool ShelfLayoutManager::IsVisible() const { |
220 return shelf_->status_area_widget()->IsVisible() && | 228 // status_area_widget() may be NULL during the shutdown. |
| 229 return shelf_->status_area_widget() && |
| 230 shelf_->status_area_widget()->IsVisible() && |
221 (state_.visibility_state == SHELF_VISIBLE || | 231 (state_.visibility_state == SHELF_VISIBLE || |
222 (state_.visibility_state == SHELF_AUTO_HIDE && | 232 (state_.visibility_state == SHELF_AUTO_HIDE && |
223 state_.auto_hide_state == SHELF_AUTO_HIDE_SHOWN)); | 233 state_.auto_hide_state == SHELF_AUTO_HIDE_SHOWN)); |
224 } | 234 } |
225 | 235 |
226 bool ShelfLayoutManager::SetAlignment(ShelfAlignment alignment) { | 236 bool ShelfLayoutManager::SetAlignment(ShelfAlignment alignment) { |
227 if (alignment_ == alignment) | 237 if (alignment_ == alignment) |
228 return false; | 238 return false; |
229 | 239 |
230 alignment_ = alignment; | 240 alignment_ = alignment; |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 | 550 |
541 void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) { | 551 void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) { |
542 if (!shelf_->GetNativeView()) | 552 if (!shelf_->GetNativeView()) |
543 return; | 553 return; |
544 | 554 |
545 State state; | 555 State state; |
546 state.visibility_state = visibility_state; | 556 state.visibility_state = visibility_state; |
547 state.auto_hide_state = CalculateAutoHideState(visibility_state); | 557 state.auto_hide_state = CalculateAutoHideState(visibility_state); |
548 state.is_screen_locked = | 558 state.is_screen_locked = |
549 Shell::GetInstance()->session_state_delegate()->IsScreenLocked(); | 559 Shell::GetInstance()->session_state_delegate()->IsScreenLocked(); |
| 560 state.window_state = workspace_controller_ ? |
| 561 workspace_controller_->GetWindowState() : WORKSPACE_WINDOW_STATE_DEFAULT; |
550 | 562 |
551 // It's possible for SetState() when a window becomes maximized but the state | 563 // It's possible for SetState() when a window becomes maximized but the state |
552 // won't have changed value. Do the dimming check before the early exit. | 564 // won't have changed value. Do the dimming check before the early exit. |
553 if (workspace_controller_) { | 565 shelf_->SetDimsShelf( |
554 shelf_->SetDimsShelf( | 566 (state.visibility_state == SHELF_VISIBLE) && |
555 (state.visibility_state == SHELF_VISIBLE) && | 567 state.window_state == WORKSPACE_WINDOW_STATE_MAXIMIZED); |
556 workspace_controller_->GetWindowState() == | |
557 WORKSPACE_WINDOW_STATE_MAXIMIZED); | |
558 } | |
559 | 568 |
560 if (state_.Equals(state)) | 569 if (state_.Equals(state)) |
561 return; // Nothing changed. | 570 return; // Nothing changed. |
562 | 571 |
563 FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_, | 572 FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_, |
564 WillChangeVisibilityState(visibility_state)); | 573 WillChangeVisibilityState(visibility_state)); |
565 | 574 |
566 if (state.visibility_state == SHELF_AUTO_HIDE) { | 575 if (state.visibility_state == SHELF_AUTO_HIDE) { |
567 // When state is SHELF_AUTO_HIDE we need to track when the mouse is over the | 576 // When state is SHELF_AUTO_HIDE we need to track when the mouse is over the |
568 // launcher to unhide the shelf. AutoHideEventFilter does that for us. | 577 // launcher to unhide the shelf. AutoHideEventFilter does that for us. |
569 if (!auto_hide_event_filter_) | 578 if (!auto_hide_event_filter_) |
570 auto_hide_event_filter_.reset(new AutoHideEventFilter(this)); | 579 auto_hide_event_filter_.reset(new AutoHideEventFilter(this)); |
571 } else { | 580 } else { |
572 auto_hide_event_filter_.reset(NULL); | 581 auto_hide_event_filter_.reset(NULL); |
573 } | 582 } |
574 | 583 |
575 auto_hide_timer_.Stop(); | 584 auto_hide_timer_.Stop(); |
576 | 585 |
577 // Animating the background when transitioning from auto-hide & hidden to | 586 // The transition of background from auto-hide to visible is janky if the |
578 // visible is janky. Update the background immediately in this case. | 587 // transition also cause the shelf's slide animation from the bottom edge. |
| 588 // This happens if: |
| 589 // - shelf is hidden |
| 590 // - or, shelf is visible but workspace state is maximized |
| 591 bool keep_maximized = state_.window_state == state.window_state && |
| 592 state_.window_state == WORKSPACE_WINDOW_STATE_MAXIMIZED; |
579 BackgroundAnimator::ChangeType change_type = | 593 BackgroundAnimator::ChangeType change_type = |
580 (state_.visibility_state == SHELF_AUTO_HIDE && | 594 (state_.visibility_state == SHELF_AUTO_HIDE && |
581 state_.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN && | 595 state.visibility_state == SHELF_VISIBLE && |
582 state.visibility_state == SHELF_VISIBLE) ? | 596 (state_.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN || |
| 597 keep_maximized)) ? |
583 BackgroundAnimator::CHANGE_IMMEDIATE : BackgroundAnimator::CHANGE_ANIMATE; | 598 BackgroundAnimator::CHANGE_IMMEDIATE : BackgroundAnimator::CHANGE_ANIMATE; |
584 | 599 |
585 State old_state = state_; | 600 State old_state = state_; |
586 state_ = state; | 601 state_ = state; |
587 TargetBounds target_bounds; | 602 TargetBounds target_bounds; |
588 CalculateTargetBounds(state_, &target_bounds); | 603 CalculateTargetBounds(state_, &target_bounds); |
589 | 604 |
590 ui::ScopedLayerAnimationSettings launcher_animation_setter( | 605 ui::ScopedLayerAnimationSettings launcher_animation_setter( |
591 GetLayer(shelf_)->GetAnimator()); | 606 GetLayer(shelf_)->GetAnimator()); |
592 launcher_animation_setter.SetTransitionDuration( | 607 launcher_animation_setter.SetTransitionDuration( |
(...skipping 10 matching lines...) Expand all Loading... |
603 base::TimeDelta::FromMilliseconds(kWorkspaceSwitchTimeMS)); | 618 base::TimeDelta::FromMilliseconds(kWorkspaceSwitchTimeMS)); |
604 status_animation_setter.SetTweenType(ui::Tween::EASE_OUT); | 619 status_animation_setter.SetTweenType(ui::Tween::EASE_OUT); |
605 status_animation_setter.SetPreemptionStrategy( | 620 status_animation_setter.SetPreemptionStrategy( |
606 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 621 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
607 | 622 |
608 // Delay updating the background when going from SHELF_AUTO_HIDE_SHOWN to | 623 // Delay updating the background when going from SHELF_AUTO_HIDE_SHOWN to |
609 // SHELF_AUTO_HIDE_HIDDEN until the shelf animates out. Otherwise during the | 624 // SHELF_AUTO_HIDE_HIDDEN until the shelf animates out. Otherwise during the |
610 // animation you see the background change. | 625 // animation you see the background change. |
611 // Also delay the animation when the shelf was hidden, and has just been made | 626 // Also delay the animation when the shelf was hidden, and has just been made |
612 // visible (e.g. using a gesture-drag). | 627 // visible (e.g. using a gesture-drag). |
| 628 // But do not delay if the transition happens when a window is maximized. |
613 bool delay_shelf_update = | 629 bool delay_shelf_update = |
614 state.visibility_state == SHELF_AUTO_HIDE && | 630 state.visibility_state == SHELF_AUTO_HIDE && |
615 state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN && | 631 state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN && |
616 old_state.visibility_state == SHELF_AUTO_HIDE; | 632 old_state.visibility_state == SHELF_AUTO_HIDE; |
617 | 633 |
618 if (state.visibility_state == SHELF_VISIBLE && | 634 if (!keep_maximized && state.visibility_state == SHELF_VISIBLE && |
619 old_state.visibility_state == SHELF_AUTO_HIDE && | 635 old_state.visibility_state == SHELF_AUTO_HIDE && |
620 old_state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN) | 636 old_state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN) |
621 delay_shelf_update = true; | 637 delay_shelf_update = true; |
622 | 638 |
623 if (delay_shelf_update) { | 639 if (delay_shelf_update) { |
624 if (update_shelf_observer_) | 640 if (update_shelf_observer_) |
625 update_shelf_observer_->Detach(); | 641 update_shelf_observer_->Detach(); |
626 // UpdateShelfBackground deletes itself when the animation is done. | 642 // UpdateShelfBackground deletes itself when the animation is done. |
627 update_shelf_observer_ = new UpdateShelfObserver(this); | 643 update_shelf_observer_ = new UpdateShelfObserver(this); |
628 status_animation_setter.AddObserver(update_shelf_observer_); | 644 status_animation_setter.AddObserver(update_shelf_observer_); |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
833 gfx::Rect status_x = target_bounds->shelf_bounds_in_root; | 849 gfx::Rect status_x = target_bounds->shelf_bounds_in_root; |
834 status_x.set_x(0); | 850 status_x.set_x(0); |
835 status_x.ClampToCenteredSize( | 851 status_x.ClampToCenteredSize( |
836 target_bounds->status_bounds_in_shelf.size()); | 852 target_bounds->status_bounds_in_shelf.size()); |
837 target_bounds->status_bounds_in_shelf.set_x(status_x.x()); | 853 target_bounds->status_bounds_in_shelf.set_x(status_x.x()); |
838 } | 854 } |
839 } | 855 } |
840 | 856 |
841 void ShelfLayoutManager::UpdateShelfBackground( | 857 void ShelfLayoutManager::UpdateShelfBackground( |
842 BackgroundAnimator::ChangeType type) { | 858 BackgroundAnimator::ChangeType type) { |
843 bool launcher_paints = GetLauncherPaintsBackground(); | 859 shelf_->SetPaintsBackground(GetShelfBackgroundType(), type); |
844 shelf_->SetPaintsBackground(launcher_paints, type); | |
845 } | 860 } |
846 | 861 |
847 bool ShelfLayoutManager::GetLauncherPaintsBackground() const { | 862 ShelfBackgroundType ShelfLayoutManager::GetShelfBackgroundType() const { |
848 return gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS || | 863 if (state_.visibility_state != SHELF_AUTO_HIDE && |
| 864 state_.window_state == WORKSPACE_WINDOW_STATE_MAXIMIZED) { |
| 865 return SHELF_BACKGROUND_MAXIMIZED; |
| 866 } |
| 867 |
| 868 if (gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS || |
849 (!state_.is_screen_locked && window_overlaps_shelf_) || | 869 (!state_.is_screen_locked && window_overlaps_shelf_) || |
850 (state_.visibility_state == SHELF_AUTO_HIDE); | 870 (state_.visibility_state == SHELF_AUTO_HIDE)) { |
| 871 return SHELF_BACKGROUND_OVERLAP; |
| 872 } |
| 873 |
| 874 return SHELF_BACKGROUND_DEFAULT; |
851 } | 875 } |
852 | 876 |
853 void ShelfLayoutManager::UpdateAutoHideStateNow() { | 877 void ShelfLayoutManager::UpdateAutoHideStateNow() { |
854 SetState(state_.visibility_state); | 878 SetState(state_.visibility_state); |
855 } | 879 } |
856 | 880 |
857 ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState( | 881 ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState( |
858 ShelfVisibilityState visibility_state) const { | 882 ShelfVisibilityState visibility_state) const { |
859 if (visibility_state != SHELF_AUTO_HIDE || !shelf_) | 883 if (visibility_state != SHELF_AUTO_HIDE || !shelf_) |
860 return SHELF_AUTO_HIDE_HIDDEN; | 884 return SHELF_AUTO_HIDE_HIDDEN; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
975 return gfx::Insets(0, distance, 0, 0); | 999 return gfx::Insets(0, distance, 0, 0); |
976 case SHELF_ALIGNMENT_TOP: | 1000 case SHELF_ALIGNMENT_TOP: |
977 return gfx::Insets(0, 0, distance, 0); | 1001 return gfx::Insets(0, 0, distance, 0); |
978 } | 1002 } |
979 NOTREACHED(); | 1003 NOTREACHED(); |
980 return gfx::Insets(); | 1004 return gfx::Insets(); |
981 } | 1005 } |
982 | 1006 |
983 } // namespace internal | 1007 } // namespace internal |
984 } // namespace ash | 1008 } // namespace ash |
OLD | NEW |