| Index: ash/common/shelf/shelf_layout_manager.cc
|
| diff --git a/ash/common/shelf/shelf_layout_manager.cc b/ash/common/shelf/shelf_layout_manager.cc
|
| deleted file mode 100644
|
| index f4ce3aead30cfa7b3ea977e4e3b7f20fdbc11803..0000000000000000000000000000000000000000
|
| --- a/ash/common/shelf/shelf_layout_manager.cc
|
| +++ /dev/null
|
| @@ -1,1143 +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/common/shelf/shelf_layout_manager.h"
|
| -
|
| -#include <algorithm>
|
| -#include <cmath>
|
| -#include <vector>
|
| -
|
| -#include "ash/animation/animation_change_type.h"
|
| -#include "ash/common/session/session_controller.h"
|
| -#include "ash/common/session/session_state_delegate.h"
|
| -#include "ash/common/shelf/shelf_constants.h"
|
| -#include "ash/common/shelf/shelf_layout_manager_observer.h"
|
| -#include "ash/common/shelf/shelf_widget.h"
|
| -#include "ash/common/shelf/wm_shelf.h"
|
| -#include "ash/common/system/status_area_widget.h"
|
| -#include "ash/common/wm/fullscreen_window_finder.h"
|
| -#include "ash/common/wm/mru_window_tracker.h"
|
| -#include "ash/common/wm/window_state.h"
|
| -#include "ash/common/wm/wm_screen_util.h"
|
| -#include "ash/common/wm_shell.h"
|
| -#include "ash/common/wm_window.h"
|
| -#include "ash/public/cpp/shell_window_ids.h"
|
| -#include "ash/root_window_controller.h"
|
| -#include "base/auto_reset.h"
|
| -#include "base/command_line.h"
|
| -#include "base/i18n/rtl.h"
|
| -#include "ui/base/ui_base_switches.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/display/display.h"
|
| -#include "ui/display/screen.h"
|
| -#include "ui/events/event.h"
|
| -#include "ui/events/event_handler.h"
|
| -#include "ui/keyboard/keyboard_controller.h"
|
| -#include "ui/keyboard/keyboard_util.h"
|
| -#include "ui/views/border.h"
|
| -#include "ui/views/widget/widget.h"
|
| -
|
| -namespace ash {
|
| -namespace {
|
| -
|
| -// Delay before showing the shelf. This is after the mouse stops moving.
|
| -const int kAutoHideDelayMS = 200;
|
| -
|
| -// Duration of the animation to show or hide the shelf.
|
| -const int kAnimationDurationMS = 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;
|
| -
|
| -// The maximum size of the region on the display opposing the shelf managed by
|
| -// this ShelfLayoutManager which can trigger showing the shelf.
|
| -// For instance:
|
| -// - Primary display is left of secondary display.
|
| -// - Shelf is left aligned
|
| -// - This ShelfLayoutManager manages the shelf for the secondary display.
|
| -// |kMaxAutoHideShowShelfRegionSize| refers to the maximum size of the region
|
| -// from the right edge of the primary display which can trigger showing the
|
| -// auto hidden shelf. The region is used to make it easier to trigger showing
|
| -// the auto hidden shelf when the shelf is on the boundary between displays.
|
| -const int kMaxAutoHideShowShelfRegionSize = 10;
|
| -
|
| -ui::Layer* GetLayer(views::Widget* widget) {
|
| - return widget->GetNativeView()->layer();
|
| -}
|
| -
|
| -// Returns true if the window is in the app list window container.
|
| -bool IsAppListWindow(WmWindow* window) {
|
| - return window->GetParent() &&
|
| - window->GetParent()->GetShellWindowId() ==
|
| - kShellWindowId_AppListContainer;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -// 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; }
|
| -
|
| - void OnImplicitAnimationsCompleted() override {
|
| - if (shelf_)
|
| - shelf_->MaybeUpdateShelfBackground(AnimationChangeType::ANIMATE);
|
| - delete this;
|
| - }
|
| -
|
| - private:
|
| - ~UpdateShelfObserver() override {
|
| - 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::State::State()
|
| - : visibility_state(SHELF_VISIBLE),
|
| - auto_hide_state(SHELF_AUTO_HIDE_HIDDEN),
|
| - window_state(wm::WORKSPACE_WINDOW_STATE_DEFAULT),
|
| - pre_lock_screen_animation_active(false),
|
| - session_state(session_manager::SessionState::UNKNOWN) {}
|
| -
|
| -bool ShelfLayoutManager::State::IsAddingSecondaryUser() const {
|
| - return session_state == session_manager::SessionState::LOGIN_SECONDARY;
|
| -}
|
| -
|
| -bool ShelfLayoutManager::State::IsScreenLocked() const {
|
| - return session_state == session_manager::SessionState::LOCKED;
|
| -}
|
| -
|
| -bool ShelfLayoutManager::State::Equals(const State& other) const {
|
| - return other.visibility_state == visibility_state &&
|
| - (visibility_state != SHELF_AUTO_HIDE ||
|
| - other.auto_hide_state == auto_hide_state) &&
|
| - other.window_state == window_state &&
|
| - other.pre_lock_screen_animation_active ==
|
| - pre_lock_screen_animation_active &&
|
| - other.session_state == session_state;
|
| -}
|
| -
|
| -// ShelfLayoutManager ----------------------------------------------------------
|
| -
|
| -ShelfLayoutManager::ShelfLayoutManager(ShelfWidget* shelf_widget,
|
| - WmShelf* wm_shelf)
|
| - : updating_bounds_(false),
|
| - shelf_widget_(shelf_widget),
|
| - wm_shelf_(wm_shelf),
|
| - window_overlaps_shelf_(false),
|
| - mouse_over_shelf_when_auto_hide_timer_started_(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),
|
| - chromevox_panel_height_(0),
|
| - duration_override_in_ms_(0),
|
| - shelf_background_type_(SHELF_BACKGROUND_OVERLAP) {
|
| - DCHECK(shelf_widget_);
|
| - DCHECK(wm_shelf_);
|
| - WmShell::Get()->AddShellObserver(this);
|
| - WmShell::Get()->AddLockStateObserver(this);
|
| - WmShell::Get()->AddActivationObserver(this);
|
| - WmShell::Get()->session_controller()->AddSessionStateObserver(this);
|
| - state_.session_state =
|
| - WmShell::Get()->session_controller()->GetSessionState();
|
| -}
|
| -
|
| -ShelfLayoutManager::~ShelfLayoutManager() {
|
| - if (update_shelf_observer_)
|
| - update_shelf_observer_->Detach();
|
| -
|
| - for (auto& observer : observers_)
|
| - observer.WillDeleteShelfLayoutManager();
|
| - WmShell::Get()->RemoveShellObserver(this);
|
| - WmShell::Get()->RemoveLockStateObserver(this);
|
| - WmShell::Get()->session_controller()->RemoveSessionStateObserver(this);
|
| -}
|
| -
|
| -void ShelfLayoutManager::PrepareForShutdown() {
|
| - in_shutdown_ = true;
|
| - // Stop observing changes to avoid updating a partially destructed shelf.
|
| - WmShell::Get()->RemoveActivationObserver(this);
|
| -}
|
| -
|
| -bool ShelfLayoutManager::IsVisible() const {
|
| - // status_area_widget() may be NULL during the shutdown.
|
| - return shelf_widget_->status_area_widget() &&
|
| - shelf_widget_->status_area_widget()->IsVisible() &&
|
| - (state_.visibility_state == SHELF_VISIBLE ||
|
| - (state_.visibility_state == SHELF_AUTO_HIDE &&
|
| - state_.auto_hide_state == SHELF_AUTO_HIDE_SHOWN));
|
| -}
|
| -
|
| -gfx::Rect ShelfLayoutManager::GetIdealBounds() {
|
| - const int shelf_size = GetShelfConstant(SHELF_SIZE);
|
| - WmWindow* shelf_window = WmWindow::Get(shelf_widget_->GetNativeWindow());
|
| - gfx::Rect rect(wm::GetDisplayBoundsInParent(shelf_window));
|
| - return SelectValueForShelfAlignment(
|
| - gfx::Rect(rect.x(), rect.bottom() - shelf_size, rect.width(), shelf_size),
|
| - gfx::Rect(rect.x(), rect.y(), shelf_size, rect.height()),
|
| - gfx::Rect(rect.right() - shelf_size, rect.y(), shelf_size,
|
| - rect.height()));
|
| -}
|
| -
|
| -gfx::Size ShelfLayoutManager::GetPreferredSize() {
|
| - TargetBounds target_bounds;
|
| - CalculateTargetBounds(state_, &target_bounds);
|
| - return target_bounds.shelf_bounds_in_root.size();
|
| -}
|
| -
|
| -void ShelfLayoutManager::LayoutShelfAndUpdateBounds(bool change_work_area) {
|
| - TargetBounds target_bounds;
|
| - CalculateTargetBounds(state_, &target_bounds);
|
| - UpdateBoundsAndOpacity(target_bounds, false, change_work_area, NULL);
|
| -
|
| - // Update insets in ShelfWindowTargeter when shelf bounds change.
|
| - for (auto& observer : observers_)
|
| - observer.WillChangeVisibilityState(visibility_state());
|
| -}
|
| -
|
| -void ShelfLayoutManager::LayoutShelf() {
|
| - LayoutShelfAndUpdateBounds(true);
|
| -}
|
| -
|
| -ShelfVisibilityState ShelfLayoutManager::CalculateShelfVisibility() {
|
| - switch (wm_shelf_->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;
|
| -}
|
| -
|
| -void ShelfLayoutManager::UpdateVisibilityState() {
|
| - // Bail out early before the shelf is initialized or after it is destroyed.
|
| - WmWindow* shelf_window = WmWindow::Get(shelf_widget_->GetNativeWindow());
|
| - if (in_shutdown_ || !wm_shelf_->IsShelfInitialized() || !shelf_window)
|
| - return;
|
| - if (state_.IsScreenLocked() || state_.IsAddingSecondaryUser()) {
|
| - SetState(SHELF_VISIBLE);
|
| - } else if (WmShell::Get()->IsPinned()) {
|
| - SetState(SHELF_HIDDEN);
|
| - } else {
|
| - // TODO(zelidrag): Verify shelf drag animation still shows on the device
|
| - // when we are in SHELF_AUTO_HIDE_ALWAYS_HIDDEN.
|
| - wm::WorkspaceWindowState window_state(
|
| - shelf_window->GetRootWindowController()->GetWorkspaceWindowState());
|
| - switch (window_state) {
|
| - case wm::WORKSPACE_WINDOW_STATE_FULL_SCREEN: {
|
| - if (IsShelfHiddenForFullscreen()) {
|
| - SetState(SHELF_HIDDEN);
|
| - } else {
|
| - // The shelf is sometimes not hidden when in immersive fullscreen.
|
| - // Force the shelf to be auto hidden in this case.
|
| - SetState(SHELF_AUTO_HIDE);
|
| - }
|
| - break;
|
| - }
|
| - case wm::WORKSPACE_WINDOW_STATE_MAXIMIZED:
|
| - SetState(CalculateShelfVisibility());
|
| - break;
|
| -
|
| - case wm::WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF:
|
| - case wm::WORKSPACE_WINDOW_STATE_DEFAULT:
|
| - SetState(CalculateShelfVisibility());
|
| - SetWindowOverlapsShelf(
|
| - window_state == wm::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);
|
| - } else {
|
| - if (!auto_hide_timer_.IsRunning()) {
|
| - mouse_over_shelf_when_auto_hide_timer_started_ =
|
| - shelf_widget_->GetWindowBoundsInScreen().Contains(
|
| - display::Screen::GetScreen()->GetCursorScreenPoint());
|
| - }
|
| - auto_hide_timer_.Start(
|
| - FROM_HERE, base::TimeDelta::FromMilliseconds(kAutoHideDelayMS), this,
|
| - &ShelfLayoutManager::UpdateAutoHideStateNow);
|
| - }
|
| - } else {
|
| - StopAutoHideTimer();
|
| - }
|
| -}
|
| -
|
| -void ShelfLayoutManager::UpdateAutoHideForMouseEvent(ui::MouseEvent* event,
|
| - WmWindow* target) {
|
| - // 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)) &&
|
| - !IsShelfWindow(target);
|
| -
|
| - // Don't update during shutdown because synthetic mouse events (e.g. mouse
|
| - // exit) may be generated during status area widget teardown.
|
| - if (visibility_state() != SHELF_AUTO_HIDE || in_shutdown_)
|
| - return;
|
| -
|
| - if (event->type() == ui::ET_MOUSE_MOVED ||
|
| - event->type() == ui::ET_MOUSE_ENTERED ||
|
| - event->type() == ui::ET_MOUSE_EXITED) {
|
| - UpdateAutoHideState();
|
| - }
|
| -}
|
| -
|
| -void ShelfLayoutManager::UpdateAutoHideForGestureEvent(ui::GestureEvent* event,
|
| - WmWindow* target) {
|
| - if (visibility_state() != SHELF_AUTO_HIDE || in_shutdown_)
|
| - return;
|
| -
|
| - if (IsShelfWindow(target) && ProcessGestureEvent(*event))
|
| - event->StopPropagation();
|
| -}
|
| -
|
| -void ShelfLayoutManager::SetWindowOverlapsShelf(bool value) {
|
| - window_overlaps_shelf_ = value;
|
| - MaybeUpdateShelfBackground(AnimationChangeType::ANIMATE);
|
| -}
|
| -
|
| -void ShelfLayoutManager::AddObserver(ShelfLayoutManagerObserver* observer) {
|
| - observers_.AddObserver(observer);
|
| -}
|
| -
|
| -void ShelfLayoutManager::RemoveObserver(ShelfLayoutManagerObserver* observer) {
|
| - observers_.RemoveObserver(observer);
|
| -}
|
| -
|
| -bool ShelfLayoutManager::ProcessGestureEvent(const ui::GestureEvent& event) {
|
| - // The gestures are disabled in the lock/login screen.
|
| - SessionStateDelegate* delegate = WmShell::Get()->GetSessionStateDelegate();
|
| - if (!delegate->NumberOfLoggedInUsers() || delegate->IsScreenLocked())
|
| - return false;
|
| -
|
| - if (IsShelfHiddenForFullscreen())
|
| - return false;
|
| -
|
| - if (event.type() == ui::ET_GESTURE_SCROLL_BEGIN) {
|
| - StartGestureDrag(event);
|
| - return true;
|
| - }
|
| -
|
| - if (gesture_drag_status_ != GESTURE_DRAG_IN_PROGRESS)
|
| - return false;
|
| -
|
| - if (event.type() == ui::ET_GESTURE_SCROLL_UPDATE) {
|
| - UpdateGestureDrag(event);
|
| - return true;
|
| - }
|
| -
|
| - if (event.type() == ui::ET_GESTURE_SCROLL_END ||
|
| - event.type() == ui::ET_SCROLL_FLING_START) {
|
| - CompleteGestureDrag(event);
|
| - return true;
|
| - }
|
| -
|
| - // Unexpected event. Reset the state and let the event fall through.
|
| - CancelGestureDrag();
|
| - return false;
|
| -}
|
| -
|
| -void ShelfLayoutManager::SetAnimationDurationOverride(
|
| - int duration_override_in_ms) {
|
| - duration_override_in_ms_ = duration_override_in_ms;
|
| -}
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -// ShelfLayoutManager, wm::WmSnapToPixelLayoutManager implementation:
|
| -
|
| -void ShelfLayoutManager::OnWindowResized() {
|
| - LayoutShelf();
|
| -}
|
| -
|
| -void ShelfLayoutManager::SetChildBounds(WmWindow* child,
|
| - const gfx::Rect& requested_bounds) {
|
| - wm::WmSnapToPixelLayoutManager::SetChildBounds(child, requested_bounds);
|
| - // We may contain other widgets (such as frame maximize bubble) but they don't
|
| - // effect the layout in anyway.
|
| - if (!updating_bounds_ &&
|
| - ((WmWindow::Get(shelf_widget_->GetNativeWindow()) == child) ||
|
| - (WmWindow::Get(shelf_widget_->status_area_widget()->GetNativeWindow()) ==
|
| - child))) {
|
| - LayoutShelf();
|
| - }
|
| -}
|
| -
|
| -void ShelfLayoutManager::OnShelfAutoHideBehaviorChanged(WmWindow* root_window) {
|
| - UpdateVisibilityState();
|
| -}
|
| -
|
| -void ShelfLayoutManager::OnPinnedStateChanged(WmWindow* pinned_window) {
|
| - // Shelf needs to be hidden on entering to pinned mode, or restored
|
| - // on exiting from pinned mode.
|
| - UpdateVisibilityState();
|
| -}
|
| -
|
| -void ShelfLayoutManager::OnWindowActivated(WmWindow* gained_active,
|
| - WmWindow* lost_active) {
|
| - UpdateAutoHideStateNow();
|
| -}
|
| -
|
| -void ShelfLayoutManager::OnKeyboardBoundsChanging(const gfx::Rect& new_bounds) {
|
| - bool keyboard_is_about_to_hide = false;
|
| - if (new_bounds.IsEmpty() && !keyboard_bounds_.IsEmpty())
|
| - keyboard_is_about_to_hide = true;
|
| - // If new window behavior flag enabled and in non-sticky mode, do not change
|
| - // the work area.
|
| - bool change_work_area =
|
| - (!base::CommandLine::ForCurrentProcess()->HasSwitch(
|
| - ::switches::kUseNewVirtualKeyboardBehavior) ||
|
| - keyboard::KeyboardController::GetInstance()->keyboard_locked());
|
| -
|
| - keyboard_bounds_ = new_bounds;
|
| - LayoutShelfAndUpdateBounds(change_work_area);
|
| -
|
| - // On login screen if keyboard has been just hidden, update bounds just once
|
| - // but ignore target_bounds.work_area_insets since shelf overlaps with login
|
| - // window.
|
| - if (WmShell::Get()->GetSessionStateDelegate()->IsUserSessionBlocked() &&
|
| - keyboard_is_about_to_hide) {
|
| - WmWindow* window = WmWindow::Get(shelf_widget_->GetNativeWindow());
|
| - WmShell::Get()->SetDisplayWorkAreaInsets(window, gfx::Insets());
|
| - }
|
| -}
|
| -
|
| -void ShelfLayoutManager::OnKeyboardClosed() {}
|
| -
|
| -ShelfBackgroundType ShelfLayoutManager::GetShelfBackgroundType() const {
|
| - if (state_.pre_lock_screen_animation_active)
|
| - return SHELF_BACKGROUND_DEFAULT;
|
| -
|
| - // Handle all non active screen states, including OOBE and pre-login.
|
| - if (state_.session_state != session_manager::SessionState::ACTIVE)
|
| - return SHELF_BACKGROUND_OVERLAP;
|
| -
|
| - if (state_.visibility_state != SHELF_AUTO_HIDE &&
|
| - state_.window_state == wm::WORKSPACE_WINDOW_STATE_MAXIMIZED) {
|
| - return SHELF_BACKGROUND_MAXIMIZED;
|
| - }
|
| -
|
| - if (gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS ||
|
| - window_overlaps_shelf_ || state_.visibility_state == SHELF_AUTO_HIDE) {
|
| - return SHELF_BACKGROUND_OVERLAP;
|
| - }
|
| -
|
| - return SHELF_BACKGROUND_DEFAULT;
|
| -}
|
| -
|
| -void ShelfLayoutManager::SetChromeVoxPanelHeight(int height) {
|
| - chromevox_panel_height_ = height;
|
| - LayoutShelf();
|
| -}
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -// ShelfLayoutManager, private:
|
| -
|
| -ShelfLayoutManager::TargetBounds::TargetBounds()
|
| - : opacity(0.0f), status_opacity(0.0f) {}
|
| -
|
| -ShelfLayoutManager::TargetBounds::~TargetBounds() {}
|
| -
|
| -void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) {
|
| - State state;
|
| - state.visibility_state = visibility_state;
|
| - state.auto_hide_state = CalculateAutoHideState(visibility_state);
|
| -
|
| - WmWindow* shelf_window = WmWindow::Get(shelf_widget_->GetNativeWindow());
|
| - RootWindowController* controller = shelf_window->GetRootWindowController();
|
| - state.window_state = controller ? controller->GetWorkspaceWindowState()
|
| - : wm::WORKSPACE_WINDOW_STATE_DEFAULT;
|
| - // Preserve the log in screen states.
|
| - state.session_state = state_.session_state;
|
| - state.pre_lock_screen_animation_active =
|
| - state_.pre_lock_screen_animation_active;
|
| -
|
| - // Force an update because gesture drags affect the shelf bounds and we
|
| - // should animate back to the normal bounds at the end of a gesture.
|
| - bool force_update =
|
| - (gesture_drag_status_ == GESTURE_DRAG_CANCEL_IN_PROGRESS ||
|
| - gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS);
|
| -
|
| - if (!force_update && state_.Equals(state))
|
| - return; // Nothing changed.
|
| -
|
| - for (auto& observer : observers_)
|
| - observer.WillChangeVisibilityState(visibility_state);
|
| -
|
| - StopAutoHideTimer();
|
| -
|
| - State old_state = state_;
|
| - state_ = state;
|
| -
|
| - AnimationChangeType change_type = AnimationChangeType::ANIMATE;
|
| - bool delay_background_change = false;
|
| -
|
| - // Do not animate the background when:
|
| - // - Going from a hidden / auto hidden shelf in fullscreen to a visible shelf
|
| - // in maximized mode.
|
| - // - Going from an auto hidden shelf in maximized mode to a visible shelf in
|
| - // maximized mode.
|
| - if (state.visibility_state == SHELF_VISIBLE &&
|
| - state.window_state == wm::WORKSPACE_WINDOW_STATE_MAXIMIZED &&
|
| - old_state.visibility_state != SHELF_VISIBLE) {
|
| - change_type = AnimationChangeType::IMMEDIATE;
|
| - } else {
|
| - // Delay the animation when the shelf was hidden, and has just been made
|
| - // visible (e.g. using a gesture-drag).
|
| - if (state.visibility_state == SHELF_VISIBLE &&
|
| - old_state.visibility_state == SHELF_AUTO_HIDE &&
|
| - old_state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN) {
|
| - delay_background_change = true;
|
| - }
|
| - }
|
| -
|
| - if (delay_background_change) {
|
| - if (update_shelf_observer_)
|
| - update_shelf_observer_->Detach();
|
| - // |update_shelf_observer_| deletes itself when the animation is done.
|
| - update_shelf_observer_ = new UpdateShelfObserver(this);
|
| - } else {
|
| - MaybeUpdateShelfBackground(change_type);
|
| - }
|
| -
|
| - TargetBounds target_bounds;
|
| - CalculateTargetBounds(state_, &target_bounds);
|
| - UpdateBoundsAndOpacity(
|
| - target_bounds, true /* animate */, true /* change_work_area */,
|
| - delay_background_change ? update_shelf_observer_ : NULL);
|
| -
|
| - // OnAutoHideStateChanged Should be emitted when:
|
| - // - firstly state changed to auto-hide from other state
|
| - // - or, auto_hide_state has changed
|
| - if ((old_state.visibility_state != state_.visibility_state &&
|
| - state_.visibility_state == SHELF_AUTO_HIDE) ||
|
| - old_state.auto_hide_state != state_.auto_hide_state) {
|
| - for (auto& observer : observers_)
|
| - observer.OnAutoHideStateChanged(state_.auto_hide_state);
|
| - }
|
| -}
|
| -
|
| -void ShelfLayoutManager::UpdateBoundsAndOpacity(
|
| - const TargetBounds& target_bounds,
|
| - bool animate,
|
| - bool change_work_area,
|
| - ui::ImplicitAnimationObserver* observer) {
|
| - base::AutoReset<bool> auto_reset_updating_bounds(&updating_bounds_, true);
|
| - {
|
| - ui::ScopedLayerAnimationSettings shelf_animation_setter(
|
| - GetLayer(shelf_widget_)->GetAnimator());
|
| - ui::ScopedLayerAnimationSettings status_animation_setter(
|
| - GetLayer(shelf_widget_->status_area_widget())->GetAnimator());
|
| - if (animate) {
|
| - int duration = duration_override_in_ms_ ? duration_override_in_ms_
|
| - : kAnimationDurationMS;
|
| - shelf_animation_setter.SetTransitionDuration(
|
| - base::TimeDelta::FromMilliseconds(duration));
|
| - shelf_animation_setter.SetTweenType(gfx::Tween::EASE_OUT);
|
| - shelf_animation_setter.SetPreemptionStrategy(
|
| - ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
|
| - status_animation_setter.SetTransitionDuration(
|
| - base::TimeDelta::FromMilliseconds(duration));
|
| - status_animation_setter.SetTweenType(gfx::Tween::EASE_OUT);
|
| - status_animation_setter.SetPreemptionStrategy(
|
| - ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
|
| - } else {
|
| - StopAnimating();
|
| - shelf_animation_setter.SetTransitionDuration(base::TimeDelta());
|
| - status_animation_setter.SetTransitionDuration(base::TimeDelta());
|
| - }
|
| - if (observer)
|
| - status_animation_setter.AddObserver(observer);
|
| -
|
| - GetLayer(shelf_widget_)->SetOpacity(target_bounds.opacity);
|
| - WmWindow* shelf_window = WmWindow::Get(shelf_widget_->GetNativeWindow());
|
| - shelf_widget_->SetBounds(shelf_window->GetParent()->ConvertRectToScreen(
|
| - target_bounds.shelf_bounds_in_root));
|
| -
|
| - GetLayer(shelf_widget_->status_area_widget())
|
| - ->SetOpacity(target_bounds.status_opacity);
|
| -
|
| - // Having a window which is visible but does not have an opacity is an
|
| - // illegal state. We therefore hide the shelf here if required.
|
| - if (!target_bounds.status_opacity)
|
| - shelf_widget_->status_area_widget()->Hide();
|
| - // Setting visibility during an animation causes the visibility property to
|
| - // animate. Override the animation settings to immediately set the
|
| - // visibility property. Opacity will still animate.
|
| -
|
| - // TODO(harrym): Once status area widget is a child view of shelf
|
| - // this can be simplified.
|
| - gfx::Rect status_bounds = target_bounds.status_bounds_in_shelf;
|
| - status_bounds.Offset(target_bounds.shelf_bounds_in_root.OffsetFromOrigin());
|
| - WmWindow* status_window =
|
| - WmWindow::Get(shelf_widget_->status_area_widget()->GetNativeWindow());
|
| - shelf_widget_->status_area_widget()->SetBounds(
|
| - status_window->GetParent()->ConvertRectToScreen(status_bounds));
|
| -
|
| - // For crbug.com/622431, when the shelf alignment is BOTTOM_LOCKED, we
|
| - // don't set display work area, as it is not real user-set alignment.
|
| - if (!state_.IsScreenLocked() &&
|
| - wm_shelf_->GetAlignment() != SHELF_ALIGNMENT_BOTTOM_LOCKED &&
|
| - change_work_area) {
|
| - gfx::Insets insets;
|
| - // If user session is blocked (login to new user session or add user to
|
| - // the existing session - multi-profile) then give 100% of work area only
|
| - // if keyboard is not shown.
|
| - if (!state_.IsAddingSecondaryUser() || !keyboard_bounds_.IsEmpty())
|
| - insets = target_bounds.work_area_insets;
|
| - WmShell::Get()->SetDisplayWorkAreaInsets(shelf_window, insets);
|
| - }
|
| - }
|
| -
|
| - // Set an empty border to avoid the shelf view and status area overlapping.
|
| - // TODO(msw): Avoid setting bounds of views within the shelf widget here.
|
| - gfx::Rect shelf_bounds = gfx::Rect(target_bounds.shelf_bounds_in_root.size());
|
| - shelf_widget_->GetContentsView()->SetBorder(views::CreateEmptyBorder(
|
| - shelf_bounds.InsetsFrom(target_bounds.shelf_bounds_in_shelf)));
|
| - shelf_widget_->GetContentsView()->Layout();
|
| -
|
| - // Setting visibility during an animation causes the visibility property to
|
| - // animate. Set the visibility property without an animation.
|
| - if (target_bounds.status_opacity)
|
| - shelf_widget_->status_area_widget()->Show();
|
| -}
|
| -
|
| -void ShelfLayoutManager::StopAnimating() {
|
| - GetLayer(shelf_widget_)->GetAnimator()->StopAnimating();
|
| - GetLayer(shelf_widget_->status_area_widget())->GetAnimator()->StopAnimating();
|
| -}
|
| -
|
| -void ShelfLayoutManager::CalculateTargetBounds(const State& state,
|
| - TargetBounds* target_bounds) {
|
| - int shelf_size = GetShelfConstant(SHELF_SIZE);
|
| - if (state.visibility_state == SHELF_AUTO_HIDE &&
|
| - state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN) {
|
| - // Auto-hidden shelf always starts with the default size. If a gesture-drag
|
| - // is in progress, then the call to UpdateTargetBoundsForGesture() below
|
| - // takes care of setting the height properly.
|
| - shelf_size = kShelfAutoHideSize;
|
| - } else if (state.visibility_state == SHELF_HIDDEN ||
|
| - (!keyboard_bounds_.IsEmpty() &&
|
| - !keyboard::IsKeyboardOverscrollEnabled())) {
|
| - shelf_size = 0;
|
| - }
|
| -
|
| - WmWindow* shelf_window = WmWindow::Get(shelf_widget_->GetNativeWindow());
|
| - gfx::Rect available_bounds = wm::GetDisplayBoundsWithShelf(shelf_window);
|
| - available_bounds.Inset(0, chromevox_panel_height_, 0, 0);
|
| - int shelf_width = PrimaryAxisValue(available_bounds.width(), shelf_size);
|
| - int shelf_height = PrimaryAxisValue(shelf_size, available_bounds.height());
|
| - int bottom_shelf_vertical_offset = available_bounds.bottom();
|
| - if (keyboard_bounds_.IsEmpty())
|
| - bottom_shelf_vertical_offset -= shelf_height;
|
| - else
|
| - bottom_shelf_vertical_offset -= keyboard_bounds_.height();
|
| -
|
| - gfx::Point shelf_origin = SelectValueForShelfAlignment(
|
| - gfx::Point(available_bounds.x(), bottom_shelf_vertical_offset),
|
| - gfx::Point(available_bounds.x(), available_bounds.y()),
|
| - gfx::Point(available_bounds.right() - shelf_width, available_bounds.y()));
|
| - target_bounds->shelf_bounds_in_root =
|
| - gfx::Rect(shelf_origin.x(), shelf_origin.y(), shelf_width, shelf_height);
|
| -
|
| - gfx::Size status_size(
|
| - shelf_widget_->status_area_widget()->GetWindowBoundsInScreen().size());
|
| - if (wm_shelf_->IsHorizontalAlignment())
|
| - status_size.set_height(GetShelfConstant(SHELF_SIZE));
|
| - else
|
| - status_size.set_width(GetShelfConstant(SHELF_SIZE));
|
| -
|
| - gfx::Point status_origin = SelectValueForShelfAlignment(
|
| - gfx::Point(0, 0), gfx::Point(shelf_width - status_size.width(),
|
| - shelf_height - status_size.height()),
|
| - gfx::Point(0, shelf_height - status_size.height()));
|
| - if (wm_shelf_->IsHorizontalAlignment() && !base::i18n::IsRTL())
|
| - status_origin.set_x(shelf_width - status_size.width());
|
| - target_bounds->status_bounds_in_shelf = gfx::Rect(status_origin, status_size);
|
| -
|
| - target_bounds->work_area_insets = SelectValueForShelfAlignment(
|
| - gfx::Insets(0, 0, GetWorkAreaInsets(state, shelf_height), 0),
|
| - gfx::Insets(0, GetWorkAreaInsets(state, shelf_width), 0, 0),
|
| - gfx::Insets(0, 0, 0, GetWorkAreaInsets(state, shelf_width)));
|
| -
|
| - // TODO(varkha): The functionality of managing insets for display areas
|
| - // should probably be pushed to a separate component. This would simplify or
|
| - // remove entirely the dependency on keyboard and dock.
|
| -
|
| - if (!keyboard_bounds_.IsEmpty() && !keyboard::IsKeyboardOverscrollEnabled()) {
|
| - // Also push in the work area inset for the keyboard if it is visible.
|
| - gfx::Insets keyboard_insets(0, 0, keyboard_bounds_.height(), 0);
|
| - target_bounds->work_area_insets += keyboard_insets;
|
| - }
|
| -
|
| - // Also push in the work area inset for the dock if it is visible.
|
| - if (!dock_bounds_.IsEmpty()) {
|
| - gfx::Insets dock_insets(
|
| - 0, (dock_bounds_.x() > 0 ? 0 : dock_bounds_.width()), 0,
|
| - (dock_bounds_.x() > 0 ? dock_bounds_.width() : 0));
|
| - target_bounds->work_area_insets += dock_insets;
|
| - }
|
| -
|
| - // Also push in the work area insets for the ChromeVox panel if it's visible.
|
| - if (chromevox_panel_height_) {
|
| - gfx::Insets chromevox_insets(chromevox_panel_height_, 0, 0, 0);
|
| - target_bounds->work_area_insets += chromevox_insets;
|
| - }
|
| -
|
| - target_bounds->opacity = ComputeTargetOpacity(state);
|
| - target_bounds->status_opacity =
|
| - (state.visibility_state == SHELF_AUTO_HIDE &&
|
| - state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN &&
|
| - gesture_drag_status_ != GESTURE_DRAG_IN_PROGRESS)
|
| - ? 0.0f
|
| - : target_bounds->opacity;
|
| -
|
| - if (gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS)
|
| - UpdateTargetBoundsForGesture(target_bounds);
|
| -
|
| - // This needs to happen after calling UpdateTargetBoundsForGesture(), because
|
| - // that can change the size of the shelf.
|
| - target_bounds->shelf_bounds_in_shelf = SelectValueForShelfAlignment(
|
| - gfx::Rect(0, 0, shelf_width - status_size.width(),
|
| - target_bounds->shelf_bounds_in_root.height()),
|
| - gfx::Rect(0, 0, target_bounds->shelf_bounds_in_root.width(),
|
| - shelf_height - status_size.height()),
|
| - gfx::Rect(0, 0, target_bounds->shelf_bounds_in_root.width(),
|
| - shelf_height - status_size.height()));
|
| -
|
| - available_bounds.Subtract(target_bounds->shelf_bounds_in_root);
|
| - available_bounds.Subtract(keyboard_bounds_);
|
| -
|
| - WmWindow* root = shelf_window->GetRootWindow();
|
| - user_work_area_bounds_ = root->ConvertRectToScreen(available_bounds);
|
| -}
|
| -
|
| -void ShelfLayoutManager::UpdateTargetBoundsForGesture(
|
| - TargetBounds* target_bounds) const {
|
| - CHECK_EQ(GESTURE_DRAG_IN_PROGRESS, gesture_drag_status_);
|
| - bool horizontal = wm_shelf_->IsHorizontalAlignment();
|
| - WmWindow* window = WmWindow::Get(shelf_widget_->GetNativeWindow());
|
| - gfx::Rect available_bounds = wm::GetDisplayBoundsWithShelf(window);
|
| - 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 = GetShelfConstant(SHELF_SIZE) - kShelfAutoHideSize;
|
| - }
|
| -
|
| - bool resist = SelectValueForShelfAlignment(
|
| - 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_;
|
| - }
|
| - int shelf_insets = GetShelfConstant(SHELF_INSETS_FOR_AUTO_HIDE);
|
| - if (horizontal) {
|
| - // Move and size the shelf with the gesture.
|
| - int shelf_height = target_bounds->shelf_bounds_in_root.height() - translate;
|
| - shelf_height = std::max(shelf_height, shelf_insets);
|
| - target_bounds->shelf_bounds_in_root.set_height(shelf_height);
|
| - if (wm_shelf_->IsHorizontalAlignment()) {
|
| - target_bounds->shelf_bounds_in_root.set_y(available_bounds.bottom() -
|
| - shelf_height);
|
| - }
|
| -
|
| - target_bounds->status_bounds_in_shelf.set_y(0);
|
| - } else {
|
| - // Move and size the shelf with the gesture.
|
| - int shelf_width = target_bounds->shelf_bounds_in_root.width();
|
| - bool right_aligned = wm_shelf_->GetAlignment() == SHELF_ALIGNMENT_RIGHT;
|
| - if (right_aligned)
|
| - shelf_width -= translate;
|
| - else
|
| - shelf_width += translate;
|
| - shelf_width = std::max(shelf_width, shelf_insets);
|
| - target_bounds->shelf_bounds_in_root.set_width(shelf_width);
|
| - if (right_aligned) {
|
| - target_bounds->shelf_bounds_in_root.set_x(available_bounds.right() -
|
| - shelf_width);
|
| - }
|
| -
|
| - if (right_aligned) {
|
| - target_bounds->status_bounds_in_shelf.set_x(0);
|
| - } else {
|
| - target_bounds->status_bounds_in_shelf.set_x(
|
| - target_bounds->shelf_bounds_in_root.width() -
|
| - GetShelfConstant(SHELF_SIZE));
|
| - }
|
| - }
|
| -}
|
| -
|
| -void ShelfLayoutManager::MaybeUpdateShelfBackground(AnimationChangeType type) {
|
| - const ShelfBackgroundType new_background_type(GetShelfBackgroundType());
|
| -
|
| - if (new_background_type == shelf_background_type_)
|
| - return;
|
| -
|
| - shelf_background_type_ = new_background_type;
|
| - for (auto& observer : observers_)
|
| - observer.OnBackgroundUpdated(shelf_background_type_, type);
|
| -}
|
| -
|
| -void ShelfLayoutManager::UpdateAutoHideStateNow() {
|
| - SetState(state_.visibility_state);
|
| -
|
| - // If the state did not change, the auto hide timer may still be running.
|
| - StopAutoHideTimer();
|
| -}
|
| -
|
| -void ShelfLayoutManager::StopAutoHideTimer() {
|
| - auto_hide_timer_.Stop();
|
| - mouse_over_shelf_when_auto_hide_timer_started_ = false;
|
| -}
|
| -
|
| -gfx::Rect ShelfLayoutManager::GetAutoHideShowShelfRegionInScreen() const {
|
| - gfx::Rect shelf_bounds_in_screen = shelf_widget_->GetWindowBoundsInScreen();
|
| - gfx::Vector2d offset = SelectValueForShelfAlignment(
|
| - gfx::Vector2d(0, shelf_bounds_in_screen.height()),
|
| - gfx::Vector2d(-kMaxAutoHideShowShelfRegionSize, 0),
|
| - gfx::Vector2d(shelf_bounds_in_screen.width(), 0));
|
| -
|
| - gfx::Rect show_shelf_region_in_screen = shelf_bounds_in_screen;
|
| - show_shelf_region_in_screen += offset;
|
| - if (wm_shelf_->IsHorizontalAlignment())
|
| - show_shelf_region_in_screen.set_height(kMaxAutoHideShowShelfRegionSize);
|
| - else
|
| - show_shelf_region_in_screen.set_width(kMaxAutoHideShowShelfRegionSize);
|
| -
|
| - // TODO: Figure out if we need any special handling when the keyboard is
|
| - // visible.
|
| - return show_shelf_region_in_screen;
|
| -}
|
| -
|
| -ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState(
|
| - ShelfVisibilityState visibility_state) const {
|
| - if (visibility_state != SHELF_AUTO_HIDE || !wm_shelf_->IsShelfInitialized())
|
| - return SHELF_AUTO_HIDE_HIDDEN;
|
| -
|
| - if (shelf_widget_->IsShowingAppList())
|
| - return SHELF_AUTO_HIDE_SHOWN;
|
| -
|
| - if (shelf_widget_->status_area_widget() &&
|
| - shelf_widget_->status_area_widget()->ShouldShowShelf())
|
| - return SHELF_AUTO_HIDE_SHOWN;
|
| -
|
| - if (shelf_widget_->IsShowingContextMenu())
|
| - return SHELF_AUTO_HIDE_SHOWN;
|
| -
|
| - if (shelf_widget_->IsShowingOverflowBubble())
|
| - return SHELF_AUTO_HIDE_SHOWN;
|
| -
|
| - if (shelf_widget_->IsActive() ||
|
| - (shelf_widget_->status_area_widget() &&
|
| - shelf_widget_->status_area_widget()->IsActive()))
|
| - return SHELF_AUTO_HIDE_SHOWN;
|
| -
|
| - const int64_t shelf_display_id =
|
| - WmWindow::Get(shelf_widget_->GetNativeWindow())
|
| - ->GetDisplayNearestWindow()
|
| - .id();
|
| - const std::vector<WmWindow*> windows =
|
| - WmShell::Get()->mru_window_tracker()->BuildWindowListIgnoreModal();
|
| - // Process the window list and check if there are any visible windows.
|
| - // Ignore app list windows that may be animating to hide after dismissal.
|
| - bool visible_window = false;
|
| - for (size_t i = 0; i < windows.size(); ++i) {
|
| - if (windows[i] && windows[i]->IsVisible() && !IsAppListWindow(windows[i]) &&
|
| - !windows[i]->GetWindowState()->IsMinimized() &&
|
| - windows[i]->GetDisplayNearestWindow().id() == shelf_display_id) {
|
| - visible_window = true;
|
| - break;
|
| - }
|
| - }
|
| - // If there are no visible windows do not hide the shelf.
|
| - if (!visible_window)
|
| - return SHELF_AUTO_HIDE_SHOWN;
|
| -
|
| - if (gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS)
|
| - return gesture_drag_auto_hide_state_;
|
| -
|
| - // Don't show if the user is dragging the mouse.
|
| - if (in_mouse_drag_)
|
| - return SHELF_AUTO_HIDE_HIDDEN;
|
| -
|
| - // Ignore the mouse position if mouse events are disabled.
|
| - if (!shelf_widget_->IsMouseEventsEnabled())
|
| - return SHELF_AUTO_HIDE_HIDDEN;
|
| -
|
| - gfx::Rect shelf_region = shelf_widget_->GetWindowBoundsInScreen();
|
| - if (shelf_widget_->status_area_widget() &&
|
| - shelf_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.
|
| - ShelfAlignment alignment = wm_shelf_->GetAlignment();
|
| - shelf_region.Inset(
|
| - alignment == SHELF_ALIGNMENT_RIGHT ? -kNotificationBubbleGapHeight : 0,
|
| - wm_shelf_->IsHorizontalAlignment() ? -kNotificationBubbleGapHeight : 0,
|
| - alignment == SHELF_ALIGNMENT_LEFT ? -kNotificationBubbleGapHeight : 0,
|
| - 0);
|
| - }
|
| -
|
| - gfx::Point cursor_position_in_screen =
|
| - display::Screen::GetScreen()->GetCursorScreenPoint();
|
| - if (shelf_region.Contains(cursor_position_in_screen))
|
| - return SHELF_AUTO_HIDE_SHOWN;
|
| -
|
| - // When the shelf is auto hidden and the shelf is on the boundary between two
|
| - // displays, it is hard to trigger showing the shelf. For instance, if a
|
| - // user's primary display is left of their secondary display, it is hard to
|
| - // unautohide a left aligned shelf on the secondary display.
|
| - // It is hard because:
|
| - // - It is hard to stop the cursor in the shelf "light bar" and not overshoot.
|
| - // - The cursor is warped to the other display if the cursor gets to the edge
|
| - // of the display.
|
| - // Show the shelf if the cursor started on the shelf and the user overshot the
|
| - // shelf slightly to make it easier to show the shelf in this situation. We
|
| - // do not check |auto_hide_timer_|.IsRunning() because it returns false when
|
| - // the timer's task is running.
|
| - if ((state_.auto_hide_state == SHELF_AUTO_HIDE_SHOWN ||
|
| - mouse_over_shelf_when_auto_hide_timer_started_) &&
|
| - GetAutoHideShowShelfRegionInScreen().Contains(
|
| - cursor_position_in_screen)) {
|
| - return SHELF_AUTO_HIDE_SHOWN;
|
| - }
|
| -
|
| - return SHELF_AUTO_HIDE_HIDDEN;
|
| -}
|
| -
|
| -bool ShelfLayoutManager::IsShelfWindow(WmWindow* window) {
|
| - if (!window)
|
| - return false;
|
| - WmWindow* shelf_window = WmWindow::Get(shelf_widget_->GetNativeWindow());
|
| - WmWindow* status_window =
|
| - WmWindow::Get(shelf_widget_->status_area_widget()->GetNativeWindow());
|
| - return (shelf_window && shelf_window->Contains(window)) ||
|
| - (status_window && status_window->Contains(window));
|
| -}
|
| -
|
| -int ShelfLayoutManager::GetWorkAreaInsets(const State& state, int size) const {
|
| - if (state.visibility_state == SHELF_VISIBLE)
|
| - return size;
|
| - if (state.visibility_state == SHELF_AUTO_HIDE)
|
| - return GetShelfConstant(SHELF_INSETS_FOR_AUTO_HIDE);
|
| - return 0;
|
| -}
|
| -
|
| -void ShelfLayoutManager::OnDockBoundsChanging(
|
| - const gfx::Rect& dock_bounds,
|
| - DockedWindowLayoutManagerObserver::Reason reason) {
|
| - // Skip shelf layout in case docked notification originates from this class.
|
| - if (reason == DISPLAY_INSETS_CHANGED)
|
| - return;
|
| - if (dock_bounds_ != dock_bounds) {
|
| - dock_bounds_ = dock_bounds;
|
| - OnWindowResized();
|
| - UpdateVisibilityState();
|
| - MaybeUpdateShelfBackground(AnimationChangeType::ANIMATE);
|
| - }
|
| -}
|
| -
|
| -void ShelfLayoutManager::OnLockStateEvent(LockStateObserver::EventType event) {
|
| - if (event == EVENT_LOCK_ANIMATION_STARTED) {
|
| - // Enter the screen locked state and update the visibility to avoid an odd
|
| - // animation when transitioning the orientation from L/R to bottom.
|
| - state_.pre_lock_screen_animation_active = true;
|
| - UpdateShelfVisibilityAfterLoginUIChange();
|
| - } else {
|
| - state_.pre_lock_screen_animation_active = false;
|
| - }
|
| - MaybeUpdateShelfBackground(AnimationChangeType::ANIMATE);
|
| -}
|
| -
|
| -void ShelfLayoutManager::SessionStateChanged(
|
| - session_manager::SessionState state) {
|
| - // Check transition changes to/from the add user to session and change the
|
| - // shelf alignment accordingly
|
| - const bool was_adding_user = state_.IsAddingSecondaryUser();
|
| - const bool was_locked = state_.IsScreenLocked();
|
| - state_.session_state = state;
|
| - MaybeUpdateShelfBackground(AnimationChangeType::ANIMATE);
|
| - if (was_adding_user != state_.IsAddingSecondaryUser()) {
|
| - UpdateShelfVisibilityAfterLoginUIChange();
|
| - return;
|
| - }
|
| -
|
| - // Force the shelf to layout for alignment (bottom if locked, restore the
|
| - // previous alignment otherwise).
|
| - if (was_locked != state_.IsScreenLocked())
|
| - UpdateShelfVisibilityAfterLoginUIChange();
|
| -
|
| - TargetBounds target_bounds;
|
| - CalculateTargetBounds(state_, &target_bounds);
|
| - UpdateBoundsAndOpacity(target_bounds, true /* animate */,
|
| - true /* change_work_area */, NULL);
|
| - UpdateVisibilityState();
|
| -}
|
| -
|
| -void ShelfLayoutManager::UpdateShelfVisibilityAfterLoginUIChange() {
|
| - UpdateVisibilityState();
|
| - LayoutShelf();
|
| -}
|
| -
|
| -float ShelfLayoutManager::ComputeTargetOpacity(const State& state) {
|
| - if (gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS ||
|
| - state.visibility_state == SHELF_VISIBLE) {
|
| - return 1.0f;
|
| - }
|
| - // In Chrome OS Material Design, when shelf is hidden during auto hide state,
|
| - // target bounds are also hidden. So the window can extend to the edge of
|
| - // screen.
|
| - return (state.visibility_state == SHELF_AUTO_HIDE &&
|
| - state.auto_hide_state == SHELF_AUTO_HIDE_SHOWN)
|
| - ? 1.0f
|
| - : 0.0f;
|
| -}
|
| -
|
| -bool ShelfLayoutManager::IsShelfHiddenForFullscreen() const {
|
| - const WmWindow* fullscreen_window = wm::GetWindowForFullscreenMode(
|
| - WmWindow::Get(shelf_widget_->GetNativeWindow()));
|
| - return fullscreen_window &&
|
| - fullscreen_window->GetWindowState()->hide_shelf_when_fullscreen();
|
| -}
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -// ShelfLayoutManager, Gesture functions:
|
| -
|
| -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;
|
| - MaybeUpdateShelfBackground(AnimationChangeType::ANIMATE);
|
| -}
|
| -
|
| -void ShelfLayoutManager::UpdateGestureDrag(const ui::GestureEvent& gesture) {
|
| - gesture_drag_amount_ += PrimaryAxisValue(gesture.details().scroll_y(),
|
| - gesture.details().scroll_x());
|
| - LayoutShelf();
|
| -}
|
| -
|
| -void ShelfLayoutManager::CompleteGestureDrag(const ui::GestureEvent& gesture) {
|
| - bool horizontal = wm_shelf_->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 (wm_shelf_->GetAlignment()) {
|
| - case SHELF_ALIGNMENT_BOTTOM:
|
| - case SHELF_ALIGNMENT_BOTTOM_LOCKED:
|
| - case SHELF_ALIGNMENT_RIGHT:
|
| - correct_direction = gesture_drag_amount_ < 0;
|
| - break;
|
| - case SHELF_ALIGNMENT_LEFT:
|
| - 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);
|
| - }
|
| - } else {
|
| - NOTREACHED();
|
| - }
|
| -
|
| - if (!should_change) {
|
| - CancelGestureDrag();
|
| - return;
|
| - }
|
| -
|
| - shelf_widget_->Deactivate();
|
| - shelf_widget_->status_area_widget()->Deactivate();
|
| -
|
| - gesture_drag_auto_hide_state_ =
|
| - gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN
|
| - ? SHELF_AUTO_HIDE_HIDDEN
|
| - : SHELF_AUTO_HIDE_SHOWN;
|
| - ShelfAutoHideBehavior new_auto_hide_behavior =
|
| - gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN
|
| - ? SHELF_AUTO_HIDE_BEHAVIOR_NEVER
|
| - : SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS;
|
| -
|
| - // When in fullscreen and the shelf is forced to be auto hidden, the auto hide
|
| - // behavior affects neither the visibility state nor the auto hide state. Set
|
| - // |gesture_drag_status_| to GESTURE_DRAG_COMPLETE_IN_PROGRESS to set the auto
|
| - // hide state to |gesture_drag_auto_hide_state_|.
|
| - gesture_drag_status_ = GESTURE_DRAG_COMPLETE_IN_PROGRESS;
|
| - if (wm_shelf_->auto_hide_behavior() != new_auto_hide_behavior)
|
| - wm_shelf_->SetAutoHideBehavior(new_auto_hide_behavior);
|
| - else
|
| - UpdateVisibilityState();
|
| - gesture_drag_status_ = GESTURE_DRAG_NONE;
|
| -}
|
| -
|
| -void ShelfLayoutManager::CancelGestureDrag() {
|
| - gesture_drag_status_ = GESTURE_DRAG_CANCEL_IN_PROGRESS;
|
| - UpdateVisibilityState();
|
| - gesture_drag_status_ = GESTURE_DRAG_NONE;
|
| -}
|
| -
|
| -} // namespace ash
|
|
|