Commit 0026387d authored by rfevang@chromium.org's avatar rfevang@chromium.org

Limit constrained windows to the size of the parent view.

Constrained windows would get drawn partially outside the browser
window, obscuring some of the contents. This CL limits their size so
everything is in view. This mimics the behavior of the old style
dialogs.

This CL also changes the size request to use the current preferred size
of the view, instead of reusing the existing size. Some dialogs (like
the print preview) changes their size preferences when the browser
window size changes, so the old size might not be optimal any more.

Additionally, added a GetMinimumSize to the bubble frame view, as
previously GetPreferredSize would get used, effectively undoing the
additional restrictions placed based on Window sizes.

BUG=272760,274236,276150

Review URL: https://chromiumcodereview.appspot.com/22903022

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@221573 0039d316-1c4b-4281-b951-d872f2087c98
parent 4e7cca28
...@@ -230,6 +230,10 @@ gfx::Point WebUILoginView::GetDialogPosition(const gfx::Size& size) { ...@@ -230,6 +230,10 @@ gfx::Point WebUILoginView::GetDialogPosition(const gfx::Size& size) {
widget_size.height() / 2 - size.height() / 2); widget_size.height() / 2 - size.height() / 2);
} }
gfx::Size WebUILoginView::GetMaximumDialogSize() {
return GetWidget()->GetWindowBoundsInScreen().size();
}
void WebUILoginView::AddObserver( void WebUILoginView::AddObserver(
web_modal::WebContentsModalDialogHostObserver* observer) { web_modal::WebContentsModalDialogHostObserver* observer) {
if (observer && !observer_list_.HasObserver(observer)) if (observer && !observer_list_.HasObserver(observer))
......
...@@ -63,6 +63,7 @@ class WebUILoginView : public views::View, ...@@ -63,6 +63,7 @@ class WebUILoginView : public views::View,
// Overridden from web_modal::WebContentsModalDialogHost: // Overridden from web_modal::WebContentsModalDialogHost:
virtual gfx::NativeView GetHostView() const OVERRIDE; virtual gfx::NativeView GetHostView() const OVERRIDE;
virtual gfx::Point GetDialogPosition(const gfx::Size& size) OVERRIDE; virtual gfx::Point GetDialogPosition(const gfx::Size& size) OVERRIDE;
virtual gfx::Size GetMaximumDialogSize() OVERRIDE;
virtual void AddObserver( virtual void AddObserver(
web_modal::WebContentsModalDialogHostObserver* observer) OVERRIDE; web_modal::WebContentsModalDialogHostObserver* observer) OVERRIDE;
virtual void RemoveObserver( virtual void RemoveObserver(
......
...@@ -311,6 +311,12 @@ gfx::Point ExtensionHost::GetDialogPosition(const gfx::Size& size) { ...@@ -311,6 +311,12 @@ gfx::Point ExtensionHost::GetDialogPosition(const gfx::Size& size) {
std::max(0, (bounds.height() - size.height()) / 2)); std::max(0, (bounds.height() - size.height()) / 2));
} }
gfx::Size ExtensionHost::GetMaximumDialogSize() {
if (!GetVisibleWebContents())
return gfx::Size();
return GetVisibleWebContents()->GetView()->GetViewBounds().size();
}
void ExtensionHost::AddObserver( void ExtensionHost::AddObserver(
web_modal::WebContentsModalDialogHostObserver* observer) { web_modal::WebContentsModalDialogHostObserver* observer) {
} }
......
...@@ -208,6 +208,7 @@ class ExtensionHost : public content::WebContentsDelegate, ...@@ -208,6 +208,7 @@ class ExtensionHost : public content::WebContentsDelegate,
// web_modal::WebContentsModalDialogHost // web_modal::WebContentsModalDialogHost
virtual gfx::NativeView GetHostView() const OVERRIDE; virtual gfx::NativeView GetHostView() const OVERRIDE;
virtual gfx::Point GetDialogPosition(const gfx::Size& size) OVERRIDE; virtual gfx::Point GetDialogPosition(const gfx::Size& size) OVERRIDE;
virtual gfx::Size GetMaximumDialogSize() OVERRIDE;
virtual void AddObserver( virtual void AddObserver(
web_modal::WebContentsModalDialogHostObserver* observer) OVERRIDE; web_modal::WebContentsModalDialogHostObserver* observer) OVERRIDE;
virtual void RemoveObserver( virtual void RemoveObserver(
......
...@@ -46,6 +46,10 @@ class PrintPreviewTestBrowserWindow ...@@ -46,6 +46,10 @@ class PrintPreviewTestBrowserWindow
return gfx::Point(); return gfx::Point();
} }
virtual gfx::Size GetMaximumDialogSize() OVERRIDE {
return gfx::Size();
}
virtual void AddObserver( virtual void AddObserver(
WebContentsModalDialogHostObserver* observer) OVERRIDE {} WebContentsModalDialogHostObserver* observer) OVERRIDE {}
virtual void RemoveObserver( virtual void RemoveObserver(
......
...@@ -129,6 +129,7 @@ class NativeAppWindowCocoa : public apps::NativeAppWindow { ...@@ -129,6 +129,7 @@ class NativeAppWindowCocoa : public apps::NativeAppWindow {
// WebContentsModalDialogHost implementation. // WebContentsModalDialogHost implementation.
virtual gfx::NativeView GetHostView() const OVERRIDE; virtual gfx::NativeView GetHostView() const OVERRIDE;
virtual gfx::Point GetDialogPosition(const gfx::Size& size) OVERRIDE; virtual gfx::Point GetDialogPosition(const gfx::Size& size) OVERRIDE;
virtual gfx::Size GetMaximumDialogSize() OVERRIDE;
virtual void AddObserver( virtual void AddObserver(
web_modal::WebContentsModalDialogHostObserver* observer) OVERRIDE; web_modal::WebContentsModalDialogHostObserver* observer) OVERRIDE;
virtual void RemoveObserver( virtual void RemoveObserver(
......
...@@ -794,6 +794,11 @@ gfx::Point NativeAppWindowCocoa::GetDialogPosition(const gfx::Size& size) { ...@@ -794,6 +794,11 @@ gfx::Point NativeAppWindowCocoa::GetDialogPosition(const gfx::Size& size) {
return gfx::Point(); return gfx::Point();
} }
gfx::Size NativeAppWindowCocoa::GetMaximumDialogSize() {
NOTIMPLEMENTED();
return gfx::Size();
}
void NativeAppWindowCocoa::AddObserver( void NativeAppWindowCocoa::AddObserver(
web_modal::WebContentsModalDialogHostObserver* observer) { web_modal::WebContentsModalDialogHostObserver* observer) {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
......
...@@ -384,6 +384,13 @@ gfx::Point NativeAppWindowGtk::GetDialogPosition(const gfx::Size& size) { ...@@ -384,6 +384,13 @@ gfx::Point NativeAppWindowGtk::GetDialogPosition(const gfx::Size& size) {
current_height / 2 - size.height() / 2); current_height / 2 - size.height() / 2);
} }
gfx::Size NativeAppWindowGtk::GetMaximumDialogSize() {
gint current_width = 0;
gint current_height = 0;
gtk_window_get_size(window_, &current_width, &current_height);
return gfx::Size(current_width, current_height);
}
void NativeAppWindowGtk::AddObserver( void NativeAppWindowGtk::AddObserver(
web_modal::WebContentsModalDialogHostObserver* observer) { web_modal::WebContentsModalDialogHostObserver* observer) {
observer_list_.AddObserver(observer); observer_list_.AddObserver(observer);
......
...@@ -77,6 +77,7 @@ class NativeAppWindowGtk : public apps::NativeAppWindow, ...@@ -77,6 +77,7 @@ class NativeAppWindowGtk : public apps::NativeAppWindow,
// web_modal::WebContentsModalDialogHost implementation. // web_modal::WebContentsModalDialogHost implementation.
virtual gfx::NativeView GetHostView() const OVERRIDE; virtual gfx::NativeView GetHostView() const OVERRIDE;
virtual gfx::Point GetDialogPosition(const gfx::Size& size) OVERRIDE; virtual gfx::Point GetDialogPosition(const gfx::Size& size) OVERRIDE;
virtual gfx::Size GetMaximumDialogSize() OVERRIDE;
virtual void AddObserver( virtual void AddObserver(
web_modal::WebContentsModalDialogHostObserver* observer) OVERRIDE; web_modal::WebContentsModalDialogHostObserver* observer) OVERRIDE;
virtual void RemoveObserver( virtual void RemoveObserver(
......
...@@ -449,6 +449,10 @@ gfx::Point NativeAppWindowViews::GetDialogPosition(const gfx::Size& size) { ...@@ -449,6 +449,10 @@ gfx::Point NativeAppWindowViews::GetDialogPosition(const gfx::Size& size) {
shell_window_size.height() / 2 - size.height() / 2); shell_window_size.height() / 2 - size.height() / 2);
} }
gfx::Size NativeAppWindowViews::GetMaximumDialogSize() {
return window_->GetWindowBoundsInScreen().size();
}
void NativeAppWindowViews::AddObserver( void NativeAppWindowViews::AddObserver(
web_modal::WebContentsModalDialogHostObserver* observer) { web_modal::WebContentsModalDialogHostObserver* observer) {
observer_list_.AddObserver(observer); observer_list_.AddObserver(observer);
......
...@@ -148,6 +148,7 @@ class NativeAppWindowViews : public apps::NativeAppWindow, ...@@ -148,6 +148,7 @@ class NativeAppWindowViews : public apps::NativeAppWindow,
// web_modal::WebContentsModalDialogHost implementation. // web_modal::WebContentsModalDialogHost implementation.
virtual gfx::NativeView GetHostView() const OVERRIDE; virtual gfx::NativeView GetHostView() const OVERRIDE;
virtual gfx::Point GetDialogPosition(const gfx::Size& size) OVERRIDE; virtual gfx::Point GetDialogPosition(const gfx::Size& size) OVERRIDE;
virtual gfx::Size GetMaximumDialogSize() OVERRIDE;
virtual void AddObserver( virtual void AddObserver(
web_modal::WebContentsModalDialogHostObserver* observer) OVERRIDE; web_modal::WebContentsModalDialogHostObserver* observer) OVERRIDE;
virtual void RemoveObserver( virtual void RemoveObserver(
......
...@@ -570,11 +570,19 @@ void ConstrainedWindowFrameView::InitClass() { ...@@ -570,11 +570,19 @@ void ConstrainedWindowFrameView::InitClass() {
void UpdateWebContentsModalDialogPosition( void UpdateWebContentsModalDialogPosition(
views::Widget* widget, views::Widget* widget,
web_modal::WebContentsModalDialogHost* dialog_host) { web_modal::WebContentsModalDialogHost* dialog_host) {
gfx::Size size = widget->GetWindowBoundsInScreen().size(); gfx::Size size = widget->GetRootView()->GetPreferredSize();
gfx::Point position = dialog_host->GetDialogPosition(size);
views::Border* border = views::Border* border =
widget->non_client_view()->frame_view()->border(); widget->non_client_view()->frame_view()->border();
gfx::Size max_size = dialog_host->GetMaximumDialogSize();
// Enlarge the max size by the top border, as the dialog will be shifted
// outside the area specified by the dialog host by this amount later in the
// function.
// Border may be null during widget initialization. // Border may be null during widget initialization.
if (border)
max_size.Enlarge(0, border->GetInsets().top());
size.SetToMin(max_size);
gfx::Point position = dialog_host->GetDialogPosition(size);
if (border) { if (border) {
// Align the first row of pixels inside the border. This is the apparent // Align the first row of pixels inside the border. This is the apparent
// top of the dialog. // top of the dialog.
......
// Copyright 2013 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/views/constrained_window_views.h"
#include "components/web_modal/web_contents_modal_dialog_host.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/point.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/widget.h"
#include "ui/views/window/dialog_delegate.h"
namespace web_modal {
class WebContentsModalDialogHostObserver;
}
namespace views {
class DialogContents : public DialogDelegateView {
public:
DialogContents() {}
virtual ~DialogContents() {}
void set_preferred_size(const gfx::Size& preferred_size) {
preferred_size_ = preferred_size;
}
// Overriden from DialogDelegateView:
virtual View* GetContentsView() OVERRIDE { return this; }
virtual gfx::Size GetPreferredSize() OVERRIDE { return preferred_size_; }
virtual gfx::Size GetMinimumSize() OVERRIDE { return gfx::Size(); }
private:
gfx::Size preferred_size_;
DISALLOW_COPY_AND_ASSIGN(DialogContents);
};
class DialogHost : public web_modal::WebContentsModalDialogHost {
public:
explicit DialogHost(gfx::NativeView host_view)
: host_view_(host_view),
max_dialog_size_(5000, 5000) {
}
virtual ~DialogHost() {}
void set_max_dialog_size(const gfx::Size& max_dialog_size) {
max_dialog_size_ = max_dialog_size;
}
// Overridden from WebContentsModalDialogHost:
virtual gfx::NativeView GetHostView() const OVERRIDE { return host_view_; }
virtual gfx::Point GetDialogPosition(const gfx::Size& size) OVERRIDE {
return gfx::Point();
}
virtual gfx::Size GetMaximumDialogSize() OVERRIDE { return max_dialog_size_; }
virtual void AddObserver(
web_modal::WebContentsModalDialogHostObserver* observer) OVERRIDE {};
virtual void RemoveObserver(
web_modal::WebContentsModalDialogHostObserver* observer) OVERRIDE {};
private:
gfx::NativeView host_view_;
gfx::Size max_dialog_size_;
DISALLOW_COPY_AND_ASSIGN(DialogHost);
};
typedef ViewsTestBase ConstrainedWindowViewsTest;
TEST_F(ConstrainedWindowViewsTest, UpdateDialogPosition) {
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
Widget parent;
parent.Init(params);
DialogContents* contents = new DialogContents;
Widget* dialog =
CreateBrowserModalDialogViews(contents, parent.GetNativeWindow());
DialogHost dialog_host(parent.GetNativeView());
UpdateWebContentsModalDialogPosition(dialog, &dialog_host);
// Set the preferred size to something larger than the size of a dialog with
// no content.
gfx::Size preferred_size = dialog->GetClientAreaBoundsInScreen().size();
preferred_size.Enlarge(50, 50);
contents->set_preferred_size(preferred_size);
UpdateWebContentsModalDialogPosition(dialog, &dialog_host);
// Now increase the preferred content area and make sure the dialog grows by
// the same amount after the position is updated.
gfx::Size expected_size = dialog->GetClientAreaBoundsInScreen().size();
expected_size.Enlarge(200, 200);
preferred_size.Enlarge(200, 200);
contents->set_preferred_size(preferred_size);
UpdateWebContentsModalDialogPosition(dialog, &dialog_host);
EXPECT_EQ(expected_size, dialog->GetClientAreaBoundsInScreen().size());
// Make sure the dialog shrinks when the preferred content area shrinks.
expected_size.Enlarge(-200, -200);
preferred_size.Enlarge(-200, -200);
contents->set_preferred_size(preferred_size);
UpdateWebContentsModalDialogPosition(dialog, &dialog_host);
EXPECT_EQ(expected_size, dialog->GetClientAreaBoundsInScreen().size());
// Make sure the dialog is never larger than the max dialog size the dialog
// host can handle.
gfx::Size full_dialog_size = dialog->GetClientAreaBoundsInScreen().size();
gfx::Size max_dialog_size = full_dialog_size;
max_dialog_size.Enlarge(-100, -100);
dialog_host.set_max_dialog_size(max_dialog_size);
UpdateWebContentsModalDialogPosition(dialog, &dialog_host);
// The top border of the dialog is intentionally drawn outside the area
// specified by the dialog host, so add it to the size the dialog is expected
// to occupy.
expected_size = max_dialog_size;
Border* border = dialog->non_client_view()->frame_view()->border();
if (border)
expected_size.Enlarge(0, border->GetInsets().top());
EXPECT_EQ(expected_size,
dialog->non_client_view()->GetBoundsInScreen().size());
// Enlarge the max area again and make sure the dialog again uses its
// preferred size.
dialog_host.set_max_dialog_size(gfx::Size(5000, 5000));
UpdateWebContentsModalDialogPosition(dialog, &dialog_host);
EXPECT_EQ(full_dialog_size, dialog->GetClientAreaBoundsInScreen().size());
}
} // namespace views
...@@ -99,6 +99,20 @@ class BrowserViewLayout::WebContentsModalDialogHostViews ...@@ -99,6 +99,20 @@ class BrowserViewLayout::WebContentsModalDialogHostViews
return gfx::Point(middle_x - size.width() / 2, top_y); return gfx::Point(middle_x - size.width() / 2, top_y);
} }
virtual gfx::Size GetMaximumDialogSize() OVERRIDE {
gfx::Rect content_area =
browser_view_layout_->contents_container_->ConvertRectToWidget(
browser_view_layout_->contents_container_->GetLocalBounds());
gfx::Size max_dialog_size = content_area.size();
// Adjust for difference in alignment between the dialog top and the top of
// the content area.
int height_offset = content_area.y() -
browser_view_layout_->web_contents_modal_dialog_top_y_;
max_dialog_size.Enlarge(0, height_offset);
return max_dialog_size;
}
// Add/remove observer. // Add/remove observer.
virtual void AddObserver( virtual void AddObserver(
WebContentsModalDialogHostObserver* observer) OVERRIDE { WebContentsModalDialogHostObserver* observer) OVERRIDE {
......
...@@ -1641,6 +1641,7 @@ ...@@ -1641,6 +1641,7 @@
'browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc', 'browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc',
'browser/ui/views/bookmarks/bookmark_sync_promo_view_unittest.cc', 'browser/ui/views/bookmarks/bookmark_sync_promo_view_unittest.cc',
'browser/ui/views/confirm_bubble_views_unittest.cc', 'browser/ui/views/confirm_bubble_views_unittest.cc',
'browser/ui/views/constrained_window_views_unittest.cc',
'browser/ui/views/crypto_module_password_dialog_view_unittest.cc', 'browser/ui/views/crypto_module_password_dialog_view_unittest.cc',
'browser/ui/views/extensions/browser_action_drag_data_unittest.cc', 'browser/ui/views/extensions/browser_action_drag_data_unittest.cc',
'browser/ui/views/first_run_bubble_unittest.cc', 'browser/ui/views/first_run_bubble_unittest.cc',
......
...@@ -6,8 +6,11 @@ ...@@ -6,8 +6,11 @@
#define COMPONENTS_WEB_MODAL_WEB_CONTENTS_MODAL_DIALOG_HOST_H_ #define COMPONENTS_WEB_MODAL_WEB_CONTENTS_MODAL_DIALOG_HOST_H_
#include "ui/gfx/native_widget_types.h" #include "ui/gfx/native_widget_types.h"
#include "ui/gfx/point.h"
#include "ui/gfx/size.h" namespace gfx {
class Point;
class Size;
}
namespace web_modal { namespace web_modal {
...@@ -39,6 +42,9 @@ class WebContentsModalDialogHost { ...@@ -39,6 +42,9 @@ class WebContentsModalDialogHost {
// view. // view.
virtual gfx::Point GetDialogPosition(const gfx::Size& size) = 0; virtual gfx::Point GetDialogPosition(const gfx::Size& size) = 0;
// Returns the maximum dimensions a dialog can have.
virtual gfx::Size GetMaximumDialogSize() = 0;
// Add/remove observer. // Add/remove observer.
virtual void AddObserver(WebContentsModalDialogHostObserver* observer) = 0; virtual void AddObserver(WebContentsModalDialogHostObserver* observer) = 0;
virtual void RemoveObserver(WebContentsModalDialogHostObserver* observer) = 0; virtual void RemoveObserver(WebContentsModalDialogHostObserver* observer) = 0;
......
...@@ -168,18 +168,11 @@ gfx::Insets BubbleFrameView::GetInsets() const { ...@@ -168,18 +168,11 @@ gfx::Insets BubbleFrameView::GetInsets() const {
} }
gfx::Size BubbleFrameView::GetPreferredSize() { gfx::Size BubbleFrameView::GetPreferredSize() {
const gfx::Size client(GetWidget()->client_view()->GetPreferredSize()); return GetSizeForClientSize(GetWidget()->client_view()->GetPreferredSize());
gfx::Size size(GetUpdatedWindowBounds(gfx::Rect(), client, false).size()); }
// Accommodate the width of the title bar elements.
int title_bar_width = GetInsets().width() + border()->GetInsets().width(); gfx::Size BubbleFrameView::GetMinimumSize() {
if (!title_->text().empty()) return GetSizeForClientSize(GetWidget()->client_view()->GetMinimumSize());
title_bar_width += kTitleLeftInset + title_->GetPreferredSize().width();
if (close_->visible())
title_bar_width += close_->width() + 1;
if (titlebar_extra_view_ != NULL)
title_bar_width += titlebar_extra_view_->GetPreferredSize().width();
size.SetToMax(gfx::Size(title_bar_width, 0));
return size;
} }
void BubbleFrameView::Layout() { void BubbleFrameView::Layout() {
...@@ -334,4 +327,19 @@ void BubbleFrameView::OffsetArrowIfOffScreen(const gfx::Rect& anchor_rect, ...@@ -334,4 +327,19 @@ void BubbleFrameView::OffsetArrowIfOffScreen(const gfx::Rect& anchor_rect,
SchedulePaint(); SchedulePaint();
} }
gfx::Size BubbleFrameView::GetSizeForClientSize(const gfx::Size& client_size) {
gfx::Size size(
GetUpdatedWindowBounds(gfx::Rect(), client_size, false).size());
// Accommodate the width of the title bar elements.
int title_bar_width = GetInsets().width() + border()->GetInsets().width();
if (!title_->text().empty())
title_bar_width += kTitleLeftInset + title_->GetPreferredSize().width();
if (close_->visible())
title_bar_width += close_->width() + 1;
if (titlebar_extra_view_ != NULL)
title_bar_width += titlebar_extra_view_->GetPreferredSize().width();
size.SetToMax(gfx::Size(title_bar_width, 0));
return size;
}
} // namespace views } // namespace views
...@@ -46,6 +46,7 @@ class VIEWS_EXPORT BubbleFrameView : public NonClientFrameView, ...@@ -46,6 +46,7 @@ class VIEWS_EXPORT BubbleFrameView : public NonClientFrameView,
// View overrides: // View overrides:
virtual gfx::Insets GetInsets() const OVERRIDE; virtual gfx::Insets GetInsets() const OVERRIDE;
virtual gfx::Size GetPreferredSize() OVERRIDE; virtual gfx::Size GetPreferredSize() OVERRIDE;
virtual gfx::Size GetMinimumSize() OVERRIDE;
virtual void Layout() OVERRIDE; virtual void Layout() OVERRIDE;
virtual const char* GetClassName() const OVERRIDE; virtual const char* GetClassName() const OVERRIDE;
virtual void ChildPreferredSizeChanged(View* child) OVERRIDE; virtual void ChildPreferredSizeChanged(View* child) OVERRIDE;
...@@ -87,6 +88,9 @@ class VIEWS_EXPORT BubbleFrameView : public NonClientFrameView, ...@@ -87,6 +88,9 @@ class VIEWS_EXPORT BubbleFrameView : public NonClientFrameView,
void OffsetArrowIfOffScreen(const gfx::Rect& anchor_rect, void OffsetArrowIfOffScreen(const gfx::Rect& anchor_rect,
const gfx::Size& client_size); const gfx::Size& client_size);
// Calculates the size needed to accommodate the given client area.
gfx::Size GetSizeForClientSize(const gfx::Size& client_size);
// The bubble border. // The bubble border.
BubbleBorder* bubble_border_; BubbleBorder* bubble_border_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment