| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/window_sizer/window_sizer.h" | 5 #include "chrome/browser/ui/window_sizer/window_sizer.h" |
| 6 | 6 |
| 7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "chrome/browser/browser_process.h" | 8 #include "chrome/browser/browser_process.h" |
| 9 #include "chrome/browser/prefs/pref_service.h" | 9 #include "chrome/browser/prefs/pref_service.h" |
| 10 #include "chrome/browser/profiles/profile.h" | 10 #include "chrome/browser/profiles/profile.h" |
| 11 #include "chrome/browser/ui/ash/ash_init.h" | 11 #include "chrome/browser/ui/ash/ash_init.h" |
| 12 #include "chrome/browser/ui/browser.h" | 12 #include "chrome/browser/ui/browser.h" |
| 13 #include "chrome/browser/ui/browser_list.h" | 13 #include "chrome/browser/ui/browser_list.h" |
| 14 #include "chrome/browser/ui/browser_window.h" | 14 #include "chrome/browser/ui/browser_window.h" |
| 15 #include "chrome/browser/ui/browser_window_state.h" | 15 #include "chrome/browser/ui/browser_window_state.h" |
| 16 #include "chrome/common/pref_names.h" | 16 #include "chrome/common/pref_names.h" |
| 17 #include "ui/gfx/screen.h" | 17 #include "ui/gfx/screen.h" |
| 18 | 18 |
| 19 // Minimum height of the visible part of a window. | 19 // Minimum height of the visible part of a window. |
| 20 const int kMinVisibleHeight = 30; | 20 const int kMinVisibleHeight = 30; |
| 21 // Minimum width of the visible part of a window. | 21 // Minimum width of the visible part of a window. |
| 22 const int kMinVisibleWidth = 30; | 22 const int kMinVisibleWidth = 30; |
| 23 | 23 |
| 24 class DefaultMonitorInfoProvider : public MonitorInfoProvider { | 24 class DefaultMonitorInfoProvider : public MonitorInfoProvider { |
| 25 public: | 25 public: |
| 26 // Overridden from MonitorInfoProvider: | 26 // Overridden from MonitorInfoProvider: |
| 27 virtual gfx::Rect GetPrimaryDisplayWorkArea() const OVERRIDE { | 27 virtual gfx::Rect GetPrimaryDisplayWorkArea() const OVERRIDE { |
| 28 return gfx::Screen::GetPrimaryDisplay().work_area(); | 28 return gfx::Screen::GetPrimaryDisplay( |
| 29 gfx::Screen::BadTwoWorldsContext()).work_area(); |
| 29 } | 30 } |
| 30 virtual gfx::Rect GetPrimaryDisplayBounds() const OVERRIDE { | 31 virtual gfx::Rect GetPrimaryDisplayBounds() const OVERRIDE { |
| 31 return gfx::Screen::GetPrimaryDisplay().bounds(); | 32 return gfx::Screen::GetPrimaryDisplay( |
| 33 gfx::Screen::BadTwoWorldsContext()).bounds(); |
| 32 } | 34 } |
| 33 virtual gfx::Rect GetMonitorWorkAreaMatching( | 35 virtual gfx::Rect GetMonitorWorkAreaMatching( |
| 34 const gfx::Rect& match_rect) const OVERRIDE { | 36 const gfx::Rect& match_rect) const OVERRIDE { |
| 35 return gfx::Screen::GetDisplayMatching(match_rect).work_area(); | 37 return gfx::Screen::GetDisplayMatching( |
| 38 gfx::Screen::BadTwoWorldsContext(), match_rect).work_area(); |
| 36 } | 39 } |
| 37 }; | 40 }; |
| 38 | 41 |
| 39 /////////////////////////////////////////////////////////////////////////////// | 42 /////////////////////////////////////////////////////////////////////////////// |
| 40 // An implementation of WindowSizer::StateProvider that gets the last active | 43 // An implementation of WindowSizer::StateProvider that gets the last active |
| 41 // and persistent state from the browser window and the user's profile. | 44 // and persistent state from the browser window and the user's profile. |
| 42 class DefaultStateProvider : public WindowSizer::StateProvider { | 45 class DefaultStateProvider : public WindowSizer::StateProvider { |
| 43 public: | 46 public: |
| 44 DefaultStateProvider(const std::string& app_name, const Browser* browser) | 47 DefaultStateProvider(const std::string& app_name, const Browser* browser) |
| 45 : app_name_(app_name), browser_(browser) { | 48 : app_name_(app_name), browser_(browser) { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 | 154 |
| 152 WindowSizer::~WindowSizer() { | 155 WindowSizer::~WindowSizer() { |
| 153 } | 156 } |
| 154 | 157 |
| 155 // static | 158 // static |
| 156 void WindowSizer::GetBrowserWindowBounds(const std::string& app_name, | 159 void WindowSizer::GetBrowserWindowBounds(const std::string& app_name, |
| 157 const gfx::Rect& specified_bounds, | 160 const gfx::Rect& specified_bounds, |
| 158 const Browser* browser, | 161 const Browser* browser, |
| 159 gfx::Rect* window_bounds) { | 162 gfx::Rect* window_bounds) { |
| 160 const WindowSizer sizer(new DefaultStateProvider(app_name, browser), browser); | 163 const WindowSizer sizer(new DefaultStateProvider(app_name, browser), browser); |
| 161 sizer.DetermineWindowBounds(specified_bounds, window_bounds); | 164 sizer.DetermineWindowBounds(specified_bounds, window_bounds, browser); |
| 162 } | 165 } |
| 163 | 166 |
| 164 /////////////////////////////////////////////////////////////////////////////// | 167 /////////////////////////////////////////////////////////////////////////////// |
| 165 // WindowSizer, private: | 168 // WindowSizer, private: |
| 166 | 169 |
| 167 void WindowSizer::DetermineWindowBounds(const gfx::Rect& specified_bounds, | 170 void WindowSizer::DetermineWindowBounds(const gfx::Rect& specified_bounds, |
| 168 gfx::Rect* bounds) const { | 171 gfx::Rect* bounds, |
| 172 const Browser* browser) const { |
| 169 *bounds = specified_bounds; | 173 *bounds = specified_bounds; |
| 170 if (bounds->IsEmpty()) { | 174 if (bounds->IsEmpty()) { |
| 171 if (GetBoundsOverride(specified_bounds, bounds)) | 175 if (GetBoundsOverride(specified_bounds, bounds, browser)) |
| 172 return; | 176 return; |
| 173 // See if there's saved placement information. | 177 // See if there's saved placement information. |
| 174 if (!GetLastWindowBounds(bounds)) { | 178 if (!GetLastWindowBounds(bounds, browser)) { |
| 175 if (!GetSavedWindowBounds(bounds)) { | 179 if (!GetSavedWindowBounds(bounds, browser)) { |
| 176 // No saved placement, figure out some sensible default size based on | 180 // No saved placement, figure out some sensible default size based on |
| 177 // the user's screen size. | 181 // the user's screen size. |
| 178 GetDefaultWindowBounds(bounds); | 182 GetDefaultWindowBounds(bounds, browser); |
| 179 } | 183 } |
| 180 } | 184 } |
| 181 } else { | 185 } else { |
| 182 // In case that there was a bound given we need to make sure that it is | 186 // In case that there was a bound given we need to make sure that it is |
| 183 // visible and fits on the screen. | 187 // visible and fits on the screen. |
| 184 // Find the size of the work area of the monitor that intersects the bounds | 188 // Find the size of the work area of the monitor that intersects the bounds |
| 185 // of the anchor window. Note: AdjustBoundsToBeVisibleOnMonitorContaining | 189 // of the anchor window. Note: AdjustBoundsToBeVisibleOnMonitorContaining |
| 186 // does not exactly what we want: It makes only sure that "a minimal part" | 190 // does not exactly what we want: It makes only sure that "a minimal part" |
| 187 // is visible on the screen. | 191 // is visible on the screen. |
| 188 gfx::Rect work_area = | 192 gfx::Rect work_area = |
| 189 monitor_info_provider_->GetMonitorWorkAreaMatching(*bounds); | 193 monitor_info_provider_->GetMonitorWorkAreaMatching(*bounds); |
| 190 // Resize so that it fits. | 194 // Resize so that it fits. |
| 191 *bounds = bounds->AdjustToFit(work_area); | 195 *bounds = bounds->AdjustToFit(work_area); |
| 192 } | 196 } |
| 193 } | 197 } |
| 194 | 198 |
| 195 bool WindowSizer::GetLastWindowBounds(gfx::Rect* bounds) const { | 199 bool WindowSizer::GetLastWindowBounds(gfx::Rect* bounds, |
| 200 const Browser* browser) const { |
| 196 DCHECK(bounds); | 201 DCHECK(bounds); |
| 197 if (!state_provider_.get() || | 202 if (!state_provider_.get() || |
| 198 !state_provider_->GetLastActiveWindowState(bounds)) | 203 !state_provider_->GetLastActiveWindowState(bounds)) |
| 199 return false; | 204 return false; |
| 200 gfx::Rect last_window_bounds = *bounds; | 205 gfx::Rect last_window_bounds = *bounds; |
| 201 bounds->Offset(kWindowTilePixels, kWindowTilePixels); | 206 bounds->Offset(kWindowTilePixels, kWindowTilePixels); |
| 202 AdjustBoundsToBeVisibleOnMonitorContaining(last_window_bounds, | 207 AdjustBoundsToBeVisibleOnMonitorContaining(last_window_bounds, |
| 203 gfx::Rect(), | 208 gfx::Rect(), |
| 204 bounds); | 209 bounds, |
| 210 browser); |
| 205 return true; | 211 return true; |
| 206 } | 212 } |
| 207 | 213 |
| 208 bool WindowSizer::GetSavedWindowBounds(gfx::Rect* bounds) const { | 214 bool WindowSizer::GetSavedWindowBounds(gfx::Rect* bounds, |
| 215 const Browser* browser) const { |
| 209 DCHECK(bounds); | 216 DCHECK(bounds); |
| 210 gfx::Rect saved_work_area; | 217 gfx::Rect saved_work_area; |
| 211 if (!state_provider_.get() || | 218 if (!state_provider_.get() || |
| 212 !state_provider_->GetPersistentState(bounds, &saved_work_area)) | 219 !state_provider_->GetPersistentState(bounds, &saved_work_area)) |
| 213 return false; | 220 return false; |
| 214 AdjustBoundsToBeVisibleOnMonitorContaining(*bounds, saved_work_area, bounds); | 221 AdjustBoundsToBeVisibleOnMonitorContaining( |
| 222 *bounds, saved_work_area, bounds, browser); |
| 215 return true; | 223 return true; |
| 216 } | 224 } |
| 217 | 225 |
| 218 void WindowSizer::GetDefaultWindowBounds(gfx::Rect* default_bounds) const { | 226 void WindowSizer::GetDefaultWindowBounds(gfx::Rect* default_bounds, |
| 219 #if defined(USE_ASH) | 227 const Browser* browser) const { |
| 220 // TODO(beng): insufficient but currently necessary. http://crbug.com/133312 | 228 // TODO(scottmg): http://crbug.com/133312 |
| 221 if (chrome::ShouldOpenAshOnStartup()) { | 229 if (chrome::GetHostDesktopTypeForBrowser(browser) == |
| 230 chrome::HOST_DESKTOP_TYPE_ASH) { |
| 222 GetDefaultWindowBoundsAsh(default_bounds); | 231 GetDefaultWindowBoundsAsh(default_bounds); |
| 223 return; | 232 return; |
| 224 } | 233 } |
| 225 #endif | |
| 226 DCHECK(default_bounds); | 234 DCHECK(default_bounds); |
| 227 DCHECK(monitor_info_provider_.get()); | 235 DCHECK(monitor_info_provider_.get()); |
| 228 | 236 |
| 229 gfx::Rect work_area = monitor_info_provider_->GetPrimaryDisplayWorkArea(); | 237 gfx::Rect work_area = monitor_info_provider_->GetPrimaryDisplayWorkArea(); |
| 230 | 238 |
| 231 // The default size is either some reasonably wide width, or if the work | 239 // The default size is either some reasonably wide width, or if the work |
| 232 // area is narrower, then the work area width less some aesthetic padding. | 240 // area is narrower, then the work area width less some aesthetic padding. |
| 233 int default_width = std::min(work_area.width() - 2 * kWindowTilePixels, 1050); | 241 int default_width = std::min(work_area.width() - 2 * kWindowTilePixels, 1050); |
| 234 int default_height = work_area.height() - 2 * kWindowTilePixels; | 242 int default_height = work_area.height() - 2 * kWindowTilePixels; |
| 235 | 243 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 252 1.5 * kWindowTilePixels); | 260 1.5 * kWindowTilePixels); |
| 253 } | 261 } |
| 254 default_bounds->SetRect(kWindowTilePixels + work_area.x(), | 262 default_bounds->SetRect(kWindowTilePixels + work_area.x(), |
| 255 kWindowTilePixels + work_area.y(), | 263 kWindowTilePixels + work_area.y(), |
| 256 default_width, default_height); | 264 default_width, default_height); |
| 257 } | 265 } |
| 258 | 266 |
| 259 void WindowSizer::AdjustBoundsToBeVisibleOnMonitorContaining( | 267 void WindowSizer::AdjustBoundsToBeVisibleOnMonitorContaining( |
| 260 const gfx::Rect& other_bounds, | 268 const gfx::Rect& other_bounds, |
| 261 const gfx::Rect& saved_work_area, | 269 const gfx::Rect& saved_work_area, |
| 262 gfx::Rect* bounds) const { | 270 gfx::Rect* bounds, |
| 271 const Browser* browser) const { |
| 263 DCHECK(bounds); | 272 DCHECK(bounds); |
| 264 DCHECK(monitor_info_provider_.get()); | 273 DCHECK(monitor_info_provider_.get()); |
| 265 | 274 |
| 266 // Find the size of the work area of the monitor that intersects the bounds | 275 // Find the size of the work area of the monitor that intersects the bounds |
| 267 // of the anchor window. | 276 // of the anchor window. |
| 268 gfx::Rect work_area = | 277 gfx::Rect work_area = |
| 269 monitor_info_provider_->GetMonitorWorkAreaMatching(other_bounds); | 278 monitor_info_provider_->GetMonitorWorkAreaMatching(other_bounds); |
| 270 | 279 |
| 271 // If height or width are 0, reset to the default size. | 280 // If height or width are 0, reset to the default size. |
| 272 gfx::Rect default_bounds; | 281 gfx::Rect default_bounds; |
| 273 GetDefaultWindowBounds(&default_bounds); | 282 GetDefaultWindowBounds(&default_bounds, browser); |
| 274 if (bounds->height() <= 0) | 283 if (bounds->height() <= 0) |
| 275 bounds->set_height(default_bounds.height()); | 284 bounds->set_height(default_bounds.height()); |
| 276 if (bounds->width() <= 0) | 285 if (bounds->width() <= 0) |
| 277 bounds->set_width(default_bounds.width()); | 286 bounds->set_width(default_bounds.width()); |
| 278 | 287 |
| 279 // Ensure the minimum height and width. | 288 // Ensure the minimum height and width. |
| 280 bounds->set_height(std::max(kMinVisibleHeight, bounds->height())); | 289 bounds->set_height(std::max(kMinVisibleHeight, bounds->height())); |
| 281 bounds->set_width(std::max(kMinVisibleWidth, bounds->width())); | 290 bounds->set_width(std::max(kMinVisibleWidth, bounds->width())); |
| 282 | 291 |
| 283 // Ensure that the title bar is not above the work area. | 292 // Ensure that the title bar is not above the work area. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 const int min_x = work_area.x() + kMinVisibleWidth - bounds->width(); | 334 const int min_x = work_area.x() + kMinVisibleWidth - bounds->width(); |
| 326 const int max_y = work_area.bottom() - kMinVisibleHeight; | 335 const int max_y = work_area.bottom() - kMinVisibleHeight; |
| 327 const int max_x = work_area.right() - kMinVisibleWidth; | 336 const int max_x = work_area.right() - kMinVisibleWidth; |
| 328 bounds->set_y(std::max(min_y, std::min(max_y, bounds->y()))); | 337 bounds->set_y(std::max(min_y, std::min(max_y, bounds->y()))); |
| 329 bounds->set_x(std::max(min_x, std::min(max_x, bounds->x()))); | 338 bounds->set_x(std::max(min_x, std::min(max_x, bounds->x()))); |
| 330 #endif // defined(OS_MACOSX) | 339 #endif // defined(OS_MACOSX) |
| 331 } | 340 } |
| 332 | 341 |
| 333 bool WindowSizer::GetBoundsOverride( | 342 bool WindowSizer::GetBoundsOverride( |
| 334 const gfx::Rect& specified_bounds, | 343 const gfx::Rect& specified_bounds, |
| 335 gfx::Rect* bounds) const { | 344 gfx::Rect* bounds, |
| 345 const Browser* browser) const { |
| 336 #if defined(USE_ASH) | 346 #if defined(USE_ASH) |
| 337 // TODO(beng): insufficient but currently necessary. http://crbug.com/133312 | 347 // TODO(scottmg): http://crbug.com/133312 |
| 338 if (chrome::ShouldOpenAshOnStartup()) | 348 if (chrome::GetHostDesktopTypeForBrowser(browser) == |
| 339 return GetBoundsOverrideAsh(specified_bounds, bounds); | 349 chrome::HOST_DESKTOP_TYPE_ASH) |
| 350 return GetBoundsOverrideAsh(specified_bounds, bounds, browser); |
| 340 #endif | 351 #endif |
| 341 return false; | 352 return false; |
| 342 } | 353 } |
| OLD | NEW |