Index: chrome/browser/ui/extensions/shell_window.cc |
diff --git a/chrome/browser/ui/extensions/shell_window.cc b/chrome/browser/ui/extensions/shell_window.cc |
index 5d3f4af6c8a6a10ccbecf89a2503c6dbb22bd386..7e748a49774cddd4acb3d1c37a8309d77f7fe3ad 100644 |
--- a/chrome/browser/ui/extensions/shell_window.cc |
+++ b/chrome/browser/ui/extensions/shell_window.cc |
@@ -152,6 +152,7 @@ void ShellWindow::Init(const GURL& url, |
// If left and top are left undefined, the native shell window will center |
// the window on the main screen in a platform-defined manner. |
+ gfx::Rect cached_screen_bounds; |
ui::WindowShowState cached_state = ui::SHOW_STATE_DEFAULT; |
if (!params.window_key.empty()) { |
window_key_ = params.window_key; |
@@ -160,8 +161,8 @@ void ShellWindow::Init(const GURL& url, |
apps::ShellWindowGeometryCache::Get(profile()); |
gfx::Rect cached_bounds; |
- if (cache->GetGeometry(extension()->id(), params.window_key, |
- &cached_bounds, &cached_state)) { |
+ if (cache->GetGeometry(extension()->id(), params.window_key, &cached_bounds, |
+ &cached_screen_bounds, &cached_state)) { |
bounds = cached_bounds; |
} |
} |
@@ -195,6 +196,19 @@ void ShellWindow::Init(const GURL& url, |
native_app_window_.reset(NativeAppWindow::Create(this, new_params)); |
+ // App window has cached screen bounds, make sure it fits on screen in case of |
+ // the screen resolution changed before show. We can't adjust bounds before |
+ // the creation of native app window because current screen bounds is needed. |
+ if (!cached_screen_bounds.IsEmpty()) { |
+ gfx::Rect new_bounds; |
+ gfx::Rect current_screen_bounds = native_app_window_->GetScreenBounds(); |
+ AdjustBoundsToBeVisibleOnScreen(bounds, |
+ cached_screen_bounds, |
+ current_screen_bounds, |
+ minimum_size, |
+ &new_bounds); |
+ native_app_window_->SetBounds(new_bounds); |
+ } |
if (!new_params.hidden) { |
if (window_type_is_panel()) |
GetBaseWindow()->ShowInactive(); // Panels are not activated by default. |
@@ -618,10 +632,52 @@ void ShellWindow::SaveWindowPosition() { |
gfx::Rect bounds = native_app_window_->GetRestoredBounds(); |
bounds.Inset(native_app_window_->GetFrameInsets()); |
+ gfx::Rect screen_bounds = native_app_window_->GetScreenBounds(); |
ui::WindowShowState window_state = native_app_window_->GetRestoredState(); |
- cache->SaveGeometry(extension()->id(), window_key_, bounds, window_state); |
+ cache->SaveGeometry(extension()->id(), |
+ window_key_, |
+ bounds, |
+ screen_bounds, |
+ window_state); |
+} |
+ |
+void ShellWindow::AdjustBoundsToBeVisibleOnScreen( |
+ const gfx::Rect& cached_bounds, |
+ const gfx::Rect& cached_screen_bounds, |
+ const gfx::Rect& current_screen_bounds, |
+ const gfx::Size& minimum_size, |
+ gfx::Rect* bounds) const { |
+ if (!native_app_window_) |
+ return; |
+ if (!bounds) |
+ return; |
+ |
+ *bounds = cached_bounds; |
+ |
+ // Reposition and resize the bounds if the cached_screen_bounds is different |
+ // from the current screen bounds and the current screen bounds doesn't |
+ // completely contain the bounds. |
+ if (!cached_screen_bounds.IsEmpty() && |
+ cached_screen_bounds != current_screen_bounds && |
+ !current_screen_bounds.Contains(cached_bounds)) { |
+ bounds->set_width( |
+ std::max(minimum_size.width(), |
+ std::min(bounds->width(), current_screen_bounds.width()))); |
+ bounds->set_height( |
+ std::max(minimum_size.height(), |
+ std::min(bounds->height(), current_screen_bounds.height()))); |
+ bounds->set_x( |
+ std::max(current_screen_bounds.x(), |
+ std::min(bounds->x(), |
+ current_screen_bounds.right() - bounds->width()))); |
+ bounds->set_y( |
+ std::max(current_screen_bounds.y(), |
+ std::min(bounds->y(), |
+ current_screen_bounds.bottom() - bounds->height()))); |
+ } |
} |
+ |
// static |
SkRegion* ShellWindow::RawDraggableRegionsToSkRegion( |
const std::vector<extensions::DraggableRegion>& regions) { |