Chromium Code Reviews| Index: ash/wm/overview/window_selector_unittest.cc |
| diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc |
| index ef985d8f1069c0641738adc3fdd2e911526e736b..228ba4c9c2cdd80ba84744ae595101e420496df2 100644 |
| --- a/ash/wm/overview/window_selector_unittest.cc |
| +++ b/ash/wm/overview/window_selector_unittest.cc |
| @@ -3,8 +3,10 @@ |
| // found in the LICENSE file. |
| #include <algorithm> |
| +#include <vector> |
| #include "ash/accessibility_delegate.h" |
| +#include "ash/ash_switches.h" |
| #include "ash/drag_drop/drag_drop_controller.h" |
| #include "ash/root_window_controller.h" |
| #include "ash/screen_util.h" |
| @@ -28,6 +30,7 @@ |
| #include "ash/wm/window_util.h" |
| #include "ash/wm/wm_event.h" |
| #include "base/basictypes.h" |
| +#include "base/command_line.h" |
| #include "base/compiler_specific.h" |
| #include "base/memory/scoped_vector.h" |
| #include "base/run_loop.h" |
| @@ -42,6 +45,7 @@ |
| #include "ui/aura/window_event_dispatcher.h" |
| #include "ui/compositor/scoped_animation_duration_scale_mode.h" |
| #include "ui/events/test/event_generator.h" |
| +#include "ui/gfx/geometry/vector2d_f.h" |
| #include "ui/gfx/rect_conversions.h" |
| #include "ui/gfx/transform.h" |
| #include "ui/views/controls/label.h" |
| @@ -53,6 +57,12 @@ |
| namespace ash { |
| namespace { |
| +// A short drag distance that will not cause an overview item to close. |
| +const int kShortDragDistance = 10; |
| + |
| +// A far drag distance that will cause an overview item to close. |
| +const int kFarDragDistance = 200; |
| + |
| class NonActivatableActivationDelegate |
| : public aura::client::ActivationDelegate { |
| public: |
| @@ -117,6 +127,17 @@ class WindowSelectorTest : public test::AshTestBase { |
| return widget; |
| } |
| + scoped_ptr<views::Widget> CreateWindowWidget(const gfx::Rect& bounds) { |
| + scoped_ptr<views::Widget> widget(new views::Widget); |
| + views::Widget::InitParams params; |
| + params.bounds = bounds; |
| + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| + widget->Init(params); |
| + widget->Show(); |
| + ParentWindowInPrimaryRootWindow(widget->GetNativeWindow()); |
| + return widget.Pass(); |
| + } |
| + |
| bool WindowsOverlapping(aura::Window* window1, aura::Window* window2) { |
| gfx::RectF window1_bounds = GetTransformedTargetBounds(window1); |
| gfx::RectF window2_bounds = GetTransformedTargetBounds(window2); |
| @@ -261,6 +282,24 @@ class WindowSelectorTest : public test::AshTestBase { |
| DISALLOW_COPY_AND_ASSIGN(WindowSelectorTest); |
| }; |
| +class WindowSelectorSwipeToCloseDisabledTest : public WindowSelectorTest { |
| + public: |
| + WindowSelectorSwipeToCloseDisabledTest() {} |
| + virtual ~WindowSelectorSwipeToCloseDisabledTest() {} |
| + |
| + // WindowSelectorTest: |
| + virtual void SetUp() override; |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(WindowSelectorSwipeToCloseDisabledTest); |
| +}; |
| + |
| +void WindowSelectorSwipeToCloseDisabledTest::SetUp() { |
| + CommandLine::ForCurrentProcess()->AppendSwitch( |
| + switches::kAshDisableSwipeToCloseInOverviewMode); |
| + WindowSelectorTest::SetUp(); |
| +} |
| + |
| // Tests that an a11y alert is sent on entering overview mode. |
| TEST_F(WindowSelectorTest, A11yAlertOnOverviewMode) { |
| gfx::Rect bounds(0, 0, 400, 400); |
| @@ -394,22 +433,15 @@ TEST_F(WindowSelectorTest, WindowDoesNotReceiveEvents) { |
| // Tests that clicking on the close button effectively closes the window. |
| TEST_F(WindowSelectorTest, CloseButton) { |
| - scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(200, 300, 250, 450))); |
| - |
| // We need a widget for the close button to work, a bare window will crash. |
| - scoped_ptr<views::Widget> widget(new views::Widget); |
| - views::Widget::InitParams params; |
| - params.bounds = gfx::Rect(0, 0, 400, 400); |
| - params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| - params.parent = window1->parent(); |
| - widget->Init(params); |
| - widget->Show(); |
| + scoped_ptr<views::Widget> widget = |
| + CreateWindowWidget(gfx::Rect(0, 0, 400, 400)); |
| ToggleOverview(); |
| - aura::Window* window2 = widget->GetNativeWindow(); |
| - gfx::RectF bounds = GetTransformedBoundsInRootWindow(window2); |
| + aura::Window* window = widget->GetNativeWindow(); |
| + gfx::RectF bounds = GetTransformedBoundsInRootWindow(window); |
| gfx::Point point(bounds.top_right().x() - 1, bounds.top_right().y() - 1); |
| - ui::test::EventGenerator event_generator(window2->GetRootWindow(), point); |
| + ui::test::EventGenerator event_generator(window->GetRootWindow(), point); |
| EXPECT_FALSE(widget->IsClosed()); |
| event_generator.ClickLeftButton(); |
| @@ -1176,38 +1208,38 @@ TEST_F(WindowSelectorTest, BasicTextFiltering) { |
| // Tests selecting in the overview with dimmed and undimmed items. |
| TEST_F(WindowSelectorTest, TextFilteringSelection) { |
| gfx::Rect bounds(0, 0, 100, 100); |
| - scoped_ptr<aura::Window> window2(CreateWindow(bounds)); |
| - scoped_ptr<aura::Window> window1(CreateWindow(bounds)); |
| - scoped_ptr<aura::Window> window0(CreateWindow(bounds)); |
| - base::string16 window2_title = base::UTF8ToUTF16("Rock and roll"); |
| - base::string16 window1_title = base::UTF8ToUTF16("Rock and"); |
| - base::string16 window0_title = base::UTF8ToUTF16("Rock"); |
| - window0->SetTitle(window0_title); |
| - window1->SetTitle(window1_title); |
| - window2->SetTitle(window2_title); |
| - ToggleOverview(); |
| - SendKey(ui::VKEY_RIGHT); |
| - EXPECT_TRUE(selection_widget_active()); |
| - EXPECT_EQ(GetSelectedWindow(), window0.get()); |
| - |
| - // Dim the first item, the selection should jump to the next item. |
| - std::vector<WindowSelectorItem*> items = GetWindowItemsForRoot(0); |
| - FilterItems("Rock and"); |
| - EXPECT_EQ(GetSelectedWindow(), window1.get()); |
| - |
| - // Cycle the selection, the dimmed window should not be selected. |
| - SendKey(ui::VKEY_RIGHT); |
| - EXPECT_EQ(GetSelectedWindow(), window2.get()); |
| - SendKey(ui::VKEY_RIGHT); |
| - EXPECT_EQ(GetSelectedWindow(), window1.get()); |
| - |
| - // Dimming all the items should hide the selection widget. |
| - FilterItems("Pop"); |
| - EXPECT_FALSE(selection_widget_active()); |
| - |
| - // Undimming one window should automatically select it. |
| - FilterItems("Rock and roll"); |
| - EXPECT_EQ(GetSelectedWindow(), window2.get()); |
| + scoped_ptr<aura::Window> window2(CreateWindow(bounds)); |
| + scoped_ptr<aura::Window> window1(CreateWindow(bounds)); |
| + scoped_ptr<aura::Window> window0(CreateWindow(bounds)); |
| + base::string16 window2_title = base::UTF8ToUTF16("Rock and roll"); |
| + base::string16 window1_title = base::UTF8ToUTF16("Rock and"); |
| + base::string16 window0_title = base::UTF8ToUTF16("Rock"); |
| + window0->SetTitle(window0_title); |
| + window1->SetTitle(window1_title); |
| + window2->SetTitle(window2_title); |
| + ToggleOverview(); |
| + SendKey(ui::VKEY_RIGHT); |
| + EXPECT_TRUE(selection_widget_active()); |
| + EXPECT_EQ(GetSelectedWindow(), window0.get()); |
| + |
| + // Dim the first item, the selection should jump to the next item. |
| + std::vector<WindowSelectorItem*> items = GetWindowItemsForRoot(0); |
| + FilterItems("Rock and"); |
| + EXPECT_EQ(GetSelectedWindow(), window1.get()); |
| + |
| + // Cycle the selection, the dimmed window should not be selected. |
| + SendKey(ui::VKEY_RIGHT); |
| + EXPECT_EQ(GetSelectedWindow(), window2.get()); |
| + SendKey(ui::VKEY_RIGHT); |
| + EXPECT_EQ(GetSelectedWindow(), window1.get()); |
| + |
| + // Dimming all the items should hide the selection widget. |
| + FilterItems("Pop"); |
| + EXPECT_FALSE(selection_widget_active()); |
| + |
| + // Undimming one window should automatically select it. |
| + FilterItems("Rock and roll"); |
| + EXPECT_EQ(GetSelectedWindow(), window2.get()); |
| } |
| // Tests clicking on the desktop itself to cancel overview mode. |
| @@ -1267,4 +1299,254 @@ TEST_F(WindowSelectorTest, CancelOverviewOnTap) { |
| EXPECT_FALSE(IsSelecting()); |
| } |
| +// Verify swipe to close doesn't work when swipe to close is disabled. |
| +TEST_F(WindowSelectorSwipeToCloseDisabledTest, WindowTapDragFarDistance) { |
|
flackr
2014/11/07 19:10:52
I'm not sure testing the lack of a feature is some
bruthig
2015/01/02 16:49:17
I would argue that testing a non-existent feature/
jonross
2015/01/06 15:02:28
Could you clarify in the name+description?
|
| + // We need a widget for the close button to work, a bare window will crash. |
| + scoped_ptr<views::Widget> widget = |
| + CreateWindowWidget(gfx::Rect(0, 0, 400, 400)); |
| + |
| + ToggleOverview(); |
| + ASSERT_TRUE(IsSelecting()); |
| + |
| + aura::Window* window = widget->GetNativeWindow(); |
| + gfx::Rect bounds = ToNearestRect(GetTransformedBoundsInRootWindow(window)); |
| + ui::test::EventGenerator event_generator(window->GetRootWindow()); |
| + |
| + ASSERT_FALSE(widget->IsClosed()); |
| + |
| + gfx::Point start(bounds.CenterPoint()); |
| + gfx::Point end(start.x() - kFarDragDistance, start.y()); |
| + event_generator.GestureScrollSequence( |
| + start, end, base::TimeDelta::FromMilliseconds(10), 5); |
| + |
| + EXPECT_FALSE(widget->IsClosed()); |
| + |
| + RunAllPendingInMessageLoop(); |
| + EXPECT_TRUE(IsSelecting()); |
| +} |
| + |
| +// Test dragging a window a short distance. |
| +TEST_F(WindowSelectorTest, WindowTapDragShortDistance) { |
| + // We need a widget for the close button to work, a bare window will crash. |
| + scoped_ptr<views::Widget> widget = |
| + CreateWindowWidget(gfx::Rect(0, 0, 400, 400)); |
| + |
| + ToggleOverview(); |
| + |
| + aura::Window* window = widget->GetNativeWindow(); |
| + gfx::Rect bounds = ToNearestRect(GetTransformedBoundsInRootWindow(window)); |
| + ui::test::EventGenerator event_generator(window->GetRootWindow()); |
| + |
| + ASSERT_FALSE(widget->IsClosed()); |
| + |
| + gfx::Point start(bounds.CenterPoint()); |
| + gfx::Point end(start.x() - kShortDragDistance, start.y()); |
| + event_generator.GestureScrollSequence( |
| + start, end, base::TimeDelta::FromMilliseconds(10), 5); |
| + |
| + EXPECT_FALSE(widget->IsClosed()); |
| + |
| + RunAllPendingInMessageLoop(); |
| + EXPECT_TRUE(IsSelecting()); |
| +} |
| + |
| +// Test dragging a window a far distance. |
| +TEST_F(WindowSelectorTest, WindowTapDragFarDistance) { |
| + // We need a widget for the close button to work, a bare window will crash. |
| + scoped_ptr<views::Widget> widget = |
| + CreateWindowWidget(gfx::Rect(0, 0, 400, 400)); |
| + |
| + ToggleOverview(); |
| + ASSERT_TRUE(IsSelecting()); |
| + |
| + aura::Window* window = widget->GetNativeWindow(); |
| + gfx::Rect bounds = ToNearestRect(GetTransformedBoundsInRootWindow(window)); |
| + ui::test::EventGenerator event_generator(window->GetRootWindow()); |
| + |
| + ASSERT_FALSE(widget->IsClosed()); |
| + |
| + gfx::Point start(bounds.CenterPoint()); |
| + gfx::Point end(start.x() - kFarDragDistance, start.y()); |
| + event_generator.GestureScrollSequence( |
| + start, end, base::TimeDelta::FromMilliseconds(10), 5); |
| + |
| + EXPECT_TRUE(widget->IsClosed()); |
| + |
| + RunAllPendingInMessageLoop(); |
| + EXPECT_FALSE(IsSelecting()); |
| +} |
| + |
| +// Test dragging a window in a multi window SelectorItem a short distance. |
| +TEST_F(WindowSelectorTest, MultiWindowTapDragShortDistance) { |
|
flackr
2014/11/07 19:10:52
Is this exercising a different code path than Wind
bruthig
2015/01/02 16:49:17
Removed.
|
| + scoped_ptr<views::Widget> widget1( |
| + CreatePanelWindowWidget(gfx::Rect(0, 0, 300, 100))); |
| + scoped_ptr<views::Widget> widget2( |
| + CreatePanelWindowWidget(gfx::Rect(100, 0, 100, 100))); |
| + aura::Window* window1 = widget1->GetNativeWindow(); |
| + wm::ActivateWindow(window1); |
| + ToggleOverview(); |
| + |
| + gfx::Rect bounds1 = ToNearestRect(GetTransformedBoundsInRootWindow(window1)); |
| + ui::test::EventGenerator event_generator1(window1->GetRootWindow()); |
| + |
| + ASSERT_FALSE(widget1->IsClosed()); |
| + ASSERT_FALSE(widget2->IsClosed()); |
| + |
| + gfx::Point start(bounds1.CenterPoint()); |
| + gfx::Point end(start.x() - kShortDragDistance, start.y()); |
| + event_generator1.GestureScrollSequence( |
| + start, end, base::TimeDelta::FromMilliseconds(10), 5); |
| + |
| + EXPECT_FALSE(widget1->IsClosed()); |
| + EXPECT_FALSE(widget2->IsClosed()); |
| + |
| + RunAllPendingInMessageLoop(); |
| + EXPECT_TRUE(IsSelecting()); |
| +} |
| + |
| +// Test dragging a window in a multi window SelectorItem a far distance. |
| +TEST_F(WindowSelectorTest, MultiWindowTapDragFarDistance) { |
| + scoped_ptr<views::Widget> widget1( |
| + CreatePanelWindowWidget(gfx::Rect(0, 0, 300, 100))); |
| + scoped_ptr<views::Widget> widget2( |
| + CreatePanelWindowWidget(gfx::Rect(100, 0, 100, 100))); |
| + aura::Window* window1 = widget1->GetNativeWindow(); |
| + wm::ActivateWindow(window1); |
| + ToggleOverview(); |
| + |
| + gfx::Rect bounds1 = ToNearestRect(GetTransformedBoundsInRootWindow(window1)); |
| + ui::test::EventGenerator event_generator1(window1->GetRootWindow()); |
| + |
| + ASSERT_FALSE(widget1->IsClosed()); |
| + ASSERT_FALSE(widget2->IsClosed()); |
| + |
| + gfx::Point start(bounds1.CenterPoint()); |
| + gfx::Point end(start.x() - kFarDragDistance, start.y()); |
| + event_generator1.GestureScrollSequence( |
| + start, end, base::TimeDelta::FromMilliseconds(10), 5); |
| + |
| + EXPECT_TRUE(widget1->IsClosed()); |
| + EXPECT_FALSE(widget2->IsClosed()); |
| + |
| + RunAllPendingInMessageLoop(); |
| + EXPECT_TRUE(IsSelecting()); |
| +} |
| + |
| +// Test dragging all windows in a multi window SelectorItem a short distance. |
| +TEST_F(WindowSelectorTest, MultiWindowTapDragLabelShortDistance) { |
| + scoped_ptr<views::Widget> widget1( |
| + CreatePanelWindowWidget(gfx::Rect(0, 0, 300, 100))); |
| + scoped_ptr<views::Widget> widget2( |
| + CreatePanelWindowWidget(gfx::Rect(100, 0, 100, 100))); |
| + aura::Window* window1 = widget1->GetNativeWindow(); |
| + wm::ActivateWindow(window1); |
| + ToggleOverview(); |
| + |
| + gfx::Rect bounds = GetWindowItemsForRoot(0).back()->target_bounds(); |
| + ui::test::EventGenerator event_generator1(window1->GetRootWindow()); |
| + |
| + ASSERT_FALSE(widget1->IsClosed()); |
| + ASSERT_FALSE(widget2->IsClosed()); |
| + |
| + gfx::Point start(bounds.CenterPoint().x(), bounds.y() + 3); |
| + gfx::Point end(start.x() - kShortDragDistance, start.y()); |
| + event_generator1.GestureScrollSequence( |
| + start, end, base::TimeDelta::FromMilliseconds(10), 5); |
| + |
| + EXPECT_FALSE(widget1->IsClosed()); |
| + EXPECT_FALSE(widget2->IsClosed()); |
| + |
| + RunAllPendingInMessageLoop(); |
| + |
| + RunAllPendingInMessageLoop(); |
| + EXPECT_TRUE(IsSelecting()); |
| +} |
| + |
| +// Test dragging all windows in a multi window SelectorItem a far distance. |
| +TEST_F(WindowSelectorTest, MultiWindowTapDragLabelFarDistance) { |
|
flackr
2014/11/07 19:10:52
Aren't these multi window drag tests a superset of
bruthig
2015/01/02 16:49:17
I will remove the MultiWindowTapDragShortDistance
|
| + scoped_ptr<views::Widget> widget1( |
| + CreatePanelWindowWidget(gfx::Rect(0, 0, 300, 100))); |
| + scoped_ptr<views::Widget> widget2( |
| + CreatePanelWindowWidget(gfx::Rect(100, 0, 100, 100))); |
| + aura::Window* window1 = widget1->GetNativeWindow(); |
| + wm::ActivateWindow(window1); |
| + ToggleOverview(); |
| + |
| + gfx::Rect bounds = GetWindowItemsForRoot(0).back()->target_bounds(); |
| + ui::test::EventGenerator event_generator1(window1->GetRootWindow()); |
| + |
| + ASSERT_FALSE(widget1->IsClosed()); |
| + ASSERT_FALSE(widget2->IsClosed()); |
| + |
| + gfx::Point start(bounds.CenterPoint().x(), bounds.y() + 3); |
| + gfx::Point end(start.x() - kFarDragDistance, start.y()); |
| + event_generator1.GestureScrollSequence( |
| + start, end, base::TimeDelta::FromMilliseconds(10), 5); |
| + |
| + EXPECT_TRUE(widget1->IsClosed()); |
| + EXPECT_TRUE(widget2->IsClosed()); |
| + |
| + RunAllPendingInMessageLoop(); |
| + EXPECT_FALSE(IsSelecting()); |
| +} |
| + |
| +// Test a low velocity fling. |
| +TEST_F(WindowSelectorTest, LowVelocityFling) { |
|
flackr
2014/11/07 19:10:52
Can probably merge this with the short distance dr
bruthig
2015/01/02 16:49:17
Unless you feel super strongly about this I would
|
| + const float kFlingVelocity = 2000; |
| + const int kSmallSwipeDistance = 25; |
| + |
| + // We need a widget for the close button to work, a bare window will crash. |
| + scoped_ptr<views::Widget> widget = |
| + CreateWindowWidget(gfx::Rect(0, 0, 400, 400)); |
| + |
| + ToggleOverview(); |
| + |
| + aura::Window* window = widget->GetNativeWindow(); |
| + gfx::RectF bounds = GetTransformedBoundsInRootWindow(window); |
| + ui::test::EventGenerator event_generator(window->GetRootWindow()); |
| + |
| + ASSERT_FALSE(widget->IsClosed()); |
| + |
| + gfx::Point start(bounds.CenterPoint().x(), bounds.CenterPoint().y()); |
| + gfx::Point end(start.x() - kSmallSwipeDistance, start.y()); |
| + const base::TimeDelta kScrollDuration = |
| + event_generator.CalculateDuration(start, end, kFlingVelocity, 10); |
| + event_generator.GestureScrollSequence(start, end, kScrollDuration, 10); |
| + |
| + EXPECT_FALSE(widget->IsClosed()); |
| + |
| + RunAllPendingInMessageLoop(); |
| + EXPECT_TRUE(IsSelecting()); |
| +} |
| + |
| +// Test a high velocity fling. |
| +TEST_F(WindowSelectorTest, HighVelocityFling) { |
| + const float kFlingVelocity = 10000; |
| + const int kSmallSwipeDistance = 25; |
| + |
| + // We need a widget for the close button to work, a bare window will crash. |
| + scoped_ptr<views::Widget> widget = |
| + CreateWindowWidget(gfx::Rect(0, 0, 400, 400)); |
| + |
| + ToggleOverview(); |
| + ASSERT_TRUE(IsSelecting()); |
| + |
| + aura::Window* window = widget->GetNativeWindow(); |
| + gfx::RectF bounds = GetTransformedBoundsInRootWindow(window); |
| + ui::test::EventGenerator event_generator(window->GetRootWindow()); |
| + |
| + ASSERT_FALSE(widget->IsClosed()); |
| + |
| + gfx::Point start(bounds.CenterPoint().x(), bounds.CenterPoint().y()); |
| + gfx::Point end(start.x() - kSmallSwipeDistance, start.y()); |
| + const base::TimeDelta kScrollDuration = |
| + event_generator.CalculateDuration(start, end, kFlingVelocity, 10); |
| + event_generator.GestureScrollSequence(start, end, kScrollDuration, 10); |
| + |
| + EXPECT_TRUE(widget->IsClosed()); |
| + |
| + RunAllPendingInMessageLoop(); |
| + EXPECT_FALSE(IsSelecting()); |
| +} |
| + |
| } // namespace ash |