| Index: apps/app_window.cc
|
| diff --git a/apps/app_window.cc b/apps/app_window.cc
|
| index 8bb2b7ec0987e4a6a2ec49b37d7fcc04ef64cab6..e6f5a5e6f05554f128ddb929273db7c978af8ffd 100644
|
| --- a/apps/app_window.cc
|
| +++ b/apps/app_window.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "apps/app_window.h"
|
|
|
| +#include <algorithm>
|
| +
|
| #include "apps/app_window_geometry_cache.h"
|
| #include "apps/app_window_registry.h"
|
| #include "apps/apps_client.h"
|
| @@ -95,14 +97,62 @@ void SetBoundsProperties(const gfx::Rect& bounds,
|
| window_properties->Set(bounds_name, bounds_properties.release());
|
| }
|
|
|
| +// Combines the constraints of the content and window, and returns constraints
|
| +// for the window.
|
| +gfx::Size GetCombinedWindowConstraints(const gfx::Size& window_constraints,
|
| + const gfx::Size& content_constraints,
|
| + const gfx::Insets& frame_insets) {
|
| + gfx::Size combined_constraints(window_constraints);
|
| + if (content_constraints.width() > 0) {
|
| + combined_constraints.set_width(
|
| + content_constraints.width() + frame_insets.width());
|
| + }
|
| + if (content_constraints.height() > 0) {
|
| + combined_constraints.set_height(
|
| + content_constraints.height() + frame_insets.height());
|
| + }
|
| + return combined_constraints;
|
| +}
|
| +
|
| +// Combines the constraints of the content and window, and returns constraints
|
| +// for the content.
|
| +gfx::Size GetCombinedContentConstraints(const gfx::Size& window_constraints,
|
| + const gfx::Size& content_constraints,
|
| + const gfx::Insets& frame_insets) {
|
| + gfx::Size combined_constraints(content_constraints);
|
| + if (window_constraints.width() > 0) {
|
| + combined_constraints.set_width(
|
| + std::max(0, window_constraints.width() - frame_insets.width()));
|
| + }
|
| + if (window_constraints.height() > 0) {
|
| + combined_constraints.set_height(
|
| + std::max(0, window_constraints.height() - frame_insets.height()));
|
| + }
|
| + return combined_constraints;
|
| +}
|
| +
|
| } // namespace
|
|
|
| +// AppWindow::BoundsSpecification
|
| +
|
| +const int AppWindow::BoundsSpecification::kUnspecifiedPosition = INT_MIN;
|
| +
|
| +AppWindow::BoundsSpecification::BoundsSpecification()
|
| + : bounds(kUnspecifiedPosition, kUnspecifiedPosition, 0, 0) {}
|
| +
|
| +AppWindow::BoundsSpecification::~BoundsSpecification() {}
|
| +
|
| +void AppWindow::BoundsSpecification::ResetBounds() {
|
| + bounds.SetRect(kUnspecifiedPosition, kUnspecifiedPosition, 0, 0);
|
| +}
|
| +
|
| +// AppWindow::CreateParams
|
| +
|
| AppWindow::CreateParams::CreateParams()
|
| : window_type(AppWindow::WINDOW_TYPE_DEFAULT),
|
| frame(AppWindow::FRAME_CHROME),
|
| has_frame_color(false),
|
| transparent_background(false),
|
| - bounds(INT_MIN, INT_MIN, 0, 0),
|
| creator_process_id(0),
|
| state(ui::SHOW_STATE_DEFAULT),
|
| hidden(false),
|
| @@ -112,8 +162,68 @@ AppWindow::CreateParams::CreateParams()
|
|
|
| AppWindow::CreateParams::~CreateParams() {}
|
|
|
| +gfx::Rect AppWindow::CreateParams::GetInitialWindowBounds(
|
| + const gfx::Insets& frame_insets) const {
|
| + // Combine into a single window bounds.
|
| + gfx::Rect combined_bounds(window_spec.bounds);
|
| + if (content_spec.bounds.x() != BoundsSpecification::kUnspecifiedPosition)
|
| + combined_bounds.set_x(content_spec.bounds.x() - frame_insets.left());
|
| + if (content_spec.bounds.y() != BoundsSpecification::kUnspecifiedPosition)
|
| + combined_bounds.set_y(content_spec.bounds.y() - frame_insets.top());
|
| + if (content_spec.bounds.width() > 0) {
|
| + combined_bounds.set_width(
|
| + content_spec.bounds.width() + frame_insets.width());
|
| + }
|
| + if (content_spec.bounds.height() > 0) {
|
| + combined_bounds.set_height(
|
| + content_spec.bounds.height() + frame_insets.height());
|
| + }
|
| +
|
| + // Constrain the bounds.
|
| + SizeConstraints constraints(
|
| + GetCombinedWindowConstraints(
|
| + window_spec.minimum_size, content_spec.minimum_size, frame_insets),
|
| + GetCombinedWindowConstraints(
|
| + window_spec.maximum_size, content_spec.maximum_size, frame_insets));
|
| + combined_bounds.set_size(constraints.ClampSize(combined_bounds.size()));
|
| +
|
| + return combined_bounds;
|
| +}
|
| +
|
| +gfx::Size AppWindow::CreateParams::GetContentMinimumSize(
|
| + const gfx::Insets& frame_insets) const {
|
| + return GetCombinedContentConstraints(window_spec.minimum_size,
|
| + content_spec.minimum_size,
|
| + frame_insets);
|
| +}
|
| +
|
| +gfx::Size AppWindow::CreateParams::GetContentMaximumSize(
|
| + const gfx::Insets& frame_insets) const {
|
| + return GetCombinedContentConstraints(window_spec.maximum_size,
|
| + content_spec.maximum_size,
|
| + frame_insets);
|
| +}
|
| +
|
| +gfx::Size AppWindow::CreateParams::GetWindowMinimumSize(
|
| + const gfx::Insets& frame_insets) const {
|
| + return GetCombinedWindowConstraints(window_spec.minimum_size,
|
| + content_spec.minimum_size,
|
| + frame_insets);
|
| +}
|
| +
|
| +gfx::Size AppWindow::CreateParams::GetWindowMaximumSize(
|
| + const gfx::Insets& frame_insets) const {
|
| + return GetCombinedWindowConstraints(window_spec.maximum_size,
|
| + content_spec.maximum_size,
|
| + frame_insets);
|
| +}
|
| +
|
| +// AppWindow::Delegate
|
| +
|
| AppWindow::Delegate::~Delegate() {}
|
|
|
| +// AppWindow
|
| +
|
| AppWindow::AppWindow(BrowserContext* context,
|
| Delegate* delegate,
|
| const extensions::Extension* extension)
|
| @@ -154,7 +264,7 @@ void AppWindow::Init(const GURL& url,
|
| extensions::SetViewType(web_contents, extensions::VIEW_TYPE_APP_WINDOW);
|
|
|
| // Initialize the window
|
| - CreateParams new_params = LoadDefaultsAndConstrain(params);
|
| + CreateParams new_params = LoadDefaults(params);
|
| window_type_ = new_params.window_type;
|
| window_key_ = new_params.window_key;
|
|
|
| @@ -208,7 +318,10 @@ void AppWindow::Init(const GURL& url,
|
| // that to happen, we need to define a size for the content, otherwise the
|
| // layout will happen in a 0x0 area.
|
| // Note: WebContents::GetView() is guaranteed to be non-null.
|
| - web_contents->GetView()->SizeContents(new_params.bounds.size());
|
| + gfx::Insets frame_insets = native_app_window_->GetFrameInsets();
|
| + gfx::Rect initial_bounds = new_params.GetInitialWindowBounds(frame_insets);
|
| + initial_bounds.Inset(frame_insets);
|
| + web_contents->GetView()->SizeContents(initial_bounds.size());
|
| }
|
|
|
| // Prevent the browser process from shutting down while this window is open.
|
| @@ -519,13 +632,13 @@ void AppWindow::ForcedFullscreen() {
|
| SetNativeWindowFullscreen();
|
| }
|
|
|
| -void AppWindow::SetMinimumSize(const gfx::Size& min_size) {
|
| - native_app_window_->SetMinimumSize(min_size);
|
| +void AppWindow::SetContentMinimumSize(const gfx::Size& min_size) {
|
| + native_app_window_->SetContentMinimumSize(min_size);
|
| OnSizeConstraintsChanged();
|
| }
|
|
|
| -void AppWindow::SetMaximumSize(const gfx::Size& max_size) {
|
| - native_app_window_->SetMaximumSize(max_size);
|
| +void AppWindow::SetContentMaximumSize(const gfx::Size& max_size) {
|
| + native_app_window_->SetContentMaximumSize(max_size);
|
| OnSizeConstraintsChanged();
|
| }
|
|
|
| @@ -588,17 +701,23 @@ void AppWindow::GetSerializedState(base::DictionaryValue* properties) const {
|
| properties->SetInteger("frameColor", native_app_window_->FrameColor());
|
|
|
| gfx::Rect content_bounds = GetClientBounds();
|
| + gfx::Size content_min_size = native_app_window_->GetContentMinimumSize();
|
| + gfx::Size content_max_size = native_app_window_->GetContentMaximumSize();
|
| SetBoundsProperties(content_bounds,
|
| - native_app_window_->GetMinimumSize(),
|
| - native_app_window_->GetMaximumSize(),
|
| + content_min_size,
|
| + content_max_size,
|
| "innerBounds",
|
| properties);
|
|
|
| - // TODO(tmdiep): Frame constraints will be implemented in a future patch.
|
| + gfx::Insets frame_insets = native_app_window_->GetFrameInsets();
|
| gfx::Rect frame_bounds = native_app_window_->GetBounds();
|
| + gfx::Size frame_min_size =
|
| + SizeConstraints::AddFrameToConstraints(content_min_size, frame_insets);
|
| + gfx::Size frame_max_size =
|
| + SizeConstraints::AddFrameToConstraints(content_max_size, frame_insets);
|
| SetBoundsProperties(frame_bounds,
|
| - gfx::Size(),
|
| - gfx::Size(),
|
| + frame_min_size,
|
| + frame_max_size,
|
| "outerBounds",
|
| properties);
|
| }
|
| @@ -663,12 +782,13 @@ void AppWindow::UpdateExtensionAppIcon() {
|
| }
|
|
|
| void AppWindow::OnSizeConstraintsChanged() {
|
| - SizeConstraints size_constraints(native_app_window_->GetMinimumSize(),
|
| - native_app_window_->GetMaximumSize());
|
| + SizeConstraints size_constraints(native_app_window_->GetContentMinimumSize(),
|
| + native_app_window_->GetContentMaximumSize());
|
| gfx::Rect bounds = GetClientBounds();
|
| gfx::Size constrained_size = size_constraints.ClampSize(bounds.size());
|
| if (bounds.size() != constrained_size) {
|
| bounds.set_size(constrained_size);
|
| + bounds.Inset(-native_app_window_->GetFrameInsets());
|
| native_app_window_->SetBounds(bounds);
|
| }
|
| OnNativeWindowChanged();
|
| @@ -852,7 +972,6 @@ void AppWindow::SaveWindowPosition() {
|
| AppWindowGeometryCache::Get(browser_context());
|
|
|
| gfx::Rect bounds = native_app_window_->GetRestoredBounds();
|
| - bounds.Inset(native_app_window_->GetFrameInsets());
|
| gfx::Rect screen_bounds =
|
| gfx::Screen::GetNativeScreen()->GetDisplayMatching(bounds).work_area();
|
| ui::WindowShowState window_state = native_app_window_->GetRestoredState();
|
| @@ -890,12 +1009,17 @@ void AppWindow::AdjustBoundsToBeVisibleOnScreen(
|
| }
|
| }
|
|
|
| -AppWindow::CreateParams AppWindow::LoadDefaultsAndConstrain(CreateParams params)
|
| +AppWindow::CreateParams AppWindow::LoadDefaults(CreateParams params)
|
| const {
|
| - if (params.bounds.width() == 0)
|
| - params.bounds.set_width(kDefaultWidth);
|
| - if (params.bounds.height() == 0)
|
| - params.bounds.set_height(kDefaultHeight);
|
| + // Ensure width and height are specified.
|
| + if (params.content_spec.bounds.width() == 0 &&
|
| + params.window_spec.bounds.width() == 0) {
|
| + params.content_spec.bounds.set_width(kDefaultWidth);
|
| + }
|
| + if (params.content_spec.bounds.height() == 0 &&
|
| + params.window_spec.bounds.height() == 0) {
|
| + params.content_spec.bounds.set_height(kDefaultHeight);
|
| + }
|
|
|
| // If left and top are left undefined, the native app window will center
|
| // the window on the main screen in a platform-defined manner.
|
| @@ -913,25 +1037,27 @@ AppWindow::CreateParams AppWindow::LoadDefaultsAndConstrain(CreateParams params)
|
| &cached_bounds,
|
| &cached_screen_bounds,
|
| &cached_state)) {
|
| +
|
| // App window has cached screen bounds, make sure it fits on screen in
|
| // case the screen resolution changed.
|
| gfx::Screen* screen = gfx::Screen::GetNativeScreen();
|
| gfx::Display display = screen->GetDisplayMatching(cached_bounds);
|
| gfx::Rect current_screen_bounds = display.work_area();
|
| + SizeConstraints constraints(params.GetWindowMinimumSize(gfx::Insets()),
|
| + params.GetWindowMaximumSize(gfx::Insets()));
|
| AdjustBoundsToBeVisibleOnScreen(cached_bounds,
|
| cached_screen_bounds,
|
| current_screen_bounds,
|
| - params.minimum_size,
|
| - ¶ms.bounds);
|
| + constraints.GetMinimumSize(),
|
| + ¶ms.window_spec.bounds);
|
| params.state = cached_state;
|
| +
|
| + // Since we are restoring a cached state, reset the content bounds spec to
|
| + // ensure it is not used.
|
| + params.content_spec.ResetBounds();
|
| }
|
| }
|
|
|
| - SizeConstraints size_constraints(params.minimum_size, params.maximum_size);
|
| - params.bounds.set_size(size_constraints.ClampSize(params.bounds.size()));
|
| - params.minimum_size = size_constraints.GetMinimumSize();
|
| - params.maximum_size = size_constraints.GetMaximumSize();
|
| -
|
| return params;
|
| }
|
|
|
|
|