15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/window_sizer/window_sizer.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_list.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window_state.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/host_desktop.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/pref_names.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/base/ui_base_switches.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#if defined(USE_ASH) 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/shell.h" 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/wm/window_positioner.h" 25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/ui/ash/ash_init.h" 26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#endif 27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace { 29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Minimum height of the visible part of a window. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMinVisibleHeight = 30; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Minimum width of the visible part of a window. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMinVisibleWidth = 30; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An implementation of WindowSizer::StateProvider that gets the last active 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and persistent state from the browser window and the user's profile. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DefaultStateProvider : public WindowSizer::StateProvider { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DefaultStateProvider(const std::string& app_name, const Browser* browser) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : app_name_(app_name), browser_(browser) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Overridden from WindowSizer::StateProvider: 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool GetPersistentState( 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect* bounds, 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect* work_area, 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::WindowShowState* show_state) const OVERRIDE { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bounds); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(show_state); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!browser_ || !browser_->profile()->GetPrefs()) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::DictionaryValue* wp_pref = 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chrome::GetWindowPlacementDictionaryReadOnly( 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chrome::GetWindowName(browser_), browser_->profile()->GetPrefs()); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int top = 0, left = 0, bottom = 0, right = 0; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool maximized = false; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_prefs = wp_pref && 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wp_pref->GetInteger("top", &top) && 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wp_pref->GetInteger("left", &left) && 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wp_pref->GetInteger("bottom", &bottom) && 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wp_pref->GetInteger("right", &right) && 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wp_pref->GetBoolean("maximized", &maximized); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds->SetRect(left, top, std::max(0, right - left), 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::max(0, bottom - top)); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int work_area_top = 0; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int work_area_left = 0; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int work_area_bottom = 0; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int work_area_right = 0; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (wp_pref) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wp_pref->GetInteger("work_area_top", &work_area_top); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wp_pref->GetInteger("work_area_left", &work_area_left); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wp_pref->GetInteger("work_area_bottom", &work_area_bottom); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wp_pref->GetInteger("work_area_right", &work_area_right); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*show_state == ui::SHOW_STATE_DEFAULT && maximized) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *show_state = ui::SHOW_STATE_MAXIMIZED; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) work_area->SetRect(work_area_left, work_area_top, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::max(0, work_area_right - work_area_left), 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::max(0, work_area_bottom - work_area_top)); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return has_prefs; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetLastActiveWindowState( 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect* bounds, 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::WindowShowState* show_state) const OVERRIDE { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(show_state); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Applications are always restored with the same position. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!app_name_.empty()) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If a reference browser is set, use its window. Otherwise find last 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // active. Panels are never used as reference browsers as panels are 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // specially positioned. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserWindow* window = NULL; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Window may be null if browser is just starting up. 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (browser_ && browser_->window()) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window = browser_->window(); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // This code is only ran on the native desktop (on the ash 10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // desktop, GetTabbedBrowserBoundsAsh should take over below 10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // before this is reached). TODO(gab): This code should go in a 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // native desktop specific window sizer as part of fixing 10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // crbug.com/175812. 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BrowserList* native_browser_list = 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_NATIVE); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (BrowserList::const_reverse_iterator it = 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) native_browser_list->begin_last_active(); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != native_browser_list->end_last_active(); ++it) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* last_active = *it; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_active && last_active->is_type_tabbed()) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window = last_active->window(); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(window); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bounds = window->GetRestoredBounds(); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*show_state == ui::SHOW_STATE_DEFAULT && window->IsMaximized()) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *show_state = ui::SHOW_STATE_MAXIMIZED; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string app_name_; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If set, is used as the reference browser for GetLastActiveWindowState. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Browser* browser_; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DefaultStateProvider); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class DefaultTargetDisplayProvider : public WindowSizer::TargetDisplayProvider { 142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DefaultTargetDisplayProvider() {} 144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual ~DefaultTargetDisplayProvider() {} 145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual gfx::Display GetTargetDisplay( 147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const gfx::Screen* screen, 148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const gfx::Rect& bounds) const OVERRIDE { 149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(USE_ASH) 1506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) bool force_ash = false; 1516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // On Windows check if the browser is launched to serve ASH. If yes then 1526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // we should get the display for the corresponding root window created for 1536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // ASH. This ensures that the display gets the correct workarea, etc. 154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If the ASH shell does not exist then the current behavior is to open 155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // browser windows if any on the desktop. Preserve that for now. 156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // TODO(ananta). 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // This effectively means that the running browser process is in a split 158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // personality mode, part of it running in ASH and the other running in 159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // desktop. This may cause apps and other widgets to not work correctly. 160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Revisit and address. 1616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#if defined(OS_WIN) 162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch force_ash = ash::Shell::HasInstance() && 1636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) CommandLine::ForCurrentProcess()->HasSwitch(switches::kViewerConnect); 1646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#endif 165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Use the target display on ash. 1666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (chrome::ShouldOpenAshOnStartup() || force_ash) { 167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) aura::Window* target = ash::Shell::GetTargetRootWindow(); 168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return screen->GetDisplayNearestWindow(target); 169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif 171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Find the size of the work area of the monitor that intersects the bounds 172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // of the anchor window. 173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return screen->GetDisplayMatching(bounds); 174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private: 177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DefaultTargetDisplayProvider); 178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace 181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WindowSizer, public: 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)WindowSizer::WindowSizer( 186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<StateProvider> state_provider, 187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<TargetDisplayProvider> target_display_provider, 188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const Browser* browser) 189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : state_provider_(state_provider.Pass()), 190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) target_display_provider_(target_display_provider.Pass()), 191424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // TODO(scottmg): NativeScreen is wrong. http://crbug.com/133312 192424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) screen_(gfx::Screen::GetNativeScreen()), 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_(browser) { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)WindowSizer::WindowSizer( 197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<StateProvider> state_provider, 198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<TargetDisplayProvider> target_display_provider, 199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Screen* screen, 200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const Browser* browser) 201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : state_provider_(state_provider.Pass()), 202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) target_display_provider_(target_display_provider.Pass()), 203424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) screen_(screen), 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_(browser) { 205424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(screen_); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WindowSizer::~WindowSizer() { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WindowSizer::GetBrowserWindowBoundsAndShowState( 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& app_name, 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& specified_bounds, 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Browser* browser, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect* window_bounds, 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::WindowShowState* show_state) { 218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<StateProvider> state_provider( 219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new DefaultStateProvider(app_name, browser)); 220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<TargetDisplayProvider> target_display_provider( 221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new DefaultTargetDisplayProvider); 222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const WindowSizer sizer(state_provider.Pass(), 223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) target_display_provider.Pass(), 224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) browser); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizer.DetermineWindowBoundsAndShowState(specified_bounds, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_bounds, 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_state); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WindowSizer, private: 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WindowSizer::DetermineWindowBoundsAndShowState( 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& specified_bounds, 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect* bounds, 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::WindowShowState* show_state) const { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bounds); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(show_state); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pre-populate the window state with our default. 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *show_state = GetWindowDefaultShowState(); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bounds = specified_bounds; 242a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_ASH) 244a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // See if ash should decide the window placement. 245a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (GetBrowserBoundsAsh(bounds, show_state)) 246a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 248a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 249a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (bounds->IsEmpty()) { 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // See if there's last active window's placement information. 251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (GetLastActiveWindowBounds(bounds, show_state)) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See if there's saved placement information. 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (GetSavedWindowBounds(bounds, show_state)) 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 256a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // No saved placement, figure out some sensible default size based on 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the user's screen size. 259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) GetDefaultWindowBounds(GetTargetDisplay(gfx::Rect()), bounds); 260a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 262a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 263a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // In case that there was a bound given we need to make sure that it is 264a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // visible and fits on the screen. 265a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Find the size of the work area of the monitor that intersects the bounds 266a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // of the anchor window. Note: AdjustBoundsToBeVisibleOnMonitorContaining 267a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // does not exactly what we want: It makes only sure that "a minimal part" 268a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // is visible on the screen. 269a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Rect work_area = screen_->GetDisplayMatching(*bounds).work_area(); 270a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Resize so that it fits. 271a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch bounds->AdjustToFit(work_area); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool WindowSizer::GetLastActiveWindowBounds( 275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Rect* bounds, 276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ui::WindowShowState* show_state) const { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bounds); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(show_state); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!state_provider_.get() || 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !state_provider_->GetLastActiveWindowState(bounds, show_state)) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect last_window_bounds = *bounds; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds->Offset(kWindowTilePixels, kWindowTilePixels); 284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AdjustBoundsToBeVisibleOnDisplay(screen_->GetDisplayMatching(*bounds), 285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Rect(), 286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bounds); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WindowSizer::GetSavedWindowBounds(gfx::Rect* bounds, 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::WindowShowState* show_state) const { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bounds); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(show_state); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect saved_work_area; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!state_provider_.get() || 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !state_provider_->GetPersistentState(bounds, 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &saved_work_area, 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_state)) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AdjustBoundsToBeVisibleOnDisplay(GetTargetDisplay(*bounds), 301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) saved_work_area, 302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bounds); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WindowSizer::GetDefaultWindowBounds(const gfx::Display& display, 3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) gfx::Rect* default_bounds) const { 3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(default_bounds); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_ASH) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(beng): insufficient but currently necessary. http://crbug.com/133312 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (chrome::ShouldOpenAshOnStartup()) { 312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) *default_bounds = ash::WindowPositioner::GetDefaultWindowBounds(display); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) gfx::Rect work_area = display.work_area(); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The default size is either some reasonably wide width, or if the work 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // area is narrower, then the work area width less some aesthetic padding. 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int default_width = std::min(work_area.width() - 2 * kWindowTilePixels, 1050); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int default_height = work_area.height() - 2 * kWindowTilePixels; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For wider aspect ratio displays at higher resolutions, we might size the 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // window narrower to allow two windows to easily be placed side-by-side. 325424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) gfx::Rect screen_size = screen_->GetPrimaryDisplay().bounds(); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double width_to_height = 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<double>(screen_size.width()) / screen_size.height(); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The least wide a screen can be to qualify for the halving described above. 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kMinScreenWidthForWindowHalving = 1600; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We assume 16:9/10 is a fairly standard indicator of a wide aspect ratio 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // computer display. 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (((width_to_height * 10) >= 16) && 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) work_area.width() > kMinScreenWidthForWindowHalving) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Halve the work area, subtracting aesthetic padding on either side. 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The padding is set so that two windows, side by side have 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // kWindowTilePixels between screen edge and each other. 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_width = static_cast<int>(work_area.width() / 2. - 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1.5 * kWindowTilePixels); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_bounds->SetRect(kWindowTilePixels + work_area.x(), 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kWindowTilePixels + work_area.y(), 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_width, default_height); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 346a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void WindowSizer::AdjustBoundsToBeVisibleOnDisplay( 347a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const gfx::Display& display, 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& saved_work_area, 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect* bounds) const { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bounds); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // If |bounds| is empty, reset to the default size. 353a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (bounds->IsEmpty()) { 354a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Rect default_bounds; 355a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) GetDefaultWindowBounds(display, &default_bounds); 356a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (bounds->height() <= 0) 357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bounds->set_height(default_bounds.height()); 358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (bounds->width() <= 0) 359a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bounds->set_width(default_bounds.width()); 360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure the minimum height and width. 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds->set_height(std::max(kMinVisibleHeight, bounds->height())); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds->set_width(std::max(kMinVisibleWidth, bounds->width())); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) gfx::Rect work_area = display.work_area(); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the title bar is not above the work area. 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bounds->y() < work_area.y()) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds->set_y(work_area.y()); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reposition and resize the bounds if the saved_work_area is different from 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the current work area and the current work area doesn't completely contain 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the bounds. 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!saved_work_area.IsEmpty() && 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) saved_work_area != work_area && 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !work_area.Contains(*bounds)) { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds->set_width(std::min(bounds->width(), work_area.width())); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds->set_height(std::min(bounds->height(), work_area.height())); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds->set_x( 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::max(work_area.x(), 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::min(bounds->x(), work_area.right() - bounds->width()))); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds->set_y( 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::max(work_area.y(), 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::min(bounds->y(), work_area.bottom() - bounds->height()))); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Limit the maximum height. On the Mac the sizer is on the 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bottom-right of the window, and a window cannot be moved "up" 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // past the menubar. If the window is too tall you'll never be able 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to shrink it again. Windows does not have this limitation 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (e.g. can be resized from the top). 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds->set_height(std::min(work_area.height(), bounds->height())); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On mac, we want to be aggressive about repositioning windows that are 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // partially offscreen. If the window is partially offscreen horizontally, 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // move it to be flush with the left edge of the work area. 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bounds->x() < work_area.x() || bounds->right() > work_area.right()) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds->set_x(work_area.x()); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the window is partially offscreen vertically, move it to be flush with 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the top of the work area. 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bounds->y() < work_area.y() || bounds->bottom() > work_area.bottom()) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds->set_y(work_area.y()); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On non-Mac platforms, we are less aggressive about repositioning. Simply 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ensure that at least kMinVisibleWidth * kMinVisibleHeight is visible. 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int min_y = work_area.y() + kMinVisibleHeight - bounds->height(); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int min_x = work_area.x() + kMinVisibleWidth - bounds->width(); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int max_y = work_area.bottom() - kMinVisibleHeight; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int max_x = work_area.right() - kMinVisibleWidth; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds->set_y(std::max(min_y, std::min(max_y, bounds->y()))); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds->set_x(std::max(min_x, std::min(max_x, bounds->x()))); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_MACOSX) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 417a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)gfx::Display WindowSizer::GetTargetDisplay(const gfx::Rect& bounds) const { 418a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return target_display_provider_->GetTargetDisplay(screen_, bounds); 419a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 420a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::WindowShowState WindowSizer::GetWindowDefaultShowState() const { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!browser_) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::SHOW_STATE_DEFAULT; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only tabbed browsers use the command line or preference state, with the 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // exception of devtools. 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool show_state = !browser_->is_type_tabbed() && !browser_->is_devtools(); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We use the apps save state on aura. 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_state &= !browser_->is_app(); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (show_state) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return browser_->initial_show_state(); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kStartMaximized)) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::SHOW_STATE_MAXIMIZED; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser_->initial_show_state() != ui::SHOW_STATE_DEFAULT) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return browser_->initial_show_state(); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise we use the default which can be overridden later on. 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::SHOW_STATE_DEFAULT; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 446