1// Copyright (c) 2012 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 CHROME_BROWSER_UI_WINDOW_SIZER_WINDOW_SIZER_H_ 6#define CHROME_BROWSER_UI_WINDOW_SIZER_WINDOW_SIZER_H_ 7 8#include "base/basictypes.h" 9#include "base/memory/scoped_ptr.h" 10#include "chrome/browser/ui/host_desktop.h" 11#include "ui/base/ui_base_types.h" 12#include "ui/gfx/rect.h" 13 14class Browser; 15 16namespace gfx { 17class Display; 18class Screen; 19} 20 21/////////////////////////////////////////////////////////////////////////////// 22// WindowSizer 23// 24// A class that determines the best new size and position for a window to be 25// shown at based several factors, including the position and size of the last 26// window of the same type, the last saved bounds of the window from the 27// previous session, and default system metrics if neither of the above two 28// conditions exist. The system has built-in providers for monitor metrics 29// and persistent storage (using preferences) but can be overrided with mocks 30// for testing. 31// 32class WindowSizer { 33 public: 34 class StateProvider; 35 class TargetDisplayProvider; 36 37 // WindowSizer owns |state_provider| and |target_display_provider|, 38 // and will use the platforms's gfx::Screen. 39 WindowSizer(scoped_ptr<StateProvider> state_provider, 40 scoped_ptr<TargetDisplayProvider> target_display_provider, 41 const Browser* browser); 42 43 // WindowSizer owns |state_provider| and |target_display_provider|, 44 // and will use the supplied |screen|. Used only for testing. 45 WindowSizer(scoped_ptr<StateProvider> state_provider, 46 scoped_ptr<TargetDisplayProvider> target_display_provider, 47 gfx::Screen* screen, 48 const Browser* browser); 49 50 virtual ~WindowSizer(); 51 52 // An interface implemented by an object that can retrieve state from either a 53 // persistent store or an existing window. 54 class StateProvider { 55 public: 56 virtual ~StateProvider() {} 57 58 // Retrieve the persisted bounds of the window. Returns true if there was 59 // persisted data to retrieve state information, false otherwise. 60 // The |show_state| variable will only be touched if there was persisted 61 // data and the |show_state| variable is SHOW_STATE_DEFAULT. 62 virtual bool GetPersistentState(gfx::Rect* bounds, 63 gfx::Rect* work_area, 64 ui::WindowShowState* show_state) const = 0; 65 66 // Retrieve the bounds of the most recent window of the matching type. 67 // Returns true if there was a last active window to retrieve state 68 // information from, false otherwise. 69 // The |show_state| variable will only be touched if we have found a 70 // suitable window and the |show_state| variable is SHOW_STATE_DEFAULT. 71 virtual bool GetLastActiveWindowState( 72 gfx::Rect* bounds, 73 ui::WindowShowState* show_state) const = 0; 74 }; 75 76 // An interface implemented by an object to identify on which 77 // display a new window should be located. 78 class TargetDisplayProvider { 79 public: 80 virtual ~TargetDisplayProvider() {} 81 virtual gfx::Display GetTargetDisplay(const gfx::Screen* screen, 82 const gfx::Rect& bounds) const = 0; 83 }; 84 85 // Determines the position and size for a window as it is created as well 86 // as the initial state. This function uses several strategies to figure out 87 // optimal size and placement, first looking for an existing active window, 88 // then falling back to persisted data from a previous session, finally 89 // utilizing a default algorithm. If |specified_bounds| are non-empty, this 90 // value is returned instead. For use only in testing. 91 // |show_state| will be overwritten and return the initial visual state of 92 // the window to use. 93 void DetermineWindowBoundsAndShowState( 94 const gfx::Rect& specified_bounds, 95 gfx::Rect* bounds, 96 ui::WindowShowState* show_state) const; 97 98 // Determines the size, position and maximized state for the browser window. 99 // See documentation for DetermineWindowBounds above. Normally, 100 // |window_bounds| is calculated by calling GetLastActiveWindowState(). To 101 // explicitly specify a particular window to base the bounds on, pass in a 102 // non-NULL value for |browser|. 103 static void GetBrowserWindowBoundsAndShowState( 104 const std::string& app_name, 105 const gfx::Rect& specified_bounds, 106 const Browser* browser, 107 gfx::Rect* window_bounds, 108 ui::WindowShowState* show_state); 109 110 // Returns the default origin for popups of the given size. 111 static gfx::Point GetDefaultPopupOrigin(const gfx::Size& size, 112 chrome::HostDesktopType type); 113 114 // How much horizontal and vertical offset there is between newly 115 // opened windows. This value may be different on each platform. 116 static const int kWindowTilePixels; 117 118 private: 119 // The edge of the screen to check for out-of-bounds. 120 enum Edge { TOP, LEFT, BOTTOM, RIGHT }; 121 122 // Gets the size and placement of the last active window. Returns true if this 123 // data is valid, false if there is no last window and the application should 124 // restore saved state from preferences using RestoreWindowPosition. 125 // |show_state| will only be changed if it was set to SHOW_STATE_DEFAULT. 126 bool GetLastActiveWindowBounds(gfx::Rect* bounds, 127 ui::WindowShowState* show_state) const; 128 129 // Gets the size and placement of the last window in the last session, saved 130 // in local state preferences. Returns true if local state exists containing 131 // this information, false if this information does not exist and a default 132 // size should be used. 133 // |show_state| will only be changed if it was set to SHOW_STATE_DEFAULT. 134 bool GetSavedWindowBounds(gfx::Rect* bounds, 135 ui::WindowShowState* show_state) const; 136 137 // Gets the default window position and size to be shown on 138 // |display| if there is no last window and no saved window 139 // placement in prefs. This function determines the default size 140 // based on monitor size, etc. 141 void GetDefaultWindowBounds(const gfx::Display& display, 142 gfx::Rect* default_bounds) const; 143 144 // Adjusts |bounds| to be visible on-screen, biased toward the work area of 145 // the |display|. Despite the name, this doesn't 146 // guarantee the bounds are fully contained within this display's work rect; 147 // it just tried to ensure the edges are visible on _some_ work rect. 148 // If |saved_work_area| is non-empty, it is used to determine whether the 149 // monitor configuration has changed. If it has, bounds are repositioned and 150 // resized if necessary to make them completely contained in the current work 151 // area. 152 void AdjustBoundsToBeVisibleOnDisplay( 153 const gfx::Display& display, 154 const gfx::Rect& saved_work_area, 155 gfx::Rect* bounds) const; 156 157 // Determine the target display for a new window based on 158 // |bounds|. On ash environment, this returns the display containing 159 // ash's the target root window. 160 gfx::Display GetTargetDisplay(const gfx::Rect& bounds) const; 161 162#if defined(USE_ASH) 163 // Ash specific logic for window placement. Returns true if |bounds| and 164 // |show_state| have been fully determined, otherwise returns false (but 165 // may still affect |show_state|). 166 // If the window is too big to fit in the display work area then the |bounds| 167 // are adjusted to default bounds and the |show_state| is adjusted to 168 // SHOW_STATE_MAXIMIZED. 169 bool GetBrowserBoundsAsh(gfx::Rect* bounds, 170 ui::WindowShowState* show_state) const; 171 172 // Determines the position and size for a tabbed browser window in 173 // ash as it gets created. This will be called before other standard 174 // placement logic. |show_state| will only be changed 175 // if it was set to SHOW_STATE_DEFAULT. 176 void GetTabbedBrowserBoundsAsh(gfx::Rect* bounds, 177 ui::WindowShowState* show_state) const; 178#endif 179 180 // Determine the default show state for the window - not looking at other 181 // windows or at persistent information. 182 ui::WindowShowState GetWindowDefaultShowState() const; 183 184 // Providers for persistent storage and monitor metrics. 185 scoped_ptr<StateProvider> state_provider_; 186 scoped_ptr<TargetDisplayProvider> target_display_provider_; 187 gfx::Screen* screen_; // not owned. 188 189 // Note that this browser handle might be NULL. 190 const Browser* browser_; 191 192 DISALLOW_COPY_AND_ASSIGN(WindowSizer); 193}; 194 195#endif // CHROME_BROWSER_UI_WINDOW_SIZER_WINDOW_SIZER_H_ 196