shelf_layout_manager.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
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"
175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ash/session/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"
495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/keyboard/keyboard_util.h"
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/widget.h"
51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/wm/public/activation_client.h"
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ash {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Delay before showing the shelf. This is after the mouse stops moving.
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kAutoHideDelayMS = 200;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// To avoid hiding the shelf when the mouse transitions from a message bubble
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// into the shelf, the hit test area is enlarged by this amount of pixels to
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// keep the shelf from hiding.
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kNotificationBubbleGapHeight = 6;
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
64bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// The maximum size of the region on the display opposing the shelf managed by
65bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// this ShelfLayoutManager which can trigger showing the shelf.
66bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// For instance:
67bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// - Primary display is left of secondary display.
68bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// - Shelf is left aligned
69bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// - This ShelfLayoutManager manages the shelf for the secondary display.
70bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// |kMaxAutoHideShowShelfRegionSize| refers to the maximum size of the region
71bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// from the right edge of the primary display which can trigger showing the
72bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// auto hidden shelf. The region is used to make it easier to trigger showing
73bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// the auto hidden shelf when the shelf is on the boundary between displays.
74bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochconst int kMaxAutoHideShowShelfRegionSize = 10;
75bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ui::Layer* GetLayer(views::Widget* widget) {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return widget->GetNativeView()->layer();
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsDraggingTrayEnabled() {
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static bool dragging_tray_allowed = CommandLine::ForCurrentProcess()->
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HasSwitch(ash::switches::kAshEnableTrayDragging);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return dragging_tray_allowed;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int ShelfLayoutManager::kWorkspaceAreaVisibleInset = 2;
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int ShelfLayoutManager::kWorkspaceAreaAutoHideInset = 5;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int ShelfLayoutManager::kAutoHideSize = 3;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// static
98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)const int ShelfLayoutManager::kShelfItemInset = 3;
99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager::AutoHideEventFilter -------------------------------------
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Notifies ShelfLayoutManager any time the mouse moves.
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ShelfLayoutManager::AutoHideEventFilter : public ui::EventHandler {
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit AutoHideEventFilter(ShelfLayoutManager* shelf);
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~AutoHideEventFilter();
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if the last mouse event was a mouse drag.
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool in_mouse_drag() const { return in_mouse_drag_; }
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from ui::EventHandler:
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE;
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShelfLayoutManager* shelf_;
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool in_mouse_drag_;
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ShelfGestureHandler gesture_handler_;
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AutoHideEventFilter);
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::AutoHideEventFilter::AutoHideEventFilter(
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShelfLayoutManager* shelf)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : shelf_(shelf),
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      in_mouse_drag_(false) {
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->AddPreTargetHandler(this);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::AutoHideEventFilter::~AutoHideEventFilter() {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->RemovePreTargetHandler(this);
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::AutoHideEventFilter::OnMouseEvent(
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::MouseEvent* event) {
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This also checks IsShelfWindow() to make sure we don't attempt to hide the
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // shelf if the mouse down occurs on the shelf.
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_mouse_drag_ = (event->type() == ui::ET_MOUSE_DRAGGED ||
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    (in_mouse_drag_ && event->type() != ui::ET_MOUSE_RELEASED &&
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     event->type() != ui::ET_MOUSE_CAPTURE_CHANGED)) &&
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !shelf_->IsShelfWindow(static_cast<aura::Window*>(event->target()));
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (event->type() == ui::ET_MOUSE_MOVED)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_->UpdateAutoHideState();
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return;
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShelfLayoutManager::AutoHideEventFilter::OnGestureEvent(
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ui::GestureEvent* event) {
148a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (shelf_->IsShelfWindow(static_cast<aura::Window*>(event->target()))) {
149a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (gesture_handler_.ProcessGestureEvent(*event))
150a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      event->StopPropagation();
151a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager:UpdateShelfObserver --------------------------------------
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// UpdateShelfObserver is used to delay updating the background until the
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// animation completes.
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ShelfLayoutManager::UpdateShelfObserver
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public ui::ImplicitAnimationObserver {
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit UpdateShelfObserver(ShelfLayoutManager* shelf) : shelf_(shelf) {
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_->update_shelf_observer_ = this;
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Detach() {
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_ = NULL;
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnImplicitAnimationsCompleted() OVERRIDE {
170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (shelf_)
171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      shelf_->UpdateShelfBackground(BACKGROUND_CHANGE_ANIMATE);
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete this;
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~UpdateShelfObserver() {
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (shelf_)
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->update_shelf_observer_ = NULL;
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Shelf we're in. NULL if deleted before we're deleted.
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShelfLayoutManager* shelf_;
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(UpdateShelfObserver);
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager ----------------------------------------------------------
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::ShelfLayoutManager(ShelfWidget* shelf)
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : root_window_(shelf->GetNativeView()->GetRootWindow()),
1913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      updating_bounds_(false),
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_hide_behavior_(SHELF_AUTO_HIDE_BEHAVIOR_NEVER),
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      alignment_(SHELF_ALIGNMENT_BOTTOM),
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_(shelf),
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      workspace_controller_(NULL),
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      window_overlaps_shelf_(false),
197bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      mouse_over_shelf_when_auto_hide_timer_started_(false),
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      bezel_event_filter_(new ShelfBezelEventFilter(this)),
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_status_(GESTURE_DRAG_NONE),
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_(0.f),
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_auto_hide_state_(SHELF_AUTO_HIDE_SHOWN),
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      update_shelf_observer_(NULL),
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      duration_override_in_ms_(0) {
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->AddShellObserver(this);
20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Shell::GetInstance()->lock_state_controller()->AddObserver(this);
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::client::GetActivationClient(root_window_)->AddObserver(this);
207a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  Shell::GetInstance()->session_state_delegate()->AddSessionStateObserver(this);
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::~ShelfLayoutManager() {
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (update_shelf_observer_)
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    update_shelf_observer_->Detach();
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
214b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_, WillDeleteShelf());
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->RemoveShellObserver(this);
21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Shell::GetInstance()->lock_state_controller()->RemoveObserver(this);
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::client::GetActivationClient(root_window_)->RemoveObserver(this);
218a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  Shell::GetInstance()->
219a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      session_state_delegate()->RemoveSessionStateObserver(this);
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::SetAutoHideBehavior(ShelfAutoHideBehavior behavior) {
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (auto_hide_behavior_ == behavior)
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  auto_hide_behavior_ = behavior;
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateVisibilityState();
227b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_,
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                    OnAutoHideBehaviorChanged(root_window_,
2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                              auto_hide_behavior_));
2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ShelfLayoutManager::PrepareForShutdown() {
2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Clear all event filters, otherwise sometimes those filters may catch
2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // synthesized mouse event and cause crashes during the shutdown.
2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  set_workspace_controller(NULL);
2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  auto_hide_event_filter_.reset();
2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bezel_event_filter_.reset();
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShelfLayoutManager::IsVisible() const {
2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // status_area_widget() may be NULL during the shutdown.
2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return shelf_->status_area_widget() &&
2437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      shelf_->status_area_widget()->IsVisible() &&
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (state_.visibility_state == SHELF_VISIBLE ||
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       (state_.visibility_state == SHELF_AUTO_HIDE &&
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        state_.auto_hide_state == SHELF_AUTO_HIDE_SHOWN));
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShelfLayoutManager::SetAlignment(ShelfAlignment alignment) {
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (alignment_ == alignment)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
25358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // This should not be called during the lock screen transitions.
25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!Shell::GetInstance()->session_state_delegate()->IsScreenLocked());
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  alignment_ = alignment;
25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  shelf_->SetAlignment(alignment);
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayoutShelf();
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)ShelfAlignment ShelfLayoutManager::GetAlignment() const {
26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // When the screen is locked, the shelf is forced into bottom alignment.
26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (Shell::GetInstance()->session_state_delegate()->IsScreenLocked())
26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return SHELF_ALIGNMENT_BOTTOM;
26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return alignment_;
26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Rect ShelfLayoutManager::GetIdealBounds() {
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect bounds(
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ScreenUtil::GetDisplayBoundsInParent(shelf_->GetNativeView()));
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int width = 0, height = 0;
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetShelfSize(&width, &height);
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SelectValueForShelfAlignment(
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(bounds.x(), bounds.bottom() - height, bounds.width(), height),
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(bounds.x(), bounds.y(), width, bounds.height()),
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(bounds.right() - width, bounds.y(), width, bounds.height()),
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(bounds.x(), bounds.y(), bounds.width(), height));
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::LayoutShelf() {
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TargetBounds target_bounds;
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalculateTargetBounds(state_, &target_bounds);
2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  UpdateBoundsAndOpacity(target_bounds, false, NULL);
2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (shelf_->shelf()) {
2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // This is not part of UpdateBoundsAndOpacity() because
2878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // SetShelfViewBounds() sets the bounds immediately and does not animate.
2888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // The height of the ShelfView for a horizontal shelf and the width of
2898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // the ShelfView for a vertical shelf are set when |shelf_|'s bounds
2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // are changed via UpdateBoundsAndOpacity(). This sets the origin and the
2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // dimension in the other direction.
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    shelf_->shelf()->SetShelfViewBounds(
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        target_bounds.shelf_bounds_in_shelf);
2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfVisibilityState ShelfLayoutManager::CalculateShelfVisibility() {
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch(auto_hide_behavior_) {
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS:
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return SHELF_AUTO_HIDE;
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case SHELF_AUTO_HIDE_BEHAVIOR_NEVER:
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return SHELF_VISIBLE;
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case SHELF_AUTO_HIDE_ALWAYS_HIDDEN:
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return SHELF_HIDDEN;
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SHELF_VISIBLE;
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateVisibilityState() {
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Bail out early when there is no |workspace_controller_|, which happens
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // during shutdown after PrepareForShutdown.
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!workspace_controller_)
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
31546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (Shell::GetInstance()->session_state_delegate()->IsScreenLocked()) {
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetState(SHELF_VISIBLE);
3177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  } else {
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(zelidrag): Verify shelf drag animation still shows on the device
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // when we are in SHELF_AUTO_HIDE_ALWAYS_HIDDEN.
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WorkspaceWindowState window_state(workspace_controller_->GetWindowState());
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (window_state) {
322a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case WORKSPACE_WINDOW_STATE_FULL_SCREEN: {
323a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        const aura::Window* fullscreen_window = GetRootWindowController(
324a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            root_window_)->GetWindowForFullscreenMode();
325a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        if (fullscreen_window && wm::GetWindowState(fullscreen_window)->
326a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                hide_shelf_when_fullscreen()) {
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          SetState(SHELF_HIDDEN);
3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        } else {
3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          // The shelf is sometimes not hidden when in immersive fullscreen.
3301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          // Force the shelf to be auto hidden in this case.
3311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          SetState(SHELF_AUTO_HIDE);
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case WORKSPACE_WINDOW_STATE_MAXIMIZED:
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        SetState(CalculateShelfVisibility());
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
339a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF:
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case WORKSPACE_WINDOW_STATE_DEFAULT:
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        SetState(CalculateShelfVisibility());
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        SetWindowOverlapsShelf(window_state ==
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF);
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateAutoHideState() {
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShelfAutoHideState auto_hide_state =
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CalculateAutoHideState(state_.visibility_state);
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (auto_hide_state != state_.auto_hide_state) {
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (auto_hide_state == SHELF_AUTO_HIDE_HIDDEN) {
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Hides happen immediately.
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SetState(state_.visibility_state);
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
358bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      if (!auto_hide_timer_.IsRunning()) {
359bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        mouse_over_shelf_when_auto_hide_timer_started_ =
360bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch            shelf_->GetWindowBoundsInScreen().Contains(
361bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                Shell::GetScreen()->GetCursorScreenPoint());
362bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      }
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_hide_timer_.Start(
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          FROM_HERE,
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::TimeDelta::FromMilliseconds(kAutoHideDelayMS),
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this, &ShelfLayoutManager::UpdateAutoHideStateNow);
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
369bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    StopAutoHideTimer();
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::SetWindowOverlapsShelf(bool value) {
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_overlaps_shelf_ = value;
375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  UpdateShelfBackground(BACKGROUND_CHANGE_ANIMATE);
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
378b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ShelfLayoutManager::AddObserver(ShelfLayoutManagerObserver* observer) {
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.AddObserver(observer);
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ShelfLayoutManager::RemoveObserver(ShelfLayoutManagerObserver* observer) {
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.RemoveObserver(observer);
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ShelfLayoutManager, Gesture functions:
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ShelfLayoutManager::OnGestureEdgeSwipe(const ui::GestureEvent& gesture) {
39023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (visibility_state() == SHELF_AUTO_HIDE) {
39123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gesture_drag_auto_hide_state_ = SHELF_AUTO_HIDE_SHOWN;
39223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gesture_drag_status_ = GESTURE_DRAG_COMPLETE_IN_PROGRESS;
39323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    UpdateVisibilityState();
39423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gesture_drag_status_ = GESTURE_DRAG_NONE;
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::StartGestureDrag(const ui::GestureEvent& gesture) {
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_status_ = GESTURE_DRAG_IN_PROGRESS;
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_amount_ = 0.f;
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_auto_hide_state_ = visibility_state() == SHELF_AUTO_HIDE ?
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_hide_state() : SHELF_AUTO_HIDE_SHOWN;
403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  UpdateShelfBackground(BACKGROUND_CHANGE_ANIMATE);
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::DragState ShelfLayoutManager::UpdateGestureDrag(
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ui::GestureEvent& gesture) {
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool horizontal = IsHorizontalAlignment();
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_amount_ += horizontal ? gesture.details().scroll_y() :
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       gesture.details().scroll_x();
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayoutShelf();
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Start reveling the status menu when:
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   - dragging up on an already visible shelf
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   - dragging up on a hidden shelf, but it is currently completely visible.
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (horizontal && gesture.details().scroll_y() < 0) {
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int min_height = 0;
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_HIDDEN && shelf_)
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      min_height = shelf_->GetContentsView()->GetPreferredSize().height();
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (min_height < shelf_->GetWindowBoundsInScreen().height() &&
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gesture.root_location().x() >=
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        shelf_->status_area_widget()->GetWindowBoundsInScreen().x() &&
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        IsDraggingTrayEnabled())
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return DRAG_TRAY;
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return DRAG_SHELF;
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::CompleteGestureDrag(const ui::GestureEvent& gesture) {
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool horizontal = IsHorizontalAlignment();
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool should_change = false;
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gesture.type() == ui::ET_GESTURE_SCROLL_END) {
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The visibility of the shelf changes only if the shelf was dragged X%
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // along the correct axis. If the shelf was already visible, then the
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // direction of the drag does not matter.
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const float kDragHideThreshold = 0.4f;
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect bounds = GetIdealBounds();
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    float drag_ratio = fabs(gesture_drag_amount_) /
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       (horizontal ?  bounds.height() : bounds.width());
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN) {
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      should_change = drag_ratio > kDragHideThreshold;
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool correct_direction = false;
44658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      switch (GetAlignment()) {
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case SHELF_ALIGNMENT_BOTTOM:
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case SHELF_ALIGNMENT_RIGHT:
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          correct_direction = gesture_drag_amount_ < 0;
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          break;
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case SHELF_ALIGNMENT_LEFT:
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        case SHELF_ALIGNMENT_TOP:
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          correct_direction = gesture_drag_amount_ > 0;
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          break;
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      should_change = correct_direction && drag_ratio > kDragHideThreshold;
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (gesture.type() == ui::ET_SCROLL_FLING_START) {
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN) {
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      should_change = horizontal ? fabs(gesture.details().velocity_y()) > 0 :
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   fabs(gesture.details().velocity_x()) > 0;
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      should_change = SelectValueForShelfAlignment(
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gesture.details().velocity_y() < 0,
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gesture.details().velocity_x() > 0,
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gesture.details().velocity_x() < 0,
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gesture.details().velocity_y() > 0);
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!should_change) {
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CancelGestureDrag();
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
47790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (shelf_) {
47890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    shelf_->Deactivate();
47990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    shelf_->status_area_widget()->Deactivate();
48090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gesture_drag_auto_hide_state_ =
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN ?
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SHELF_AUTO_HIDE_HIDDEN : SHELF_AUTO_HIDE_SHOWN;
4847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ShelfAutoHideBehavior new_auto_hide_behavior =
4857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_SHOWN ?
4867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      SHELF_AUTO_HIDE_BEHAVIOR_NEVER : SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS;
4877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // When in fullscreen and the shelf is forced to be auto hidden, the auto hide
4891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // behavior affects neither the visibility state nor the auto hide state. Set
4901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // |gesture_drag_status_| to GESTURE_DRAG_COMPLETE_IN_PROGRESS to set the auto
4911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // hide state to |gesture_drag_auto_hide_state_|.
4927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gesture_drag_status_ = GESTURE_DRAG_COMPLETE_IN_PROGRESS;
4937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (auto_hide_behavior_ != new_auto_hide_behavior)
4947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    SetAutoHideBehavior(new_auto_hide_behavior);
4957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  else
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateVisibilityState();
4977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gesture_drag_status_ = GESTURE_DRAG_NONE;
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::CancelGestureDrag() {
5013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  gesture_drag_status_ = GESTURE_DRAG_CANCEL_IN_PROGRESS;
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateVisibilityState();
5033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  gesture_drag_status_ = GESTURE_DRAG_NONE;
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ShelfLayoutManager::SetAnimationDurationOverride(
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int duration_override_in_ms) {
5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  duration_override_in_ms_ = duration_override_in_ms;
5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager, aura::LayoutManager implementation:
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWindowResized() {
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayoutShelf();
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) {
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWindowRemovedFromLayout(aura::Window* child) {
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child,
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                        bool visible) {
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::SetChildBounds(aura::Window* child,
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        const gfx::Rect& requested_bounds) {
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetChildBoundsDirect(child, requested_bounds);
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We may contain other widgets (such as frame maximize bubble) but they don't
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // effect the layout in anyway.
5363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!updating_bounds_ &&
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ((shelf_->GetNativeView() == child) ||
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       (shelf_->status_area_widget()->GetNativeView() == child))) {
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayoutShelf();
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnLockStateChanged(bool locked) {
54458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Force the shelf to layout for alignment (bottom if locked, restore
54558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // the previous alignment otherwise).
546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  state_.is_screen_locked = locked;
54758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  shelf_->SetAlignment(locked ? SHELF_ALIGNMENT_BOTTOM : alignment_);
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateVisibilityState();
54958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  LayoutShelf();
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ShelfLayoutManager::OnMaximizeModeStarted() {
55346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
554effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
555effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::OnWindowActivated(aura::Window* gained_active,
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           aura::Window* lost_active) {
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAutoHideStateNow();
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShelfLayoutManager::IsHorizontalAlignment() const {
56258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return GetAlignment() == SHELF_ALIGNMENT_BOTTOM ||
56358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)         GetAlignment() == SHELF_ALIGNMENT_TOP;
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ShelfLayoutManager* ShelfLayoutManager::ForShelf(aura::Window* window) {
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ShelfWidget* shelf = RootWindowController::ForShelf(window)->shelf();
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return shelf ? shelf->shelf_layout_manager() : NULL;
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ShelfLayoutManager, private:
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::TargetBounds::TargetBounds() : opacity(0.0f) {}
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfLayoutManager::TargetBounds::~TargetBounds() {}
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) {
579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!shelf_->GetNativeView())
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  State state;
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state.visibility_state = visibility_state;
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state.auto_hide_state = CalculateAutoHideState(visibility_state);
5857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  state.window_state = workspace_controller_ ?
5867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      workspace_controller_->GetWindowState() : WORKSPACE_WINDOW_STATE_DEFAULT;
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Force an update because gesture drags affect the shelf bounds and we
5893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // should animate back to the normal bounds at the end of a gesture.
5903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool force_update =
5913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      (gesture_drag_status_ == GESTURE_DRAG_CANCEL_IN_PROGRESS ||
5923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)       gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS);
5933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!force_update && state_.Equals(state))
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;  // Nothing changed.
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
597b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_,
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    WillChangeVisibilityState(visibility_state));
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state.visibility_state == SHELF_AUTO_HIDE) {
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // When state is SHELF_AUTO_HIDE we need to track when the mouse is over the
6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // shelf to unhide it. AutoHideEventFilter does that for us.
603868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!auto_hide_event_filter_)
604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      auto_hide_event_filter_.reset(new AutoHideEventFilter(this));
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    auto_hide_event_filter_.reset(NULL);
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
609bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  StopAutoHideTimer();
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  State old_state = state_;
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_ = state;
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
614a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  BackgroundAnimatorChangeType change_type = BACKGROUND_CHANGE_ANIMATE;
615ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  bool delay_background_change = false;
616ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
617ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Do not animate the background when:
618ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // - Going from a hidden / auto hidden shelf in fullscreen to a visible shelf
619ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //   in maximized mode.
620ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // - Going from an auto hidden shelf in maximized mode to a visible shelf in
621ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //   maximized mode.
622ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (state.visibility_state == SHELF_VISIBLE &&
623ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      state.window_state == WORKSPACE_WINDOW_STATE_MAXIMIZED &&
624ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      old_state.visibility_state != SHELF_VISIBLE) {
625a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    change_type = BACKGROUND_CHANGE_IMMEDIATE;
626ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  } else {
627ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // Delay the animation when the shelf was hidden, and has just been made
628ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // visible (e.g. using a gesture-drag).
629ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (state.visibility_state == SHELF_VISIBLE &&
630ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        old_state.visibility_state == SHELF_AUTO_HIDE &&
631ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        old_state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN) {
632ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      delay_background_change = true;
633ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
634ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
635ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
636ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (delay_background_change) {
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (update_shelf_observer_)
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      update_shelf_observer_->Detach();
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // UpdateShelfBackground deletes itself when the animation is done.
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    update_shelf_observer_ = new UpdateShelfObserver(this);
641ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  } else {
642ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    UpdateShelfBackground(change_type);
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
644ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
645ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  shelf_->SetDimsShelf(
646ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      state.visibility_state == SHELF_VISIBLE &&
647ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      state.window_state == WORKSPACE_WINDOW_STATE_MAXIMIZED);
648ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
6493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TargetBounds target_bounds;
6503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CalculateTargetBounds(state_, &target_bounds);
6513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  UpdateBoundsAndOpacity(target_bounds, true,
6523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      delay_background_change ? update_shelf_observer_ : NULL);
653558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
654558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // OnAutoHideStateChanged Should be emitted when:
655558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  //  - firstly state changed to auto-hide from other state
656558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  //  - or, auto_hide_state has changed
657558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if ((old_state.visibility_state != state_.visibility_state &&
658558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch       state_.visibility_state == SHELF_AUTO_HIDE) ||
659558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      old_state.auto_hide_state != state_.auto_hide_state) {
660558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_,
661558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                      OnAutoHideStateChanged(state_.auto_hide_state));
662558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ShelfLayoutManager::UpdateBoundsAndOpacity(
6663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const TargetBounds& target_bounds,
6673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    bool animate,
6683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ui::ImplicitAnimationObserver* observer) {
6693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::AutoReset<bool> auto_reset_updating_bounds(&updating_bounds_, true);
6703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::ScopedLayerAnimationSettings shelf_animation_setter(
6723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      GetLayer(shelf_)->GetAnimator());
6733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ui::ScopedLayerAnimationSettings status_animation_setter(
6743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      GetLayer(shelf_->status_area_widget())->GetAnimator());
6753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (animate) {
6765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int duration = duration_override_in_ms_ ? duration_override_in_ms_ :
6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              kCrossFadeDurationMS;
6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    shelf_animation_setter.SetTransitionDuration(
6795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::TimeDelta::FromMilliseconds(duration));
6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    shelf_animation_setter.SetTweenType(gfx::Tween::EASE_OUT);
6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    shelf_animation_setter.SetPreemptionStrategy(
6823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
6833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    status_animation_setter.SetTransitionDuration(
6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::TimeDelta::FromMilliseconds(duration));
685d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    status_animation_setter.SetTweenType(gfx::Tween::EASE_OUT);
6863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    status_animation_setter.SetPreemptionStrategy(
6873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
6883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else {
6893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    StopAnimating();
6905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    shelf_animation_setter.SetTransitionDuration(base::TimeDelta());
6913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    status_animation_setter.SetTransitionDuration(base::TimeDelta());
6923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
6933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (observer)
6943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    status_animation_setter.AddObserver(observer);
6953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  GetLayer(shelf_)->SetOpacity(target_bounds.opacity);
6975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  shelf_->SetBounds(ScreenUtil::ConvertRectToScreen(
6983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)       shelf_->GetNativeView()->parent(),
6993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)       target_bounds.shelf_bounds_in_root));
7003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
7013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  GetLayer(shelf_->status_area_widget())->SetOpacity(
7023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      target_bounds.status_opacity);
703cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
704cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Having a window which is visible but does not have an opacity is an illegal
705cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // state. We therefore show / hide the shelf here if required.
706cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!target_bounds.status_opacity)
707cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    shelf_->status_area_widget()->Hide();
708cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  else if (target_bounds.status_opacity)
709cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    shelf_->status_area_widget()->Show();
710cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
7113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // TODO(harrym): Once status area widget is a child view of shelf
7123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // this can be simplified.
7133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  gfx::Rect status_bounds = target_bounds.status_bounds_in_shelf;
7143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  status_bounds.set_x(status_bounds.x() +
7153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                      target_bounds.shelf_bounds_in_root.x());
7163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  status_bounds.set_y(status_bounds.y() +
7173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                      target_bounds.shelf_bounds_in_root.y());
7183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  shelf_->status_area_widget()->SetBounds(
7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ScreenUtil::ConvertRectToScreen(
7203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          shelf_->status_area_widget()->GetNativeView()->parent(),
7213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          status_bounds));
722c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SessionStateDelegate* session_state_delegate =
723c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      Shell::GetInstance()->session_state_delegate();
724a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!state_.is_screen_locked) {
725a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    gfx::Insets insets;
726a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // If user session is blocked (login to new user session or add user to
727a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // the existing session - multi-profile) then give 100% of work area only if
728a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // keyboard is not shown.
729a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (!session_state_delegate->IsUserSessionBlocked() ||
730a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        !keyboard_bounds_.IsEmpty()) {
731a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      insets = target_bounds.work_area_insets;
732a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    }
733a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    Shell::GetInstance()->SetDisplayWorkAreaInsets(root_window_, insets);
734a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
7353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
7363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::StopAnimating() {
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetLayer(shelf_)->GetAnimator()->StopAnimating();
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetLayer(shelf_->status_area_widget())->GetAnimator()->StopAnimating();
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::GetShelfSize(int* width, int* height) {
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *width = *height = 0;
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size status_size(
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->status_area_widget()->GetWindowBoundsInScreen().size());
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsHorizontalAlignment())
747a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    *height = kShelfSize;
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
749a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    *width = kShelfSize;
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::AdjustBoundsBasedOnAlignment(int inset,
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                      gfx::Rect* bounds) const {
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bounds->Inset(SelectValueForShelfAlignment(
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, 0, inset, 0),
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, inset, 0, 0),
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, 0, 0, inset),
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(inset, 0, 0, 0)));
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::CalculateTargetBounds(
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const State& state,
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TargetBounds* target_bounds) {
7645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  const gfx::Rect available_bounds(root_window_->bounds());
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect status_size(
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->status_area_widget()->GetWindowBoundsInScreen().size());
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int shelf_width = 0, shelf_height = 0;
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetShelfSize(&shelf_width, &shelf_height);
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsHorizontalAlignment())
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_width = available_bounds.width();
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shelf_height = available_bounds.height();
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state.visibility_state == SHELF_AUTO_HIDE &&
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN) {
776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Auto-hidden shelf always starts with the default size. If a gesture-drag
777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // is in progress, then the call to UpdateTargetBoundsForGesture() below
778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // takes care of setting the height properly.
779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (IsHorizontalAlignment())
780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      shelf_height = kAutoHideSize;
781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    else
782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      shelf_width = kAutoHideSize;
783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (state.visibility_state == SHELF_HIDDEN ||
7845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      (!keyboard_bounds_.IsEmpty() && !keyboard::IsKeyboardOverscrollEnabled()))
7855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  {
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsHorizontalAlignment())
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_height = 0;
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_width = 0;
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int bottom_shelf_vertical_offset = available_bounds.bottom();
7935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (keyboard_bounds_.IsEmpty())
7945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    bottom_shelf_vertical_offset -= shelf_height;
7955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  else
7965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    bottom_shelf_vertical_offset -= keyboard_bounds_.height();
7975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_bounds->shelf_bounds_in_root = SelectValueForShelfAlignment(
7995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      gfx::Rect(available_bounds.x(), bottom_shelf_vertical_offset,
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    available_bounds.width(), shelf_height),
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(available_bounds.x(), available_bounds.y(),
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    shelf_width, available_bounds.height()),
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(available_bounds.right() - shelf_width, available_bounds.y(),
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    shelf_width, available_bounds.height()),
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(available_bounds.x(), available_bounds.y(),
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    available_bounds.width(), shelf_height));
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
808a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (IsHorizontalAlignment())
809a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    status_size.set_height(kShelfSize);
810a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  else
811a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    status_size.set_width(kShelfSize);
812ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_bounds->status_bounds_in_shelf = SelectValueForShelfAlignment(
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(base::i18n::IsRTL() ? 0 : shelf_width - status_size.width(),
815a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                    0, status_size.width(), status_size.height()),
816a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      gfx::Rect(shelf_width - status_size.width(),
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    shelf_height - status_size.height(), status_size.width(),
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    status_size.height()),
819a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      gfx::Rect(0, shelf_height - status_size.height(),
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    status_size.width(), status_size.height()),
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(base::i18n::IsRTL() ? 0 : shelf_width - status_size.width(),
822a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                    shelf_height - status_size.height(),
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    status_size.width(), status_size.height()));
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_bounds->work_area_insets = SelectValueForShelfAlignment(
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, 0, GetWorkAreaSize(state, shelf_height), 0),
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, GetWorkAreaSize(state, shelf_width), 0, 0),
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(0, 0, 0, GetWorkAreaSize(state, shelf_width)),
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets(GetWorkAreaSize(state, shelf_height), 0, 0, 0));
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
831ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // TODO(varkha): The functionality of managing insets for display areas
832ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // should probably be pushed to a separate component. This would simplify or
833ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // remove entirely the dependency on keyboard and dock.
834ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
8355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!keyboard_bounds_.IsEmpty() && !keyboard::IsKeyboardOverscrollEnabled()) {
8365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Also push in the work area inset for the keyboard if it is visible.
837ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    gfx::Insets keyboard_insets(0, 0, keyboard_bounds_.height(), 0);
838ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    target_bounds->work_area_insets += keyboard_insets;
839ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
840ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
841ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Also push in the work area inset for the dock if it is visible.
842ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!dock_bounds_.IsEmpty()) {
843ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    gfx::Insets dock_insets(
844ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        0, (dock_bounds_.x() > 0 ? 0 : dock_bounds_.width()),
845ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        0, (dock_bounds_.x() > 0 ? dock_bounds_.width() : 0));
846ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    target_bounds->work_area_insets += dock_insets;
847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target_bounds->opacity =
8507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      (gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS ||
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       state.visibility_state == SHELF_VISIBLE ||
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       state.visibility_state == SHELF_AUTO_HIDE) ? 1.0f : 0.0f;
853eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  target_bounds->status_opacity =
854eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      (state.visibility_state == SHELF_AUTO_HIDE &&
855ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch       state.auto_hide_state == SHELF_AUTO_HIDE_HIDDEN &&
856ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch       gesture_drag_status_ != GESTURE_DRAG_IN_PROGRESS) ?
857eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      0.0f : target_bounds->opacity;
858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS)
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTargetBoundsForGesture(target_bounds);
861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This needs to happen after calling UpdateTargetBoundsForGesture(), because
863c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // that can change the size of the shelf.
8645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  target_bounds->shelf_bounds_in_shelf = SelectValueForShelfAlignment(
8658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      gfx::Rect(0, 0,
8668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                shelf_width - status_size.width(),
8678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                target_bounds->shelf_bounds_in_root.height()),
86890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      gfx::Rect(0, 0, target_bounds->shelf_bounds_in_root.width(),
86990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                shelf_height - status_size.height()),
87090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      gfx::Rect(0, 0, target_bounds->shelf_bounds_in_root.width(),
87190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                shelf_height - status_size.height()),
8728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      gfx::Rect(0, 0,
8738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                shelf_width - status_size.width(),
8748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                target_bounds->shelf_bounds_in_root.height()));
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateTargetBoundsForGesture(
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TargetBounds* target_bounds) const {
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_EQ(GESTURE_DRAG_IN_PROGRESS, gesture_drag_status_);
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool horizontal = IsHorizontalAlignment();
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::Rect& available_bounds(root_window_->bounds());
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int resistance_free_region = 0;
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gesture_drag_auto_hide_state_ == SHELF_AUTO_HIDE_HIDDEN &&
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      visibility_state() == SHELF_AUTO_HIDE &&
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_hide_state() != SHELF_AUTO_HIDE_SHOWN) {
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If the shelf was hidden when the drag started (and the state hasn't
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // changed since then, e.g. because the tray-menu was shown because of the
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // drag), then allow the drag some resistance-free region at first to make
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // sure the shelf sticks with the finger until the shelf is visible.
891a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    resistance_free_region = kShelfSize - kAutoHideSize;
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool resist = SelectValueForShelfAlignment(
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_ < -resistance_free_region,
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_ > resistance_free_region,
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_ < -resistance_free_region,
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gesture_drag_amount_ > resistance_free_region);
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float translate = 0.f;
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (resist) {
9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    float diff = fabsf(gesture_drag_amount_) - resistance_free_region;
9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    diff = std::min(diff, sqrtf(diff));
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gesture_drag_amount_ < 0)
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      translate = -resistance_free_region - diff;
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      translate = resistance_free_region + diff;
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    translate = gesture_drag_amount_;
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (horizontal) {
9135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Move and size the shelf with the gesture.
914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int shelf_height = target_bounds->shelf_bounds_in_root.height() - translate;
915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shelf_height = std::max(shelf_height, kAutoHideSize);
916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    target_bounds->shelf_bounds_in_root.set_height(shelf_height);
91758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (GetAlignment() == SHELF_ALIGNMENT_BOTTOM) {
918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      target_bounds->shelf_bounds_in_root.set_y(
919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          available_bounds.bottom() - shelf_height);
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    target_bounds->status_bounds_in_shelf.set_y(0);
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
9245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Move and size the shelf with the gesture.
92590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    int shelf_width = target_bounds->shelf_bounds_in_root.width();
92658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool right_aligned = GetAlignment() == SHELF_ALIGNMENT_RIGHT;
92758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (right_aligned)
92890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      shelf_width -= translate;
92990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    else
93090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      shelf_width += translate;
931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shelf_width = std::max(shelf_width, kAutoHideSize);
932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    target_bounds->shelf_bounds_in_root.set_width(shelf_width);
93358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (right_aligned) {
93490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      target_bounds->shelf_bounds_in_root.set_x(
935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          available_bounds.right() - shelf_width);
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
938a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (right_aligned)
939a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      target_bounds->status_bounds_in_shelf.set_x(0);
940a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    else
941a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      target_bounds->status_bounds_in_shelf.set_x(
942a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          target_bounds->shelf_bounds_in_root.width() -
943a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          kShelfSize);
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateShelfBackground(
948a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    BackgroundAnimatorChangeType type) {
949a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const ShelfBackgroundType background_type(GetShelfBackgroundType());
950a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  shelf_->SetPaintsBackground(background_type, type);
951a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_,
952a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                    OnBackgroundUpdated(background_type, type));
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9557dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochShelfBackgroundType ShelfLayoutManager::GetShelfBackgroundType() const {
9567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (state_.visibility_state != SHELF_AUTO_HIDE &&
9577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      state_.window_state == WORKSPACE_WINDOW_STATE_MAXIMIZED) {
9587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return SHELF_BACKGROUND_MAXIMIZED;
9597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
9607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
9617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (gesture_drag_status_ == GESTURE_DRAG_IN_PROGRESS ||
9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (!state_.is_screen_locked && window_overlaps_shelf_) ||
9637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      (state_.visibility_state == SHELF_AUTO_HIDE)) {
9647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return SHELF_BACKGROUND_OVERLAP;
9657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
9667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
9677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return SHELF_BACKGROUND_DEFAULT;
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShelfLayoutManager::UpdateAutoHideStateNow() {
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetState(state_.visibility_state);
972bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
973bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // If the state did not change, the auto hide timer may still be running.
974bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  StopAutoHideTimer();
975bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
976bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
977bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid ShelfLayoutManager::StopAutoHideTimer() {
978bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  auto_hide_timer_.Stop();
979bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  mouse_over_shelf_when_auto_hide_timer_started_ = false;
980bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
981bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
982bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochgfx::Rect ShelfLayoutManager::GetAutoHideShowShelfRegionInScreen() const {
983bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  gfx::Rect shelf_bounds_in_screen = shelf_->GetWindowBoundsInScreen();
984bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  gfx::Vector2d offset = SelectValueForShelfAlignment(
985bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      gfx::Vector2d(0, shelf_bounds_in_screen.height()),
986bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      gfx::Vector2d(-kMaxAutoHideShowShelfRegionSize, 0),
987bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      gfx::Vector2d(shelf_bounds_in_screen.width(), 0),
988bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      gfx::Vector2d(0, -kMaxAutoHideShowShelfRegionSize));
989bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
990bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  gfx::Rect show_shelf_region_in_screen = shelf_bounds_in_screen;
991bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  show_shelf_region_in_screen += offset;
992bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (IsHorizontalAlignment())
993bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    show_shelf_region_in_screen.set_height(kMaxAutoHideShowShelfRegionSize);
994bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  else
995bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    show_shelf_region_in_screen.set_width(kMaxAutoHideShowShelfRegionSize);
996bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
997bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // TODO: Figure out if we need any special handling when the keyboard is
998bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // visible.
999bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return show_shelf_region_in_screen;
10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ShelfAutoHideState ShelfLayoutManager::CalculateAutoHideState(
10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShelfVisibilityState visibility_state) const {
10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (visibility_state != SHELF_AUTO_HIDE || !shelf_)
10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_HIDDEN;
10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell* shell = Shell::GetInstance();
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shell->GetAppListTargetVisibility())
10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_->status_area_widget() &&
10125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      shelf_->status_area_widget()->ShouldShowShelf())
10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (shelf_->shelf() && shelf_->shelf()->IsShowingMenu())
10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (shelf_->shelf() && shelf_->shelf()->IsShowingOverflowBubble())
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (shelf_->IsActive() ||
10220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      (shelf_->status_area_widget() &&
10230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       shelf_->status_area_widget()->IsActive()))
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1026ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const std::vector<aura::Window*> windows =
1027ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      ash::MruWindowTracker::BuildWindowList(false);
1028ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1029ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Process the window list and check if there are any visible windows.
1030ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  bool visible_window = false;
1031ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  for (size_t i = 0; i < windows.size(); ++i) {
1032ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (windows[i] && windows[i]->IsVisible() &&
103368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        !wm::GetWindowState(windows[i])->IsMinimized() &&
1034ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        root_window_ == windows[i]->GetRootWindow()) {
1035ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      visible_window = true;
1036ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      break;
1037ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
1038ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
1039ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // If there are no visible windows do not hide the shelf.
1040ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (!visible_window)
1041ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return SHELF_AUTO_HIDE_SHOWN;
1042ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1043ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS)
1044ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return gesture_drag_auto_hide_state_;
1045ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't show if the user is dragging the mouse.
1047868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (auto_hide_event_filter_.get() && auto_hide_event_filter_->in_mouse_drag())
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_HIDDEN;
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1050ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Ignore the mouse position if mouse events are disabled.
1051ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  aura::client::CursorClient* cursor_client = aura::client::GetCursorClient(
1052ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      shelf_->GetNativeWindow()->GetRootWindow());
1053ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (!cursor_client->IsMouseEventsEnabled())
1054ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return SHELF_AUTO_HIDE_HIDDEN;
1055ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect shelf_region = shelf_->GetWindowBoundsInScreen();
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf_->status_area_widget() &&
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shelf_->status_area_widget()->IsMessageBubbleShown() &&
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      IsVisible()) {
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Increase the the hit test area to prevent the shelf from disappearing
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // when the mouse is over the bubble gap.
106258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ShelfAlignment alignment = GetAlignment();
106358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    shelf_region.Inset(alignment == SHELF_ALIGNMENT_RIGHT ?
10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           -kNotificationBubbleGapHeight : 0,
106558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       alignment == SHELF_ALIGNMENT_BOTTOM ?
10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           -kNotificationBubbleGapHeight : 0,
106758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       alignment == SHELF_ALIGNMENT_LEFT ?
10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           -kNotificationBubbleGapHeight : 0,
106958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                       alignment == SHELF_ALIGNMENT_TOP ?
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           -kNotificationBubbleGapHeight : 0);
10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1073bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  gfx::Point cursor_position_in_screen =
1074bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      Shell::GetScreen()->GetCursorScreenPoint();
1075bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (shelf_region.Contains(cursor_position_in_screen))
1076bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    return SHELF_AUTO_HIDE_SHOWN;
1077bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
1078bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // When the shelf is auto hidden and the shelf is on the boundary between two
1079bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // displays, it is hard to trigger showing the shelf. For instance, if a
1080bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // user's primary display is left of their secondary display, it is hard to
1081bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // unautohide a left aligned shelf on the secondary display.
1082bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // It is hard because:
1083bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // - It is hard to stop the cursor in the shelf "light bar" and not overshoot.
1084bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // - The cursor is warped to the other display if the cursor gets to the edge
1085bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  //   of the display.
1086bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Show the shelf if the cursor started on the shelf and the user overshot the
1087bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // shelf slightly to make it easier to show the shelf in this situation. We
1088bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // do not check |auto_hide_timer_|.IsRunning() because it returns false when
1089bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // the timer's task is running.
1090bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if ((state_.auto_hide_state == SHELF_AUTO_HIDE_SHOWN ||
1091bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch       mouse_over_shelf_when_auto_hide_timer_started_) &&
1092bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      GetAutoHideShowShelfRegionInScreen().Contains(
1093bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch          cursor_position_in_screen)) {
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SHELF_AUTO_HIDE_SHOWN;
1095bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1097ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  return SHELF_AUTO_HIDE_HIDDEN;
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShelfLayoutManager::IsShelfWindow(aura::Window* window) {
11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!window)
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
110390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return (shelf_ && shelf_->GetNativeWindow()->Contains(window)) ||
110490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      (shelf_->status_area_widget() &&
110590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       shelf_->status_area_widget()->GetNativeWindow()->Contains(window));
11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int ShelfLayoutManager::GetWorkAreaSize(const State& state, int size) const {
11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state.visibility_state == SHELF_VISIBLE)
11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return size;
11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state.visibility_state == SHELF_AUTO_HIDE)
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return kAutoHideSize;
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1116c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ShelfLayoutManager::OnKeyboardBoundsChanging(const gfx::Rect& new_bounds) {
1117c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  bool keyboard_is_about_to_hide = false;
1118c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (new_bounds.IsEmpty() && !keyboard_bounds_.IsEmpty())
1119c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    keyboard_is_about_to_hide = true;
1120c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  keyboard_bounds_ = new_bounds;
1122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  OnWindowResized();
1123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1124c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SessionStateDelegate* session_state_delegate =
1125c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      Shell::GetInstance()->session_state_delegate();
1126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // On login screen if keyboard has been just hidden, update bounds just once
1128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // but ignore target_bounds.work_area_insets since shelf overlaps with login
1129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // window.
1130a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (session_state_delegate->IsUserSessionBlocked() &&
1131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      keyboard_is_about_to_hide) {
1132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Shell::GetInstance()->SetDisplayWorkAreaInsets(root_window_, gfx::Insets());
1133c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
1134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1136ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ShelfLayoutManager::OnDockBoundsChanging(
11374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const gfx::Rect& dock_bounds,
11384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    DockedWindowLayoutManagerObserver::Reason reason) {
11394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Skip shelf layout in case docked notification originates from this class.
11404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (reason == DISPLAY_INSETS_CHANGED)
11414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
1142ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (dock_bounds_ != dock_bounds) {
1143ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    dock_bounds_ = dock_bounds;
1144ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    OnWindowResized();
11455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UpdateVisibilityState();
1146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    UpdateShelfBackground(BACKGROUND_CHANGE_ANIMATE);
1147ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
1148ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
1149ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
115058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void ShelfLayoutManager::OnLockStateEvent(LockStateObserver::EventType event) {
115158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (event == EVENT_LOCK_ANIMATION_STARTED) {
1152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Enter the screen locked state.
1153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    state_.is_screen_locked = true;
115458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
115558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
115658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1157a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid ShelfLayoutManager::SessionStateChanged(
1158a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    SessionStateDelegate::SessionState state) {
1159a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  TargetBounds target_bounds;
1160a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  CalculateTargetBounds(state_, &target_bounds);
1161a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  UpdateBoundsAndOpacity(target_bounds, true, NULL);
1162a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  UpdateVisibilityState();
1163a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
1164a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace ash
1166