| Index: ash/wm/shelf_layout_manager.cc
|
| diff --git a/ash/wm/shelf_layout_manager.cc b/ash/wm/shelf_layout_manager.cc
|
| deleted file mode 100644
|
| index edbd359099ee1578156a433c538ec2a638fd41ba..0000000000000000000000000000000000000000
|
| --- a/ash/wm/shelf_layout_manager.cc
|
| +++ /dev/null
|
| @@ -1,945 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "ash/wm/shelf_layout_manager.h"
|
| -
|
| -#include <algorithm>
|
| -#include <cmath>
|
| -
|
| -#include "ash/ash_switches.h"
|
| -#include "ash/launcher/launcher.h"
|
| -#include "ash/root_window_controller.h"
|
| -#include "ash/screen_ash.h"
|
| -#include "ash/shell.h"
|
| -#include "ash/shell_delegate.h"
|
| -#include "ash/shell_window_ids.h"
|
| -#include "ash/system/status_area_widget.h"
|
| -#include "ash/wm/property_util.h"
|
| -#include "ash/wm/window_cycle_controller.h"
|
| -#include "ash/wm/window_util.h"
|
| -#include "ash/wm/workspace_controller.h"
|
| -#include "ash/wm/workspace/workspace_animations.h"
|
| -#include "base/auto_reset.h"
|
| -#include "base/command_line.h"
|
| -#include "base/i18n/rtl.h"
|
| -#include "ui/aura/client/activation_client.h"
|
| -#include "ui/aura/root_window.h"
|
| -#include "ui/base/events/event.h"
|
| -#include "ui/base/events/event_handler.h"
|
| -#include "ui/compositor/layer.h"
|
| -#include "ui/compositor/layer_animation_observer.h"
|
| -#include "ui/compositor/layer_animator.h"
|
| -#include "ui/compositor/scoped_layer_animation_settings.h"
|
| -#include "ui/gfx/screen.h"
|
| -#include "ui/views/widget/widget.h"
|
| -
|
| -namespace ash {
|
| -namespace internal {
|
| -
|
| -namespace {
|
| -
|
| -// Delay before showing the launcher. This is after the mouse stops moving.
|
| -const int kAutoHideDelayMS = 200;
|
| -
|
| -// To avoid hiding the shelf when the mouse transitions from a message bubble
|
| -// into the shelf, the hit test area is enlarged by this amount of pixels to
|
| -// keep the shelf from hiding.
|
| -const int kNotificationBubbleGapHeight = 6;
|
| -
|
| -ui::Layer* GetLayer(views::Widget* widget) {
|
| - return widget->GetNativeView()->layer();
|
| -}
|
| -
|
| -bool IsDraggingTrayEnabled() {
|
| - static bool dragging_tray_allowed = CommandLine::ForCurrentProcess()->
|
| - HasSwitch(ash::switches::kAshEnableTrayDragging);
|
| - return dragging_tray_allowed;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -// static
|
| -const int ShelfLayoutManager::kWorkspaceAreaBottomInset = 2;
|
| -
|
| -// static
|
| -const int ShelfLayoutManager::kAutoHideSize = 3;
|
| -
|
| -// ShelfLayoutManager::AutoHideEventFilter -------------------------------------
|
| -
|
| -// Notifies ShelfLayoutManager any time the mouse moves.
|
| -class ShelfLayoutManager::AutoHideEventFilter : public ui::EventHandler {
|
| - public:
|
| - explicit AutoHideEventFilter(ShelfLayoutManager* shelf);
|
| - virtual ~AutoHideEventFilter();
|
| -
|
| - // Returns true if the last mouse event was a mouse drag.
|
| - bool in_mouse_drag() const { return in_mouse_drag_; }
|
| -
|
| - // Overridden from ui::EventHandler:
|
| - virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE;
|
| -
|
| - private:
|
| - ShelfLayoutManager* shelf_;
|
| - bool in_mouse_drag_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(AutoHideEventFilter);
|
| -};
|
| -
|
| -ShelfLayoutManager::AutoHideEventFilter::AutoHideEventFilter(
|
| - ShelfLayoutManager* shelf)
|
| - : shelf_(shelf),
|
| - in_mouse_drag_(false) {
|
| - Shell::GetInstance()->AddPreTargetHandler(this);
|
| -}
|
| -
|
| -ShelfLayoutManager::AutoHideEventFilter::~AutoHideEventFilter() {
|
| - Shell::GetInstance()->RemovePreTargetHandler(this);
|
| -}
|
| -
|
| -void ShelfLayoutManager::AutoHideEventFilter::OnMouseEvent(
|
| - ui::MouseEvent* event) {
|
| - // This also checks IsShelfWindow() to make sure we don't attempt to hide the
|
| - // shelf if the mouse down occurs on the shelf.
|
| - in_mouse_drag_ = (event->type() == ui::ET_MOUSE_DRAGGED ||
|
| - (in_mouse_drag_ && event->type() != ui::ET_MOUSE_RELEASED &&
|
| - event->type() != ui::ET_MOUSE_CAPTURE_CHANGED)) &&
|
| - !shelf_->IsShelfWindow(static_cast<aura::Window*>(event->target()));
|
| - if (event->type() == ui::ET_MOUSE_MOVED)
|
| - shelf_->UpdateAutoHideState();
|
| - return;
|
| -}
|
| -
|
| -// ShelfLayoutManager:UpdateShelfObserver --------------------------------------
|
| -
|
| -// UpdateShelfObserver is used to delay updating the background until the
|
| -// animation completes.
|
| -class ShelfLayoutManager::UpdateShelfObserver
|
| - : public ui::ImplicitAnimationObserver {
|
| - public:
|
| - explicit UpdateShelfObserver(ShelfLayoutManager* shelf) : shelf_(shelf) {
|
| - shelf_->update_shelf_observer_ = this;
|
| - }
|
| -
|
| - void Detach() {
|
| - shelf_ = NULL;
|
| - }
|
| -
|
| - virtual void OnImplicitAnimationsCompleted() OVERRIDE {
|
| - if (shelf_) {
|
| - shelf_->UpdateShelfBackground(BackgroundAnimator::CHANGE_ANIMATE);
|
| - }
|
| - delete this;
|
| - }
|
| -
|
| - private:
|
| - virtual ~UpdateShelfObserver() {
|
| - if (shelf_)
|
| - shelf_->update_shelf_observer_ = NULL;
|
| - }
|
| -
|
| - // Shelf we're in. NULL if deleted before we're deleted.
|
| - ShelfLayoutManager* shelf_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(UpdateShelfObserver);
|
| -};
|
| -
|
| -// ShelfLayoutManager ----------------------------------------------------------
|
| -
|
| -ShelfLayoutManager::ShelfLayoutManager(StatusAreaWidget* status_area_widget)
|
| - : root_window_(status_area_widget->GetNativeView()->GetRootWindow()),
|
| - in_layout_(false),
|
| - auto_hide_behavior_(SHELF_AUTO_HIDE_BEHAVIOR_NEVER),
|
| - alignment_(SHELF_ALIGNMENT_BOTTOM),
|
| - launcher_(NULL),
|
| - status_area_widget_(status_area_widget),
|
| - workspace_controller_(NULL),
|
| - window_overlaps_shelf_(false),
|
| - gesture_drag_status_(GESTURE_DRAG_NONE),
|
| - gesture_drag_amount_(0.f),
|
| - gesture_drag_auto_hide_state_(SHELF_AUTO_HIDE_SHOWN),
|
| - update_shelf_observer_(NULL) {
|
| - Shell::GetInstance()->AddShellObserver(this);
|
| - aura::client::GetActivationClient(root_window_)->AddObserver(this);
|
| -}
|
| -
|
| -ShelfLayoutManager::~ShelfLayoutManager() {
|
| - if (update_shelf_observer_)
|
| - update_shelf_observer_->Detach();
|
| -
|
| - FOR_EACH_OBSERVER(Observer, observers_, WillDeleteShelf());
|
| - Shell::GetInstance()->RemoveShellObserver(this);
|
| - aura::client::GetActivationClient(root_window_)->RemoveObserver(this);
|
| -}
|
| -
|
| -void ShelfLayoutManager::SetAutoHideBehavior(ShelfAutoHideBehavior behavior) {
|
| - if (auto_hide_behavior_ == behavior)
|
| - return;
|
| - auto_hide_behavior_ = behavior;
|
| - UpdateVisibilityState();
|
| - FOR_EACH_OBSERVER(Observer, observers_,
|
| - OnAutoHideStateChanged(state_.auto_hide_state));
|
| -}
|
| -
|
| -bool ShelfLayoutManager::IsVisible() const {
|
| - return status_area_widget_->IsVisible() &&
|
| - (state_.visibility_state == SHELF_VISIBLE ||
|
| - (state_.visibility_state == SHELF_AUTO_HIDE &&
|
| - state_.auto_hide_state == SHELF_AUTO_HIDE_SHOWN));
|
| -}
|
| -
|
| -void ShelfLayoutManager::SetLauncher(Launcher* launcher) {
|
| - if (launcher == launcher_)
|
| - return;
|
| -
|
| - launcher_ = launcher;
|
| - if (launcher_)
|
| - launcher_->SetAlignment(alignment_);
|
| - LayoutShelf();
|
| -}
|
| -
|
| -bool ShelfLayoutManager::SetAlignment(ShelfAlignment alignment) {
|
| - if (alignment_ == alignment)
|
| - return false;
|
| -
|
| - alignment_ = alignment;
|
| - if (launcher_)
|
| - launcher_->SetAlignment(alignment);
|
| - status_area_widget_->SetShelfAlignment(alignment);
|
| - LayoutShelf();
|
| - return true;
|
| -}
|
| -
|
| -gfx::Rect ShelfLayoutManager::GetIdealBounds() {
|
| - // TODO(oshima): this is wrong. Figure out what display shelf is on
|
| - // and everything should be based on it.
|
| - gfx::Rect bounds(ScreenAsh::GetDisplayBoundsInParent(
|
| - status_area_widget_->GetNativeView()));
|
| - int width = 0, height = 0;
|
| - GetShelfSize(&width, &height);
|
| - return SelectValueForShelfAlignment(
|
| - gfx::Rect(bounds.x(), bounds.bottom() - height, bounds.width(), height),
|
| - gfx::Rect(bounds.x(), bounds.y(), width, bounds.height()),
|
| - gfx::Rect(bounds.right() - width, bounds.y(), width, bounds.height()),
|
| - gfx::Rect(bounds.x(), bounds.y(), bounds.width(), height));
|
| -}
|
| -
|
| -void ShelfLayoutManager::LayoutShelf() {
|
| - base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true);
|
| - StopAnimating();
|
| - TargetBounds target_bounds;
|
| - CalculateTargetBounds(state_, &target_bounds);
|
| - if (launcher_widget()) {
|
| - GetLayer(launcher_widget())->SetOpacity(target_bounds.opacity);
|
| - launcher_->SetWidgetBounds(
|
| - ScreenAsh::ConvertRectToScreen(
|
| - launcher_widget()->GetNativeView()->parent(),
|
| - target_bounds.launcher_bounds_in_root));
|
| - launcher_->SetStatusSize(target_bounds.status_bounds_in_root.size());
|
| - }
|
| - GetLayer(status_area_widget_)->SetOpacity(target_bounds.opacity);
|
| - status_area_widget_->SetBounds(
|
| - ScreenAsh::ConvertRectToScreen(
|
| - status_area_widget_->GetNativeView()->parent(),
|
| - target_bounds.status_bounds_in_root));
|
| - Shell::GetInstance()->SetDisplayWorkAreaInsets(
|
| - root_window_, target_bounds.work_area_insets);
|
| - UpdateHitTestBounds();
|
| -}
|
| -
|
| -ShelfVisibilityState ShelfLayoutManager::CalculateShelfVisibility() {
|
| - switch(auto_hide_behavior_) {
|
| - case SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS:
|
| - return SHELF_AUTO_HIDE;
|
| - case SHELF_AUTO_HIDE_BEHAVIOR_NEVER:
|
| - return SHELF_VISIBLE;
|
| - case SHELF_AUTO_HIDE_ALWAYS_HIDDEN:
|
| - return SHELF_HIDDEN;
|
| - }
|
| - return SHELF_VISIBLE;
|
| -}
|
| -
|
| -ShelfVisibilityState
|
| -ShelfLayoutManager::CalculateShelfVisibilityWhileDragging() {
|
| - switch(auto_hide_behavior_) {
|
| - case SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS:
|
| - case SHELF_AUTO_HIDE_BEHAVIOR_NEVER:
|
| - return SHELF_AUTO_HIDE;
|
| - case SHELF_AUTO_HIDE_ALWAYS_HIDDEN:
|
| - return SHELF_HIDDEN;
|
| - }
|
| - return SHELF_VISIBLE;
|
| -}
|
| -
|
| -void ShelfLayoutManager::UpdateVisibilityState() {
|
| - ShellDelegate* delegate = Shell::GetInstance()->delegate();
|
| - if (delegate && delegate->IsScreenLocked()) {
|
| - SetState(SHELF_VISIBLE);
|
| - } else if (gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS) {
|
| - // TODO(zelidrag): Verify shelf drag animation still shows on the device
|
| - // when we are in SHELF_AUTO_HIDE_ALWAYS_HIDDEN.
|
| - SetState(CalculateShelfVisibilityWhileDragging());
|
| - } else if (GetRootWindowController(root_window_)->IsImmersiveMode()) {
|
| - // The user choosing immersive mode indicates he or she wants to maximize
|
| - // screen real-estate for content, so always auto-hide the shelf.
|
| - DCHECK_NE(auto_hide_behavior_, SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
|
| - SetState(SHELF_AUTO_HIDE);
|
| - } else {
|
| - WorkspaceWindowState window_state(workspace_controller_->GetWindowState());
|
| - switch (window_state) {
|
| - case WORKSPACE_WINDOW_STATE_FULL_SCREEN:
|
| - SetState(SHELF_HIDDEN);
|
| - break;
|
| -
|
| - case WORKSPACE_WINDOW_STATE_MAXIMIZED:
|
| - SetState(CalculateShelfVisibility());
|
| - break;
|
| -
|
| - case WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF:
|
| - case WORKSPACE_WINDOW_STATE_DEFAULT:
|
| - SetState(CalculateShelfVisibility());
|
| - SetWindowOverlapsShelf(window_state ==
|
| - WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF);
|
| - break;
|
| - }
|
| - }
|
| -}
|
| -
|
| -void ShelfLayoutManager::UpdateAutoHideState() {
|
| - ShelfAutoHideState auto_hide_state =
|
| - CalculateAutoHideState(state_.visibility_state);
|
| - if (auto_hide_state != state_.auto_hide_state) {
|
| - if (auto_hide_state == SHELF_AUTO_HIDE_HIDDEN) {
|
| - // Hides happen immediately.
|
| - SetState(state_.visibility_state);
|
| - FOR_EACH_OBSERVER(Observer, observers_,
|
| - OnAutoHideStateChanged(auto_hide_state));
|
| - } else {
|
| - auto_hide_timer_.Stop();
|
| - auto_hide_timer_.Start(
|
| - FROM_HERE,
|
| - base::TimeDelta::FromMilliseconds(kAutoHideDelayMS),
|
| - this, &ShelfLayoutManager::UpdateAutoHideStateNow);
|
| - FOR_EACH_OBSERVER(Observer, observers_, OnAutoHideStateChanged(
|
| - CalculateAutoHideState(state_.visibility_state)));
|
| - }
|
| - } else {
|
| - auto_hide_timer_.Stop();
|
| - }
|
| -}
|
| -
|
| -void ShelfLayoutManager::SetWindowOverlapsShelf(bool value) {
|
| - window_overlaps_shelf_ = value;
|
| - UpdateShelfBackground(BackgroundAnimator::CHANGE_ANIMATE);
|
| -}
|
| -
|
| -void ShelfLayoutManager::AddObserver(Observer* observer) {
|
| - observers_.AddObserver(observer);
|
| -}
|
| -
|
| -void ShelfLayoutManager::RemoveObserver(Observer* observer) {
|
| - observers_.RemoveObserver(observer);
|
| -}
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -// ShelfLayoutManager, Gesture dragging:
|
| -
|
| -void ShelfLayoutManager::StartGestureDrag(const ui::GestureEvent& gesture) {
|
| - gesture_drag_status_ = GESTURE_DRAG_IN_PROGRESS;
|
| - gesture_drag_amount_ = 0.f;
|
| - gesture_drag_auto_hide_state_ = visibility_state() == SHELF_AUTO_HIDE ?
|
| - auto_hide_state() : SHELF_AUTO_HIDE_SHOWN;
|
| - UpdateShelfBackground(BackgroundAnimator::CHANGE_ANIMATE);
|
| -}
|
| -
|
| -ShelfLayoutManager::DragState ShelfLayoutManager::UpdateGestureDrag(
|
| - const ui::GestureEvent& gesture) {
|
| - bool horizontal = IsHorizontalAlignment();
|
| - gesture_drag_amount_ += horizontal ? gesture.details().scroll_y() :
|
| - gesture.details().scroll_x();
|
| - LayoutShelf();
|
| -
|
| - // Start reveling the status menu when:
|
| - // - dragging up on an already visible shelf
|
| - // - dragging up on a hidden shelf, but it is currently completely visible.
|
| - if (horizontal && gesture.details().scroll_y() < 0) {
|
| - int min_height = 0;
|
| - if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_HIDDEN &&
|
| - launcher_widget())
|
| - min_height = launcher_widget()->GetContentsView()->
|
| - GetPreferredSize().height();
|
| -
|
| - if (min_height < launcher_widget()->GetWindowBoundsInScreen().height() &&
|
| - gesture.root_location().x() >=
|
| - status_area_widget_->GetWindowBoundsInScreen().x() &&
|
| - IsDraggingTrayEnabled())
|
| - return DRAG_TRAY;
|
| - }
|
| -
|
| - return DRAG_SHELF;
|
| -}
|
| -
|
| -void ShelfLayoutManager::CompleteGestureDrag(const ui::GestureEvent& gesture) {
|
| - bool horizontal = IsHorizontalAlignment();
|
| - bool should_change = false;
|
| - if (gesture.type() == ui::ET_GESTURE_SCROLL_END) {
|
| - // The visibility of the shelf changes only if the shelf was dragged X%
|
| - // along the correct axis. If the shelf was already visible, then the
|
| - // direction of the drag does not matter.
|
| - const float kDragHideThreshold = 0.4f;
|
| - gfx::Rect bounds = GetIdealBounds();
|
| - float drag_ratio = fabs(gesture_drag_amount_) /
|
| - (horizontal ? bounds.height() : bounds.width());
|
| - if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN) {
|
| - should_change = drag_ratio > kDragHideThreshold;
|
| - } else {
|
| - bool correct_direction = false;
|
| - switch (alignment_) {
|
| - case SHELF_ALIGNMENT_BOTTOM:
|
| - case SHELF_ALIGNMENT_RIGHT:
|
| - correct_direction = gesture_drag_amount_ < 0;
|
| - break;
|
| - case SHELF_ALIGNMENT_LEFT:
|
| - case SHELF_ALIGNMENT_TOP:
|
| - correct_direction = gesture_drag_amount_ > 0;
|
| - break;
|
| - }
|
| - should_change = correct_direction && drag_ratio > kDragHideThreshold;
|
| - }
|
| - } else if (gesture.type() == ui::ET_SCROLL_FLING_START) {
|
| - if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN) {
|
| - should_change = horizontal ? fabs(gesture.details().velocity_y()) > 0 :
|
| - fabs(gesture.details().velocity_x()) > 0;
|
| - } else {
|
| - should_change = SelectValueForShelfAlignment(
|
| - gesture.details().velocity_y() < 0,
|
| - gesture.details().velocity_x() > 0,
|
| - gesture.details().velocity_x() < 0,
|
| - gesture.details().velocity_y() > 0);
|
| - }
|
| - } else {
|
| - NOTREACHED();
|
| - }
|
| -
|
| - if (!should_change) {
|
| - CancelGestureDrag();
|
| - return;
|
| - }
|
| -
|
| - gesture_drag_auto_hide_state_ =
|
| - gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN ?
|
| - SHELF_AUTO_HIDE_HIDDEN : SHELF_AUTO_HIDE_SHOWN;
|
| - if (launcher_widget())
|
| - launcher_widget()->Deactivate();
|
| - status_area_widget_->Deactivate();
|
| - if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_HIDDEN &&
|
| - auto_hide_behavior_ != SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS) {
|
| - gesture_drag_status_ = GESTURE_DRAG_NONE;
|
| - SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
|
| - } else if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN &&
|
| - auto_hide_behavior_ != SHELF_AUTO_HIDE_BEHAVIOR_NEVER) {
|
| - gesture_drag_status_ = GESTURE_DRAG_NONE;
|
| - SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
|
| - } else {
|
| - gesture_drag_status_ = GESTURE_DRAG_COMPLETE_IN_PROGRESS;
|
| - UpdateVisibilityState();
|
| - gesture_drag_status_ = GESTURE_DRAG_NONE;
|
| - }
|
| -}
|
| -
|
| -void ShelfLayoutManager::CancelGestureDrag() {
|
| - gesture_drag_status_ = GESTURE_DRAG_NONE;
|
| - ui::ScopedLayerAnimationSettings
|
| - launcher_settings(GetLayer(launcher_widget())->GetAnimator()),
|
| - status_settings(GetLayer(status_area_widget_)->GetAnimator());
|
| - LayoutShelf();
|
| - UpdateVisibilityState();
|
| - UpdateShelfBackground(BackgroundAnimator::CHANGE_ANIMATE);
|
| -}
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -// ShelfLayoutManager, aura::LayoutManager implementation:
|
| -
|
| -void ShelfLayoutManager::OnWindowResized() {
|
| - LayoutShelf();
|
| -}
|
| -
|
| -void ShelfLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
|
| -}
|
| -
|
| -void ShelfLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) {
|
| -}
|
| -
|
| -void ShelfLayoutManager::OnWindowRemovedFromLayout(aura::Window* child) {
|
| -}
|
| -
|
| -void ShelfLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child,
|
| - bool visible) {
|
| -}
|
| -
|
| -void ShelfLayoutManager::SetChildBounds(aura::Window* child,
|
| - const gfx::Rect& requested_bounds) {
|
| - SetChildBoundsDirect(child, requested_bounds);
|
| - // We may contain other widgets (such as frame maximize bubble) but they don't
|
| - // effect the layout in anyway.
|
| - if (!in_layout_ &&
|
| - ((launcher_widget() && launcher_widget()->GetNativeView() == child) ||
|
| - (status_area_widget_->GetNativeView() == child))) {
|
| - LayoutShelf();
|
| - }
|
| -}
|
| -
|
| -void ShelfLayoutManager::OnLockStateChanged(bool locked) {
|
| - UpdateVisibilityState();
|
| -}
|
| -
|
| -void ShelfLayoutManager::OnWindowActivated(aura::Window* gained_active,
|
| - aura::Window* lost_active) {
|
| - UpdateAutoHideStateNow();
|
| -}
|
| -
|
| -bool ShelfLayoutManager::IsHorizontalAlignment() const {
|
| - return alignment_ == SHELF_ALIGNMENT_BOTTOM ||
|
| - alignment_ == SHELF_ALIGNMENT_TOP;
|
| -}
|
| -
|
| -// static
|
| -ShelfLayoutManager* ShelfLayoutManager::ForLauncher(aura::Window* window) {
|
| - return RootWindowController::ForLauncher(window)->shelf();
|
| -}
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -// ShelfLayoutManager, private:
|
| -
|
| -ShelfLayoutManager::TargetBounds::TargetBounds() : opacity(0.0f) {}
|
| -
|
| -void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) {
|
| - ShellDelegate* delegate = Shell::GetInstance()->delegate();
|
| - State state;
|
| - state.visibility_state = visibility_state;
|
| - state.auto_hide_state = CalculateAutoHideState(visibility_state);
|
| - state.is_screen_locked = delegate && delegate->IsScreenLocked();
|
| -
|
| - // It's possible for SetState() when a window becomes maximized but the state
|
| - // won't have changed value. Do the dimming check before the early exit.
|
| - if (launcher_ && workspace_controller_) {
|
| - launcher_->SetDimsShelf(
|
| - (state.visibility_state == SHELF_VISIBLE) &&
|
| - workspace_controller_->GetWindowState() ==
|
| - WORKSPACE_WINDOW_STATE_MAXIMIZED);
|
| - }
|
| -
|
| - if (state_.Equals(state))
|
| - return; // Nothing changed.
|
| -
|
| - FOR_EACH_OBSERVER(Observer, observers_,
|
| - WillChangeVisibilityState(visibility_state));
|
| -
|
| - if (state.visibility_state == SHELF_AUTO_HIDE) {
|
| - // When state is SHELF_AUTO_HIDE we need to track when the mouse is over the
|
| - // launcher to unhide the shelf. AutoHideEventFilter does that for us.
|
| - if (!event_filter_.get())
|
| - event_filter_.reset(new AutoHideEventFilter(this));
|
| - } else {
|
| - event_filter_.reset(NULL);
|
| - }
|
| -
|
| - auto_hide_timer_.Stop();
|
| -
|
| - // Animating the background when transitioning from auto-hide & hidden to
|
| - // visible is janky. Update the background immediately in this case.
|
| - BackgroundAnimator::ChangeType change_type =
|
| - (state_.visibility_state == SHELF_AUTO_HIDE &&
|
| - state_.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN &&
|
| - state.visibility_state == SHELF_VISIBLE) ?
|
| - BackgroundAnimator::CHANGE_IMMEDIATE : BackgroundAnimator::CHANGE_ANIMATE;
|
| - StopAnimating();
|
| -
|
| - State old_state = state_;
|
| - state_ = state;
|
| - TargetBounds target_bounds;
|
| - CalculateTargetBounds(state_, &target_bounds);
|
| - if (launcher_widget()) {
|
| - ui::ScopedLayerAnimationSettings launcher_animation_setter(
|
| - GetLayer(launcher_widget())->GetAnimator());
|
| - launcher_animation_setter.SetTransitionDuration(
|
| - base::TimeDelta::FromMilliseconds(kWorkspaceSwitchTimeMS));
|
| - launcher_animation_setter.SetTweenType(ui::Tween::EASE_OUT);
|
| - GetLayer(launcher_widget())->SetBounds(
|
| - target_bounds.launcher_bounds_in_root);
|
| - GetLayer(launcher_widget())->SetOpacity(target_bounds.opacity);
|
| - }
|
| - ui::ScopedLayerAnimationSettings status_animation_setter(
|
| - GetLayer(status_area_widget_)->GetAnimator());
|
| - status_animation_setter.SetTransitionDuration(
|
| - base::TimeDelta::FromMilliseconds(kWorkspaceSwitchTimeMS));
|
| - status_animation_setter.SetTweenType(ui::Tween::EASE_OUT);
|
| -
|
| - // Delay updating the background when going from SHELF_AUTO_HIDE_SHOWN to
|
| - // SHELF_AUTO_HIDE_HIDDEN until the shelf animates out. Otherwise during the
|
| - // animation you see the background change.
|
| - // Also delay the animation when the shelf was hidden, and has just been made
|
| - // visible (e.g. using a gesture-drag).
|
| - bool delay_shelf_update =
|
| - state.visibility_state == SHELF_AUTO_HIDE &&
|
| - state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN &&
|
| - old_state.visibility_state == SHELF_AUTO_HIDE;
|
| -
|
| - if (state.visibility_state == SHELF_VISIBLE &&
|
| - old_state.visibility_state == SHELF_AUTO_HIDE &&
|
| - old_state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN)
|
| - delay_shelf_update = true;
|
| -
|
| - if (delay_shelf_update) {
|
| - if (update_shelf_observer_)
|
| - update_shelf_observer_->Detach();
|
| - // UpdateShelfBackground deletes itself when the animation is done.
|
| - update_shelf_observer_ = new UpdateShelfObserver(this);
|
| - status_animation_setter.AddObserver(update_shelf_observer_);
|
| - }
|
| - ui::Layer* layer = GetLayer(status_area_widget_);
|
| - layer->SetBounds(target_bounds.status_bounds_in_root);
|
| - layer->SetOpacity(target_bounds.opacity);
|
| - Shell::GetInstance()->SetDisplayWorkAreaInsets(
|
| - root_window_, target_bounds.work_area_insets);
|
| - UpdateHitTestBounds();
|
| - if (!delay_shelf_update)
|
| - UpdateShelfBackground(change_type);
|
| -}
|
| -
|
| -void ShelfLayoutManager::StopAnimating() {
|
| - ui::Layer* layer = GetLayer(status_area_widget_);
|
| - if (launcher_widget())
|
| - layer->GetAnimator()->StopAnimating();
|
| - layer->GetAnimator()->StopAnimating();
|
| -}
|
| -
|
| -void ShelfLayoutManager::GetShelfSize(int* width, int* height) {
|
| - *width = *height = 0;
|
| - gfx::Size status_size(status_area_widget_->GetWindowBoundsInScreen().size());
|
| - gfx::Size launcher_size = launcher_ ?
|
| - launcher_widget()->GetContentsView()->GetPreferredSize() : gfx::Size();
|
| - if (IsHorizontalAlignment())
|
| - *height = std::max(launcher_size.height(), status_size.height());
|
| - else
|
| - *width = std::max(launcher_size.width(), status_size.width());
|
| -}
|
| -
|
| -void ShelfLayoutManager::AdjustBoundsBasedOnAlignment(int inset,
|
| - gfx::Rect* bounds) const {
|
| - bounds->Inset(SelectValueForShelfAlignment(
|
| - gfx::Insets(0, 0, inset, 0),
|
| - gfx::Insets(0, inset, 0, 0),
|
| - gfx::Insets(0, 0, 0, inset),
|
| - gfx::Insets(inset, 0, 0, 0)));
|
| -}
|
| -
|
| -void ShelfLayoutManager::CalculateTargetBounds(
|
| - const State& state,
|
| - TargetBounds* target_bounds) {
|
| - const gfx::Rect& available_bounds(root_window_->bounds());
|
| - gfx::Rect status_size(status_area_widget_->GetWindowBoundsInScreen().size());
|
| - gfx::Size launcher_size = launcher_ ?
|
| - launcher_widget()->GetContentsView()->GetPreferredSize() : gfx::Size();
|
| - int shelf_size = 0;
|
| - int shelf_width = 0, shelf_height = 0;
|
| - GetShelfSize(&shelf_width, &shelf_height);
|
| - if (state.visibility_state == SHELF_VISIBLE ||
|
| - (state.visibility_state == SHELF_AUTO_HIDE &&
|
| - state.auto_hide_state == SHELF_AUTO_HIDE_SHOWN)) {
|
| - shelf_size = std::max(shelf_width, shelf_height);
|
| - launcher_size.set_width(std::max(shelf_width,launcher_size.width()));
|
| - launcher_size.set_height(std::max(shelf_height,launcher_size.height()));
|
| - } else if (state.visibility_state == SHELF_AUTO_HIDE &&
|
| - state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN) {
|
| - shelf_size = kAutoHideSize;
|
| - // Keep the launcher to its full height when dragging is in progress.
|
| - if (gesture_drag_status_ == GESTURE_DRAG_NONE) {
|
| - if (IsHorizontalAlignment())
|
| - launcher_size.set_height(kAutoHideSize);
|
| - else
|
| - launcher_size.set_width(kAutoHideSize);
|
| - }
|
| - }
|
| - switch(alignment_) {
|
| - case SHELF_ALIGNMENT_BOTTOM:
|
| - // The status widget should extend to the bottom and right edges.
|
| - target_bounds->status_bounds_in_root = gfx::Rect(
|
| - base::i18n::IsRTL() ? available_bounds.x() :
|
| - available_bounds.right() - status_size.width(),
|
| - available_bounds.bottom() - shelf_size + shelf_height -
|
| - status_size.height(),
|
| - status_size.width(), status_size.height());
|
| - if (launcher_widget())
|
| - target_bounds->launcher_bounds_in_root = gfx::Rect(
|
| - available_bounds.x(),
|
| - available_bounds.bottom() - shelf_size,
|
| - available_bounds.width(),
|
| - launcher_size.height());
|
| - target_bounds->work_area_insets.Set(
|
| - 0, 0, GetWorkAreaSize(state, shelf_height), 0);
|
| - break;
|
| - case SHELF_ALIGNMENT_LEFT:
|
| - target_bounds->status_bounds_in_root = gfx::Rect(
|
| - available_bounds.x() + launcher_size.width() - status_size.width(),
|
| - available_bounds.bottom() - status_size.height(),
|
| - shelf_width, status_size.height());
|
| - if (launcher_widget())
|
| - target_bounds->launcher_bounds_in_root = gfx::Rect(
|
| - available_bounds.x(), available_bounds.y(),
|
| - launcher_size.width(), available_bounds.height());
|
| - target_bounds->work_area_insets.Set(
|
| - 0, GetWorkAreaSize(state, launcher_size.width()), 0, 0);
|
| - break;
|
| - case SHELF_ALIGNMENT_RIGHT:
|
| - target_bounds->status_bounds_in_root = gfx::Rect(
|
| - available_bounds.right()- status_size.width() -
|
| - shelf_size + shelf_width,
|
| - available_bounds.bottom() - status_size.height(),
|
| - shelf_width, status_size.height());
|
| - if (launcher_widget())
|
| - target_bounds->launcher_bounds_in_root = gfx::Rect(
|
| - available_bounds.right() - launcher_size.width(),
|
| - available_bounds.y(),
|
| - launcher_size.width(), available_bounds.height());
|
| - target_bounds->work_area_insets.Set(
|
| - 0, 0, 0, GetWorkAreaSize(state, launcher_size.width()));
|
| - break;
|
| - case SHELF_ALIGNMENT_TOP:
|
| - target_bounds->status_bounds_in_root = gfx::Rect(
|
| - base::i18n::IsRTL() ? available_bounds.x() :
|
| - available_bounds.right() - status_size.width(),
|
| - available_bounds.y() + launcher_size.height() - status_size.height(),
|
| - status_size.width(), status_size.height());
|
| - if (launcher_widget())
|
| - target_bounds->launcher_bounds_in_root = gfx::Rect(
|
| - available_bounds.x(),
|
| - available_bounds.y(),
|
| - available_bounds.width(),
|
| - launcher_size.height());
|
| - target_bounds->work_area_insets.Set(
|
| - GetWorkAreaSize(state, shelf_height), 0, 0, 0);
|
| - break;
|
| - }
|
| - target_bounds->opacity =
|
| - (gesture_drag_status_ != GESTURE_DRAG_NONE ||
|
| - state.visibility_state == SHELF_VISIBLE ||
|
| - state.visibility_state == SHELF_AUTO_HIDE) ? 1.0f : 0.0f;
|
| - if (gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS)
|
| - UpdateTargetBoundsForGesture(target_bounds);
|
| -}
|
| -
|
| -void ShelfLayoutManager::UpdateTargetBoundsForGesture(
|
| - TargetBounds* target_bounds) const {
|
| - CHECK_EQ(GESTURE_DRAG_IN_PROGRESS, gesture_drag_status_);
|
| - bool horizontal = IsHorizontalAlignment();
|
| - int resistance_free_region = 0;
|
| -
|
| - if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_HIDDEN &&
|
| - visibility_state() == SHELF_AUTO_HIDE &&
|
| - auto_hide_state() != SHELF_AUTO_HIDE_SHOWN) {
|
| - // If the shelf was hidden when the drag started (and the state hasn't
|
| - // changed since then, e.g. because the tray-menu was shown because of the
|
| - // drag), then allow the drag some resistance-free region at first to make
|
| - // sure the shelf sticks with the finger until the shelf is visible.
|
| - resistance_free_region += horizontal ?
|
| - target_bounds->launcher_bounds_in_root.height() :
|
| - target_bounds->launcher_bounds_in_root.width();
|
| - resistance_free_region -= kAutoHideSize;
|
| - }
|
| -
|
| - bool resist = SelectValueForShelfAlignment(
|
| - gesture_drag_amount_ < -resistance_free_region,
|
| - gesture_drag_amount_ > resistance_free_region,
|
| - gesture_drag_amount_ < -resistance_free_region,
|
| - gesture_drag_amount_ > resistance_free_region);
|
| -
|
| - float translate = 0.f;
|
| - if (resist) {
|
| - float diff = fabsf(gesture_drag_amount_) - resistance_free_region;
|
| - diff = std::min(diff, sqrtf(diff));
|
| - if (gesture_drag_amount_ < 0)
|
| - translate = -resistance_free_region - diff;
|
| - else
|
| - translate = resistance_free_region + diff;
|
| - } else {
|
| - translate = gesture_drag_amount_;
|
| - }
|
| -
|
| - if (horizontal) {
|
| - // Move the launcher with the gesture.
|
| - target_bounds->launcher_bounds_in_root.Offset(0, translate);
|
| - target_bounds->status_bounds_in_root.Offset(0, translate);
|
| -
|
| - if (translate < 0) {
|
| - // When dragging up, the launcher height should increase.
|
| - float move = std::max(translate,
|
| - -static_cast<float>(resistance_free_region));
|
| - target_bounds->launcher_bounds_in_root.set_height(
|
| - target_bounds->launcher_bounds_in_root.height() + move - translate);
|
| - }
|
| - } else {
|
| - // Move the launcher with the gesture.
|
| - if (alignment_ == SHELF_ALIGNMENT_RIGHT)
|
| - target_bounds->launcher_bounds_in_root.Offset(translate, 0);
|
| -
|
| - if ((translate > 0 && alignment_ == SHELF_ALIGNMENT_RIGHT) ||
|
| - (translate < 0 && alignment_ == SHELF_ALIGNMENT_LEFT)) {
|
| - // When dragging towards the edge, the statusbar should move.
|
| - target_bounds->status_bounds_in_root.Offset(translate, 0);
|
| - } else {
|
| - // When dragging away from the edge, the launcher width should increase.
|
| - float move = alignment_ == SHELF_ALIGNMENT_RIGHT ?
|
| - std::max(translate, -static_cast<float>(resistance_free_region)) :
|
| - std::min(translate, static_cast<float>(resistance_free_region));
|
| -
|
| - if (alignment_ == SHELF_ALIGNMENT_RIGHT) {
|
| - target_bounds->launcher_bounds_in_root.set_width(
|
| - target_bounds->launcher_bounds_in_root.width() + move - translate);
|
| - } else {
|
| - target_bounds->launcher_bounds_in_root.set_width(
|
| - target_bounds->launcher_bounds_in_root.width() - move + translate);
|
| - }
|
| -
|
| - // The statusbar should be in the center.
|
| - gfx::Rect status_x = target_bounds->launcher_bounds_in_root;
|
| - status_x.ClampToCenteredSize(
|
| - target_bounds->status_bounds_in_root.size());
|
| - target_bounds->status_bounds_in_root.set_x(status_x.x());
|
| - }
|
| - }
|
| -}
|
| -
|
| -void ShelfLayoutManager::UpdateShelfBackground(
|
| - BackgroundAnimator::ChangeType type) {
|
| - bool launcher_paints = GetLauncherPaintsBackground();
|
| - if (launcher_)
|
| - launcher_->SetPaintsBackground(launcher_paints, type);
|
| - // The status area normally draws a background, but we don't want it to draw a
|
| - // background when the launcher does or when we're at login/lock screen.
|
| - ShellDelegate* delegate = Shell::GetInstance()->delegate();
|
| - bool delegate_allows_tray_bg =
|
| - delegate->IsUserLoggedIn() && !delegate->IsScreenLocked();
|
| - bool status_area_paints = !launcher_paints && delegate_allows_tray_bg;
|
| - status_area_widget_->SetPaintsBackground(status_area_paints, type);
|
| -}
|
| -
|
| -bool ShelfLayoutManager::GetLauncherPaintsBackground() const {
|
| - return gesture_drag_status_ != GESTURE_DRAG_NONE ||
|
| - (!state_.is_screen_locked && window_overlaps_shelf_) ||
|
| - (state_.visibility_state == SHELF_AUTO_HIDE) ;
|
| -}
|
| -
|
| -void ShelfLayoutManager::UpdateAutoHideStateNow() {
|
| - SetState(state_.visibility_state);
|
| -}
|
| -
|
| -ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState(
|
| - ShelfVisibilityState visibility_state) const {
|
| - if (visibility_state != SHELF_AUTO_HIDE || !launcher_widget())
|
| - return SHELF_AUTO_HIDE_HIDDEN;
|
| -
|
| - if (gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS)
|
| - return gesture_drag_auto_hide_state_;
|
| -
|
| - Shell* shell = Shell::GetInstance();
|
| - if (shell->GetAppListTargetVisibility())
|
| - return SHELF_AUTO_HIDE_SHOWN;
|
| -
|
| - if (status_area_widget_ && status_area_widget_->ShouldShowLauncher())
|
| - return SHELF_AUTO_HIDE_SHOWN;
|
| -
|
| - if (launcher_ && launcher_->IsShowingMenu())
|
| - return SHELF_AUTO_HIDE_SHOWN;
|
| -
|
| - if (launcher_ && launcher_->IsShowingOverflowBubble())
|
| - return SHELF_AUTO_HIDE_SHOWN;
|
| -
|
| - if (launcher_widget()->IsActive() || status_area_widget_->IsActive())
|
| - return SHELF_AUTO_HIDE_SHOWN;
|
| -
|
| - // Don't show if the user is dragging the mouse.
|
| - if (event_filter_.get() && event_filter_->in_mouse_drag())
|
| - return SHELF_AUTO_HIDE_HIDDEN;
|
| -
|
| - gfx::Rect shelf_region = launcher_widget()->GetWindowBoundsInScreen();
|
| - if (status_area_widget_ &&
|
| - status_area_widget_->IsMessageBubbleShown() &&
|
| - IsVisible()) {
|
| - // Increase the the hit test area to prevent the shelf from disappearing
|
| - // when the mouse is over the bubble gap.
|
| - shelf_region.Inset(alignment_ == SHELF_ALIGNMENT_RIGHT ?
|
| - -kNotificationBubbleGapHeight : 0,
|
| - alignment_ == SHELF_ALIGNMENT_BOTTOM ?
|
| - -kNotificationBubbleGapHeight : 0,
|
| - alignment_ == SHELF_ALIGNMENT_LEFT ?
|
| - -kNotificationBubbleGapHeight : 0,
|
| - alignment_ == SHELF_ALIGNMENT_TOP ?
|
| - -kNotificationBubbleGapHeight : 0);
|
| - }
|
| -
|
| - if (shelf_region.Contains(Shell::GetScreen()->GetCursorScreenPoint()))
|
| - return SHELF_AUTO_HIDE_SHOWN;
|
| -
|
| - const std::vector<aura::Window*> windows =
|
| - ash::WindowCycleController::BuildWindowList(NULL);
|
| -
|
| - // Process the window list and check if there are any visible windows.
|
| - for (size_t i = 0; i < windows.size(); ++i) {
|
| - if (windows[i] && windows[i]->IsVisible() &&
|
| - !ash::wm::IsWindowMinimized(windows[i]))
|
| - return SHELF_AUTO_HIDE_HIDDEN;
|
| - }
|
| -
|
| - // If there are no visible windows do not hide the shelf.
|
| - return SHELF_AUTO_HIDE_SHOWN;
|
| -}
|
| -
|
| -void ShelfLayoutManager::UpdateHitTestBounds() {
|
| - gfx::Insets insets;
|
| - // Only modify the hit test when the shelf is visible, so we don't mess with
|
| - // hover hit testing in the auto-hide state.
|
| - if (state_.visibility_state == SHELF_VISIBLE) {
|
| - // Let clicks at the very top of the launcher through so windows can be
|
| - // resized with the bottom-right corner and bottom edge.
|
| - switch (alignment_) {
|
| - case SHELF_ALIGNMENT_BOTTOM:
|
| - insets.Set(kWorkspaceAreaBottomInset, 0, 0, 0);
|
| - break;
|
| - case SHELF_ALIGNMENT_LEFT:
|
| - insets.Set(0, 0, 0, kWorkspaceAreaBottomInset);
|
| - break;
|
| - case SHELF_ALIGNMENT_RIGHT:
|
| - insets.Set(0, kWorkspaceAreaBottomInset, 0, 0);
|
| - break;
|
| - case SHELF_ALIGNMENT_TOP:
|
| - insets.Set(0, 0, kWorkspaceAreaBottomInset, 0);
|
| - break;
|
| - }
|
| - }
|
| - if (launcher_widget() && launcher_widget()->GetNativeWindow()) {
|
| - launcher_widget()->GetNativeWindow()->SetHitTestBoundsOverrideOuter(
|
| - insets, 1);
|
| - }
|
| - status_area_widget_->GetNativeWindow()->
|
| - SetHitTestBoundsOverrideOuter(insets, 1);
|
| -}
|
| -
|
| -bool ShelfLayoutManager::IsShelfWindow(aura::Window* window) {
|
| - if (!window)
|
| - return false;
|
| - return (launcher_widget() &&
|
| - launcher_widget()->GetNativeWindow()->Contains(window)) ||
|
| - (status_area_widget_->GetNativeWindow()->Contains(window));
|
| -}
|
| -
|
| -int ShelfLayoutManager::GetWorkAreaSize(const State& state, int size) const {
|
| - if (state.visibility_state == SHELF_VISIBLE)
|
| - return size;
|
| - if (state.visibility_state == SHELF_AUTO_HIDE)
|
| - return kAutoHideSize;
|
| - return 0;
|
| -}
|
| -
|
| -} // namespace internal
|
| -} // namespace ash
|
|
|