1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef ASH_WM_DOCK_DOCKED_WINDOW_LAYOUT_MANAGER_H_ 6#define ASH_WM_DOCK_DOCKED_WINDOW_LAYOUT_MANAGER_H_ 7 8#include "ash/ash_export.h" 9#include "ash/shelf/shelf_layout_manager_observer.h" 10#include "ash/shell_observer.h" 11#include "ash/wm/dock/dock_types.h" 12#include "ash/wm/property_util.h" 13#include "base/basictypes.h" 14#include "base/compiler_specific.h" 15#include "base/gtest_prod_util.h" 16#include "base/memory/scoped_ptr.h" 17#include "base/observer_list.h" 18#include "ui/aura/client/activation_change_observer.h" 19#include "ui/aura/layout_manager.h" 20#include "ui/aura/window_observer.h" 21#include "ui/gfx/rect.h" 22#include "ui/keyboard/keyboard_controller_observer.h" 23 24namespace aura { 25class Window; 26} 27 28namespace gfx { 29class Point; 30} 31 32namespace views { 33class Widget; 34} 35 36namespace ash { 37class Launcher; 38 39namespace internal { 40class DockedWindowLayoutManagerObserver; 41class DockedWindowResizerTest; 42class ShelfLayoutManager; 43 44// DockedWindowLayoutManager is responsible for organizing windows when they are 45// docked to the side of a screen. It is associated with a specific container 46// window (i.e. kShellWindowId_DockContainer) and controls the layout of any 47// windows added to that container. 48// 49// The constructor takes a |dock_container| argument which is expected to set 50// its layout manager to this instance, e.g.: 51// dock_container->SetLayoutManager( 52// new DockedWindowLayoutManager(dock_container)); 53 54class ASH_EXPORT DockedWindowLayoutManager 55 : public aura::LayoutManager, 56 public ash::ShellObserver, 57 public aura::WindowObserver, 58 public aura::client::ActivationChangeObserver, 59 public keyboard::KeyboardControllerObserver, 60 public ash::ShelfLayoutManagerObserver { 61 public: 62 explicit DockedWindowLayoutManager(aura::Window* dock_container); 63 virtual ~DockedWindowLayoutManager(); 64 65 // Disconnects observers before container windows get destroyed. 66 void Shutdown(); 67 68 // Management of the observer list. 69 virtual void AddObserver(DockedWindowLayoutManagerObserver* observer); 70 virtual void RemoveObserver(DockedWindowLayoutManagerObserver* observer); 71 72 // Called by a DockedWindowResizer to update which window is being dragged. 73 void StartDragging(aura::Window* window); 74 void FinishDragging(); 75 76 // Returns true if a window is touching the side of the screen except 2 cases: 77 // when some other windows are already docked on the other side or 78 // when launcher (shelf) is aligned on the same side. 79 static bool ShouldWindowDock(aura::Window* window, 80 const gfx::Point& location); 81 82 ash::Launcher* launcher() { return launcher_; } 83 void SetLauncher(ash::Launcher* launcher); 84 85 // Used to snap docked windows to the side of screen during drag. 86 DockedAlignment CalculateAlignment() const; 87 88 // Returns current bounding rectangle of docked windows area. 89 const gfx::Rect& docked_bounds() const { return docked_bounds_; } 90 91 // Currently dragged window should be able to dock on another screen 92 aura::Window* dragged_window() const { return dragged_window_;} 93 94 // aura::LayoutManager: 95 virtual void OnWindowResized() OVERRIDE; 96 virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE; 97 virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE {} 98 virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE; 99 virtual void OnChildWindowVisibilityChanged(aura::Window* child, 100 bool visibile) OVERRIDE; 101 virtual void SetChildBounds(aura::Window* child, 102 const gfx::Rect& requested_bounds) OVERRIDE; 103 104 // ash::ShellObserver: 105 virtual void OnShelfAlignmentChanged(aura::RootWindow* root_window) OVERRIDE; 106 107 // aura::WindowObserver: 108 virtual void OnWindowPropertyChanged(aura::Window* window, 109 const void* key, 110 intptr_t old) OVERRIDE; 111 virtual void OnWindowBoundsChanged(aura::Window* window, 112 const gfx::Rect& old_bounds, 113 const gfx::Rect& new_bounds) OVERRIDE; 114 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE; 115 116 // aura::client::ActivationChangeObserver: 117 virtual void OnWindowActivated(aura::Window* gained_active, 118 aura::Window* lost_active) OVERRIDE; 119 120 // ShelfLayoutManagerObserver: 121 virtual void WillChangeVisibilityState( 122 ShelfVisibilityState new_state) OVERRIDE; 123 124 private: 125 FRIEND_TEST_ALL_PREFIXES(DockedWindowResizerTest, AttachTwoWindowsDetachOne); 126 FRIEND_TEST_ALL_PREFIXES(DockedWindowResizerTest, AttachWindowMaximizeOther); 127 FRIEND_TEST_ALL_PREFIXES(DockedWindowResizerTest, AttachOneTestSticky); 128 FRIEND_TEST_ALL_PREFIXES(DockedWindowResizerTest, ResizeTwoWindows); 129 FRIEND_TEST_ALL_PREFIXES(DockedWindowResizerTest, DragToShelf); 130 friend class DockedWindowLayoutManagerTest; 131 friend class DockedWindowResizerTest; 132 133 // Minimum width of the docked windows area. 134 static const int kMinDockWidth; 135 136 // Maximum width of the docked windows area. 137 static const int kMaxDockWidth; 138 139 // Width of the gap between the docked windows and a workspace. 140 static const int kMinDockGap; 141 142 // Minimize / restore window and relayout. 143 void MinimizeWindow(aura::Window* window); 144 void RestoreWindow(aura::Window* window); 145 146 // Calculates if a window is touching the screen edges and returns edge. 147 DockedAlignment AlignmentOfWindow(const aura::Window* window) const; 148 149 // Called whenever the window layout might change. 150 void Relayout(); 151 152 // Updates |docked_bounds_| and workspace insets when bounds of docked windows 153 // area change. 154 void UpdateDockBounds(); 155 156 // Called whenever the window stacking order needs to be updated (e.g. focus 157 // changes or a window is moved). 158 void UpdateStacking(aura::Window* active_window); 159 160 // keyboard::KeyboardControllerObserver: 161 virtual void OnKeyboardBoundsChanging( 162 const gfx::Rect& keyboard_bounds) OVERRIDE; 163 164 // Parent window associated with this layout manager. 165 aura::Window* dock_container_; 166 // Protect against recursive calls to Relayout(). 167 bool in_layout_; 168 // The docked window being dragged. 169 aura::Window* dragged_window_; 170 // The launcher we are observing for launcher icon changes. 171 Launcher* launcher_; 172 // The shelf layout manager being observed for visibility changes. 173 ShelfLayoutManager* shelf_layout_manager_; 174 // Tracks the visibility of the shelf. Defaults to false when there is no 175 // shelf. 176 bool shelf_hidden_; 177 // Current width of the dock. 178 int docked_width_; 179 180 // Last bounds that were sent to observers. 181 gfx::Rect docked_bounds_; 182 183 // Side of the screen that the dock is positioned at. 184 DockedAlignment alignment_; 185 186 // The last active window. Used to maintain stacking order even if no windows 187 // are currently focused. 188 aura::Window* last_active_window_; 189 190 // Widget used to paint a background for the docked area. 191 scoped_ptr<views::Widget> background_widget_; 192 193 // Observers of dock bounds changes. 194 ObserverList<DockedWindowLayoutManagerObserver> observer_list_; 195 196 DISALLOW_COPY_AND_ASSIGN(DockedWindowLayoutManager); 197}; 198 199} // namespace internal 200} // namespace ash 201 202#endif // ASH_WM_DOCK_DOCKED_WINDOW_LAYOUT_MANAGER_H_ 203