// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/ui/browser_window_state.h" #include "base/command_line.h" #include "base/prefs/pref_service.h" #include "base/prefs/scoped_user_pref_update.h" #include "base/strings/string_number_conversions.h" #include "chrome/browser/defaults.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sessions/session_service.h" #include "chrome/browser/sessions/session_service_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/window_sizer/window_sizer.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" namespace chrome { namespace { // Parse two comma-separated integers from str. Return true on success. bool ParseCommaSeparatedIntegers(const std::string& str, int* ret_num1, int* ret_num2) { size_t num1_size = str.find_first_of(','); if (num1_size == std::string::npos) return false; size_t num2_pos = num1_size + 1; size_t num2_size = str.size() - num2_pos; int num1 = 0; int num2 = 0; if (!base::StringToInt(str.substr(0, num1_size), &num1) || !base::StringToInt(str.substr(num2_pos, num2_size), &num2)) return false; *ret_num1 = num1; *ret_num2 = num2; return true; } class WindowPlacementPrefUpdate : public DictionaryPrefUpdate { public: WindowPlacementPrefUpdate(PrefService* service, const std::string& window_name) : DictionaryPrefUpdate(service, prefs::kAppWindowPlacement), window_name_(window_name) {} ~WindowPlacementPrefUpdate() override {} base::DictionaryValue* Get() override { base::DictionaryValue* all_apps_dict = DictionaryPrefUpdate::Get(); base::DictionaryValue* this_app_dict = NULL; if (!all_apps_dict->GetDictionary(window_name_, &this_app_dict)) { this_app_dict = new base::DictionaryValue; all_apps_dict->Set(window_name_, this_app_dict); } return this_app_dict; } private: const std::string window_name_; DISALLOW_COPY_AND_ASSIGN(WindowPlacementPrefUpdate); }; } // namespace std::string GetWindowName(const Browser* browser) { if (browser->app_name().empty()) { return browser->is_type_popup() ? prefs::kBrowserWindowPlacementPopup : prefs::kBrowserWindowPlacement; } return browser->app_name(); } scoped_ptr GetWindowPlacementDictionaryReadWrite( const std::string& window_name, PrefService* prefs) { DCHECK(!window_name.empty()); // A normal DictionaryPrefUpdate will suffice for non-app windows. if (prefs->FindPreference(window_name.c_str())) { return make_scoped_ptr( new DictionaryPrefUpdate(prefs, window_name.c_str())); } return scoped_ptr( new WindowPlacementPrefUpdate(prefs, window_name)); } const base::DictionaryValue* GetWindowPlacementDictionaryReadOnly( const std::string& window_name, PrefService* prefs) { DCHECK(!window_name.empty()); if (prefs->FindPreference(window_name.c_str())) return prefs->GetDictionary(window_name.c_str()); const base::DictionaryValue* app_windows = prefs->GetDictionary(prefs::kAppWindowPlacement); if (!app_windows) return NULL; const base::DictionaryValue* to_return = NULL; app_windows->GetDictionary(window_name, &to_return); return to_return; } bool ShouldSaveWindowPlacement(const Browser* browser) { // Only save the window placement of popups if the window is from a trusted // source (v1 app, devtools, or system window). return (browser->type() == Browser::TYPE_TABBED) || ((browser->type() == Browser::TYPE_POPUP) && browser->is_trusted_source()); } void SaveWindowPlacement(const Browser* browser, const gfx::Rect& bounds, ui::WindowShowState show_state) { // Save to the session storage service, used when reloading a past session. // Note that we don't want to be the ones who cause lazy initialization of // the session service. This function gets called during initial window // showing, and we don't want to bring in the session service this early. SessionService* session_service = SessionServiceFactory::GetForProfileIfExisting(browser->profile()); if (session_service) session_service->SetWindowBounds(browser->session_id(), bounds, show_state); } void GetSavedWindowBoundsAndShowState(const Browser* browser, gfx::Rect* bounds, ui::WindowShowState* show_state) { DCHECK(browser); DCHECK(bounds); DCHECK(show_state); *bounds = browser->override_bounds(); WindowSizer::GetBrowserWindowBoundsAndShowState(browser->app_name(), *bounds, browser, bounds, show_state); const base::CommandLine& parsed_command_line = *base::CommandLine::ForCurrentProcess(); if (parsed_command_line.HasSwitch(switches::kWindowSize)) { std::string str = parsed_command_line.GetSwitchValueASCII(switches::kWindowSize); int width, height; if (ParseCommaSeparatedIntegers(str, &width, &height)) bounds->set_size(gfx::Size(width, height)); } if (parsed_command_line.HasSwitch(switches::kWindowPosition)) { std::string str = parsed_command_line.GetSwitchValueASCII(switches::kWindowPosition); int x, y; if (ParseCommaSeparatedIntegers(str, &x, &y)) bounds->set_origin(gfx::Point(x, y)); } } } // namespace chrome