shelf_layout_manager.cc revision a36e5920737c6adbddd3e43b760e5de8431db6e0
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_layout_manager.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <algorithm>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <cmath>
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <cstring>
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <string>
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <vector>
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/ash_switches.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/launcher/launcher.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/launcher/launcher_types.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/root_window_controller.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/screen_ash.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/session_state_delegate.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ash/shelf/shelf_bezel_event_filter.h"
20b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "ash/shelf/shelf_layout_manager_observer.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_widget.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shell.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shell_window_ids.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/status_area_widget.h"
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/wm/gestures/shelf_gesture_handler.h"
26a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ash/wm/mru_window_tracker.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/property_util.h"
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/wm/window_properties.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/window_util.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/workspace/workspace_animations.h"
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ash/wm/workspace_controller.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/auto_reset.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h"
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/command_line.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/i18n/rtl.h"
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/activation_client.h"
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/root_window.h"
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/events/event.h"
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/events/event_handler.h"
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/base/ui_base_switches.h"
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/layer.h"
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/layer_animation_observer.h"
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/layer_animator.h"
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/scoped_layer_animation_settings.h"
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/screen.h"
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/widget.h"
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ash {
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace internal {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Delay before showing the launcher. This is after the mouse stops moving.
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kAutoHideDelayMS = 200;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// To avoid hiding the shelf when the mouse transitions from a message bubble
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// into the shelf, the hit test area is enlarged by this amount of pixels to
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// keep the shelf from hiding.
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kNotificationBubbleGapHeight = 6;
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ui::Layer* GetLayer(views::Widget* widget) {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return widget->GetNativeView()->layer();
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsDraggingTrayEnabled() {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static bool dragging_tray_allowed = CommandLine::ForCurrentProcess()->
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HasSwitch(ash::switches::kAshEnableTrayDragging);
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return dragging_tray_allowed;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int ShelfLayoutManager::kWorkspaceAreaVisibleInset = 2;
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int ShelfLayoutManager::kWorkspaceAreaAutoHideInset = 5;
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int ShelfLayoutManager::kAutoHideSize = 3;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// static
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const int ShelfLayoutManager::kShelfSize = 47;
867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
87ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochint ShelfLayoutManager::GetPreferredShelfSize() {
88ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return ash::switches::UseAlternateShelfLayout() ?
89ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      ShelfLayoutManager::kShelfSize : kLauncherPreferredSize;
90ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
91ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager::AutoHideEventFilter -------------------------------------
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Notifies ShelfLayoutManager any time the mouse moves.
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ShelfLayoutManager::AutoHideEventFilter : public ui::EventHandler {
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit AutoHideEventFilter(ShelfLayoutManager* shelf);
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~AutoHideEventFilter();
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if the last mouse event was a mouse drag.
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool in_mouse_drag() const { return in_mouse_drag_; }
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from ui::EventHandler:
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE;
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShelfLayoutManager* shelf_;
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool in_mouse_drag_;
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ShelfGestureHandler gesture_handler_;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AutoHideEventFilter);
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::AutoHideEventFilter::AutoHideEventFilter(
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShelfLayoutManager* shelf)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : shelf_(shelf),
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      in_mouse_drag_(false) {
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->AddPreTargetHandler(this);
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::AutoHideEventFilter::~AutoHideEventFilter() {
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->RemovePreTargetHandler(this);
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::AutoHideEventFilter::OnMouseEvent(
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::MouseEvent* event) {
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This also checks IsShelfWindow() to make sure we don't attempt to hide the
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // shelf if the mouse down occurs on the shelf.
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_mouse_drag_ = (event->type() == ui::ET_MOUSE_DRAGGED ||
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    (in_mouse_drag_ && event->type() != ui::ET_MOUSE_RELEASED &&
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     event->type() != ui::ET_MOUSE_CAPTURE_CHANGED)) &&
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !shelf_->IsShelfWindow(static_cast<aura::Window*>(event->target()));
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (event->type() == ui::ET_MOUSE_MOVED)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_->UpdateAutoHideState();
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShelfLayoutManager::AutoHideEventFilter::OnGestureEvent(
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ui::GestureEvent* event) {
140a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (shelf_->IsShelfWindow(static_cast<aura::Window*>(event->target()))) {
141a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (gesture_handler_.ProcessGestureEvent(*event))
142a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      event->StopPropagation();
143a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager:UpdateShelfObserver --------------------------------------
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// UpdateShelfObserver is used to delay updating the background until the
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// animation completes.
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ShelfLayoutManager::UpdateShelfObserver
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public ui::ImplicitAnimationObserver {
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit UpdateShelfObserver(ShelfLayoutManager* shelf) : shelf_(shelf) {
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_->update_shelf_observer_ = this;
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Detach() {
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_ = NULL;
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnImplicitAnimationsCompleted() OVERRIDE {
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (shelf_) {
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->UpdateShelfBackground(BackgroundAnimator::CHANGE_ANIMATE);
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete this;
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~UpdateShelfObserver() {
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (shelf_)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->update_shelf_observer_ = NULL;
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Shelf we're in. NULL if deleted before we're deleted.
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShelfLayoutManager* shelf_;
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(UpdateShelfObserver);
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager ----------------------------------------------------------
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::ShelfLayoutManager(ShelfWidget* shelf)
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : root_window_(shelf->GetNativeView()->GetRootWindow()),
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      in_layout_(false),
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_hide_behavior_(SHELF_AUTO_HIDE_BEHAVIOR_NEVER),
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      alignment_(SHELF_ALIGNMENT_BOTTOM),
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_(shelf),
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      workspace_controller_(NULL),
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      window_overlaps_shelf_(false),
190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      bezel_event_filter_(new ShelfBezelEventFilter(this)),
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_status_(GESTURE_DRAG_NONE),
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_(0.f),
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_auto_hide_state_(SHELF_AUTO_HIDE_SHOWN),
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      update_shelf_observer_(NULL) {
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->AddShellObserver(this);
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::client::GetActivationClient(root_window_)->AddObserver(this);
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::~ShelfLayoutManager() {
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (update_shelf_observer_)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    update_shelf_observer_->Detach();
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
203b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_, WillDeleteShelf());
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->RemoveShellObserver(this);
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::client::GetActivationClient(root_window_)->RemoveObserver(this);
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::SetAutoHideBehavior(ShelfAutoHideBehavior behavior) {
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (auto_hide_behavior_ == behavior)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  auto_hide_behavior_ = behavior;
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateVisibilityState();
213b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_,
2147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                    OnAutoHideBehaviorChanged(root_window_,
2157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                              auto_hide_behavior_));
2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ShelfLayoutManager::PrepareForShutdown() {
2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Clear all event filters, otherwise sometimes those filters may catch
2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // synthesized mouse event and cause crashes during the shutdown.
2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  set_workspace_controller(NULL);
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  auto_hide_event_filter_.reset();
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bezel_event_filter_.reset();
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShelfLayoutManager::IsVisible() const {
2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // status_area_widget() may be NULL during the shutdown.
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return shelf_->status_area_widget() &&
2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      shelf_->status_area_widget()->IsVisible() &&
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (state_.visibility_state == SHELF_VISIBLE ||
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       (state_.visibility_state == SHELF_AUTO_HIDE &&
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        state_.auto_hide_state == SHELF_AUTO_HIDE_SHOWN));
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShelfLayoutManager::SetAlignment(ShelfAlignment alignment) {
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (alignment_ == alignment)
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  alignment_ = alignment;
24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  shelf_->SetAlignment(alignment);
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayoutShelf();
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Rect ShelfLayoutManager::GetIdealBounds() {
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect bounds(
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ScreenAsh::GetDisplayBoundsInParent(shelf_->GetNativeView()));
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int width = 0, height = 0;
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetShelfSize(&width, &height);
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SelectValueForShelfAlignment(
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(bounds.x(), bounds.bottom() - height, bounds.width(), height),
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(bounds.x(), bounds.y(), width, bounds.height()),
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(bounds.right() - width, bounds.y(), width, bounds.height()),
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(bounds.x(), bounds.y(), bounds.width(), height));
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::LayoutShelf() {
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true);
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StopAnimating();
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TargetBounds target_bounds;
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalculateTargetBounds(state_, &target_bounds);
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetLayer(shelf_)->SetOpacity(target_bounds.opacity);
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  shelf_->SetWidgetBounds(
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ScreenAsh::ConvertRectToScreen(
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          shelf_->GetNativeView()->parent(),
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          target_bounds.shelf_bounds_in_root));
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_->launcher())
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_->launcher()->SetLauncherViewBounds(
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        target_bounds.launcher_bounds_in_shelf);
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetLayer(shelf_->status_area_widget())->SetOpacity(target_bounds.opacity);
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(harrym): Once status area widget is a child view of shelf
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // this can be simplified.
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect status_bounds = target_bounds.status_bounds_in_shelf;
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  status_bounds.set_x(status_bounds.x() +
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      target_bounds.shelf_bounds_in_root.x());
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  status_bounds.set_y(status_bounds.y() +
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      target_bounds.shelf_bounds_in_root.y());
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  shelf_->status_area_widget()->SetBounds(
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ScreenAsh::ConvertRectToScreen(
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          shelf_->status_area_widget()->GetNativeView()->parent(),
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          status_bounds));
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      root_window_, target_bounds.work_area_insets);
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateHitTestBounds();
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfVisibilityState ShelfLayoutManager::CalculateShelfVisibility() {
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch(auto_hide_behavior_) {
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS:
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return SHELF_AUTO_HIDE;
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case SHELF_AUTO_HIDE_BEHAVIOR_NEVER:
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return SHELF_VISIBLE;
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case SHELF_AUTO_HIDE_ALWAYS_HIDDEN:
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return SHELF_HIDDEN;
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SHELF_VISIBLE;
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateVisibilityState() {
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (Shell::GetInstance()->session_state_delegate()->IsScreenLocked()) {
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetState(SHELF_VISIBLE);
3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  } else {
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(zelidrag): Verify shelf drag animation still shows on the device
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // when we are in SHELF_AUTO_HIDE_ALWAYS_HIDDEN.
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WorkspaceWindowState window_state(workspace_controller_->GetWindowState());
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (window_state) {
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case WORKSPACE_WINDOW_STATE_FULL_SCREEN:
30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        if (FullscreenWithMinimalChrome()) {
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          SetState(SHELF_AUTO_HIDE);
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        } else {
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          SetState(SHELF_HIDDEN);
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case WORKSPACE_WINDOW_STATE_MAXIMIZED:
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        SetState(CalculateShelfVisibility());
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF:
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case WORKSPACE_WINDOW_STATE_DEFAULT:
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        SetState(CalculateShelfVisibility());
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        SetWindowOverlapsShelf(window_state ==
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF);
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateAutoHideState() {
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShelfAutoHideState auto_hide_state =
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CalculateAutoHideState(state_.visibility_state);
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (auto_hide_state != state_.auto_hide_state) {
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (auto_hide_state == SHELF_AUTO_HIDE_HIDDEN) {
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Hides happen immediately.
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SetState(state_.visibility_state);
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_hide_timer_.Stop();
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_hide_timer_.Start(
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          FROM_HERE,
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::TimeDelta::FromMilliseconds(kAutoHideDelayMS),
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this, &ShelfLayoutManager::UpdateAutoHideStateNow);
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    auto_hide_timer_.Stop();
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::SetWindowOverlapsShelf(bool value) {
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_overlaps_shelf_ = value;
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateShelfBackground(BackgroundAnimator::CHANGE_ANIMATE);
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
351b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ShelfLayoutManager::AddObserver(ShelfLayoutManagerObserver* observer) {
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.AddObserver(observer);
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
355b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ShelfLayoutManager::RemoveObserver(ShelfLayoutManagerObserver* observer) {
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.RemoveObserver(observer);
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager, Gesture dragging:
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::StartGestureDrag(const ui::GestureEvent& gesture) {
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_status_ = GESTURE_DRAG_IN_PROGRESS;
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_amount_ = 0.f;
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_auto_hide_state_ = visibility_state() == SHELF_AUTO_HIDE ?
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_hide_state() : SHELF_AUTO_HIDE_SHOWN;
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateShelfBackground(BackgroundAnimator::CHANGE_ANIMATE);
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::DragState ShelfLayoutManager::UpdateGestureDrag(
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ui::GestureEvent& gesture) {
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool horizontal = IsHorizontalAlignment();
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_amount_ += horizontal ? gesture.details().scroll_y() :
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       gesture.details().scroll_x();
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayoutShelf();
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Start reveling the status menu when:
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   - dragging up on an already visible shelf
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   - dragging up on a hidden shelf, but it is currently completely visible.
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (horizontal && gesture.details().scroll_y() < 0) {
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int min_height = 0;
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_HIDDEN && shelf_)
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      min_height = shelf_->GetContentsView()->GetPreferredSize().height();
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (min_height < shelf_->GetWindowBoundsInScreen().height() &&
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gesture.root_location().x() >=
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        shelf_->status_area_widget()->GetWindowBoundsInScreen().x() &&
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IsDraggingTrayEnabled())
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return DRAG_TRAY;
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return DRAG_SHELF;
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::CompleteGestureDrag(const ui::GestureEvent& gesture) {
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool horizontal = IsHorizontalAlignment();
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool should_change = false;
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gesture.type() == ui::ET_GESTURE_SCROLL_END) {
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The visibility of the shelf changes only if the shelf was dragged X%
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // along the correct axis. If the shelf was already visible, then the
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // direction of the drag does not matter.
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const float kDragHideThreshold = 0.4f;
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect bounds = GetIdealBounds();
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    float drag_ratio = fabs(gesture_drag_amount_) /
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       (horizontal ?  bounds.height() : bounds.width());
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN) {
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      should_change = drag_ratio > kDragHideThreshold;
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool correct_direction = false;
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      switch (alignment_) {
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case SHELF_ALIGNMENT_BOTTOM:
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case SHELF_ALIGNMENT_RIGHT:
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          correct_direction = gesture_drag_amount_ < 0;
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          break;
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case SHELF_ALIGNMENT_LEFT:
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case SHELF_ALIGNMENT_TOP:
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          correct_direction = gesture_drag_amount_ > 0;
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          break;
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      should_change = correct_direction && drag_ratio > kDragHideThreshold;
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (gesture.type() == ui::ET_SCROLL_FLING_START) {
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN) {
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      should_change = horizontal ? fabs(gesture.details().velocity_y()) > 0 :
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   fabs(gesture.details().velocity_x()) > 0;
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      should_change = SelectValueForShelfAlignment(
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gesture.details().velocity_y() < 0,
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gesture.details().velocity_x() > 0,
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gesture.details().velocity_x() < 0,
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gesture.details().velocity_y() > 0);
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!should_change) {
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CancelGestureDrag();
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
44190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (shelf_) {
44290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    shelf_->Deactivate();
44390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    shelf_->status_area_widget()->Deactivate();
44490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_auto_hide_state_ =
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN ?
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SHELF_AUTO_HIDE_HIDDEN : SHELF_AUTO_HIDE_SHOWN;
4487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ShelfAutoHideBehavior new_auto_hide_behavior =
4497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN ?
4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      SHELF_AUTO_HIDE_BEHAVIOR_NEVER : SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS;
4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // In fullscreen with minimal chrome, the auto hide behavior affects neither
4537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // the visibility state nor the auto hide state. Set |gesture_drag_status_|
4547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // to GESTURE_DRAG_COMPLETE_IN_PROGRESS to set the auto hide state to
4557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // |gesture_drag_auto_hide_state_|.
4567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gesture_drag_status_ = GESTURE_DRAG_COMPLETE_IN_PROGRESS;
4577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (auto_hide_behavior_ != new_auto_hide_behavior)
4587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    SetAutoHideBehavior(new_auto_hide_behavior);
4597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  else
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateVisibilityState();
4617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gesture_drag_status_ = GESTURE_DRAG_NONE;
462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LayoutShelf();
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::CancelGestureDrag() {
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_status_ = GESTURE_DRAG_NONE;
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ScopedLayerAnimationSettings
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      launcher_settings(GetLayer(shelf_)->GetAnimator()),
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      status_settings(GetLayer(shelf_->status_area_widget())->GetAnimator());
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayoutShelf();
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateVisibilityState();
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateShelfBackground(BackgroundAnimator::CHANGE_ANIMATE);
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager, aura::LayoutManager implementation:
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWindowResized() {
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayoutShelf();
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) {
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWindowRemovedFromLayout(aura::Window* child) {
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child,
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                        bool visible) {
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::SetChildBounds(aura::Window* child,
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        const gfx::Rect& requested_bounds) {
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetChildBoundsDirect(child, requested_bounds);
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We may contain other widgets (such as frame maximize bubble) but they don't
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // effect the layout in anyway.
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!in_layout_ &&
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ((shelf_->GetNativeView() == child) ||
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       (shelf_->status_area_widget()->GetNativeView() == child))) {
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayoutShelf();
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnLockStateChanged(bool locked) {
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateVisibilityState();
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWindowActivated(aura::Window* gained_active,
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           aura::Window* lost_active) {
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAutoHideStateNow();
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShelfLayoutManager::IsHorizontalAlignment() const {
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return alignment_ == SHELF_ALIGNMENT_BOTTOM ||
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         alignment_ == SHELF_ALIGNMENT_TOP;
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool ShelfLayoutManager::FullscreenWithMinimalChrome() const {
52290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  RootWindowController* controller = GetRootWindowController(root_window_);
52390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!controller)
52490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return false;
52590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  aura::Window* window = controller->GetFullscreenWindow();
52690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!window)
52790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return false;
52890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!window->GetProperty(kFullscreenUsesMinimalChromeKey))
52990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return false;
53090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return true;
53190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
53290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager* ShelfLayoutManager::ForLauncher(aura::Window* window) {
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShelfWidget* shelf = RootWindowController::ForLauncher(window)->shelf();
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return shelf ? shelf->shelf_layout_manager() : NULL;
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager, private:
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::TargetBounds::TargetBounds() : opacity(0.0f) {}
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::TargetBounds::~TargetBounds() {}
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) {
546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!shelf_->GetNativeView())
547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  State state;
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state.visibility_state = visibility_state;
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state.auto_hide_state = CalculateAutoHideState(visibility_state);
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  state.is_screen_locked =
553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      Shell::GetInstance()->session_state_delegate()->IsScreenLocked();
5547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  state.window_state = workspace_controller_ ?
5557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      workspace_controller_->GetWindowState() : WORKSPACE_WINDOW_STATE_DEFAULT;
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // It's possible for SetState() when a window becomes maximized but the state
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // won't have changed value. Do the dimming check before the early exit.
5597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  shelf_->SetDimsShelf(
5607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      (state.visibility_state == SHELF_VISIBLE) &&
5617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      state.window_state == WORKSPACE_WINDOW_STATE_MAXIMIZED);
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state_.Equals(state))
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;  // Nothing changed.
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
566b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_,
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    WillChangeVisibilityState(visibility_state));
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state.visibility_state == SHELF_AUTO_HIDE) {
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // When state is SHELF_AUTO_HIDE we need to track when the mouse is over the
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // launcher to unhide the shelf. AutoHideEventFilter does that for us.
572868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!auto_hide_event_filter_)
573868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      auto_hide_event_filter_.reset(new AutoHideEventFilter(this));
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
575868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    auto_hide_event_filter_.reset(NULL);
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  auto_hide_timer_.Stop();
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // The transition of background from auto-hide to visible is janky if the
5817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // transition also cause the shelf's slide animation from the bottom edge.
5827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // This happens if:
5837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  //  - shelf is hidden
5847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  //  - or, shelf is visible but workspace state is maximized
5857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool keep_maximized = state_.window_state == state.window_state &&
5867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      state_.window_state == WORKSPACE_WINDOW_STATE_MAXIMIZED;
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BackgroundAnimator::ChangeType change_type =
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (state_.visibility_state == SHELF_AUTO_HIDE &&
5897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       state.visibility_state == SHELF_VISIBLE &&
5907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       (state_.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN ||
5917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        keep_maximized)) ?
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BackgroundAnimator::CHANGE_IMMEDIATE : BackgroundAnimator::CHANGE_ANIMATE;
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  State old_state = state_;
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_ = state;
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TargetBounds target_bounds;
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalculateTargetBounds(state_, &target_bounds);
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ScopedLayerAnimationSettings launcher_animation_setter(
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetLayer(shelf_)->GetAnimator());
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  launcher_animation_setter.SetTransitionDuration(
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(kWorkspaceSwitchTimeMS));
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  launcher_animation_setter.SetTweenType(ui::Tween::EASE_OUT);
604eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  launcher_animation_setter.SetPreemptionStrategy(
605eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetLayer(shelf_)->SetBounds(
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      target_bounds.shelf_bounds_in_root);
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetLayer(shelf_)->SetOpacity(target_bounds.opacity);
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ScopedLayerAnimationSettings status_animation_setter(
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetLayer(shelf_->status_area_widget())->GetAnimator());
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  status_animation_setter.SetTransitionDuration(
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(kWorkspaceSwitchTimeMS));
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  status_animation_setter.SetTweenType(ui::Tween::EASE_OUT);
614eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  status_animation_setter.SetPreemptionStrategy(
615eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Delay updating the background when going from SHELF_AUTO_HIDE_SHOWN to
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SHELF_AUTO_HIDE_HIDDEN until the shelf animates out. Otherwise during the
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // animation you see the background change.
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Also delay the animation when the shelf was hidden, and has just been made
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // visible (e.g. using a gesture-drag).
6227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // But do not delay if the transition happens when a window is maximized.
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool delay_shelf_update =
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      state.visibility_state == SHELF_AUTO_HIDE &&
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN &&
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      old_state.visibility_state == SHELF_AUTO_HIDE;
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!keep_maximized && state.visibility_state == SHELF_VISIBLE &&
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      old_state.visibility_state == SHELF_AUTO_HIDE &&
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      old_state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN)
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delay_shelf_update = true;
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (delay_shelf_update) {
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (update_shelf_observer_)
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      update_shelf_observer_->Detach();
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // UpdateShelfBackground deletes itself when the animation is done.
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    update_shelf_observer_ = new UpdateShelfObserver(this);
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    status_animation_setter.AddObserver(update_shelf_observer_);
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::Layer* layer = GetLayer(shelf_->status_area_widget());
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(harrym): Remove when status_area is view (crbug.com/180422).
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect status_bounds = target_bounds.status_bounds_in_shelf;
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  status_bounds.set_x(status_bounds.x() +
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      target_bounds.shelf_bounds_in_root.x());
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  status_bounds.set_y(status_bounds.y() +
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      target_bounds.shelf_bounds_in_root.y());
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(status_bounds);
648eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->SetOpacity(target_bounds.status_opacity);
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      root_window_, target_bounds.work_area_insets);
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateHitTestBounds();
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!delay_shelf_update)
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateShelfBackground(change_type);
654558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
655558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // OnAutoHideStateChanged Should be emitted when:
656558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  //  - firstly state changed to auto-hide from other state
657558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  //  - or, auto_hide_state has changed
658558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if ((old_state.visibility_state != state_.visibility_state &&
659558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch       state_.visibility_state == SHELF_AUTO_HIDE) ||
660558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      old_state.auto_hide_state != state_.auto_hide_state) {
661558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_,
662558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                      OnAutoHideStateChanged(state_.auto_hide_state));
663558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::StopAnimating() {
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetLayer(shelf_)->GetAnimator()->StopAnimating();
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetLayer(shelf_->status_area_widget())->GetAnimator()->StopAnimating();
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::GetShelfSize(int* width, int* height) {
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *width = *height = 0;
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size status_size(
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->status_area_widget()->GetWindowBoundsInScreen().size());
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsHorizontalAlignment())
6767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    *height = GetPreferredShelfSize();
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
6787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    *width = GetPreferredShelfSize();
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::AdjustBoundsBasedOnAlignment(int inset,
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                      gfx::Rect* bounds) const {
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bounds->Inset(SelectValueForShelfAlignment(
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, 0, inset, 0),
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, inset, 0, 0),
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, 0, 0, inset),
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(inset, 0, 0, 0)));
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::CalculateTargetBounds(
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const State& state,
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TargetBounds* target_bounds) {
693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const gfx::Rect available_bounds(GetAvailableBounds());
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect status_size(
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->status_area_widget()->GetWindowBoundsInScreen().size());
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shelf_width = 0, shelf_height = 0;
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetShelfSize(&shelf_width, &shelf_height);
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsHorizontalAlignment())
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_width = available_bounds.width();
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_height = available_bounds.height();
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state.visibility_state == SHELF_AUTO_HIDE &&
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN) {
705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Auto-hidden shelf always starts with the default size. If a gesture-drag
706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // is in progress, then the call to UpdateTargetBoundsForGesture() below
707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // takes care of setting the height properly.
708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (IsHorizontalAlignment())
709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      shelf_height = kAutoHideSize;
710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    else
711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      shelf_width = kAutoHideSize;
712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (state.visibility_state == SHELF_HIDDEN ||
713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !keyboard_bounds_.IsEmpty()) {
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsHorizontalAlignment())
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_height = 0;
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_width = 0;
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_bounds->shelf_bounds_in_root = SelectValueForShelfAlignment(
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(available_bounds.x(), available_bounds.bottom() - shelf_height,
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    available_bounds.width(), shelf_height),
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(available_bounds.x(), available_bounds.y(),
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    shelf_width, available_bounds.height()),
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(available_bounds.right() - shelf_width, available_bounds.y(),
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    shelf_width, available_bounds.height()),
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(available_bounds.x(), available_bounds.y(),
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    available_bounds.width(), shelf_height));
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int status_inset = std::max(0, GetPreferredShelfSize() -
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PrimaryAxisValue(status_size.height(), status_size.width()));
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_bounds->status_bounds_in_shelf = SelectValueForShelfAlignment(
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(base::i18n::IsRTL() ? 0 : shelf_width - status_size.width(),
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    status_inset, status_size.width(), status_size.height()),
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(shelf_width - (status_size.width() + status_inset),
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    shelf_height - status_size.height(), status_size.width(),
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    status_size.height()),
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(status_inset, shelf_height - status_size.height(),
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    status_size.width(), status_size.height()),
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(base::i18n::IsRTL() ? 0 : shelf_width - status_size.width(),
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    shelf_height - (status_size.height() + status_inset),
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    status_size.width(), status_size.height()));
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_bounds->work_area_insets = SelectValueForShelfAlignment(
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, 0, GetWorkAreaSize(state, shelf_height), 0),
7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, GetWorkAreaSize(state, shelf_width), 0, 0),
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, 0, 0, GetWorkAreaSize(state, shelf_width)),
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(GetWorkAreaSize(state, shelf_height), 0, 0, 0));
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
751ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // TODO(varkha): The functionality of managing insets for display areas
752ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // should probably be pushed to a separate component. This would simplify or
753ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // remove entirely the dependency on keyboard and dock.
754ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Also push in the work area inset for the keyboard if it is visible.
756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!keyboard_bounds_.IsEmpty()) {
757ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    gfx::Insets keyboard_insets(0, 0, keyboard_bounds_.height(), 0);
758ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    target_bounds->work_area_insets += keyboard_insets;
759ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
760ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
761ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Also push in the work area inset for the dock if it is visible.
762ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!dock_bounds_.IsEmpty()) {
763ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    gfx::Insets dock_insets(
764ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        0, (dock_bounds_.x() > 0 ? 0 : dock_bounds_.width()),
765ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        0, (dock_bounds_.x() > 0 ? dock_bounds_.width() : 0));
766ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    target_bounds->work_area_insets += dock_insets;
767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_bounds->opacity =
7707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      (gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS ||
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       state.visibility_state == SHELF_VISIBLE ||
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       state.visibility_state == SHELF_AUTO_HIDE) ? 1.0f : 0.0f;
773eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  target_bounds->status_opacity =
774eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      (state.visibility_state == SHELF_AUTO_HIDE &&
775eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch       state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN) ?
776eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      0.0f : target_bounds->opacity;
777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS)
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTargetBoundsForGesture(target_bounds);
780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This needs to happen after calling UpdateTargetBoundsForGesture(), because
782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // that can change the size of the shelf.
783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  target_bounds->launcher_bounds_in_shelf = SelectValueForShelfAlignment(
784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gfx::Rect(base::i18n::IsRTL() ? status_size.width() : 0, 0,
785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    shelf_width - status_size.width(),
786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    target_bounds->shelf_bounds_in_root.height()),
78790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      gfx::Rect(0, 0, target_bounds->shelf_bounds_in_root.width(),
78890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                shelf_height - status_size.height()),
78990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      gfx::Rect(0, 0, target_bounds->shelf_bounds_in_root.width(),
79090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                shelf_height - status_size.height()),
791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gfx::Rect(base::i18n::IsRTL() ? status_size.width() : 0, 0,
792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    shelf_width - status_size.width(),
793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    target_bounds->shelf_bounds_in_root.height()));
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateTargetBoundsForGesture(
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TargetBounds* target_bounds) const {
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_EQ(GESTURE_DRAG_IN_PROGRESS, gesture_drag_status_);
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool horizontal = IsHorizontalAlignment();
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::Rect& available_bounds(root_window_->bounds());
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int resistance_free_region = 0;
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_HIDDEN &&
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      visibility_state() == SHELF_AUTO_HIDE &&
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_hide_state() != SHELF_AUTO_HIDE_SHOWN) {
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If the shelf was hidden when the drag started (and the state hasn't
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // changed since then, e.g. because the tray-menu was shown because of the
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // drag), then allow the drag some resistance-free region at first to make
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // sure the shelf sticks with the finger until the shelf is visible.
8107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    resistance_free_region = GetPreferredShelfSize() - kAutoHideSize;
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool resist = SelectValueForShelfAlignment(
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_ < -resistance_free_region,
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_ > resistance_free_region,
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_ < -resistance_free_region,
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_ > resistance_free_region);
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float translate = 0.f;
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (resist) {
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    float diff = fabsf(gesture_drag_amount_) - resistance_free_region;
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    diff = std::min(diff, sqrtf(diff));
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gesture_drag_amount_ < 0)
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      translate = -resistance_free_region - diff;
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      translate = resistance_free_region + diff;
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    translate = gesture_drag_amount_;
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (horizontal) {
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Move and size the launcher with the gesture.
833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int shelf_height = target_bounds->shelf_bounds_in_root.height() - translate;
834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shelf_height = std::max(shelf_height, kAutoHideSize);
835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    target_bounds->shelf_bounds_in_root.set_height(shelf_height);
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (alignment_ == SHELF_ALIGNMENT_BOTTOM) {
837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      target_bounds->shelf_bounds_in_root.set_y(
838c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          available_bounds.bottom() - shelf_height);
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The statusbar should be in the center of the shelf.
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect status_y = target_bounds->shelf_bounds_in_root;
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    status_y.set_y(0);
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    status_y.ClampToCenteredSize(
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        target_bounds->status_bounds_in_shelf.size());
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    target_bounds->status_bounds_in_shelf.set_y(status_y.y());
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Move and size the launcher with the gesture.
84990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    int shelf_width = target_bounds->shelf_bounds_in_root.width();
85090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (alignment_ == SHELF_ALIGNMENT_RIGHT)
85190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      shelf_width -= translate;
85290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    else
85390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      shelf_width += translate;
854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shelf_width = std::max(shelf_width, kAutoHideSize);
855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    target_bounds->shelf_bounds_in_root.set_width(shelf_width);
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (alignment_ == SHELF_ALIGNMENT_RIGHT) {
85790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      target_bounds->shelf_bounds_in_root.set_x(
858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          available_bounds.right() - shelf_width);
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The statusbar should be in the center of the shelf.
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect status_x = target_bounds->shelf_bounds_in_root;
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    status_x.set_x(0);
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    status_x.ClampToCenteredSize(
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        target_bounds->status_bounds_in_shelf.size());
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    target_bounds->status_bounds_in_shelf.set_x(status_x.x());
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateShelfBackground(
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BackgroundAnimator::ChangeType type) {
8727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  shelf_->SetPaintsBackground(GetShelfBackgroundType(), type);
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8757dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochShelfBackgroundType ShelfLayoutManager::GetShelfBackgroundType() const {
8767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (state_.visibility_state != SHELF_AUTO_HIDE &&
8777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      state_.window_state == WORKSPACE_WINDOW_STATE_MAXIMIZED) {
8787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return SHELF_BACKGROUND_MAXIMIZED;
8797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
8807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
8817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS ||
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (!state_.is_screen_locked && window_overlaps_shelf_) ||
8837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      (state_.visibility_state == SHELF_AUTO_HIDE)) {
8847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return SHELF_BACKGROUND_OVERLAP;
8857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
8867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
8877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return SHELF_BACKGROUND_DEFAULT;
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateAutoHideStateNow() {
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetState(state_.visibility_state);
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState(
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShelfVisibilityState visibility_state) const {
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (visibility_state != SHELF_AUTO_HIDE || !shelf_)
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_HIDDEN;
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS)
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return gesture_drag_auto_hide_state_;
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell* shell = Shell::GetInstance();
9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shell->GetAppListTargetVisibility())
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_->status_area_widget() &&
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->status_area_widget()->ShouldShowLauncher())
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_->launcher() && shelf_->launcher()->IsShowingMenu())
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_->launcher() && shelf_->launcher()->IsShowingOverflowBubble())
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_->IsActive() || shelf_->status_area_widget()->IsActive())
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't show if the user is dragging the mouse.
920868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (auto_hide_event_filter_.get() && auto_hide_event_filter_->in_mouse_drag())
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_HIDDEN;
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect shelf_region = shelf_->GetWindowBoundsInScreen();
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_->status_area_widget() &&
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->status_area_widget()->IsMessageBubbleShown() &&
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      IsVisible()) {
9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Increase the the hit test area to prevent the shelf from disappearing
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // when the mouse is over the bubble gap.
9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_region.Inset(alignment_ == SHELF_ALIGNMENT_RIGHT ?
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           -kNotificationBubbleGapHeight : 0,
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       alignment_ == SHELF_ALIGNMENT_BOTTOM ?
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           -kNotificationBubbleGapHeight : 0,
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       alignment_ == SHELF_ALIGNMENT_LEFT ?
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           -kNotificationBubbleGapHeight : 0,
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       alignment_ == SHELF_ALIGNMENT_TOP ?
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           -kNotificationBubbleGapHeight : 0);
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_region.Contains(Shell::GetScreen()->GetCursorScreenPoint()))
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::vector<aura::Window*> windows =
943a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ash::MruWindowTracker::BuildWindowList(false);
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Process the window list and check if there are any visible windows.
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < windows.size(); ++i) {
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (windows[i] && windows[i]->IsVisible() &&
948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        !ash::wm::IsWindowMinimized(windows[i]) &&
949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        root_window_ == windows[i]->GetRootWindow())
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return SHELF_AUTO_HIDE_HIDDEN;
9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If there are no visible windows do not hide the shelf.
9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SHELF_AUTO_HIDE_SHOWN;
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateHitTestBounds() {
958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Insets mouse_insets;
959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Insets touch_insets;
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state_.visibility_state == SHELF_VISIBLE) {
9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Let clicks at the very top of the launcher through so windows can be
9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // resized with the bottom-right corner and bottom edge.
963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    mouse_insets = GetInsetsForAlignment(kWorkspaceAreaVisibleInset);
964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (state_.visibility_state == SHELF_AUTO_HIDE) {
965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Extend the touch hit target out a bit to allow users to drag shelf out
966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // while hidden.
967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    touch_insets = GetInsetsForAlignment(-kWorkspaceAreaAutoHideInset);
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (shelf_ && shelf_->GetNativeWindow())
971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      shelf_->GetNativeWindow()->SetHitTestBoundsOverrideOuter(mouse_insets,
972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                               touch_insets);
973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shelf_->status_area_widget()->GetNativeWindow()->
974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        SetHitTestBoundsOverrideOuter(mouse_insets, touch_insets);
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShelfLayoutManager::IsShelfWindow(aura::Window* window) {
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!window)
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
98090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return (shelf_ && shelf_->GetNativeWindow()->Contains(window)) ||
98190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      (shelf_->status_area_widget() &&
98290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       shelf_->status_area_widget()->GetNativeWindow()->Contains(window));
9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int ShelfLayoutManager::GetWorkAreaSize(const State& state, int size) const {
9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state.visibility_state == SHELF_VISIBLE)
9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return size;
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state.visibility_state == SHELF_AUTO_HIDE)
9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kAutoHideSize;
9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
993c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Rect ShelfLayoutManager::GetAvailableBounds() const {
994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Rect bounds(root_window_->bounds());
995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bounds.set_height(bounds.height() - keyboard_bounds_.height());
996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return bounds;
997c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
999c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShelfLayoutManager::OnKeyboardBoundsChanging(
1000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const gfx::Rect& keyboard_bounds) {
1001c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  keyboard_bounds_ = keyboard_bounds;
1002c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  OnWindowResized();
1003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1005ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ShelfLayoutManager::OnDockBoundsChanging(
1006ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const gfx::Rect& dock_bounds) {
1007ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (dock_bounds_ != dock_bounds) {
1008ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    dock_bounds_ = dock_bounds;
1009ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    OnWindowResized();
1010ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
1011ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
1012ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
1013c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Insets ShelfLayoutManager::GetInsetsForAlignment(int distance) const {
1014c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch (alignment_) {
1015c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case SHELF_ALIGNMENT_BOTTOM:
1016c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return gfx::Insets(distance, 0, 0, 0);
1017c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case SHELF_ALIGNMENT_LEFT:
1018c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return gfx::Insets(0, 0, 0, distance);
1019c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case SHELF_ALIGNMENT_RIGHT:
1020c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return gfx::Insets(0, distance, 0, 0);
1021c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case SHELF_ALIGNMENT_TOP:
1022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return gfx::Insets(0, 0, distance, 0);
1023c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1024c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NOTREACHED();
1025c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return gfx::Insets();
1026c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1027c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace internal
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace ash
1030