Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(633)

Unified Diff: ui/views/widget/widget_unittest.cc

Issue 1059853007: Mac/Linux: Ensure window size constraints propagate to the window server during Init (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cracked the case on Windows Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/views/widget/native_widget_mac.mm ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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)
« no previous file with comments | « ui/views/widget/native_widget_mac.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698