| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/wm/dock/docked_window_layout_manager.h" | 5 #include "ash/wm/dock/docked_window_layout_manager.h" |
| 6 | 6 |
| 7 #include "ash/ash_switches.h" | 7 #include "ash/ash_switches.h" |
| 8 #include "ash/display/display_controller.h" | 8 #include "ash/display/display_controller.h" |
| 9 #include "ash/launcher/launcher.h" | 9 #include "ash/launcher/launcher.h" |
| 10 #include "ash/launcher/launcher_model.h" | 10 #include "ash/launcher/launcher_model.h" |
| 11 #include "ash/root_window_controller.h" | 11 #include "ash/root_window_controller.h" |
| 12 #include "ash/screen_ash.h" | 12 #include "ash/screen_ash.h" |
| 13 #include "ash/shelf/shelf_layout_manager.h" | 13 #include "ash/shelf/shelf_layout_manager.h" |
| 14 #include "ash/shelf/shelf_types.h" | 14 #include "ash/shelf/shelf_types.h" |
| 15 #include "ash/shelf/shelf_widget.h" | 15 #include "ash/shelf/shelf_widget.h" |
| 16 #include "ash/shell.h" | 16 #include "ash/shell.h" |
| 17 #include "ash/shell_window_ids.h" | 17 #include "ash/shell_window_ids.h" |
| 18 #include "ash/test/ash_test_base.h" | 18 #include "ash/test/ash_test_base.h" |
| 19 #include "ash/test/launcher_view_test_api.h" | 19 #include "ash/test/launcher_view_test_api.h" |
| 20 #include "ash/test/shell_test_api.h" | 20 #include "ash/test/shell_test_api.h" |
| 21 #include "ash/test/test_launcher_delegate.h" | 21 #include "ash/test/test_launcher_delegate.h" |
| 22 #include "ash/wm/coordinate_conversion.h" |
| 22 #include "ash/wm/panels/panel_layout_manager.h" | 23 #include "ash/wm/panels/panel_layout_manager.h" |
| 23 #include "ash/wm/window_resizer.h" | 24 #include "ash/wm/window_resizer.h" |
| 24 #include "ash/wm/window_settings.h" | 25 #include "ash/wm/window_settings.h" |
| 25 #include "ash/wm/window_util.h" | 26 #include "ash/wm/window_util.h" |
| 26 #include "base/basictypes.h" | 27 #include "base/basictypes.h" |
| 27 #include "base/command_line.h" | 28 #include "base/command_line.h" |
| 28 #include "base/strings/string_number_conversions.h" | 29 #include "base/strings/string_number_conversions.h" |
| 29 #include "ui/aura/client/aura_constants.h" | 30 #include "ui/aura/client/aura_constants.h" |
| 30 #include "ui/aura/root_window.h" | 31 #include "ui/aura/root_window.h" |
| 31 #include "ui/aura/window.h" | 32 #include "ui/aura/window.h" |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 const gfx::Point& point_in_parent, | 93 const gfx::Point& point_in_parent, |
| 93 int window_component) { | 94 int window_component) { |
| 94 return CreateWindowResizer( | 95 return CreateWindowResizer( |
| 95 window, | 96 window, |
| 96 point_in_parent, | 97 point_in_parent, |
| 97 window_component, | 98 window_component, |
| 98 aura::client::WINDOW_MOVE_SOURCE_MOUSE).release(); | 99 aura::client::WINDOW_MOVE_SOURCE_MOUSE).release(); |
| 99 } | 100 } |
| 100 | 101 |
| 101 void DragStart(aura::Window* window) { | 102 void DragStart(aura::Window* window) { |
| 102 initial_location_in_parent_ = window->bounds().origin(); | 103 DragStartAtOffsetFromwindowOrigin(window, 0, 0); |
| 103 resizer_.reset(CreateSomeWindowResizer(window, | |
| 104 initial_location_in_parent_, | |
| 105 HTCAPTION)); | |
| 106 ASSERT_TRUE(resizer_.get()); | |
| 107 } | 104 } |
| 108 | 105 |
| 109 void DragStartAtOffsetFromwindowOrigin(aura::Window* window, | 106 void DragStartAtOffsetFromwindowOrigin(aura::Window* window, |
| 110 int dx, | 107 int dx, int dy) { |
| 111 int dy) { | |
| 112 initial_location_in_parent_ = | 108 initial_location_in_parent_ = |
| 113 window->bounds().origin() + gfx::Vector2d(dx, dy); | 109 window->bounds().origin() + gfx::Vector2d(dx, dy); |
| 114 resizer_.reset(CreateSomeWindowResizer(window, | 110 resizer_.reset(CreateSomeWindowResizer(window, |
| 115 initial_location_in_parent_, | 111 initial_location_in_parent_, |
| 116 HTCAPTION)); | 112 HTCAPTION)); |
| 117 ASSERT_TRUE(resizer_.get()); | 113 ASSERT_TRUE(resizer_.get()); |
| 118 } | 114 } |
| 119 | 115 |
| 120 void DragMove(int dx, int dy) { | 116 void DragMove(int dx, int dy) { |
| 121 resizer_->Drag(initial_location_in_parent_ + gfx::Vector2d(dx, dy), 0); | 117 resizer_->Drag(initial_location_in_parent_ + gfx::Vector2d(dx, dy), 0); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 int dx, | 160 int dx, |
| 165 int y) { | 161 int y) { |
| 166 gfx::Rect initial_bounds = window->GetBoundsInScreen(); | 162 gfx::Rect initial_bounds = window->GetBoundsInScreen(); |
| 167 DragVerticallyAndRelativeToEdge(edge, window, dx, y - initial_bounds.y()); | 163 DragVerticallyAndRelativeToEdge(edge, window, dx, y - initial_bounds.y()); |
| 168 } | 164 } |
| 169 | 165 |
| 170 // Detach if our window is a panel, then drag it vertically by |dy| and | 166 // Detach if our window is a panel, then drag it vertically by |dy| and |
| 171 // horizontally to the edge with an added offset from the edge of |dx|. | 167 // horizontally to the edge with an added offset from the edge of |dx|. |
| 172 void DragVerticallyAndRelativeToEdge(DockedEdge edge, | 168 void DragVerticallyAndRelativeToEdge(DockedEdge edge, |
| 173 aura::Window* window, | 169 aura::Window* window, |
| 174 int dx, | 170 int dx, int dy) { |
| 175 int dy) { | |
| 176 aura::RootWindow* root_window = window->GetRootWindow(); | |
| 177 gfx::Rect initial_bounds = window->GetBoundsInScreen(); | 171 gfx::Rect initial_bounds = window->GetBoundsInScreen(); |
| 178 | |
| 179 if (window_type_ == aura::client::WINDOW_TYPE_PANEL) { | |
| 180 ASSERT_NO_FATAL_FAILURE(DragStart(window)); | |
| 181 EXPECT_TRUE(wm::GetWindowSettings(window)->panel_attached()); | |
| 182 | |
| 183 // Drag enough to detach since our tests assume panels to be initially | |
| 184 // detached. | |
| 185 DragMove(0, dy); | |
| 186 EXPECT_EQ(CorrectContainerIdDuringDrag(), window->parent()->id()); | |
| 187 EXPECT_EQ(initial_bounds.x(), window->GetBoundsInScreen().x()); | |
| 188 EXPECT_EQ(initial_bounds.y() + dy, window->GetBoundsInScreen().y()); | |
| 189 | |
| 190 // The panel should be detached when the drag completes. | |
| 191 DragEnd(); | |
| 192 | |
| 193 EXPECT_FALSE(wm::GetWindowSettings(window)->panel_attached()); | |
| 194 EXPECT_EQ(internal::kShellWindowId_DefaultContainer, | |
| 195 window->parent()->id()); | |
| 196 EXPECT_EQ(root_window, window->GetRootWindow()); | |
| 197 } | |
| 198 | |
| 199 // avoid snap by clicking away from the border | 172 // avoid snap by clicking away from the border |
| 200 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromwindowOrigin(window, 25, 5)); | 173 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromwindowOrigin(window, 25, 5)); |
| 201 | 174 |
| 175 gfx::Rect work_area = |
| 176 Shell::GetScreen()->GetDisplayNearestWindow(window).work_area(); |
| 177 gfx::Point initial_location_in_screen = initial_location_in_parent_; |
| 178 wm::ConvertPointToScreen(window->parent(), &initial_location_in_screen); |
| 202 // Drag the window left or right to the edge (or almost to it). | 179 // Drag the window left or right to the edge (or almost to it). |
| 203 if (edge == DOCKED_EDGE_LEFT) | 180 if (edge == DOCKED_EDGE_LEFT) |
| 204 dx += window->GetRootWindow()->bounds().x() - initial_bounds.x(); | 181 dx += work_area.x() - initial_location_in_screen.x(); |
| 205 else if (edge == DOCKED_EDGE_RIGHT) | 182 else if (edge == DOCKED_EDGE_RIGHT) |
| 206 dx += window->GetRootWindow()->bounds().right() - initial_bounds.right(); | 183 dx += work_area.right() - 1 - initial_location_in_screen.x(); |
| 207 DragMove(dx, window_type_ == aura::client::WINDOW_TYPE_PANEL ? 0 : dy); | 184 DragMove(dx, dy); |
| 208 EXPECT_EQ(CorrectContainerIdDuringDrag(), window->parent()->id()); | 185 EXPECT_EQ(CorrectContainerIdDuringDrag(), window->parent()->id()); |
| 209 // Release the mouse and the panel should be attached to the dock. | 186 // Release the mouse and the panel should be attached to the dock. |
| 210 DragEnd(); | 187 DragEnd(); |
| 211 | 188 |
| 212 // x-coordinate can get adjusted by snapping or sticking. | 189 // x-coordinate can get adjusted by snapping or sticking. |
| 213 // y-coordinate could be changed by possible automatic layout if docked. | 190 // y-coordinate could be changed by possible automatic layout if docked. |
| 214 if (window->parent()->id() != internal::kShellWindowId_DockedContainer) | 191 if (window->parent()->id() != internal::kShellWindowId_DockedContainer && |
| 192 GetRestoreBoundsInScreen(window) == NULL) { |
| 215 EXPECT_EQ(initial_bounds.y() + dy, window->GetBoundsInScreen().y()); | 193 EXPECT_EQ(initial_bounds.y() + dy, window->GetBoundsInScreen().y()); |
| 194 } |
| 216 } | 195 } |
| 217 | 196 |
| 218 private: | 197 private: |
| 219 scoped_ptr<WindowResizer> resizer_; | 198 scoped_ptr<WindowResizer> resizer_; |
| 220 scoped_ptr<test::LauncherViewTestAPI> launcher_view_test_; | 199 scoped_ptr<test::LauncherViewTestAPI> launcher_view_test_; |
| 221 aura::client::WindowType window_type_; | 200 aura::client::WindowType window_type_; |
| 222 | 201 |
| 223 // Location at start of the drag in |window->parent()|'s coordinates. | 202 // Location at start of the drag in |window->parent()|'s coordinates. |
| 224 gfx::Point initial_location_in_parent_; | 203 gfx::Point initial_location_in_parent_; |
| 225 | 204 |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 | 314 |
| 336 // |window1| should be flush left and |window2| flush right. | 315 // |window1| should be flush left and |window2| flush right. |
| 337 EXPECT_EQ("0,32 231x320", window1->bounds().ToString()); | 316 EXPECT_EQ("0,32 231x320", window1->bounds().ToString()); |
| 338 EXPECT_EQ( | 317 EXPECT_EQ( |
| 339 base::IntToString( | 318 base::IntToString( |
| 340 desktop_area.width() - window2->bounds().width() - | 319 desktop_area.width() - window2->bounds().width() - |
| 341 manager->docked_width_ - DockedWindowLayoutManager::kMinDockGap) + | 320 manager->docked_width_ - DockedWindowLayoutManager::kMinDockGap) + |
| 342 ",48 256x512", window2->bounds().ToString()); | 321 ",48 256x512", window2->bounds().ToString()); |
| 343 } | 322 } |
| 344 | 323 |
| 345 // Tests that with a window docked on the left the auto-placing logic in | |
| 346 // RearrangeVisibleWindowOnShow places windows flush with work area edges. | |
| 347 // Test case for the secondary screen. | |
| 348 TEST_P(DockedWindowLayoutManagerTest, AutoPlacingLeftSecondScreen) { | |
| 349 if (!SupportsMultipleDisplays() || !SupportsHostWindowResize()) | |
| 350 return; | |
| 351 | |
| 352 // Create two screen layout. | |
| 353 UpdateDisplay("600x600,600x600"); | |
| 354 | |
| 355 gfx::Rect bounds(600, 0, 201, 201); | |
| 356 scoped_ptr<aura::Window> window(CreateTestWindow(bounds)); | |
| 357 DragRelativeToEdge(DOCKED_EDGE_LEFT, window.get(), 600); | |
| 358 | |
| 359 // The window should be attached and snapped to the right side of the screen. | |
| 360 EXPECT_EQ(window->GetRootWindow()->GetBoundsInScreen().x(), | |
| 361 window->GetBoundsInScreen().x()); | |
| 362 EXPECT_EQ(internal::kShellWindowId_DockedContainer, window->parent()->id()); | |
| 363 | |
| 364 DockedWindowLayoutManager* manager = static_cast<DockedWindowLayoutManager*>( | |
| 365 window->parent()->layout_manager()); | |
| 366 | |
| 367 // Create two additional windows and test their auto-placement | |
| 368 bounds = gfx::Rect(850, 32, 231, 320); | |
| 369 scoped_ptr<aura::Window> window1( | |
| 370 CreateTestWindowInShellWithDelegate(NULL, 1, bounds)); | |
| 371 gfx::Rect desktop_area = window1->parent()->bounds(); | |
| 372 wm::GetWindowSettings(window1.get())->set_window_position_managed(true); | |
| 373 window1->Hide(); | |
| 374 window1->Show(); | |
| 375 // |window1| should be centered in work area. | |
| 376 EXPECT_EQ(base::IntToString( | |
| 377 600 + manager->docked_width_ + DockedWindowLayoutManager::kMinDockGap + | |
| 378 (desktop_area.width() - manager->docked_width_ - | |
| 379 DockedWindowLayoutManager::kMinDockGap - window1->bounds().width()) / 2)+ | |
| 380 ",32 231x320", window1->GetBoundsInScreen().ToString()); | |
| 381 | |
| 382 bounds = gfx::Rect(850, 48, 150, 300); | |
| 383 scoped_ptr<aura::Window> window2( | |
| 384 CreateTestWindowInShellWithDelegate(NULL, 2, bounds)); | |
| 385 wm::GetWindowSettings(window2.get())->set_window_position_managed(true); | |
| 386 // To avoid any auto window manager changes due to SetBounds, the window | |
| 387 // gets first hidden and then shown again. | |
| 388 window2->Hide(); | |
| 389 window2->Show(); | |
| 390 | |
| 391 // |window1| should be flush left and |window2| flush right. | |
| 392 EXPECT_EQ( | |
| 393 base::IntToString(600 + | |
| 394 manager->docked_width_ + DockedWindowLayoutManager::kMinDockGap) + | |
| 395 ",32 231x320", window1->GetBoundsInScreen().ToString()); | |
| 396 EXPECT_EQ( | |
| 397 base::IntToString( | |
| 398 600 + desktop_area.width() - window2->bounds().width()) + | |
| 399 ",48 150x300", window2->GetBoundsInScreen().ToString()); | |
| 400 } | |
| 401 | |
| 402 // Tests that with a window docked on the right the auto-placing logic in | 324 // Tests that with a window docked on the right the auto-placing logic in |
| 403 // RearrangeVisibleWindowOnShow places windows flush with work area edges. | 325 // RearrangeVisibleWindowOnShow places windows flush with work area edges. |
| 404 // Test case for the secondary screen. | 326 // Test case for the secondary screen. |
| 405 TEST_P(DockedWindowLayoutManagerTest, AutoPlacingRightSecondScreen) { | 327 TEST_P(DockedWindowLayoutManagerTest, AutoPlacingRightSecondScreen) { |
| 406 if (!SupportsMultipleDisplays() || !SupportsHostWindowResize()) | 328 if (!SupportsMultipleDisplays() || !SupportsHostWindowResize()) |
| 407 return; | 329 return; |
| 408 | 330 |
| 409 // Create two screen layout. | 331 // Create two screen layout. |
| 410 UpdateDisplay("600x600,600x600"); | 332 UpdateDisplay("600x600,600x600"); |
| 411 | 333 |
| 412 gfx::Rect bounds(600, 0, 201, 201); | 334 gfx::Rect bounds(600, 0, 201, 201); |
| 413 scoped_ptr<aura::Window> window(CreateTestWindow(bounds)); | 335 scoped_ptr<aura::Window> window(CreateTestWindow(bounds)); |
| 414 DragRelativeToEdge(DOCKED_EDGE_RIGHT, window.get(), 600); | 336 // Drag pointer to the right edge of the second screen. |
| 337 DragRelativeToEdge(DOCKED_EDGE_RIGHT, window.get(), 0); |
| 415 | 338 |
| 416 // The window should be attached and snapped to the right side of the screen. | 339 // The window should be attached and snapped to the right side of the screen. |
| 417 EXPECT_EQ(window->GetRootWindow()->GetBoundsInScreen().right(), | 340 EXPECT_EQ(window->GetRootWindow()->GetBoundsInScreen().right(), |
| 418 window->GetBoundsInScreen().right()); | 341 window->GetBoundsInScreen().right()); |
| 419 EXPECT_EQ(internal::kShellWindowId_DockedContainer, window->parent()->id()); | 342 EXPECT_EQ(internal::kShellWindowId_DockedContainer, window->parent()->id()); |
| 420 | 343 |
| 421 DockedWindowLayoutManager* manager = static_cast<DockedWindowLayoutManager*>( | 344 DockedWindowLayoutManager* manager = static_cast<DockedWindowLayoutManager*>( |
| 422 window->parent()->layout_manager()); | 345 window->parent()->layout_manager()); |
| 423 | 346 |
| 424 // Create two additional windows and test their auto-placement | 347 // Create two additional windows and test their auto-placement |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 // The windows should be attached and snapped to the right side of the screen. | 418 // The windows should be attached and snapped to the right side of the screen. |
| 496 EXPECT_EQ(w1->GetRootWindow()->bounds().right(), | 419 EXPECT_EQ(w1->GetRootWindow()->bounds().right(), |
| 497 w1->GetBoundsInScreen().right()); | 420 w1->GetBoundsInScreen().right()); |
| 498 EXPECT_EQ(internal::kShellWindowId_DockedContainer, w1->parent()->id()); | 421 EXPECT_EQ(internal::kShellWindowId_DockedContainer, w1->parent()->id()); |
| 499 EXPECT_EQ(w2->GetRootWindow()->bounds().right(), | 422 EXPECT_EQ(w2->GetRootWindow()->bounds().right(), |
| 500 w2->GetBoundsInScreen().right()); | 423 w2->GetBoundsInScreen().right()); |
| 501 EXPECT_EQ(internal::kShellWindowId_DockedContainer, w2->parent()->id()); | 424 EXPECT_EQ(internal::kShellWindowId_DockedContainer, w2->parent()->id()); |
| 502 | 425 |
| 503 // Drag w2 above w1. | 426 // Drag w2 above w1. |
| 504 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromwindowOrigin(w2.get(), 0, 20)); | 427 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromwindowOrigin(w2.get(), 0, 20)); |
| 505 DragMove(0, w1->bounds().y() - w2->bounds().y() - 20); | 428 DragMove(0, w1->bounds().y() - w2->bounds().y() + 20); |
| 506 DragEnd(); | 429 DragEnd(); |
| 507 | 430 |
| 508 // Test the new windows order and that the gaps differ at most by a pixel. | 431 // Test the new windows order and that the gaps differ at most by a pixel. |
| 509 int gap1 = w2->GetBoundsInScreen().y(); | 432 int gap1 = w2->GetBoundsInScreen().y(); |
| 510 int gap2 = w1->GetBoundsInScreen().y() - w2->GetBoundsInScreen().bottom(); | 433 int gap2 = w1->GetBoundsInScreen().y() - w2->GetBoundsInScreen().bottom(); |
| 511 int gap3 = ScreenAsh::GetDisplayWorkAreaBoundsInParent(w1.get()).bottom() - | 434 int gap3 = ScreenAsh::GetDisplayWorkAreaBoundsInParent(w1.get()).bottom() - |
| 512 w1->GetBoundsInScreen().bottom(); | 435 w1->GetBoundsInScreen().bottom(); |
| 513 EXPECT_LE(abs(gap1 - gap2), 1); | 436 EXPECT_LE(abs(gap1 - gap2), 1); |
| 514 EXPECT_LE(abs(gap2 - gap3), 1); | 437 EXPECT_LE(abs(gap2 - gap3), 1); |
| 515 EXPECT_LE(abs(gap3 - gap1), 1); | 438 EXPECT_LE(abs(gap3 - gap1), 1); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 EXPECT_EQ(0, overlap4); | 562 EXPECT_EQ(0, overlap4); |
| 640 } | 563 } |
| 641 | 564 |
| 642 // Tests run twice - on both panels and normal windows | 565 // Tests run twice - on both panels and normal windows |
| 643 INSTANTIATE_TEST_CASE_P(NormalOrPanel, | 566 INSTANTIATE_TEST_CASE_P(NormalOrPanel, |
| 644 DockedWindowLayoutManagerTest, | 567 DockedWindowLayoutManagerTest, |
| 645 testing::Values(aura::client::WINDOW_TYPE_NORMAL, | 568 testing::Values(aura::client::WINDOW_TYPE_NORMAL, |
| 646 aura::client::WINDOW_TYPE_PANEL)); | 569 aura::client::WINDOW_TYPE_PANEL)); |
| 647 } // namespace internal | 570 } // namespace internal |
| 648 } // namespace ash | 571 } // namespace ash |
| OLD | NEW |