| Index: ui/views/widget/widget_unittest.cc
|
| diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc
|
| index be4c1dfba0f5c6e8b8917f40706b7f8a215ee059..b564366fd0672cfa209ba25c840b3d917a7653dc 100644
|
| --- a/ui/views/widget/widget_unittest.cc
|
| +++ b/ui/views/widget/widget_unittest.cc
|
| @@ -209,6 +209,67 @@ class EventCountHandler : public ui::EventHandler {
|
| DISALLOW_COPY_AND_ASSIGN(EventCountHandler);
|
| };
|
|
|
| +// A helper WidgetDelegate for tests that require hooks into WidgetDelegate
|
| +// calls, and removes some of the boilerplate for initializing a Widget. Calls
|
| +// Widget::CloseNow() when destroyed if it hasn't already been done.
|
| +class TestDesktopWidgetDelegate : public WidgetDelegate {
|
| + public:
|
| + TestDesktopWidgetDelegate() : widget_(new Widget) {}
|
| +
|
| + ~TestDesktopWidgetDelegate() override {
|
| + if (widget_)
|
| + widget_->CloseNow();
|
| + EXPECT_FALSE(widget_);
|
| + }
|
| +
|
| + // Initialize the Widget, adding some meaningful default InitParams.
|
| + void InitWidget(Widget::InitParams init_params) {
|
| + init_params.delegate = this;
|
| +#if !defined(OS_CHROMEOS)
|
| + init_params.native_widget = new PlatformDesktopNativeWidget(widget_);
|
| +#endif
|
| + init_params.bounds = initial_bounds_;
|
| + widget_->Init(init_params);
|
| + }
|
| +
|
| + // Set the contents view to be used during Widget initialization. For Widgets
|
| + // that use non-client views, this will be the contents_view used to
|
| + // initialize the ClientView in WidgetDelegate::CreateClientView(). Otherwise,
|
| + // it is the ContentsView of the Widget's RootView. Ownership passes to the
|
| + // view hierarchy during InitWidget().
|
| + void set_contents_view(View* contents_view) {
|
| + contents_view_ = contents_view;
|
| + }
|
| +
|
| + int window_closing_count() const { return window_closing_count_; }
|
| + const gfx::Rect& initial_bounds() { return initial_bounds_; }
|
| +
|
| + // WidgetDelegate overrides:
|
| + void WindowClosing() override {
|
| + window_closing_count_++;
|
| + widget_ = nullptr;
|
| + }
|
| +
|
| + Widget* GetWidget() override { return widget_; }
|
| + const Widget* GetWidget() const override { return widget_; }
|
| +
|
| + View* GetContentsView() override {
|
| + return contents_view_ ? contents_view_ : WidgetDelegate::GetContentsView();
|
| + }
|
| +
|
| + bool ShouldAdvanceFocusToTopLevelWidget() const override {
|
| + return true; // Same default as DefaultWidgetDelegate in widget.cc.
|
| + }
|
| +
|
| + private:
|
| + Widget* widget_;
|
| + View* contents_view_ = nullptr;
|
| + int window_closing_count_ = 0;
|
| + gfx::Rect initial_bounds_ = gfx::Rect(100, 100, 200, 200);
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(TestDesktopWidgetDelegate);
|
| +};
|
| +
|
| TEST_F(WidgetTest, WidgetInitParams) {
|
| // Widgets are not transparent by default.
|
| Widget::InitParams init1;
|
| @@ -1117,6 +1178,54 @@ TEST_F(WidgetTest, GetWindowPlacement) {
|
| widget->CloseNow();
|
| }
|
|
|
| +// Test that widget size constraints are properly applied immediately after
|
| +// Init(), and that SetBounds() calls are appropriately clamped.
|
| +TEST_F(WidgetTest, MinimumSizeConstraints) {
|
| + TestDesktopWidgetDelegate delegate;
|
| + gfx::Size minimum_size(100, 100);
|
| + const gfx::Size smaller_size(90, 90);
|
| +
|
| + delegate.set_contents_view(new StaticSizedView(minimum_size));
|
| + delegate.InitWidget(CreateParams(Widget::InitParams::TYPE_WINDOW));
|
| + Widget* widget = delegate.GetWidget();
|
| +
|
| + // On desktop Linux, the Widget must be shown to ensure the window is mapped.
|
| + // On other platforms this line is optional.
|
| + widget->Show();
|
| +
|
| + // Sanity checks.
|
| + EXPECT_GT(delegate.initial_bounds().width(), minimum_size.width());
|
| + EXPECT_GT(delegate.initial_bounds().height(), minimum_size.height());
|
| + EXPECT_EQ(delegate.initial_bounds().size(),
|
| + widget->GetWindowBoundsInScreen().size());
|
| + // Note: StaticSizedView doesn't currently provide a maximum size.
|
| + EXPECT_EQ(gfx::Size(), widget->GetMaximumSize());
|
| +
|
| + if (!widget->ShouldUseNativeFrame()) {
|
| + // The test environment may have dwm disabled on Windows. In this case,
|
| + // CustomFrameView is used instead of the NativeFrameView, which will
|
| + // provide a minimum size that includes frame decorations.
|
| + minimum_size = widget->non_client_view()->GetWindowBoundsForClientBounds(
|
| + gfx::Rect(minimum_size)).size();
|
| + }
|
| +
|
| + EXPECT_EQ(minimum_size, widget->GetMinimumSize());
|
| + EXPECT_EQ(minimum_size, GetNativeWidgetMinimumContentSize(widget));
|
| +
|
| + // Trying to resize smaller than the minimum size should restrict the content
|
| + // size to the minimum size.
|
| + widget->SetBounds(gfx::Rect(smaller_size));
|
| + EXPECT_EQ(minimum_size, widget->GetClientAreaBoundsInScreen().size());
|
| +
|
| + widget->SetSize(smaller_size);
|
| +#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
|
| + // TODO(tapted): Desktop Linux ignores size constraints for SetSize. Fix it.
|
| + EXPECT_EQ(smaller_size, widget->GetClientAreaBoundsInScreen().size());
|
| +#else
|
| + EXPECT_EQ(minimum_size, widget->GetClientAreaBoundsInScreen().size());
|
| +#endif
|
| +}
|
| +
|
| // Tests that SetBounds() and GetWindowBoundsInScreen() is symmetric when the
|
| // widget is visible and not maximized or fullscreen.
|
| TEST_F(WidgetTest, GetWindowBoundsInScreen) {
|
| @@ -1768,44 +1877,14 @@ TEST_F(WidgetTest, MouseEventDispatchWhileTouchIsDown) {
|
|
|
| #endif // !defined(OS_MACOSX) || defined(USE_AURA)
|
|
|
| -// Used by SingleWindowClosing to count number of times WindowClosing() has
|
| -// been invoked.
|
| -class ClosingDelegate : public WidgetDelegate {
|
| - public:
|
| - ClosingDelegate() : count_(0), widget_(NULL) {}
|
| -
|
| - int count() const { return count_; }
|
| -
|
| - void set_widget(views::Widget* widget) { widget_ = widget; }
|
| -
|
| - // WidgetDelegate overrides:
|
| - Widget* GetWidget() override { return widget_; }
|
| - const Widget* GetWidget() const override { return widget_; }
|
| - void WindowClosing() override { count_++; }
|
| -
|
| - private:
|
| - int count_;
|
| - views::Widget* widget_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(ClosingDelegate);
|
| -};
|
| -
|
| // Verifies WindowClosing() is invoked correctly on the delegate when a Widget
|
| // is closed.
|
| TEST_F(WidgetTest, SingleWindowClosing) {
|
| - scoped_ptr<ClosingDelegate> delegate(new ClosingDelegate());
|
| - Widget* widget = new Widget(); // Destroyed by CloseNow() below.
|
| - Widget::InitParams init_params =
|
| - CreateParams(Widget::InitParams::TYPE_WINDOW);
|
| - init_params.bounds = gfx::Rect(0, 0, 200, 200);
|
| - init_params.delegate = delegate.get();
|
| -#if !defined(OS_CHROMEOS)
|
| - init_params.native_widget = new PlatformDesktopNativeWidget(widget);
|
| -#endif
|
| - widget->Init(init_params);
|
| - EXPECT_EQ(0, delegate->count());
|
| - widget->CloseNow();
|
| - EXPECT_EQ(1, delegate->count());
|
| + TestDesktopWidgetDelegate delegate;
|
| + delegate.InitWidget(CreateParams(Widget::InitParams::TYPE_WINDOW));
|
| + EXPECT_EQ(0, delegate.window_closing_count());
|
| + delegate.GetWidget()->CloseNow();
|
| + EXPECT_EQ(1, delegate.window_closing_count());
|
| }
|
|
|
| class WidgetWindowTitleTest : public WidgetTest {
|
| @@ -3093,70 +3172,17 @@ TEST_F(WidgetTest, FullscreenStatePropagated) {
|
| }
|
| #if defined(OS_WIN)
|
|
|
| -// Provides functionality to test widget activation via an activation flag
|
| -// which can be set by an accessor.
|
| -class ModalWindowTestWidgetDelegate : public WidgetDelegate {
|
| - public:
|
| - ModalWindowTestWidgetDelegate()
|
| - : widget_(NULL),
|
| - can_activate_(true) {}
|
| -
|
| - virtual ~ModalWindowTestWidgetDelegate() {}
|
| -
|
| - // Overridden from WidgetDelegate:
|
| - virtual void DeleteDelegate() override {
|
| - delete this;
|
| - }
|
| - virtual Widget* GetWidget() override {
|
| - return widget_;
|
| - }
|
| - virtual const Widget* GetWidget() const override {
|
| - return widget_;
|
| - }
|
| - virtual bool CanActivate() const override {
|
| - return can_activate_;
|
| - }
|
| - virtual bool ShouldAdvanceFocusToTopLevelWidget() const override {
|
| - return true;
|
| - }
|
| -
|
| - void set_can_activate(bool can_activate) {
|
| - can_activate_ = can_activate;
|
| - }
|
| -
|
| - void set_widget(Widget* widget) {
|
| - widget_ = widget;
|
| - }
|
| -
|
| - private:
|
| - Widget* widget_;
|
| - bool can_activate_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(ModalWindowTestWidgetDelegate);
|
| -};
|
| -
|
| // Tests whether we can activate the top level widget when a modal dialog is
|
| // active.
|
| TEST_F(WidgetTest, WindowModalityActivationTest) {
|
| - // Destroyed when the top level widget created below is destroyed.
|
| - ModalWindowTestWidgetDelegate* widget_delegate =
|
| - new ModalWindowTestWidgetDelegate;
|
| - // Create a top level widget.
|
| - Widget top_level_widget;
|
| - Widget::InitParams init_params =
|
| - CreateParams(Widget::InitParams::TYPE_WINDOW);
|
| - init_params.show_state = ui::SHOW_STATE_NORMAL;
|
| - gfx::Rect initial_bounds(0, 0, 500, 500);
|
| - init_params.bounds = initial_bounds;
|
| - init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
|
| - init_params.native_widget = new DesktopNativeWidgetAura(&top_level_widget);
|
| - init_params.delegate = widget_delegate;
|
| - top_level_widget.Init(init_params);
|
| - widget_delegate->set_widget(&top_level_widget);
|
| - top_level_widget.Show();
|
| - EXPECT_TRUE(top_level_widget.IsVisible());
|
| + TestDesktopWidgetDelegate widget_delegate;
|
| + widget_delegate.InitWidget(CreateParams(Widget::InitParams::TYPE_WINDOW));
|
|
|
| - HWND win32_window = views::HWNDForWidget(&top_level_widget);
|
| + Widget* top_level_widget = widget_delegate.GetWidget();
|
| + top_level_widget->Show();
|
| + EXPECT_TRUE(top_level_widget->IsVisible());
|
| +
|
| + HWND win32_window = views::HWNDForWidget(top_level_widget);
|
| EXPECT_TRUE(::IsWindow(win32_window));
|
|
|
| // This instance will be destroyed when the dialog is destroyed.
|
| @@ -3164,10 +3190,10 @@ TEST_F(WidgetTest, WindowModalityActivationTest) {
|
|
|
| // We should be able to activate the window even if the WidgetDelegate
|
| // says no, when a modal dialog is active.
|
| - widget_delegate->set_can_activate(false);
|
| + widget_delegate.set_can_activate(false);
|
|
|
| Widget* modal_dialog_widget = views::DialogDelegate::CreateDialogWidget(
|
| - dialog_delegate, NULL, top_level_widget.GetNativeWindow());
|
| + dialog_delegate, NULL, top_level_widget->GetNativeView());
|
| modal_dialog_widget->SetBounds(gfx::Rect(100, 100, 200, 200));
|
| modal_dialog_widget->Show();
|
| EXPECT_TRUE(modal_dialog_widget->IsVisible());
|
| @@ -3180,7 +3206,6 @@ TEST_F(WidgetTest, WindowModalityActivationTest) {
|
| EXPECT_EQ(activate_result, MA_ACTIVATE);
|
|
|
| modal_dialog_widget->CloseNow();
|
| - top_level_widget.CloseNow();
|
| }
|
| #endif // defined(OS_WIN)
|
| #endif // !defined(OS_CHROMEOS)
|
|
|