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 14 class Browser; 15 16 namespace gfx { 17 class Display; 18 class 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 // 32 class 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 // Determines the position and size for a tabbed browser window in 164 // ash as it gets created. This will be called before other standard 165 // placement logic. |show_state| will only be changed 166 // if it was set to SHOW_STATE_DEFAULT. 167 void GetTabbedBrowserBoundsAsh(gfx::Rect* bounds_in_screen, 168 ui::WindowShowState* show_state) const; 169 #endif 170 171 // Determine the default show state for the window - not looking at other 172 // windows or at persistent information. 173 ui::WindowShowState GetWindowDefaultShowState() const; 174 175 #if defined(USE_ASH) 176 bool IsTabbedBrowserInAsh() const; 177 bool IsPopupBrowserInAsh() const; 178 #endif 179 180 // Providers for persistent storage and monitor metrics. 181 scoped_ptr<StateProvider> state_provider_; 182 scoped_ptr<TargetDisplayProvider> target_display_provider_; 183 gfx::Screen* screen_; // not owned. 184 185 // Note that this browser handle might be NULL. 186 const Browser* browser_; 187 188 DISALLOW_COPY_AND_ASSIGN(WindowSizer); 189 }; 190 191 #endif // CHROME_BROWSER_UI_WINDOW_SIZER_WINDOW_SIZER_H_ 192