shelf_layout_manager.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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)
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/accelerators/accelerator_commands.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/ash_switches.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/root_window_controller.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/screen_util.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/session_state_delegate.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shelf/shelf.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ash/shelf/shelf_bezel_event_filter.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shelf/shelf_constants.h"
21b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "ash/shelf/shelf_layout_manager_observer.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_widget.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shell.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shell_window_ids.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/status_area_widget.h"
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/wm/gestures/shelf_gesture_handler.h"
2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ash/wm/lock_state_controller.h"
28a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ash/wm/mru_window_tracker.h"
292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "ash/wm/window_animations.h"
3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/wm/window_state.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/window_util.h"
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ash/wm/workspace_controller.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/auto_reset.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h"
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/command_line.h"
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/i18n/rtl.h"
37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
39ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/aura/client/cursor_client.h"
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/base/ui_base_switches.h"
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/layer.h"
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/layer_animation_observer.h"
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/layer_animator.h"
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/compositor/scoped_layer_animation_settings.h"
46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h"
47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event_handler.h"
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/screen.h"
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/widget.h"
50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/wm/public/activation_client.h"
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ash {
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Delay before showing the shelf. 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)
63bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// The maximum size of the region on the display opposing the shelf managed by
64bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// this ShelfLayoutManager which can trigger showing the shelf.
65bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// For instance:
66bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// - Primary display is left of secondary display.
67bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// - Shelf is left aligned
68bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// - This ShelfLayoutManager manages the shelf for the secondary display.
69bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// |kMaxAutoHideShowShelfRegionSize| refers to the maximum size of the region
70bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// from the right edge of the primary display which can trigger showing the
71bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// auto hidden shelf. The region is used to make it easier to trigger showing
72bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// the auto hidden shelf when the shelf is on the boundary between displays.
73bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochconst int kMaxAutoHideShowShelfRegionSize = 10;
74bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ui::Layer* GetLayer(views::Widget* widget) {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return widget->GetNativeView()->layer();
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsDraggingTrayEnabled() {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static bool dragging_tray_allowed = CommandLine::ForCurrentProcess()->
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HasSwitch(ash::switches::kAshEnableTrayDragging);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return dragging_tray_allowed;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int ShelfLayoutManager::kWorkspaceAreaVisibleInset = 2;
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int ShelfLayoutManager::kWorkspaceAreaAutoHideInset = 5;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int ShelfLayoutManager::kAutoHideSize = 3;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// static
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const int ShelfLayoutManager::kShelfSize = 47;
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// static
100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)const int ShelfLayoutManager::kShelfItemInset = 3;
101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
102ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochint ShelfLayoutManager::GetPreferredShelfSize() {
103ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return ash::switches::UseAlternateShelfLayout() ?
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ShelfLayoutManager::kShelfSize : kShelfPreferredSize;
105ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
106ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager::AutoHideEventFilter -------------------------------------
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Notifies ShelfLayoutManager any time the mouse moves.
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ShelfLayoutManager::AutoHideEventFilter : public ui::EventHandler {
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit AutoHideEventFilter(ShelfLayoutManager* shelf);
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~AutoHideEventFilter();
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if the last mouse event was a mouse drag.
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool in_mouse_drag() const { return in_mouse_drag_; }
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from ui::EventHandler:
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE;
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShelfLayoutManager* shelf_;
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool in_mouse_drag_;
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ShelfGestureHandler gesture_handler_;
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AutoHideEventFilter);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::AutoHideEventFilter::AutoHideEventFilter(
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShelfLayoutManager* shelf)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : shelf_(shelf),
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      in_mouse_drag_(false) {
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->AddPreTargetHandler(this);
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::AutoHideEventFilter::~AutoHideEventFilter() {
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->RemovePreTargetHandler(this);
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::AutoHideEventFilter::OnMouseEvent(
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::MouseEvent* event) {
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This also checks IsShelfWindow() to make sure we don't attempt to hide the
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // shelf if the mouse down occurs on the shelf.
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_mouse_drag_ = (event->type() == ui::ET_MOUSE_DRAGGED ||
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    (in_mouse_drag_ && event->type() != ui::ET_MOUSE_RELEASED &&
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     event->type() != ui::ET_MOUSE_CAPTURE_CHANGED)) &&
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !shelf_->IsShelfWindow(static_cast<aura::Window*>(event->target()));
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (event->type() == ui::ET_MOUSE_MOVED)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_->UpdateAutoHideState();
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return;
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShelfLayoutManager::AutoHideEventFilter::OnGestureEvent(
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ui::GestureEvent* event) {
155a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (shelf_->IsShelfWindow(static_cast<aura::Window*>(event->target()))) {
156a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (gesture_handler_.ProcessGestureEvent(*event))
157a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      event->StopPropagation();
158a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager:UpdateShelfObserver --------------------------------------
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// UpdateShelfObserver is used to delay updating the background until the
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// animation completes.
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ShelfLayoutManager::UpdateShelfObserver
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public ui::ImplicitAnimationObserver {
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit UpdateShelfObserver(ShelfLayoutManager* shelf) : shelf_(shelf) {
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_->update_shelf_observer_ = this;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Detach() {
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_ = NULL;
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnImplicitAnimationsCompleted() OVERRIDE {
177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (shelf_)
178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      shelf_->UpdateShelfBackground(BACKGROUND_CHANGE_ANIMATE);
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete this;
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~UpdateShelfObserver() {
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (shelf_)
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->update_shelf_observer_ = NULL;
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Shelf we're in. NULL if deleted before we're deleted.
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShelfLayoutManager* shelf_;
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(UpdateShelfObserver);
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager ----------------------------------------------------------
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::ShelfLayoutManager(ShelfWidget* shelf)
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : root_window_(shelf->GetNativeView()->GetRootWindow()),
1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      updating_bounds_(false),
199effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      force_shelf_always_visibile_(
200effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          Shell::GetInstance()->IsMaximizeModeWindowManagerEnabled()),
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_hide_behavior_(SHELF_AUTO_HIDE_BEHAVIOR_NEVER),
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      alignment_(SHELF_ALIGNMENT_BOTTOM),
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_(shelf),
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      workspace_controller_(NULL),
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      window_overlaps_shelf_(false),
206bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      mouse_over_shelf_when_auto_hide_timer_started_(false),
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      bezel_event_filter_(new ShelfBezelEventFilter(this)),
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_status_(GESTURE_DRAG_NONE),
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_(0.f),
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_auto_hide_state_(SHELF_AUTO_HIDE_SHOWN),
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      update_shelf_observer_(NULL),
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      duration_override_in_ms_(0) {
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->AddShellObserver(this);
21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Shell::GetInstance()->lock_state_controller()->AddObserver(this);
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::client::GetActivationClient(root_window_)->AddObserver(this);
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::~ShelfLayoutManager() {
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (update_shelf_observer_)
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    update_shelf_observer_->Detach();
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_, WillDeleteShelf());
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->RemoveShellObserver(this);
22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Shell::GetInstance()->lock_state_controller()->RemoveObserver(this);
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::client::GetActivationClient(root_window_)->RemoveObserver(this);
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::SetAutoHideBehavior(ShelfAutoHideBehavior behavior) {
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (auto_hide_behavior_ == behavior)
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  auto_hide_behavior_ = behavior;
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateVisibilityState();
233b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_,
2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                    OnAutoHideBehaviorChanged(root_window_,
2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                              auto_hide_behavior_));
2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ShelfLayoutManager::PrepareForShutdown() {
2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Clear all event filters, otherwise sometimes those filters may catch
2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // synthesized mouse event and cause crashes during the shutdown.
2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  set_workspace_controller(NULL);
2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  auto_hide_event_filter_.reset();
2437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bezel_event_filter_.reset();
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShelfLayoutManager::IsVisible() const {
2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // status_area_widget() may be NULL during the shutdown.
2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return shelf_->status_area_widget() &&
2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      shelf_->status_area_widget()->IsVisible() &&
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (state_.visibility_state == SHELF_VISIBLE ||
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       (state_.visibility_state == SHELF_AUTO_HIDE &&
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        state_.auto_hide_state == SHELF_AUTO_HIDE_SHOWN));
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShelfLayoutManager::SetAlignment(ShelfAlignment alignment) {
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (alignment_ == alignment)
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // This should not be called during the lock screen transitions.
26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!Shell::GetInstance()->session_state_delegate()->IsScreenLocked());
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  alignment_ = alignment;
26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  shelf_->SetAlignment(alignment);
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayoutShelf();
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)ShelfAlignment ShelfLayoutManager::GetAlignment() const {
26858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // When the screen is locked, the shelf is forced into bottom alignment.
26958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (Shell::GetInstance()->session_state_delegate()->IsScreenLocked())
27058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return SHELF_ALIGNMENT_BOTTOM;
27158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return alignment_;
27258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
27358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Rect ShelfLayoutManager::GetIdealBounds() {
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect bounds(
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ScreenUtil::GetDisplayBoundsInParent(shelf_->GetNativeView()));
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int width = 0, height = 0;
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetShelfSize(&width, &height);
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SelectValueForShelfAlignment(
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(bounds.x(), bounds.bottom() - height, bounds.width(), height),
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(bounds.x(), bounds.y(), width, bounds.height()),
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(bounds.right() - width, bounds.y(), width, bounds.height()),
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(bounds.x(), bounds.y(), bounds.width(), height));
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::LayoutShelf() {
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TargetBounds target_bounds;
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalculateTargetBounds(state_, &target_bounds);
2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  UpdateBoundsAndOpacity(target_bounds, false, NULL);
2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (shelf_->shelf()) {
2923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // This is not part of UpdateBoundsAndOpacity() because
2938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // SetShelfViewBounds() sets the bounds immediately and does not animate.
2948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // The height of the ShelfView for a horizontal shelf and the width of
2958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // the ShelfView for a vertical shelf are set when |shelf_|'s bounds
2963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // are changed via UpdateBoundsAndOpacity(). This sets the origin and the
2973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // dimension in the other direction.
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    shelf_->shelf()->SetShelfViewBounds(
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        target_bounds.shelf_bounds_in_shelf);
3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfVisibilityState ShelfLayoutManager::CalculateShelfVisibility() {
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch(auto_hide_behavior_) {
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS:
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return SHELF_AUTO_HIDE;
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case SHELF_AUTO_HIDE_BEHAVIOR_NEVER:
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return SHELF_VISIBLE;
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case SHELF_AUTO_HIDE_ALWAYS_HIDDEN:
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return SHELF_HIDDEN;
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SHELF_VISIBLE;
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateVisibilityState() {
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Bail out early when there is no |workspace_controller_|, which happens
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // during shutdown after PrepareForShutdown.
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!workspace_controller_)
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
321effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (Shell::GetInstance()->session_state_delegate()->IsScreenLocked() ||
322effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      force_shelf_always_visibile_) {
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetState(SHELF_VISIBLE);
3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  } else {
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(zelidrag): Verify shelf drag animation still shows on the device
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // when we are in SHELF_AUTO_HIDE_ALWAYS_HIDDEN.
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WorkspaceWindowState window_state(workspace_controller_->GetWindowState());
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (window_state) {
329a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case WORKSPACE_WINDOW_STATE_FULL_SCREEN: {
330a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        const aura::Window* fullscreen_window = GetRootWindowController(
331a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            root_window_)->GetWindowForFullscreenMode();
332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        if (fullscreen_window && wm::GetWindowState(fullscreen_window)->
333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                hide_shelf_when_fullscreen()) {
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          SetState(SHELF_HIDDEN);
3351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        } else {
3361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          // The shelf is sometimes not hidden when in immersive fullscreen.
3371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          // Force the shelf to be auto hidden in this case.
3381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          SetState(SHELF_AUTO_HIDE);
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case WORKSPACE_WINDOW_STATE_MAXIMIZED:
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        SetState(CalculateShelfVisibility());
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
346a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF:
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case WORKSPACE_WINDOW_STATE_DEFAULT:
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        SetState(CalculateShelfVisibility());
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        SetWindowOverlapsShelf(window_state ==
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF);
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateAutoHideState() {
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShelfAutoHideState auto_hide_state =
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CalculateAutoHideState(state_.visibility_state);
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (auto_hide_state != state_.auto_hide_state) {
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (auto_hide_state == SHELF_AUTO_HIDE_HIDDEN) {
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Hides happen immediately.
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SetState(state_.visibility_state);
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
365bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      if (!auto_hide_timer_.IsRunning()) {
366bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        mouse_over_shelf_when_auto_hide_timer_started_ =
367bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch            shelf_->GetWindowBoundsInScreen().Contains(
368bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                Shell::GetScreen()->GetCursorScreenPoint());
369bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      }
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_hide_timer_.Start(
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          FROM_HERE,
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::TimeDelta::FromMilliseconds(kAutoHideDelayMS),
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this, &ShelfLayoutManager::UpdateAutoHideStateNow);
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
376bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    StopAutoHideTimer();
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::SetWindowOverlapsShelf(bool value) {
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_overlaps_shelf_ = value;
382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  UpdateShelfBackground(BACKGROUND_CHANGE_ANIMATE);
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
385b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ShelfLayoutManager::AddObserver(ShelfLayoutManagerObserver* observer) {
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.AddObserver(observer);
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
389b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ShelfLayoutManager::RemoveObserver(ShelfLayoutManagerObserver* observer) {
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.RemoveObserver(observer);
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ShelfLayoutManager, Gesture functions:
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ShelfLayoutManager::OnGestureEdgeSwipe(const ui::GestureEvent& gesture) {
397effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (force_shelf_always_visibile_)
398effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
399effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
40023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (visibility_state() == SHELF_AUTO_HIDE) {
40123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gesture_drag_auto_hide_state_ = SHELF_AUTO_HIDE_SHOWN;
40223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gesture_drag_status_ = GESTURE_DRAG_COMPLETE_IN_PROGRESS;
40323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    UpdateVisibilityState();
40423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gesture_drag_status_ = GESTURE_DRAG_NONE;
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::StartGestureDrag(const ui::GestureEvent& gesture) {
409effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (force_shelf_always_visibile_)
410effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_status_ = GESTURE_DRAG_IN_PROGRESS;
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_amount_ = 0.f;
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_auto_hide_state_ = visibility_state() == SHELF_AUTO_HIDE ?
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_hide_state() : SHELF_AUTO_HIDE_SHOWN;
415a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  UpdateShelfBackground(BACKGROUND_CHANGE_ANIMATE);
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::DragState ShelfLayoutManager::UpdateGestureDrag(
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ui::GestureEvent& gesture) {
420effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (force_shelf_always_visibile_)
421effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return DRAG_SHELF;
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool horizontal = IsHorizontalAlignment();
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_amount_ += horizontal ? gesture.details().scroll_y() :
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       gesture.details().scroll_x();
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayoutShelf();
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Start reveling the status menu when:
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   - dragging up on an already visible shelf
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   - dragging up on a hidden shelf, but it is currently completely visible.
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (horizontal && gesture.details().scroll_y() < 0) {
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int min_height = 0;
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_HIDDEN && shelf_)
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      min_height = shelf_->GetContentsView()->GetPreferredSize().height();
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (min_height < shelf_->GetWindowBoundsInScreen().height() &&
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gesture.root_location().x() >=
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        shelf_->status_area_widget()->GetWindowBoundsInScreen().x() &&
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IsDraggingTrayEnabled())
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return DRAG_TRAY;
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return DRAG_SHELF;
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::CompleteGestureDrag(const ui::GestureEvent& gesture) {
446effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (force_shelf_always_visibile_)
447effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool horizontal = IsHorizontalAlignment();
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool should_change = false;
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gesture.type() == ui::ET_GESTURE_SCROLL_END) {
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The visibility of the shelf changes only if the shelf was dragged X%
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // along the correct axis. If the shelf was already visible, then the
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // direction of the drag does not matter.
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const float kDragHideThreshold = 0.4f;
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect bounds = GetIdealBounds();
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    float drag_ratio = fabs(gesture_drag_amount_) /
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       (horizontal ?  bounds.height() : bounds.width());
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN) {
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      should_change = drag_ratio > kDragHideThreshold;
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool correct_direction = false;
46258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      switch (GetAlignment()) {
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case SHELF_ALIGNMENT_BOTTOM:
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case SHELF_ALIGNMENT_RIGHT:
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          correct_direction = gesture_drag_amount_ < 0;
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          break;
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case SHELF_ALIGNMENT_LEFT:
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case SHELF_ALIGNMENT_TOP:
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          correct_direction = gesture_drag_amount_ > 0;
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          break;
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      should_change = correct_direction && drag_ratio > kDragHideThreshold;
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (gesture.type() == ui::ET_SCROLL_FLING_START) {
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN) {
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      should_change = horizontal ? fabs(gesture.details().velocity_y()) > 0 :
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   fabs(gesture.details().velocity_x()) > 0;
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      should_change = SelectValueForShelfAlignment(
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gesture.details().velocity_y() < 0,
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gesture.details().velocity_x() > 0,
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gesture.details().velocity_x() < 0,
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gesture.details().velocity_y() > 0);
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!should_change) {
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CancelGestureDrag();
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
49390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (shelf_) {
49490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    shelf_->Deactivate();
49590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    shelf_->status_area_widget()->Deactivate();
49690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_auto_hide_state_ =
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN ?
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SHELF_AUTO_HIDE_HIDDEN : SHELF_AUTO_HIDE_SHOWN;
5007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ShelfAutoHideBehavior new_auto_hide_behavior =
5017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN ?
5027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      SHELF_AUTO_HIDE_BEHAVIOR_NEVER : SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS;
5037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // When in fullscreen and the shelf is forced to be auto hidden, the auto hide
5051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // behavior affects neither the visibility state nor the auto hide state. Set
5061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // |gesture_drag_status_| to GESTURE_DRAG_COMPLETE_IN_PROGRESS to set the auto
5071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // hide state to |gesture_drag_auto_hide_state_|.
5087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gesture_drag_status_ = GESTURE_DRAG_COMPLETE_IN_PROGRESS;
5097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (auto_hide_behavior_ != new_auto_hide_behavior)
5107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    SetAutoHideBehavior(new_auto_hide_behavior);
5117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  else
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateVisibilityState();
5137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gesture_drag_status_ = GESTURE_DRAG_NONE;
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::CancelGestureDrag() {
5173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  gesture_drag_status_ = GESTURE_DRAG_CANCEL_IN_PROGRESS;
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateVisibilityState();
5193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  gesture_drag_status_ = GESTURE_DRAG_NONE;
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ShelfLayoutManager::SetAnimationDurationOverride(
5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int duration_override_in_ms) {
5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  duration_override_in_ms_ = duration_override_in_ms;
5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager, aura::LayoutManager implementation:
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWindowResized() {
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayoutShelf();
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) {
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWindowRemovedFromLayout(aura::Window* child) {
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child,
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                        bool visible) {
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::SetChildBounds(aura::Window* child,
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        const gfx::Rect& requested_bounds) {
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetChildBoundsDirect(child, requested_bounds);
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We may contain other widgets (such as frame maximize bubble) but they don't
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // effect the layout in anyway.
5523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!updating_bounds_ &&
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ((shelf_->GetNativeView() == child) ||
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       (shelf_->status_area_widget()->GetNativeView() == child))) {
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayoutShelf();
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnLockStateChanged(bool locked) {
56058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Force the shelf to layout for alignment (bottom if locked, restore
56158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // the previous alignment otherwise).
562a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  state_.is_screen_locked = locked;
56358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  shelf_->SetAlignment(locked ? SHELF_ALIGNMENT_BOTTOM : alignment_);
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateVisibilityState();
56558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  LayoutShelf();
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
568effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ShelfLayoutManager::OnMaximizeModeStarted() {
569effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(!force_shelf_always_visibile_);
570effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  force_shelf_always_visibile_ = true;
571effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  UpdateVisibilityState();
572effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
573effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
574effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ShelfLayoutManager::OnMaximizeModeEnded() {
575effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(force_shelf_always_visibile_);
576effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Note: At this time Ash::Shell::IsMaximizeModeWindowManagerEnabled() will
577effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // report true, even though it is in progress of shut down. To address this
578effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // |force_shelf_always_visibile_| will be read.
579effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  force_shelf_always_visibile_ = false;
580effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  UpdateVisibilityState();
581effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
582effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWindowActivated(aura::Window* gained_active,
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           aura::Window* lost_active) {
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAutoHideStateNow();
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShelfLayoutManager::IsHorizontalAlignment() const {
58958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return GetAlignment() == SHELF_ALIGNMENT_BOTTOM ||
59058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)         GetAlignment() == SHELF_ALIGNMENT_TOP;
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ShelfLayoutManager* ShelfLayoutManager::ForShelf(aura::Window* window) {
5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ShelfWidget* shelf = RootWindowController::ForShelf(window)->shelf();
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return shelf ? shelf->shelf_layout_manager() : NULL;
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager, private:
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::TargetBounds::TargetBounds() : opacity(0.0f) {}
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::TargetBounds::~TargetBounds() {}
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) {
606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!shelf_->GetNativeView())
607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  State state;
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state.visibility_state = visibility_state;
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state.auto_hide_state = CalculateAutoHideState(visibility_state);
6127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  state.window_state = workspace_controller_ ?
6137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      workspace_controller_->GetWindowState() : WORKSPACE_WINDOW_STATE_DEFAULT;
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Force an update because gesture drags affect the shelf bounds and we
6163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // should animate back to the normal bounds at the end of a gesture.
6173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool force_update =
6183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      (gesture_drag_status_ == GESTURE_DRAG_CANCEL_IN_PROGRESS ||
6193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)       gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS);
6203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!force_update && state_.Equals(state))
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;  // Nothing changed.
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
624b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_,
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    WillChangeVisibilityState(visibility_state));
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state.visibility_state == SHELF_AUTO_HIDE) {
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // When state is SHELF_AUTO_HIDE we need to track when the mouse is over the
6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // shelf to unhide it. AutoHideEventFilter does that for us.
630868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!auto_hide_event_filter_)
631868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      auto_hide_event_filter_.reset(new AutoHideEventFilter(this));
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
633868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    auto_hide_event_filter_.reset(NULL);
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
636bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  StopAutoHideTimer();
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  State old_state = state_;
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_ = state;
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
641a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  BackgroundAnimatorChangeType change_type = BACKGROUND_CHANGE_ANIMATE;
642ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  bool delay_background_change = false;
643ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
644ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Do not animate the background when:
645ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // - Going from a hidden / auto hidden shelf in fullscreen to a visible shelf
646ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //   in maximized mode.
647ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // - Going from an auto hidden shelf in maximized mode to a visible shelf in
648ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //   maximized mode.
649ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (state.visibility_state == SHELF_VISIBLE &&
650ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      state.window_state == WORKSPACE_WINDOW_STATE_MAXIMIZED &&
651ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      old_state.visibility_state != SHELF_VISIBLE) {
652a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    change_type = BACKGROUND_CHANGE_IMMEDIATE;
653ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  } else {
654ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // Delay the animation when the shelf was hidden, and has just been made
655ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // visible (e.g. using a gesture-drag).
656ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (state.visibility_state == SHELF_VISIBLE &&
657ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        old_state.visibility_state == SHELF_AUTO_HIDE &&
658ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        old_state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN) {
659ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      delay_background_change = true;
660ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
661ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
662ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
663ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (delay_background_change) {
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (update_shelf_observer_)
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      update_shelf_observer_->Detach();
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // UpdateShelfBackground deletes itself when the animation is done.
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    update_shelf_observer_ = new UpdateShelfObserver(this);
668ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  } else {
669ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    UpdateShelfBackground(change_type);
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
671ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
672ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  shelf_->SetDimsShelf(
673ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      state.visibility_state == SHELF_VISIBLE &&
674ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      state.window_state == WORKSPACE_WINDOW_STATE_MAXIMIZED);
675ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
6763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TargetBounds target_bounds;
6773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CalculateTargetBounds(state_, &target_bounds);
6783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  UpdateBoundsAndOpacity(target_bounds, true,
6793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      delay_background_change ? update_shelf_observer_ : NULL);
680558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
681558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // OnAutoHideStateChanged Should be emitted when:
682558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  //  - firstly state changed to auto-hide from other state
683558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  //  - or, auto_hide_state has changed
684558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if ((old_state.visibility_state != state_.visibility_state &&
685558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch       state_.visibility_state == SHELF_AUTO_HIDE) ||
686558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      old_state.auto_hide_state != state_.auto_hide_state) {
687558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_,
688558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                      OnAutoHideStateChanged(state_.auto_hide_state));
689558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ShelfLayoutManager::UpdateBoundsAndOpacity(
6933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const TargetBounds& target_bounds,
6943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    bool animate,
6953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ui::ImplicitAnimationObserver* observer) {
6963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::AutoReset<bool> auto_reset_updating_bounds(&updating_bounds_, true);
6973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::ScopedLayerAnimationSettings shelf_animation_setter(
6993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      GetLayer(shelf_)->GetAnimator());
7003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ui::ScopedLayerAnimationSettings status_animation_setter(
7013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      GetLayer(shelf_->status_area_widget())->GetAnimator());
7023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (animate) {
7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int duration = duration_override_in_ms_ ? duration_override_in_ms_ :
7045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              kCrossFadeDurationMS;
7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    shelf_animation_setter.SetTransitionDuration(
7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::TimeDelta::FromMilliseconds(duration));
7075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    shelf_animation_setter.SetTweenType(gfx::Tween::EASE_OUT);
7085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    shelf_animation_setter.SetPreemptionStrategy(
7093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
7103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    status_animation_setter.SetTransitionDuration(
7115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::TimeDelta::FromMilliseconds(duration));
712d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    status_animation_setter.SetTweenType(gfx::Tween::EASE_OUT);
7133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    status_animation_setter.SetPreemptionStrategy(
7143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
7153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else {
7163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    StopAnimating();
7175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    shelf_animation_setter.SetTransitionDuration(base::TimeDelta());
7183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    status_animation_setter.SetTransitionDuration(base::TimeDelta());
7193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
7203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (observer)
7213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    status_animation_setter.AddObserver(observer);
7223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
7233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  GetLayer(shelf_)->SetOpacity(target_bounds.opacity);
7245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  shelf_->SetBounds(ScreenUtil::ConvertRectToScreen(
7253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)       shelf_->GetNativeView()->parent(),
7263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)       target_bounds.shelf_bounds_in_root));
7273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
7283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  GetLayer(shelf_->status_area_widget())->SetOpacity(
7293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      target_bounds.status_opacity);
7303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // TODO(harrym): Once status area widget is a child view of shelf
7313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // this can be simplified.
7323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  gfx::Rect status_bounds = target_bounds.status_bounds_in_shelf;
7333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  status_bounds.set_x(status_bounds.x() +
7343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                      target_bounds.shelf_bounds_in_root.x());
7353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  status_bounds.set_y(status_bounds.y() +
7363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                      target_bounds.shelf_bounds_in_root.y());
7373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  shelf_->status_area_widget()->SetBounds(
7385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ScreenUtil::ConvertRectToScreen(
7393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          shelf_->status_area_widget()->GetNativeView()->parent(),
7403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          status_bounds));
741c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SessionStateDelegate* session_state_delegate =
742c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      Shell::GetInstance()->session_state_delegate();
743c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!state_.is_screen_locked &&
744c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      (session_state_delegate->IsActiveUserSessionStarted() ||
745c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch       !keyboard_bounds_.IsEmpty())) {
746a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Shell::GetInstance()->SetDisplayWorkAreaInsets(
747a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        root_window_, target_bounds.work_area_insets);
748a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
7493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
7503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::StopAnimating() {
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetLayer(shelf_)->GetAnimator()->StopAnimating();
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetLayer(shelf_->status_area_widget())->GetAnimator()->StopAnimating();
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::GetShelfSize(int* width, int* height) {
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *width = *height = 0;
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size status_size(
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->status_area_widget()->GetWindowBoundsInScreen().size());
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsHorizontalAlignment())
7617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    *height = GetPreferredShelfSize();
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
7637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    *width = GetPreferredShelfSize();
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::AdjustBoundsBasedOnAlignment(int inset,
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                      gfx::Rect* bounds) const {
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bounds->Inset(SelectValueForShelfAlignment(
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, 0, inset, 0),
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, inset, 0, 0),
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, 0, 0, inset),
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(inset, 0, 0, 0)));
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::CalculateTargetBounds(
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const State& state,
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TargetBounds* target_bounds) {
778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const gfx::Rect available_bounds(GetAvailableBounds());
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect status_size(
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->status_area_widget()->GetWindowBoundsInScreen().size());
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shelf_width = 0, shelf_height = 0;
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetShelfSize(&shelf_width, &shelf_height);
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsHorizontalAlignment())
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_width = available_bounds.width();
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_height = available_bounds.height();
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state.visibility_state == SHELF_AUTO_HIDE &&
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN) {
790c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Auto-hidden shelf always starts with the default size. If a gesture-drag
791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // is in progress, then the call to UpdateTargetBoundsForGesture() below
792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // takes care of setting the height properly.
793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (IsHorizontalAlignment())
794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      shelf_height = kAutoHideSize;
795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    else
796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      shelf_width = kAutoHideSize;
797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (state.visibility_state == SHELF_HIDDEN ||
798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !keyboard_bounds_.IsEmpty()) {
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsHorizontalAlignment())
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_height = 0;
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_width = 0;
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_bounds->shelf_bounds_in_root = SelectValueForShelfAlignment(
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(available_bounds.x(), available_bounds.bottom() - shelf_height,
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    available_bounds.width(), shelf_height),
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(available_bounds.x(), available_bounds.y(),
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    shelf_width, available_bounds.height()),
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(available_bounds.right() - shelf_width, available_bounds.y(),
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    shelf_width, available_bounds.height()),
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(available_bounds.x(), available_bounds.y(),
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    available_bounds.width(), shelf_height));
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int status_inset = std::max(0, GetPreferredShelfSize() -
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PrimaryAxisValue(status_size.height(), status_size.width()));
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
818d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (ash::switches::UseAlternateShelfLayout()) {
819d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    status_inset = 0;
820d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (IsHorizontalAlignment())
821d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      status_size.set_height(kShelfSize);
822d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    else
823d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      status_size.set_width(kShelfSize);
824d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
825ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_bounds->status_bounds_in_shelf = SelectValueForShelfAlignment(
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(base::i18n::IsRTL() ? 0 : shelf_width - status_size.width(),
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    status_inset, status_size.width(), status_size.height()),
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(shelf_width - (status_size.width() + status_inset),
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    shelf_height - status_size.height(), status_size.width(),
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    status_size.height()),
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(status_inset, shelf_height - status_size.height(),
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    status_size.width(), status_size.height()),
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(base::i18n::IsRTL() ? 0 : shelf_width - status_size.width(),
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    shelf_height - (status_size.height() + status_inset),
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    status_size.width(), status_size.height()));
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_bounds->work_area_insets = SelectValueForShelfAlignment(
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, 0, GetWorkAreaSize(state, shelf_height), 0),
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, GetWorkAreaSize(state, shelf_width), 0, 0),
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, 0, 0, GetWorkAreaSize(state, shelf_width)),
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(GetWorkAreaSize(state, shelf_height), 0, 0, 0));
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
844ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // TODO(varkha): The functionality of managing insets for display areas
845ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // should probably be pushed to a separate component. This would simplify or
846ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // remove entirely the dependency on keyboard and dock.
847ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Also push in the work area inset for the keyboard if it is visible.
849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!keyboard_bounds_.IsEmpty()) {
850ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    gfx::Insets keyboard_insets(0, 0, keyboard_bounds_.height(), 0);
851ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    target_bounds->work_area_insets += keyboard_insets;
852ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
853ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
854ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Also push in the work area inset for the dock if it is visible.
855ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!dock_bounds_.IsEmpty()) {
856ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    gfx::Insets dock_insets(
857ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        0, (dock_bounds_.x() > 0 ? 0 : dock_bounds_.width()),
858ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        0, (dock_bounds_.x() > 0 ? dock_bounds_.width() : 0));
859ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    target_bounds->work_area_insets += dock_insets;
860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_bounds->opacity =
8637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      (gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS ||
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       state.visibility_state == SHELF_VISIBLE ||
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       state.visibility_state == SHELF_AUTO_HIDE) ? 1.0f : 0.0f;
866eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  target_bounds->status_opacity =
867eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      (state.visibility_state == SHELF_AUTO_HIDE &&
868ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch       state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN &&
869ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch       gesture_drag_status_ != GESTURE_DRAG_IN_PROGRESS) ?
870eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      0.0f : target_bounds->opacity;
871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS)
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTargetBoundsForGesture(target_bounds);
874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This needs to happen after calling UpdateTargetBoundsForGesture(), because
876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // that can change the size of the shelf.
8775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  target_bounds->shelf_bounds_in_shelf = SelectValueForShelfAlignment(
8788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      gfx::Rect(0, 0,
8798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                shelf_width - status_size.width(),
8808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                target_bounds->shelf_bounds_in_root.height()),
88190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      gfx::Rect(0, 0, target_bounds->shelf_bounds_in_root.width(),
88290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                shelf_height - status_size.height()),
88390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      gfx::Rect(0, 0, target_bounds->shelf_bounds_in_root.width(),
88490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                shelf_height - status_size.height()),
8858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      gfx::Rect(0, 0,
8868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                shelf_width - status_size.width(),
8878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                target_bounds->shelf_bounds_in_root.height()));
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateTargetBoundsForGesture(
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TargetBounds* target_bounds) const {
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_EQ(GESTURE_DRAG_IN_PROGRESS, gesture_drag_status_);
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool horizontal = IsHorizontalAlignment();
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::Rect& available_bounds(root_window_->bounds());
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int resistance_free_region = 0;
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_HIDDEN &&
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      visibility_state() == SHELF_AUTO_HIDE &&
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_hide_state() != SHELF_AUTO_HIDE_SHOWN) {
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If the shelf was hidden when the drag started (and the state hasn't
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // changed since then, e.g. because the tray-menu was shown because of the
9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // drag), then allow the drag some resistance-free region at first to make
9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // sure the shelf sticks with the finger until the shelf is visible.
9047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    resistance_free_region = GetPreferredShelfSize() - kAutoHideSize;
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool resist = SelectValueForShelfAlignment(
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_ < -resistance_free_region,
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_ > resistance_free_region,
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_ < -resistance_free_region,
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_ > resistance_free_region);
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float translate = 0.f;
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (resist) {
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    float diff = fabsf(gesture_drag_amount_) - resistance_free_region;
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    diff = std::min(diff, sqrtf(diff));
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gesture_drag_amount_ < 0)
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      translate = -resistance_free_region - diff;
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      translate = resistance_free_region + diff;
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    translate = gesture_drag_amount_;
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (horizontal) {
9265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Move and size the shelf with the gesture.
927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int shelf_height = target_bounds->shelf_bounds_in_root.height() - translate;
928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shelf_height = std::max(shelf_height, kAutoHideSize);
929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    target_bounds->shelf_bounds_in_root.set_height(shelf_height);
93058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (GetAlignment() == SHELF_ALIGNMENT_BOTTOM) {
931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      target_bounds->shelf_bounds_in_root.set_y(
932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          available_bounds.bottom() - shelf_height);
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
935ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (ash::switches::UseAlternateShelfLayout()) {
936d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      target_bounds->status_bounds_in_shelf.set_y(0);
937ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    } else {
938ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      // The statusbar should be in the center of the shelf.
939ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      gfx::Rect status_y = target_bounds->shelf_bounds_in_root;
940ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      status_y.set_y(0);
941ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      status_y.ClampToCenteredSize(
942ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          target_bounds->status_bounds_in_shelf.size());
943ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      target_bounds->status_bounds_in_shelf.set_y(status_y.y());
944ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
9465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Move and size the shelf with the gesture.
94790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    int shelf_width = target_bounds->shelf_bounds_in_root.width();
94858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool right_aligned = GetAlignment() == SHELF_ALIGNMENT_RIGHT;
94958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (right_aligned)
95090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      shelf_width -= translate;
95190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    else
95290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      shelf_width += translate;
953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shelf_width = std::max(shelf_width, kAutoHideSize);
954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    target_bounds->shelf_bounds_in_root.set_width(shelf_width);
95558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (right_aligned) {
95690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      target_bounds->shelf_bounds_in_root.set_x(
957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          available_bounds.right() - shelf_width);
9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
960ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (ash::switches::UseAlternateShelfLayout()) {
961d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      if (right_aligned)
962d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        target_bounds->status_bounds_in_shelf.set_x(0);
963d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      else
96458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        target_bounds->status_bounds_in_shelf.set_x(
965d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            target_bounds->shelf_bounds_in_root.width() -
966d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            kShelfSize);
967ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    } else {
968ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      // The statusbar should be in the center of the shelf.
969ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      gfx::Rect status_x = target_bounds->shelf_bounds_in_root;
970ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      status_x.set_x(0);
971ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      status_x.ClampToCenteredSize(
972ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          target_bounds->status_bounds_in_shelf.size());
973ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      target_bounds->status_bounds_in_shelf.set_x(status_x.x());
974ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateShelfBackground(
979a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    BackgroundAnimatorChangeType type) {
980a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const ShelfBackgroundType background_type(GetShelfBackgroundType());
981a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  shelf_->SetPaintsBackground(background_type, type);
982a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_,
983a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    OnBackgroundUpdated(background_type, type));
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9867dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochShelfBackgroundType ShelfLayoutManager::GetShelfBackgroundType() const {
9877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (state_.visibility_state != SHELF_AUTO_HIDE &&
9887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      state_.window_state == WORKSPACE_WINDOW_STATE_MAXIMIZED) {
9897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return SHELF_BACKGROUND_MAXIMIZED;
9907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
9917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
9927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS ||
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (!state_.is_screen_locked && window_overlaps_shelf_) ||
9947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      (state_.visibility_state == SHELF_AUTO_HIDE)) {
9957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return SHELF_BACKGROUND_OVERLAP;
9967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
9977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
9987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return SHELF_BACKGROUND_DEFAULT;
9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateAutoHideStateNow() {
10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetState(state_.visibility_state);
1003bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
1004bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // If the state did not change, the auto hide timer may still be running.
1005bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  StopAutoHideTimer();
1006bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
1007bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
1008bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid ShelfLayoutManager::StopAutoHideTimer() {
1009bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  auto_hide_timer_.Stop();
1010bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  mouse_over_shelf_when_auto_hide_timer_started_ = false;
1011bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
1012bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
1013bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochgfx::Rect ShelfLayoutManager::GetAutoHideShowShelfRegionInScreen() const {
1014bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  gfx::Rect shelf_bounds_in_screen = shelf_->GetWindowBoundsInScreen();
1015bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  gfx::Vector2d offset = SelectValueForShelfAlignment(
1016bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      gfx::Vector2d(0, shelf_bounds_in_screen.height()),
1017bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      gfx::Vector2d(-kMaxAutoHideShowShelfRegionSize, 0),
1018bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      gfx::Vector2d(shelf_bounds_in_screen.width(), 0),
1019bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      gfx::Vector2d(0, -kMaxAutoHideShowShelfRegionSize));
1020bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
1021bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  gfx::Rect show_shelf_region_in_screen = shelf_bounds_in_screen;
1022bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  show_shelf_region_in_screen += offset;
1023bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (IsHorizontalAlignment())
1024bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    show_shelf_region_in_screen.set_height(kMaxAutoHideShowShelfRegionSize);
1025bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  else
1026bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    show_shelf_region_in_screen.set_width(kMaxAutoHideShowShelfRegionSize);
1027bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
1028bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // TODO: Figure out if we need any special handling when the keyboard is
1029bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // visible.
1030bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return show_shelf_region_in_screen;
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState(
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShelfVisibilityState visibility_state) const {
1035effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (force_shelf_always_visibile_)
1036effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return SHELF_AUTO_HIDE_SHOWN;
1037effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (visibility_state != SHELF_AUTO_HIDE || !shelf_)
10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_HIDDEN;
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell* shell = Shell::GetInstance();
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shell->GetAppListTargetVisibility())
10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_->status_area_widget() &&
10465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      shelf_->status_area_widget()->ShouldShowShelf())
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (shelf_->shelf() && shelf_->shelf()->IsShowingMenu())
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (shelf_->shelf() && shelf_->shelf()->IsShowingOverflowBubble())
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_->IsActive() || shelf_->status_area_widget()->IsActive())
10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1058ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const std::vector<aura::Window*> windows =
1059ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      ash::MruWindowTracker::BuildWindowList(false);
1060ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1061ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Process the window list and check if there are any visible windows.
1062ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  bool visible_window = false;
1063ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  for (size_t i = 0; i < windows.size(); ++i) {
1064ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (windows[i] && windows[i]->IsVisible() &&
106568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        !wm::GetWindowState(windows[i])->IsMinimized() &&
1066ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        root_window_ == windows[i]->GetRootWindow()) {
1067ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      visible_window = true;
1068ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      break;
1069ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
1070ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
1071ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // If there are no visible windows do not hide the shelf.
1072ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (!visible_window)
1073ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return SHELF_AUTO_HIDE_SHOWN;
1074ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1075ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS)
1076ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return gesture_drag_auto_hide_state_;
1077ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't show if the user is dragging the mouse.
1079868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (auto_hide_event_filter_.get() && auto_hide_event_filter_->in_mouse_drag())
10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_HIDDEN;
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1082ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Ignore the mouse position if mouse events are disabled.
1083ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  aura::client::CursorClient* cursor_client = aura::client::GetCursorClient(
1084ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      shelf_->GetNativeWindow()->GetRootWindow());
1085ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (!cursor_client->IsMouseEventsEnabled())
1086ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return SHELF_AUTO_HIDE_HIDDEN;
1087ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect shelf_region = shelf_->GetWindowBoundsInScreen();
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_->status_area_widget() &&
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->status_area_widget()->IsMessageBubbleShown() &&
10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      IsVisible()) {
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Increase the the hit test area to prevent the shelf from disappearing
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // when the mouse is over the bubble gap.
109458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ShelfAlignment alignment = GetAlignment();
109558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    shelf_region.Inset(alignment == SHELF_ALIGNMENT_RIGHT ?
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           -kNotificationBubbleGapHeight : 0,
109758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       alignment == SHELF_ALIGNMENT_BOTTOM ?
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           -kNotificationBubbleGapHeight : 0,
109958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       alignment == SHELF_ALIGNMENT_LEFT ?
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           -kNotificationBubbleGapHeight : 0,
110158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       alignment == SHELF_ALIGNMENT_TOP ?
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           -kNotificationBubbleGapHeight : 0);
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1105bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  gfx::Point cursor_position_in_screen =
1106bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      Shell::GetScreen()->GetCursorScreenPoint();
1107bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (shelf_region.Contains(cursor_position_in_screen))
1108bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    return SHELF_AUTO_HIDE_SHOWN;
1109bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
1110bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // When the shelf is auto hidden and the shelf is on the boundary between two
1111bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // displays, it is hard to trigger showing the shelf. For instance, if a
1112bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // user's primary display is left of their secondary display, it is hard to
1113bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // unautohide a left aligned shelf on the secondary display.
1114bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // It is hard because:
1115bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // - It is hard to stop the cursor in the shelf "light bar" and not overshoot.
1116bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // - The cursor is warped to the other display if the cursor gets to the edge
1117bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  //   of the display.
1118bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Show the shelf if the cursor started on the shelf and the user overshot the
1119bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // shelf slightly to make it easier to show the shelf in this situation. We
1120bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // do not check |auto_hide_timer_|.IsRunning() because it returns false when
1121bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // the timer's task is running.
1122bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if ((state_.auto_hide_state == SHELF_AUTO_HIDE_SHOWN ||
1123bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch       mouse_over_shelf_when_auto_hide_timer_started_) &&
1124bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      GetAutoHideShowShelfRegionInScreen().Contains(
1125bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch          cursor_position_in_screen)) {
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
1127bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1129ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  return SHELF_AUTO_HIDE_HIDDEN;
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShelfLayoutManager::IsShelfWindow(aura::Window* window) {
11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!window)
11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
113590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return (shelf_ && shelf_->GetNativeWindow()->Contains(window)) ||
113690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      (shelf_->status_area_widget() &&
113790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       shelf_->status_area_widget()->GetNativeWindow()->Contains(window));
11382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int ShelfLayoutManager::GetWorkAreaSize(const State& state, int size) const {
11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state.visibility_state == SHELF_VISIBLE)
11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return size;
11432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state.visibility_state == SHELF_AUTO_HIDE)
11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kAutoHideSize;
11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Rect ShelfLayoutManager::GetAvailableBounds() const {
1149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Rect bounds(root_window_->bounds());
1150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bounds.set_height(bounds.height() - keyboard_bounds_.height());
1151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return bounds;
1152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ShelfLayoutManager::OnKeyboardBoundsChanging(const gfx::Rect& new_bounds) {
1155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  bool keyboard_is_about_to_hide = false;
1156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (new_bounds.IsEmpty() && !keyboard_bounds_.IsEmpty())
1157c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    keyboard_is_about_to_hide = true;
1158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  keyboard_bounds_ = new_bounds;
1160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  OnWindowResized();
1161c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SessionStateDelegate* session_state_delegate =
1163c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      Shell::GetInstance()->session_state_delegate();
1164c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1165c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // On login screen if keyboard has been just hidden, update bounds just once
1166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // but ignore target_bounds.work_area_insets since shelf overlaps with login
1167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // window.
1168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!session_state_delegate->IsActiveUserSessionStarted() &&
1169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      keyboard_is_about_to_hide) {
1170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Shell::GetInstance()->SetDisplayWorkAreaInsets(root_window_, gfx::Insets());
1171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
1172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1174ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ShelfLayoutManager::OnDockBoundsChanging(
11754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const gfx::Rect& dock_bounds,
11764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    DockedWindowLayoutManagerObserver::Reason reason) {
11774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Skip shelf layout in case docked notification originates from this class.
11784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (reason == DISPLAY_INSETS_CHANGED)
11794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
1180ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (dock_bounds_ != dock_bounds) {
1181ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    dock_bounds_ = dock_bounds;
1182ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    OnWindowResized();
11835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UpdateVisibilityState();
1184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    UpdateShelfBackground(BACKGROUND_CHANGE_ANIMATE);
1185ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
1186ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
1187ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
118858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void ShelfLayoutManager::OnLockStateEvent(LockStateObserver::EventType event) {
118958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (event == EVENT_LOCK_ANIMATION_STARTED) {
1190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Enter the screen locked state as the animation starts to prevent
1191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // layout changes as the screen locks.
1192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    state_.is_screen_locked = true;
119358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Hide the status area widget (using auto hide animation).
119458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::AutoReset<ShelfVisibilityState> state(&state_.visibility_state,
119558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                SHELF_HIDDEN);
119658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    TargetBounds target_bounds;
119758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    CalculateTargetBounds(state_, &target_bounds);
119858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    UpdateBoundsAndOpacity(target_bounds, true, NULL);
11995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UpdateVisibilityState();
120058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
120158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
120258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
12032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace ash
1204