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#include "chrome/browser/ui/window_sizer/window_sizer.h" 6 7#include "ash/shell.h" 8#include "ash/wm/window_positioner.h" 9#include "ash/wm/window_state.h" 10#include "chrome/browser/ui/browser.h" 11#include "chrome/browser/ui/browser_window.h" 12#include "ui/aura/window.h" 13#include "ui/aura/window_event_dispatcher.h" 14#include "ui/gfx/screen.h" 15 16bool WindowSizer::GetBrowserBoundsAsh(gfx::Rect* bounds, 17 ui::WindowShowState* show_state) const { 18 if (!browser_ || 19 browser_->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH) 20 return false; 21 22 bool determined = false; 23 if (bounds->IsEmpty()) { 24 if (browser_->is_type_tabbed()) { 25 GetTabbedBrowserBoundsAsh(bounds, show_state); 26 determined = true; 27 } else if (browser_->is_trusted_source()) { 28 // For trusted popups (v1 apps and system windows), do not use the last 29 // active window bounds, only use saved or default bounds. 30 if (!GetSavedWindowBounds(bounds, show_state)) 31 GetDefaultWindowBounds(GetTargetDisplay(gfx::Rect()), bounds); 32 determined = true; 33 } else { 34 // In Ash, prioritize the last saved |show_state|. If you have questions 35 // or comments about this behavior please contact oshima@chromium.org. 36 if (state_provider_) { 37 gfx::Rect ignored_bounds, ignored_work_area; 38 state_provider_->GetPersistentState(&ignored_bounds, 39 &ignored_work_area, 40 show_state); 41 } 42 } 43 } else if (browser_->is_type_popup() && bounds->origin().IsOrigin()) { 44 // In case of a popup with an 'unspecified' location in ash, we are 45 // looking for a good screen location. We are interpreting (0,0) as an 46 // unspecified location. 47 *bounds = ash::Shell::GetInstance()->window_positioner()-> 48 GetPopupPosition(*bounds); 49 determined = true; 50 } 51 52 if (browser_->is_type_tabbed() && *show_state == ui::SHOW_STATE_DEFAULT) { 53 gfx::Display display = screen_->GetDisplayMatching(*bounds); 54 gfx::Rect work_area = display.work_area(); 55 bounds->AdjustToFit(work_area); 56 if (*bounds == work_area) { 57 // A |browser_| that occupies the whole work area gets maximized. 58 // |bounds| returned here become the restore bounds once the window 59 // gets maximized after this method returns. Return a sensible default 60 // in order to make restored state visibly different from maximized. 61 *show_state = ui::SHOW_STATE_MAXIMIZED; 62 *bounds = ash::WindowPositioner::GetDefaultWindowBounds(display); 63 determined = true; 64 } 65 } 66 return determined; 67} 68 69void WindowSizer::GetTabbedBrowserBoundsAsh( 70 gfx::Rect* bounds_in_screen, 71 ui::WindowShowState* show_state) const { 72 DCHECK(show_state); 73 DCHECK(bounds_in_screen); 74 DCHECK(browser_->is_type_tabbed()); 75 DCHECK(bounds_in_screen->IsEmpty()); 76 77 ui::WindowShowState passed_show_state = *show_state; 78 79 bool is_saved_bounds = GetSavedWindowBounds(bounds_in_screen, show_state); 80 gfx::Display display; 81 if (is_saved_bounds) { 82 display = screen_->GetDisplayMatching(*bounds_in_screen); 83 } else { 84 // If there is no saved bounds (hence bounds_in_screen is empty), use the 85 // target display. 86 display = target_display_provider_->GetTargetDisplay(screen_, 87 *bounds_in_screen); 88 *bounds_in_screen = ash::WindowPositioner::GetDefaultWindowBounds(display); 89 } 90 91 if (browser_->is_session_restore()) { 92 // This is a fall-through case when there is no bounds recorded 93 // for restored window, and should not be used except for the case 94 // above. The regular path is handled in 95 // |WindowSizer::DetermineWindowBoundsAndShowState|. 96 97 // Note: How restore bounds/show state data are passed. 98 // The restore bounds is passed via |Browser::override_bounds()| in 99 // |chrome::GetBrowserWindowBoundsAndShowState()|. 100 // The restore state is passed via |Browser::initial_state()| in 101 // |WindowSizer::GetWindowDefaultShowState|. 102 bounds_in_screen->AdjustToFit(display.work_area()); 103 return; 104 } 105 106 // The |browser_window| is non NULL when this is called after 107 // browser's aura window is created. 108 aura::Window* browser_window = 109 browser_->window() ? browser_->window()->GetNativeWindow() : NULL; 110 111 ash::WindowPositioner::GetBoundsAndShowStateForNewWindow( 112 screen_, 113 browser_window, 114 is_saved_bounds, 115 passed_show_state, 116 bounds_in_screen, 117 show_state); 118} 119