| 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 <algorithm> | 5 #include <algorithm> |
| 6 #include <map> |
| 7 #include <vector> |
| 6 | 8 |
| 7 #include "ash/accessibility_delegate.h" | 9 #include "ash/accessibility_delegate.h" |
| 10 #include "ash/ash_switches.h" |
| 8 #include "ash/drag_drop/drag_drop_controller.h" | 11 #include "ash/drag_drop/drag_drop_controller.h" |
| 9 #include "ash/root_window_controller.h" | 12 #include "ash/root_window_controller.h" |
| 10 #include "ash/screen_util.h" | 13 #include "ash/screen_util.h" |
| 11 #include "ash/shelf/shelf.h" | 14 #include "ash/shelf/shelf.h" |
| 12 #include "ash/shelf/shelf_widget.h" | 15 #include "ash/shelf/shelf_widget.h" |
| 13 #include "ash/shell.h" | 16 #include "ash/shell.h" |
| 14 #include "ash/shell_window_ids.h" | 17 #include "ash/shell_window_ids.h" |
| 15 #include "ash/test/ash_test_base.h" | 18 #include "ash/test/ash_test_base.h" |
| 16 #include "ash/test/shelf_test_api.h" | 19 #include "ash/test/shelf_test_api.h" |
| 17 #include "ash/test/shelf_view_test_api.h" | 20 #include "ash/test/shelf_view_test_api.h" |
| 18 #include "ash/test/shell_test_api.h" | 21 #include "ash/test/shell_test_api.h" |
| 19 #include "ash/test/test_shelf_delegate.h" | 22 #include "ash/test/test_shelf_delegate.h" |
| 20 #include "ash/wm/maximize_mode/maximize_mode_controller.h" | 23 #include "ash/wm/maximize_mode/maximize_mode_controller.h" |
| 21 #include "ash/wm/mru_window_tracker.h" | 24 #include "ash/wm/mru_window_tracker.h" |
| 22 #include "ash/wm/overview/window_grid.h" | 25 #include "ash/wm/overview/window_grid.h" |
| 23 #include "ash/wm/overview/window_selector.h" | 26 #include "ash/wm/overview/window_selector.h" |
| 24 #include "ash/wm/overview/window_selector_controller.h" | 27 #include "ash/wm/overview/window_selector_controller.h" |
| 25 #include "ash/wm/overview/window_selector_item.h" | 28 #include "ash/wm/overview/window_selector_item.h" |
| 26 #include "ash/wm/panels/panel_layout_manager.h" | 29 #include "ash/wm/panels/panel_layout_manager.h" |
| 27 #include "ash/wm/window_state.h" | 30 #include "ash/wm/window_state.h" |
| 28 #include "ash/wm/window_util.h" | 31 #include "ash/wm/window_util.h" |
| 29 #include "ash/wm/wm_event.h" | 32 #include "ash/wm/wm_event.h" |
| 30 #include "base/basictypes.h" | 33 #include "base/basictypes.h" |
| 34 #include "base/command_line.h" |
| 31 #include "base/compiler_specific.h" | 35 #include "base/compiler_specific.h" |
| 32 #include "base/memory/scoped_vector.h" | 36 #include "base/memory/scoped_vector.h" |
| 33 #include "base/run_loop.h" | 37 #include "base/run_loop.h" |
| 34 #include "base/strings/string_piece.h" | 38 #include "base/strings/string_piece.h" |
| 35 #include "base/strings/utf_string_conversions.h" | 39 #include "base/strings/utf_string_conversions.h" |
| 36 #include "ui/aura/client/aura_constants.h" | 40 #include "ui/aura/client/aura_constants.h" |
| 37 #include "ui/aura/client/cursor_client.h" | 41 #include "ui/aura/client/cursor_client.h" |
| 38 #include "ui/aura/client/focus_client.h" | 42 #include "ui/aura/client/focus_client.h" |
| 39 #include "ui/aura/test/test_window_delegate.h" | 43 #include "ui/aura/test/test_window_delegate.h" |
| 40 #include "ui/aura/test/test_windows.h" | 44 #include "ui/aura/test/test_windows.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 61 bool ShouldActivate() const override { return false; } | 65 bool ShouldActivate() const override { return false; } |
| 62 }; | 66 }; |
| 63 | 67 |
| 64 void CancelDrag(DragDropController* controller, bool* canceled) { | 68 void CancelDrag(DragDropController* controller, bool* canceled) { |
| 65 if (controller->IsDragDropInProgress()) { | 69 if (controller->IsDragDropInProgress()) { |
| 66 *canceled = true; | 70 *canceled = true; |
| 67 controller->DragCancel(); | 71 controller->DragCancel(); |
| 68 } | 72 } |
| 69 } | 73 } |
| 70 | 74 |
| 75 // A short drag distance that will not cause an overview item to close. |
| 76 const int kShortDragDistance = 10; |
| 77 |
| 78 // A far drag distance that will cause an overview item to close. |
| 79 const int kFarDragDistance = 200; |
| 80 |
| 81 // A slow fling velocity that should not cause selctor items to close. |
| 82 const int kSlowFlingVelocity = 2000; |
| 83 |
| 84 // A fast fling velocity that should cause selector items to close. |
| 85 const int kFastFlingVelocity = 5000; |
| 86 |
| 71 } // namespace | 87 } // namespace |
| 72 | 88 |
| 89 // TODO(bruthig): Move all non-simple method definitions out of class |
| 90 // declaration. |
| 73 class WindowSelectorTest : public test::AshTestBase { | 91 class WindowSelectorTest : public test::AshTestBase { |
| 74 public: | 92 public: |
| 75 WindowSelectorTest() {} | 93 WindowSelectorTest() {} |
| 76 ~WindowSelectorTest() override {} | 94 ~WindowSelectorTest() override {} |
| 77 | 95 |
| 78 void SetUp() override { | 96 void SetUp() override { |
| 79 test::AshTestBase::SetUp(); | 97 test::AshTestBase::SetUp(); |
| 80 ASSERT_TRUE(test::TestShelfDelegate::instance()); | 98 ASSERT_TRUE(test::TestShelfDelegate::instance()); |
| 81 | 99 |
| 82 shelf_view_test_.reset(new test::ShelfViewTestAPI( | 100 shelf_view_test_.reset(new test::ShelfViewTestAPI( |
| 83 test::ShelfTestAPI(Shelf::ForPrimaryDisplay()).shelf_view())); | 101 test::ShelfTestAPI(Shelf::ForPrimaryDisplay()).shelf_view())); |
| 84 shelf_view_test_->SetAnimationDuration(1); | 102 shelf_view_test_->SetAnimationDuration(1); |
| 85 } | 103 } |
| 86 | 104 |
| 87 aura::Window* CreateWindow(const gfx::Rect& bounds) { | 105 aura::Window* CreateWindow(const gfx::Rect& bounds) { |
| 88 return CreateTestWindowInShellWithDelegate(&delegate_, -1, bounds); | 106 return CreateTestWindowInShellWithDelegate(&delegate_, -1, bounds); |
| 89 } | 107 } |
| 90 | 108 |
| 91 aura::Window* CreateWindowWithId(const gfx::Rect& bounds, int id) { | 109 aura::Window* CreateWindowWithId(const gfx::Rect& bounds, int id) { |
| 92 return CreateTestWindowInShellWithDelegate(&delegate_, id, bounds); | 110 return CreateTestWindowInShellWithDelegate(&delegate_, id, bounds); |
| 93 } | 111 } |
| 94 aura::Window* CreateNonActivatableWindow(const gfx::Rect& bounds) { | 112 aura::Window* CreateNonActivatableWindow(const gfx::Rect& bounds) { |
| 95 aura::Window* window = CreateWindow(bounds); | 113 aura::Window* window = CreateWindow(bounds); |
| 96 aura::client::SetActivationDelegate(window, | 114 aura::client::SetActivationDelegate(window, |
| 97 &non_activatable_activation_delegate_); | 115 &non_activatable_activation_delegate_); |
| 98 EXPECT_FALSE(ash::wm::CanActivateWindow(window)); | 116 EXPECT_FALSE(ash::wm::CanActivateWindow(window)); |
| 99 return window; | 117 return window; |
| 100 } | 118 } |
| 101 | 119 |
| 120 // Creates a Widget containing a Window with the given |bounds|. This should |
| 121 // be used when the test requires a Widget. For example any test that will |
| 122 // cause a window to be closed via |
| 123 // views::Widget::GetWidgetForNativeView(window)->Close(). |
| 124 scoped_ptr<views::Widget> CreateWindowWidget(const gfx::Rect& bounds) { |
| 125 scoped_ptr<views::Widget> widget(new views::Widget); |
| 126 views::Widget::InitParams params; |
| 127 params.bounds = bounds; |
| 128 params.type = views::Widget::InitParams::TYPE_WINDOW; |
| 129 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 130 widget->Init(params); |
| 131 widget->Show(); |
| 132 ParentWindowInPrimaryRootWindow(widget->GetNativeWindow()); |
| 133 return widget.Pass(); |
| 134 } |
| 135 |
| 102 aura::Window* CreatePanelWindow(const gfx::Rect& bounds) { | 136 aura::Window* CreatePanelWindow(const gfx::Rect& bounds) { |
| 103 aura::Window* window = CreateTestWindowInShellWithDelegateAndType( | 137 aura::Window* window = CreateTestWindowInShellWithDelegateAndType( |
| 104 nullptr, ui::wm::WINDOW_TYPE_PANEL, 0, bounds); | 138 nullptr, ui::wm::WINDOW_TYPE_PANEL, 0, bounds); |
| 105 test::TestShelfDelegate::instance()->AddShelfItem(window); | 139 test::TestShelfDelegate::instance()->AddShelfItem(window); |
| 106 shelf_view_test()->RunMessageLoopUntilAnimationsDone(); | 140 shelf_view_test()->RunMessageLoopUntilAnimationsDone(); |
| 107 return window; | 141 return window; |
| 108 } | 142 } |
| 109 | 143 |
| 110 views::Widget* CreatePanelWindowWidget(const gfx::Rect& bounds) { | |
| 111 views::Widget* widget = new views::Widget; | |
| 112 views::Widget::InitParams params; | |
| 113 params.bounds = bounds; | |
| 114 params.type = views::Widget::InitParams::TYPE_PANEL; | |
| 115 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 116 widget->Init(params); | |
| 117 widget->Show(); | |
| 118 ParentWindowInPrimaryRootWindow(widget->GetNativeWindow()); | |
| 119 return widget; | |
| 120 } | |
| 121 | |
| 122 bool WindowsOverlapping(aura::Window* window1, aura::Window* window2) { | 144 bool WindowsOverlapping(aura::Window* window1, aura::Window* window2) { |
| 123 gfx::RectF window1_bounds = GetTransformedTargetBounds(window1); | 145 gfx::RectF window1_bounds = GetTransformedTargetBounds(window1); |
| 124 gfx::RectF window2_bounds = GetTransformedTargetBounds(window2); | 146 gfx::RectF window2_bounds = GetTransformedTargetBounds(window2); |
| 125 return window1_bounds.Intersects(window2_bounds); | 147 return window1_bounds.Intersects(window2_bounds); |
| 126 } | 148 } |
| 127 | 149 |
| 128 void ToggleOverview() { | 150 void ToggleOverview() { |
| 129 ash::Shell::GetInstance()->window_selector_controller()->ToggleOverview(); | 151 ash::Shell::GetInstance()->window_selector_controller()->ToggleOverview(); |
| 130 } | 152 } |
| 131 | 153 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 } | 271 } |
| 250 | 272 |
| 251 private: | 273 private: |
| 252 aura::test::TestWindowDelegate delegate_; | 274 aura::test::TestWindowDelegate delegate_; |
| 253 NonActivatableActivationDelegate non_activatable_activation_delegate_; | 275 NonActivatableActivationDelegate non_activatable_activation_delegate_; |
| 254 scoped_ptr<test::ShelfViewTestAPI> shelf_view_test_; | 276 scoped_ptr<test::ShelfViewTestAPI> shelf_view_test_; |
| 255 | 277 |
| 256 DISALLOW_COPY_AND_ASSIGN(WindowSelectorTest); | 278 DISALLOW_COPY_AND_ASSIGN(WindowSelectorTest); |
| 257 }; | 279 }; |
| 258 | 280 |
| 281 class WindowSelectorSwipeToCloseDisabledTest : public WindowSelectorTest { |
| 282 public: |
| 283 WindowSelectorSwipeToCloseDisabledTest() {} |
| 284 ~WindowSelectorSwipeToCloseDisabledTest() override {} |
| 285 |
| 286 // WindowSelectorTest: |
| 287 void SetUp() override; |
| 288 |
| 289 private: |
| 290 DISALLOW_COPY_AND_ASSIGN(WindowSelectorSwipeToCloseDisabledTest); |
| 291 }; |
| 292 |
| 293 void WindowSelectorSwipeToCloseDisabledTest::SetUp() { |
| 294 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 295 switches::kAshDisableSwipeToCloseInOverviewMode); |
| 296 WindowSelectorTest::SetUp(); |
| 297 } |
| 298 |
| 259 // Tests that an a11y alert is sent on entering overview mode. | 299 // Tests that an a11y alert is sent on entering overview mode. |
| 260 TEST_F(WindowSelectorTest, A11yAlertOnOverviewMode) { | 300 TEST_F(WindowSelectorTest, A11yAlertOnOverviewMode) { |
| 261 gfx::Rect bounds(0, 0, 400, 400); | 301 gfx::Rect bounds(0, 0, 400, 400); |
| 262 AccessibilityDelegate* delegate = | 302 AccessibilityDelegate* delegate = |
| 263 ash::Shell::GetInstance()->accessibility_delegate(); | 303 ash::Shell::GetInstance()->accessibility_delegate(); |
| 264 scoped_ptr<aura::Window> window1(CreateWindow(bounds)); | 304 scoped_ptr<aura::Window> window1(CreateWindow(bounds)); |
| 265 EXPECT_NE(delegate->GetLastAccessibilityAlert(), | 305 EXPECT_NE(delegate->GetLastAccessibilityAlert(), |
| 266 ui::A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED); | 306 ui::A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED); |
| 267 ToggleOverview(); | 307 ToggleOverview(); |
| 268 EXPECT_EQ(delegate->GetLastAccessibilityAlert(), | 308 EXPECT_EQ(delegate->GetLastAccessibilityAlert(), |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 generator.GestureTapAt(gfx::ToEnclosingRect( | 358 generator.GestureTapAt(gfx::ToEnclosingRect( |
| 319 GetTransformedTargetBounds(window2.get())).CenterPoint()); | 359 GetTransformedTargetBounds(window2.get())).CenterPoint()); |
| 320 EXPECT_EQ(window2.get(), GetFocusedWindow()); | 360 EXPECT_EQ(window2.get(), GetFocusedWindow()); |
| 321 } | 361 } |
| 322 | 362 |
| 323 // Tests that we do not crash and overview mode remains engaged if the desktop | 363 // Tests that we do not crash and overview mode remains engaged if the desktop |
| 324 // is tapped while a finger is already down over a window. | 364 // is tapped while a finger is already down over a window. |
| 325 TEST_F(WindowSelectorTest, NoCrashWithDesktopTap) { | 365 TEST_F(WindowSelectorTest, NoCrashWithDesktopTap) { |
| 326 scoped_ptr<aura::Window> window(CreateWindow(gfx::Rect(200, 300, 250, 450))); | 366 scoped_ptr<aura::Window> window(CreateWindow(gfx::Rect(200, 300, 250, 450))); |
| 327 | 367 |
| 328 // We need a widget for the close button to work, a bare window will crash. | |
| 329 scoped_ptr<views::Widget> widget(new views::Widget); | |
| 330 views::Widget::InitParams params; | |
| 331 params.bounds = gfx::Rect(0, 0, 400, 400); | |
| 332 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 333 params.parent = window->parent(); | |
| 334 widget->Init(params); | |
| 335 widget->Show(); | |
| 336 | |
| 337 ToggleOverview(); | 368 ToggleOverview(); |
| 338 | 369 |
| 339 gfx::Rect bounds = | 370 gfx::Rect bounds = |
| 340 gfx::ToEnclosingRect(GetTransformedBoundsInRootWindow(window.get())); | 371 gfx::ToEnclosingRect(GetTransformedBoundsInRootWindow(window.get())); |
| 341 ui::test::EventGenerator event_generator(window->GetRootWindow(), | 372 ui::test::EventGenerator event_generator(window->GetRootWindow(), |
| 342 bounds.CenterPoint()); | 373 bounds.CenterPoint()); |
| 343 | 374 |
| 344 // Press down on the window. | 375 // Press down on the window. |
| 345 const int kTouchId = 19; | 376 const int kTouchId = 19; |
| 346 event_generator.PressTouchId(kTouchId); | 377 event_generator.PressTouchId(kTouchId); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 ui::MouseEvent event2(ui::ET_MOUSE_PRESSED, point2, point2, | 452 ui::MouseEvent event2(ui::ET_MOUSE_PRESSED, point2, point2, |
| 422 ui::EF_NONE, ui::EF_NONE); | 453 ui::EF_NONE, ui::EF_NONE); |
| 423 | 454 |
| 424 // Now the transparent window should be intercepting this event. | 455 // Now the transparent window should be intercepting this event. |
| 425 EXPECT_NE(window, static_cast<aura::Window*>( | 456 EXPECT_NE(window, static_cast<aura::Window*>( |
| 426 targeter->FindTargetForEvent(root_target, &event2))); | 457 targeter->FindTargetForEvent(root_target, &event2))); |
| 427 } | 458 } |
| 428 | 459 |
| 429 // Tests that clicking on the close button effectively closes the window. | 460 // Tests that clicking on the close button effectively closes the window. |
| 430 TEST_F(WindowSelectorTest, CloseButton) { | 461 TEST_F(WindowSelectorTest, CloseButton) { |
| 431 scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(200, 300, 250, 450))); | 462 scoped_ptr<views::Widget> widget = |
| 463 CreateWindowWidget(gfx::Rect(0, 0, 400, 400)); |
| 432 | 464 |
| 433 // We need a widget for the close button to work, a bare window will crash. | |
| 434 scoped_ptr<views::Widget> widget(new views::Widget); | |
| 435 views::Widget::InitParams params; | |
| 436 params.bounds = gfx::Rect(0, 0, 400, 400); | |
| 437 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 438 params.parent = window1->parent(); | |
| 439 widget->Init(params); | |
| 440 widget->Show(); | |
| 441 ToggleOverview(); | 465 ToggleOverview(); |
| 442 | 466 |
| 443 aura::Window* window2 = widget->GetNativeWindow(); | 467 aura::Window* window = widget->GetNativeWindow(); |
| 444 gfx::RectF bounds = GetTransformedBoundsInRootWindow(window2); | 468 gfx::RectF bounds = GetTransformedBoundsInRootWindow(window); |
| 445 gfx::Point point(bounds.top_right().x() - 1, bounds.top_right().y() - 1); | 469 gfx::Point point(bounds.top_right().x() - 1, bounds.top_right().y() - 1); |
| 446 ui::test::EventGenerator event_generator(window2->GetRootWindow(), point); | 470 ui::test::EventGenerator event_generator(window->GetRootWindow(), point); |
| 447 | 471 |
| 448 EXPECT_FALSE(widget->IsClosed()); | 472 EXPECT_FALSE(widget->IsClosed()); |
| 449 event_generator.ClickLeftButton(); | 473 event_generator.ClickLeftButton(); |
| 450 EXPECT_TRUE(widget->IsClosed()); | 474 EXPECT_TRUE(widget->IsClosed()); |
| 451 } | 475 } |
| 452 | 476 |
| 453 // Tests that clicking on the close button on a secondary display effectively | 477 // Tests that clicking on the close button on a secondary display effectively |
| 454 // closes the window. | 478 // closes the window. |
| 455 TEST_F(WindowSelectorTest, CloseButtonOnMultipleDisplay) { | 479 TEST_F(WindowSelectorTest, CloseButtonOnMultipleDisplay) { |
| 456 if (!SupportsMultipleDisplays()) | 480 if (!SupportsMultipleDisplays()) |
| 457 return; | 481 return; |
| 458 | 482 |
| 459 UpdateDisplay("600x400,600x400"); | 483 UpdateDisplay("600x400,600x400"); |
| 460 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); | 484 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); |
| 461 | 485 |
| 462 scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(650, 300, 250, 450))); | 486 scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(650, 300, 250, 450))); |
| 463 | 487 |
| 464 // We need a widget for the close button to work, a bare window will crash. | 488 // We need a widget for the close button to work because windows are closed |
| 489 // via the widget. We also use the widget to determine if the window has been |
| 490 // closed or not. We explicity create the widget so that the window can be |
| 491 // parented to a non-primary root window. |
| 465 scoped_ptr<views::Widget> widget(new views::Widget); | 492 scoped_ptr<views::Widget> widget(new views::Widget); |
| 466 views::Widget::InitParams params; | 493 views::Widget::InitParams params; |
| 467 params.bounds = gfx::Rect(650, 0, 400, 400); | 494 params.bounds = gfx::Rect(650, 0, 400, 400); |
| 468 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 495 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 469 params.parent = window1->parent(); | 496 params.parent = window1->parent(); |
| 470 widget->Init(params); | 497 widget->Init(params); |
| 471 widget->Show(); | 498 widget->Show(); |
| 472 | 499 |
| 473 ASSERT_EQ(root_windows[1], window1->GetRootWindow()); | 500 ASSERT_EQ(root_windows[1], window1->GetRootWindow()); |
| 474 | 501 |
| (...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1239 | 1266 |
| 1240 // Switch to overview mode. | 1267 // Switch to overview mode. |
| 1241 ToggleOverview(); | 1268 ToggleOverview(); |
| 1242 ASSERT_TRUE(IsSelecting()); | 1269 ASSERT_TRUE(IsSelecting()); |
| 1243 | 1270 |
| 1244 // Tap should now exit overview mode. | 1271 // Tap should now exit overview mode. |
| 1245 generator.GestureTapAt(point_in_background_page); | 1272 generator.GestureTapAt(point_in_background_page); |
| 1246 EXPECT_FALSE(IsSelecting()); | 1273 EXPECT_FALSE(IsSelecting()); |
| 1247 } | 1274 } |
| 1248 | 1275 |
| 1276 // Verify swipe to close doesn't work when swipe to close is disabled. |
| 1277 TEST_F(WindowSelectorSwipeToCloseDisabledTest, WindowTapDragFarDistance) { |
| 1278 scoped_ptr<views::Widget> widget = |
| 1279 CreateWindowWidget(gfx::Rect(0, 0, 400, 400)); |
| 1280 |
| 1281 ToggleOverview(); |
| 1282 ASSERT_TRUE(IsSelecting()); |
| 1283 |
| 1284 aura::Window* window = widget->GetNativeWindow(); |
| 1285 gfx::Rect bounds = ToNearestRect(GetTransformedBoundsInRootWindow(window)); |
| 1286 ui::test::EventGenerator event_generator(window->GetRootWindow()); |
| 1287 |
| 1288 ASSERT_FALSE(widget->IsClosed()); |
| 1289 |
| 1290 gfx::Point start(bounds.CenterPoint()); |
| 1291 gfx::Point end(start.x() - kFarDragDistance, start.y()); |
| 1292 event_generator.GestureScrollSequence( |
| 1293 start, end, base::TimeDelta::FromMilliseconds(10), 5); |
| 1294 |
| 1295 EXPECT_FALSE(widget->IsClosed()); |
| 1296 |
| 1297 RunAllPendingInMessageLoop(); |
| 1298 EXPECT_TRUE(IsSelecting()); |
| 1299 } |
| 1300 |
| 1301 // Verify the window moves and fades as it is dragged. |
| 1302 TEST_F(WindowSelectorTest, VerifyWindowBehaviourDuringTapDrag) { |
| 1303 scoped_ptr<aura::Window> window(CreateWindow(gfx::Rect(0, 0, 400, 400))); |
| 1304 |
| 1305 ToggleOverview(); |
| 1306 |
| 1307 gfx::Rect bounds = ToNearestRect(GetTransformedBoundsInRootWindow( |
| 1308 window.get())); |
| 1309 ui::test::EventGenerator event_generator(window->GetRootWindow()); |
| 1310 |
| 1311 const gfx::Point drag_start_point(bounds.CenterPoint()); |
| 1312 const gfx::Point drag_left_point(drag_start_point.x() - kFarDragDistance, |
| 1313 drag_start_point.y()); |
| 1314 const gfx::Point drag_right_point(drag_start_point.x() + kFarDragDistance, |
| 1315 drag_start_point.y()); |
| 1316 |
| 1317 const int drag_left_delta_x = drag_start_point.x() - drag_left_point.x(); |
| 1318 const int drag_right_delta_x = drag_start_point.x() - drag_right_point.x(); |
| 1319 |
| 1320 const gfx::Rect original_bounds = window->GetBoundsInScreen(); |
| 1321 |
| 1322 ASSERT_EQ(1.0f, window->layer()->opacity()); |
| 1323 |
| 1324 event_generator.set_current_location(drag_start_point); |
| 1325 event_generator.PressTouch(); |
| 1326 |
| 1327 EXPECT_EQ(1.0f, window->layer()->opacity()); |
| 1328 |
| 1329 event_generator.MoveTouch(drag_left_point); |
| 1330 |
| 1331 EXPECT_EQ(original_bounds.x() - drag_left_delta_x, |
| 1332 window->GetBoundsInScreen().x()); |
| 1333 EXPECT_EQ(original_bounds.y(), window->GetBoundsInScreen().y()); |
| 1334 |
| 1335 EXPECT_LT(window->layer()->opacity(), 0.5f); |
| 1336 |
| 1337 event_generator.MoveTouch(drag_start_point); |
| 1338 |
| 1339 EXPECT_EQ(original_bounds.x(), window->GetBoundsInScreen().x()); |
| 1340 EXPECT_EQ(original_bounds.y(), window->GetBoundsInScreen().y()); |
| 1341 EXPECT_EQ(1.0f, window->layer()->opacity()); |
| 1342 |
| 1343 event_generator.MoveTouch(drag_right_point); |
| 1344 |
| 1345 EXPECT_EQ(original_bounds.x() - drag_right_delta_x, |
| 1346 window->GetBoundsInScreen().x()); |
| 1347 EXPECT_EQ(original_bounds.y(), window->GetBoundsInScreen().y()); |
| 1348 |
| 1349 EXPECT_LT(window->layer()->opacity(), 0.5f); |
| 1350 } |
| 1351 |
| 1352 // Test dragging a window a short distance. |
| 1353 TEST_F(WindowSelectorTest, WindowTapDragShortDistance) { |
| 1354 scoped_ptr<views::Widget> widget = |
| 1355 CreateWindowWidget(gfx::Rect(0, 0, 400, 400)); |
| 1356 |
| 1357 ToggleOverview(); |
| 1358 |
| 1359 aura::Window* window = widget->GetNativeWindow(); |
| 1360 gfx::Rect bounds = ToNearestRect(GetTransformedBoundsInRootWindow(window)); |
| 1361 ui::test::EventGenerator event_generator(window->GetRootWindow()); |
| 1362 |
| 1363 ASSERT_FALSE(widget->IsClosed()); |
| 1364 |
| 1365 gfx::Point start(bounds.CenterPoint()); |
| 1366 gfx::Point end(start.x() - kShortDragDistance, start.y()); |
| 1367 event_generator.GestureScrollSequence( |
| 1368 start, end, base::TimeDelta::FromMilliseconds(10), 5); |
| 1369 |
| 1370 EXPECT_FALSE(widget->IsClosed()); |
| 1371 |
| 1372 RunAllPendingInMessageLoop(); |
| 1373 EXPECT_TRUE(IsSelecting()); |
| 1374 } |
| 1375 |
| 1376 // Test dragging a window a far distance. |
| 1377 TEST_F(WindowSelectorTest, WindowTapDragFarDistance) { |
| 1378 scoped_ptr<views::Widget> widget = |
| 1379 CreateWindowWidget(gfx::Rect(0, 0, 400, 400)); |
| 1380 |
| 1381 ToggleOverview(); |
| 1382 ASSERT_TRUE(IsSelecting()); |
| 1383 |
| 1384 aura::Window* window = widget->GetNativeWindow(); |
| 1385 gfx::Rect bounds = ToNearestRect(GetTransformedBoundsInRootWindow(window)); |
| 1386 ui::test::EventGenerator event_generator(window->GetRootWindow()); |
| 1387 |
| 1388 ASSERT_FALSE(widget->IsClosed()); |
| 1389 |
| 1390 gfx::Point start(bounds.CenterPoint()); |
| 1391 gfx::Point end(start.x() - kFarDragDistance, start.y()); |
| 1392 event_generator.GestureScrollSequence( |
| 1393 start, end, base::TimeDelta::FromMilliseconds(10), 5); |
| 1394 |
| 1395 EXPECT_TRUE(widget->IsClosed()); |
| 1396 |
| 1397 RunAllPendingInMessageLoop(); |
| 1398 EXPECT_FALSE(IsSelecting()); |
| 1399 } |
| 1400 |
| 1401 // Test a slow velocity fling. |
| 1402 TEST_F(WindowSelectorTest, SlowVelocityFling) { |
| 1403 scoped_ptr<views::Widget> widget = |
| 1404 CreateWindowWidget(gfx::Rect(0, 0, 400, 400)); |
| 1405 |
| 1406 ToggleOverview(); |
| 1407 |
| 1408 aura::Window* window = widget->GetNativeWindow(); |
| 1409 gfx::RectF bounds = GetTransformedBoundsInRootWindow(window); |
| 1410 ui::test::EventGenerator event_generator(window->GetRootWindow()); |
| 1411 |
| 1412 ASSERT_FALSE(widget->IsClosed()); |
| 1413 |
| 1414 gfx::Point start(bounds.CenterPoint().x(), bounds.CenterPoint().y()); |
| 1415 gfx::Point end(start.x() - kShortDragDistance, start.y()); |
| 1416 const base::TimeDelta kScrollDuration = |
| 1417 event_generator.CalculateScrollDurationForFlingVelocity( |
| 1418 start, end, kSlowFlingVelocity, 10); |
| 1419 event_generator.GestureScrollSequence(start, end, kScrollDuration, 10); |
| 1420 |
| 1421 EXPECT_FALSE(widget->IsClosed()); |
| 1422 |
| 1423 RunAllPendingInMessageLoop(); |
| 1424 EXPECT_TRUE(IsSelecting()); |
| 1425 } |
| 1426 |
| 1427 // Test a fast velocity fling. |
| 1428 TEST_F(WindowSelectorTest, FastVelocityFling) { |
| 1429 scoped_ptr<views::Widget> widget = |
| 1430 CreateWindowWidget(gfx::Rect(0, 0, 400, 400)); |
| 1431 |
| 1432 ToggleOverview(); |
| 1433 ASSERT_TRUE(IsSelecting()); |
| 1434 |
| 1435 aura::Window* window = widget->GetNativeWindow(); |
| 1436 gfx::RectF bounds = GetTransformedBoundsInRootWindow(window); |
| 1437 ui::test::EventGenerator event_generator(window->GetRootWindow()); |
| 1438 |
| 1439 ASSERT_FALSE(widget->IsClosed()); |
| 1440 |
| 1441 gfx::Point start(bounds.CenterPoint().x(), bounds.CenterPoint().y()); |
| 1442 gfx::Point end(start.x() - kShortDragDistance, start.y()); |
| 1443 const base::TimeDelta kScrollDuration = |
| 1444 event_generator.CalculateScrollDurationForFlingVelocity( |
| 1445 start, end, kFastFlingVelocity, 10); |
| 1446 event_generator.GestureScrollSequence(start, end, kScrollDuration, 10); |
| 1447 |
| 1448 EXPECT_TRUE(widget->IsClosed()); |
| 1449 |
| 1450 RunAllPendingInMessageLoop(); |
| 1451 EXPECT_FALSE(IsSelecting()); |
| 1452 } |
| 1453 |
| 1454 // Test a fast velocity fling. |
| 1455 TEST_F(WindowSelectorTest, SlowVelocityFlingAtAFarDistance) { |
| 1456 scoped_ptr<views::Widget> widget = |
| 1457 CreateWindowWidget(gfx::Rect(0, 0, 400, 400)); |
| 1458 |
| 1459 ToggleOverview(); |
| 1460 ASSERT_TRUE(IsSelecting()); |
| 1461 |
| 1462 aura::Window* window = widget->GetNativeWindow(); |
| 1463 gfx::RectF bounds = GetTransformedBoundsInRootWindow(window); |
| 1464 ui::test::EventGenerator event_generator(window->GetRootWindow()); |
| 1465 |
| 1466 ASSERT_FALSE(widget->IsClosed()); |
| 1467 |
| 1468 gfx::Point start(bounds.CenterPoint().x(), bounds.CenterPoint().y()); |
| 1469 gfx::Point end(start.x() - kFarDragDistance, start.y()); |
| 1470 const base::TimeDelta kScrollDuration = |
| 1471 event_generator.CalculateScrollDurationForFlingVelocity( |
| 1472 start, end, kSlowFlingVelocity, 10); |
| 1473 event_generator.GestureScrollSequence(start, end, kScrollDuration, 10); |
| 1474 |
| 1475 EXPECT_TRUE(widget->IsClosed()); |
| 1476 |
| 1477 RunAllPendingInMessageLoop(); |
| 1478 EXPECT_FALSE(IsSelecting()); |
| 1479 } |
| 1480 |
| 1249 } // namespace ash | 1481 } // namespace ash |
| OLD | NEW |