| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ash/common/wm/window_positioner.h" | 5 #include "ash/common/wm/window_positioner.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "ash/common/material_design/material_design_controller.h" |
| 9 #include "ash/common/wm/window_positioner.h" | 10 #include "ash/common/wm/window_positioner.h" |
| 10 #include "ash/common/wm/window_state.h" | 11 #include "ash/common/wm/window_state.h" |
| 11 #include "ash/shell.h" | 12 #include "ash/shell.h" |
| 12 #include "ash/shell/toplevel_window.h" | 13 #include "ash/shell/toplevel_window.h" |
| 13 #include "ash/test/ash_test_base.h" | 14 #include "ash/test/ash_md_test_base.h" |
| 14 #include "ash/test/test_shell_delegate.h" | 15 #include "ash/test/test_shell_delegate.h" |
| 15 #include "ash/wm/window_state_aura.h" | 16 #include "ash/wm/window_state_aura.h" |
| 16 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
| 17 #include "ui/aura/window_event_dispatcher.h" | 18 #include "ui/aura/window_event_dispatcher.h" |
| 18 #include "ui/display/screen.h" | 19 #include "ui/display/screen.h" |
| 19 #include "ui/views/widget/widget.h" | 20 #include "ui/views/widget/widget.h" |
| 20 #include "ui/views/widget/widget_delegate.h" | 21 #include "ui/views/widget/widget_delegate.h" |
| 21 | 22 |
| 22 namespace ash { | 23 namespace ash { |
| 23 | 24 |
| 24 typedef test::AshTestBase WindowPositionerTest; | 25 using WindowPositionerTest = test::AshMDTestBase; |
| 25 | 26 |
| 26 TEST_F(WindowPositionerTest, OpenMaximizedWindowOnSecondDisplay) { | 27 INSTANTIATE_TEST_CASE_P( |
| 28 /* prefix intentionally left blank due to only one parameterization */, |
| 29 WindowPositionerTest, |
| 30 testing::Values(MaterialDesignController::NON_MATERIAL, |
| 31 MaterialDesignController::MATERIAL_NORMAL, |
| 32 MaterialDesignController::MATERIAL_EXPERIMENTAL)); |
| 33 |
| 34 TEST_P(WindowPositionerTest, OpenMaximizedWindowOnSecondDisplay) { |
| 27 if (!SupportsMultipleDisplays()) | 35 if (!SupportsMultipleDisplays()) |
| 28 return; | 36 return; |
| 37 const int height_offset = GetMdMaximizedWindowHeightOffset(); |
| 29 // Tests that for a screen that is narrower than kForceMaximizeWidthLimit | 38 // Tests that for a screen that is narrower than kForceMaximizeWidthLimit |
| 30 // a new window gets maximized. | 39 // a new window gets maximized. |
| 31 UpdateDisplay("400x400,500x500"); | 40 UpdateDisplay("400x400,500x500"); |
| 32 Shell::GetInstance()->set_target_root_window( | 41 Shell::GetInstance()->set_target_root_window( |
| 33 Shell::GetAllRootWindows()[1]); | 42 Shell::GetAllRootWindows()[1]); |
| 34 shell::ToplevelWindow::CreateParams params; | 43 shell::ToplevelWindow::CreateParams params; |
| 35 params.can_resize = true; | 44 params.can_resize = true; |
| 36 params.can_maximize = true; | 45 params.can_maximize = true; |
| 37 views::Widget* widget = | 46 views::Widget* widget = |
| 38 shell::ToplevelWindow::CreateToplevelWindow(params); | 47 shell::ToplevelWindow::CreateToplevelWindow(params); |
| 39 EXPECT_EQ("400,0 500x453", widget->GetWindowBoundsInScreen().ToString()); | 48 EXPECT_EQ(gfx::Rect(400, 0, 500, 453 + height_offset).ToString(), |
| 49 widget->GetWindowBoundsInScreen().ToString()); |
| 40 } | 50 } |
| 41 | 51 |
| 42 TEST_F(WindowPositionerTest, OpenDefaultWindowOnSecondDisplay) { | 52 TEST_P(WindowPositionerTest, OpenDefaultWindowOnSecondDisplay) { |
| 43 if (!SupportsMultipleDisplays()) | 53 if (!SupportsMultipleDisplays()) |
| 44 return; | 54 return; |
| 45 #if defined(OS_WIN) | 55 #if defined(OS_WIN) |
| 46 ash::WindowPositioner::SetMaximizeFirstWindow(true); | 56 ash::WindowPositioner::SetMaximizeFirstWindow(true); |
| 47 #endif | 57 #endif |
| 48 UpdateDisplay("400x400,1400x900"); | 58 UpdateDisplay("400x400,1400x900"); |
| 49 aura::Window* second_root_window = Shell::GetAllRootWindows()[1]; | 59 aura::Window* second_root_window = Shell::GetAllRootWindows()[1]; |
| 50 Shell::GetInstance()->set_target_root_window( | 60 Shell::GetInstance()->set_target_root_window( |
| 51 second_root_window); | 61 second_root_window); |
| 52 shell::ToplevelWindow::CreateParams params; | 62 shell::ToplevelWindow::CreateParams params; |
| 53 params.can_resize = true; | 63 params.can_resize = true; |
| 54 params.can_maximize = true; | 64 params.can_maximize = true; |
| 55 views::Widget* widget = | 65 views::Widget* widget = |
| 56 shell::ToplevelWindow::CreateToplevelWindow(params); | 66 shell::ToplevelWindow::CreateToplevelWindow(params); |
| 57 gfx::Rect bounds = widget->GetWindowBoundsInScreen(); | 67 gfx::Rect bounds = widget->GetWindowBoundsInScreen(); |
| 58 #if defined(OS_WIN) | 68 #if defined(OS_WIN) |
| 59 EXPECT_TRUE(widget->IsMaximized()); | 69 EXPECT_TRUE(widget->IsMaximized()); |
| 60 #else | 70 #else |
| 61 // The window should be in the 2nd display with the default size. | 71 // The window should be in the 2nd display with the default size. |
| 62 EXPECT_EQ("300x300", bounds.size().ToString()); | 72 EXPECT_EQ("300x300", bounds.size().ToString()); |
| 63 #endif | 73 #endif |
| 64 EXPECT_TRUE(display::Screen::GetScreen() | 74 EXPECT_TRUE(display::Screen::GetScreen() |
| 65 ->GetDisplayNearestWindow(second_root_window) | 75 ->GetDisplayNearestWindow(second_root_window) |
| 66 .bounds() | 76 .bounds() |
| 67 .Contains(bounds)); | 77 .Contains(bounds)); |
| 68 } | 78 } |
| 69 | 79 |
| 70 // Tests that second window inherits first window's maximized state as well as | 80 // Tests that second window inherits first window's maximized state as well as |
| 71 // its restore bounds. | 81 // its restore bounds. |
| 72 #if defined(OS_WIN) && !defined(USE_ASH) | |
| 73 // TODO(msw): Broken on Windows. http://crbug.com/584038 | 82 // TODO(msw): Broken on Windows. http://crbug.com/584038 |
| 74 #define MAYBE_SecondMaximizedWindowHasProperRestoreSize \ | 83 #if defined(OS_CHROMEOS) |
| 75 DISABLED_SecondMaximizedWindowHasProperRestoreSize | 84 TEST_P(WindowPositionerTest, SecondMaximizedWindowHasProperRestoreSize) { |
| 76 #else | 85 const int height_offset = GetMdMaximizedWindowHeightOffset(); |
| 77 #define MAYBE_SecondMaximizedWindowHasProperRestoreSize \ | |
| 78 SecondMaximizedWindowHasProperRestoreSize | |
| 79 #endif | |
| 80 TEST_F(WindowPositionerTest, MAYBE_SecondMaximizedWindowHasProperRestoreSize) { | |
| 81 #if defined(OS_WIN) | |
| 82 ash::WindowPositioner::SetMaximizeFirstWindow(true); | |
| 83 #endif | |
| 84 UpdateDisplay("1400x900"); | 86 UpdateDisplay("1400x900"); |
| 85 shell::ToplevelWindow::CreateParams params; | 87 shell::ToplevelWindow::CreateParams params; |
| 86 params.can_resize = true; | 88 params.can_resize = true; |
| 87 params.can_maximize = true; | 89 params.can_maximize = true; |
| 88 views::Widget* widget1 = | 90 views::Widget* widget1 = |
| 89 shell::ToplevelWindow::CreateToplevelWindow(params); | 91 shell::ToplevelWindow::CreateToplevelWindow(params); |
| 90 gfx::Rect bounds = widget1->GetWindowBoundsInScreen(); | 92 gfx::Rect bounds = widget1->GetWindowBoundsInScreen(); |
| 91 | 93 |
| 92 #if !defined(OS_WIN) | |
| 93 // The window should have default size. | 94 // The window should have default size. |
| 94 EXPECT_FALSE(widget1->IsMaximized()); | 95 EXPECT_FALSE(widget1->IsMaximized()); |
| 95 EXPECT_EQ("300x300", bounds.size().ToString()); | 96 EXPECT_EQ("300x300", bounds.size().ToString()); |
| 96 widget1->Maximize(); | 97 widget1->Maximize(); |
| 97 #endif | 98 |
| 98 // The window should be maximized. | 99 // The window should be maximized. |
| 99 bounds = widget1->GetWindowBoundsInScreen(); | 100 bounds = widget1->GetWindowBoundsInScreen(); |
| 100 EXPECT_TRUE(widget1->IsMaximized()); | 101 EXPECT_TRUE(widget1->IsMaximized()); |
| 101 EXPECT_EQ("0,0 1400x853", bounds.ToString()); | 102 EXPECT_EQ(gfx::Rect(0, 0, 1400, 853 + height_offset).ToString(), |
| 103 bounds.ToString()); |
| 102 | 104 |
| 103 // Create another window | 105 // Create another window |
| 104 views::Widget* widget2 = | 106 views::Widget* widget2 = |
| 105 shell::ToplevelWindow::CreateToplevelWindow(params); | 107 shell::ToplevelWindow::CreateToplevelWindow(params); |
| 106 | 108 |
| 107 // The second window should be maximized. | 109 // The second window should be maximized. |
| 108 bounds = widget2->GetWindowBoundsInScreen(); | 110 bounds = widget2->GetWindowBoundsInScreen(); |
| 109 EXPECT_TRUE(widget2->IsMaximized()); | 111 EXPECT_TRUE(widget2->IsMaximized()); |
| 110 EXPECT_EQ("0,0 1400x853", bounds.ToString()); | 112 EXPECT_EQ(gfx::Rect(0, 0, 1400, 853 + height_offset).ToString(), |
| 113 bounds.ToString()); |
| 111 | 114 |
| 112 widget2->Restore(); | 115 widget2->Restore(); |
| 113 // Second window's restored size should be set to default size. | 116 // Second window's restored size should be set to default size. |
| 114 bounds = widget2->GetWindowBoundsInScreen(); | 117 bounds = widget2->GetWindowBoundsInScreen(); |
| 115 EXPECT_EQ("300x300", bounds.size().ToString()); | 118 EXPECT_EQ("300x300", bounds.size().ToString()); |
| 116 } | 119 } |
| 120 #endif // defined(OS_CHROMEOS) |
| 117 | 121 |
| 118 namespace { | 122 namespace { |
| 119 | 123 |
| 120 // A WidgetDelegate that returns the out of display saved bounds. | 124 // A WidgetDelegate that returns the out of display saved bounds. |
| 121 class OutOfDisplayDelegate : public views::WidgetDelegate { | 125 class OutOfDisplayDelegate : public views::WidgetDelegate { |
| 122 public: | 126 public: |
| 123 explicit OutOfDisplayDelegate(views::Widget* widget) : widget_(widget) {} | 127 explicit OutOfDisplayDelegate(views::Widget* widget) : widget_(widget) {} |
| 124 ~OutOfDisplayDelegate() override {} | 128 ~OutOfDisplayDelegate() override {} |
| 125 | 129 |
| 126 // Overridden from WidgetDelegate: | 130 // Overridden from WidgetDelegate: |
| 127 void DeleteDelegate() override { delete this; } | 131 void DeleteDelegate() override { delete this; } |
| 128 views::Widget* GetWidget() override { return widget_; } | 132 views::Widget* GetWidget() override { return widget_; } |
| 129 const views::Widget* GetWidget() const override { return widget_; } | 133 const views::Widget* GetWidget() const override { return widget_; } |
| 130 bool GetSavedWindowPlacement(const views::Widget* widget, | 134 bool GetSavedWindowPlacement(const views::Widget* widget, |
| 131 gfx::Rect* bounds, | 135 gfx::Rect* bounds, |
| 132 ui::WindowShowState* show_state) const override { | 136 ui::WindowShowState* show_state) const override { |
| 133 bounds->SetRect(450, 10, 100, 100); | 137 bounds->SetRect(450, 10, 100, 100); |
| 134 *show_state = ui::SHOW_STATE_NORMAL; | 138 *show_state = ui::SHOW_STATE_NORMAL; |
| 135 return true; | 139 return true; |
| 136 } | 140 } |
| 137 | 141 |
| 138 private: | 142 private: |
| 139 views::Widget* widget_; | 143 views::Widget* widget_; |
| 140 | 144 |
| 141 DISALLOW_COPY_AND_ASSIGN(OutOfDisplayDelegate); | 145 DISALLOW_COPY_AND_ASSIGN(OutOfDisplayDelegate); |
| 142 }; | 146 }; |
| 143 | 147 |
| 144 } // namespace | 148 } // namespace |
| 145 | 149 |
| 146 TEST_F(WindowPositionerTest, EnsureMinimumVisibility) { | 150 TEST_P(WindowPositionerTest, EnsureMinimumVisibility) { |
| 147 if (!SupportsHostWindowResize()) | 151 if (!SupportsHostWindowResize()) |
| 148 return; | 152 return; |
| 149 | 153 |
| 150 UpdateDisplay("400x400"); | 154 UpdateDisplay("400x400"); |
| 151 views::Widget* widget = new views::Widget(); | 155 views::Widget* widget = new views::Widget(); |
| 152 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | 156 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); |
| 153 params.delegate = new OutOfDisplayDelegate(widget); | 157 params.delegate = new OutOfDisplayDelegate(widget); |
| 154 params.context = Shell::GetPrimaryRootWindow(); | 158 params.context = Shell::GetPrimaryRootWindow(); |
| 155 widget->Init(params); | 159 widget->Init(params); |
| 156 widget->SetBounds(gfx::Rect(450,10, 100, 100)); | 160 widget->SetBounds(gfx::Rect(450,10, 100, 100)); |
| 157 wm::GetWindowState(widget->GetNativeView())->set_minimum_visibility(true); | 161 wm::GetWindowState(widget->GetNativeView())->set_minimum_visibility(true); |
| 158 widget->Show(); | 162 widget->Show(); |
| 159 // Make sure the bounds is adjusted to be inside the work area. | 163 // Make sure the bounds is adjusted to be inside the work area. |
| 160 EXPECT_EQ("375,10 100x100", widget->GetWindowBoundsInScreen().ToString()); | 164 EXPECT_EQ("375,10 100x100", widget->GetWindowBoundsInScreen().ToString()); |
| 161 widget->CloseNow(); | 165 widget->CloseNow(); |
| 162 } | 166 } |
| 163 | 167 |
| 164 // In general case on first run the browser window will be maximized only for | 168 // In general case on first run the browser window will be maximized only for |
| 165 // low resolution screens (width < 1366). In case of big screens the browser is | 169 // low resolution screens (width < 1366). In case of big screens the browser is |
| 166 // opened being not maximized. To enforce maximization for all screen | 170 // opened being not maximized. To enforce maximization for all screen |
| 167 // resolutions, one can set "ForceMaximizeBrowserWindowOnFirstRun" | 171 // resolutions, one can set "ForceMaximizeBrowserWindowOnFirstRun" |
| 168 // policy. In the following tests we check if the window will be opened in | 172 // policy. In the following tests we check if the window will be opened in |
| 169 // maximized mode for low and high resolution when this policy is set. | 173 // maximized mode for low and high resolution when this policy is set. |
| 170 TEST_F(WindowPositionerTest, FirstRunMaximizeWindowHighResloution) { | 174 TEST_P(WindowPositionerTest, FirstRunMaximizeWindowHighResloution) { |
| 171 const int width = ash::WindowPositioner::GetForceMaximizedWidthLimit() + 100; | 175 const int width = ash::WindowPositioner::GetForceMaximizedWidthLimit() + 100; |
| 172 // Set resolution to 1466x300. | 176 // Set resolution to 1466x300. |
| 173 const std::string resolution = base::IntToString(width) + "x300"; | 177 const std::string resolution = base::IntToString(width) + "x300"; |
| 174 UpdateDisplay(resolution); | 178 UpdateDisplay(resolution); |
| 175 gfx::Rect bounds_in_out(0, 0, 320, 240); // Random bounds. | 179 gfx::Rect bounds_in_out(0, 0, 320, 240); // Random bounds. |
| 176 ui::WindowShowState show_state_out = ui::SHOW_STATE_DEFAULT; | 180 ui::WindowShowState show_state_out = ui::SHOW_STATE_DEFAULT; |
| 177 | 181 |
| 178 test::TestShellDelegate* const delegate = | 182 test::TestShellDelegate* const delegate = |
| 179 static_cast<test::TestShellDelegate*>(Shell::GetInstance()->delegate()); | 183 static_cast<test::TestShellDelegate*>(Shell::GetInstance()->delegate()); |
| 180 delegate->SetForceMaximizeOnFirstRun(true); | 184 delegate->SetForceMaximizeOnFirstRun(true); |
| 181 | 185 |
| 182 WindowPositioner::GetBoundsAndShowStateForNewWindow( | 186 WindowPositioner::GetBoundsAndShowStateForNewWindow( |
| 183 nullptr, false, ui::SHOW_STATE_DEFAULT, &bounds_in_out, &show_state_out); | 187 nullptr, false, ui::SHOW_STATE_DEFAULT, &bounds_in_out, &show_state_out); |
| 184 | 188 |
| 185 EXPECT_EQ(show_state_out, ui::SHOW_STATE_MAXIMIZED); | 189 EXPECT_EQ(show_state_out, ui::SHOW_STATE_MAXIMIZED); |
| 186 } | 190 } |
| 187 | 191 |
| 188 // For detail see description of FirstRunMaximizeWindowHighResloution. | 192 // For detail see description of FirstRunMaximizeWindowHighResloution. |
| 189 TEST_F(WindowPositionerTest, FirstRunMaximizeWindowLowResolution) { | 193 TEST_P(WindowPositionerTest, FirstRunMaximizeWindowLowResolution) { |
| 190 const int width = ash::WindowPositioner::GetForceMaximizedWidthLimit() - 100; | 194 const int width = ash::WindowPositioner::GetForceMaximizedWidthLimit() - 100; |
| 191 // Set resolution to 1266x300. | 195 // Set resolution to 1266x300. |
| 192 const std::string resolution = base::IntToString(width) + "x300"; | 196 const std::string resolution = base::IntToString(width) + "x300"; |
| 193 UpdateDisplay(resolution); | 197 UpdateDisplay(resolution); |
| 194 gfx::Rect bounds_in_out(0, 0, 320, 240); // Random bounds. | 198 gfx::Rect bounds_in_out(0, 0, 320, 240); // Random bounds. |
| 195 ui::WindowShowState show_state_out = ui::SHOW_STATE_DEFAULT; | 199 ui::WindowShowState show_state_out = ui::SHOW_STATE_DEFAULT; |
| 196 | 200 |
| 197 test::TestShellDelegate* const delegate = | 201 test::TestShellDelegate* const delegate = |
| 198 static_cast<test::TestShellDelegate*>(Shell::GetInstance()->delegate()); | 202 static_cast<test::TestShellDelegate*>(Shell::GetInstance()->delegate()); |
| 199 delegate->SetForceMaximizeOnFirstRun(true); | 203 delegate->SetForceMaximizeOnFirstRun(true); |
| 200 | 204 |
| 201 WindowPositioner::GetBoundsAndShowStateForNewWindow( | 205 WindowPositioner::GetBoundsAndShowStateForNewWindow( |
| 202 nullptr, false, ui::SHOW_STATE_DEFAULT, &bounds_in_out, &show_state_out); | 206 nullptr, false, ui::SHOW_STATE_DEFAULT, &bounds_in_out, &show_state_out); |
| 203 | 207 |
| 204 EXPECT_EQ(show_state_out, ui::SHOW_STATE_MAXIMIZED); | 208 EXPECT_EQ(show_state_out, ui::SHOW_STATE_MAXIMIZED); |
| 205 } | 209 } |
| 206 | 210 |
| 207 TEST_F(WindowPositionerTest, IgnoreFullscreenInAutoRearrange) { | 211 TEST_P(WindowPositionerTest, IgnoreFullscreenInAutoRearrange) { |
| 208 if (!SupportsHostWindowResize()) | 212 if (!SupportsHostWindowResize()) |
| 209 return; | 213 return; |
| 210 // Set bigger than 1366 so that the new window is opened in normal state. | 214 // Set bigger than 1366 so that the new window is opened in normal state. |
| 211 UpdateDisplay("1400x800"); | 215 UpdateDisplay("1400x800"); |
| 212 | 216 |
| 213 // 1st window mimics fullscreen browser window behavior. | 217 // 1st window mimics fullscreen browser window behavior. |
| 214 shell::ToplevelWindow::CreateParams params; | 218 shell::ToplevelWindow::CreateParams params; |
| 215 params.can_resize = true; | 219 params.can_resize = true; |
| 216 params.can_maximize = true; | 220 params.can_maximize = true; |
| 217 views::Widget* widget1 = shell::ToplevelWindow::CreateToplevelWindow(params); | 221 views::Widget* widget1 = shell::ToplevelWindow::CreateToplevelWindow(params); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 233 widget1->SetFullscreen(false); | 237 widget1->SetFullscreen(false); |
| 234 ASSERT_EQ("300x300", widget1->GetWindowBoundsInScreen().size().ToString()); | 238 ASSERT_EQ("300x300", widget1->GetWindowBoundsInScreen().size().ToString()); |
| 235 | 239 |
| 236 // Closing 2nd widget triggers the rearrange logic but the 1st | 240 // Closing 2nd widget triggers the rearrange logic but the 1st |
| 237 // widget should stay in the current size. | 241 // widget should stay in the current size. |
| 238 widget2->CloseNow(); | 242 widget2->CloseNow(); |
| 239 ASSERT_EQ("300x300", widget1->GetWindowBoundsInScreen().size().ToString()); | 243 ASSERT_EQ("300x300", widget1->GetWindowBoundsInScreen().size().ToString()); |
| 240 } | 244 } |
| 241 | 245 |
| 242 } // namespace ash | 246 } // namespace ash |
| OLD | NEW |