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

Unified Diff: ash/wm/overview/window_selector_unittest.cc

Issue 690103008: Implemented swipe to close in overview mode. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month 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
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

Powered by Google App Engine
This is Rietveld 408576698