| Index: ui/aura/root_window_unittest.cc
|
| diff --git a/ui/aura/root_window_unittest.cc b/ui/aura/root_window_unittest.cc
|
| index 645e2f99eec274923d69f836ae3aa0a25290e2b9..fe0ca952569b4d7c79483ae67756872bca6509cd 100644
|
| --- a/ui/aura/root_window_unittest.cc
|
| +++ b/ui/aura/root_window_unittest.cc
|
| @@ -427,46 +427,46 @@ namespace {
|
| class EventFilterRecorder : public ui::EventHandler {
|
| public:
|
| typedef std::vector<ui::EventType> Events;
|
| - typedef std::vector<gfx::Point> MouseEventLocations;
|
| + typedef std::vector<gfx::Point> EventLocations;
|
|
|
| EventFilterRecorder() {}
|
|
|
| - Events& events() { return events_; }
|
| + const Events& events() const { return events_; }
|
|
|
| - MouseEventLocations& mouse_locations() { return mouse_locations_; }
|
| + const EventLocations& mouse_locations() const { return mouse_locations_; }
|
| gfx::Point mouse_location(int i) const { return mouse_locations_[i]; }
|
| + const EventLocations& touch_locations() const { return touch_locations_; }
|
|
|
| -Events GetAndResetEvents() {
|
| + Events GetAndResetEvents() {
|
| Events events = events_;
|
| - events_.clear();
|
| + Reset();
|
| return events;
|
| }
|
|
|
| + void Reset() {
|
| + events_.clear();
|
| + mouse_locations_.clear();
|
| + touch_locations_.clear();
|
| + }
|
| +
|
| // ui::EventHandler overrides:
|
| - virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE {
|
| + virtual void OnEvent(ui::Event* event) OVERRIDE {
|
| + ui::EventHandler::OnEvent(event);
|
| events_.push_back(event->type());
|
| }
|
|
|
| virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
|
| - events_.push_back(event->type());
|
| mouse_locations_.push_back(event->location());
|
| }
|
|
|
| - virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE {
|
| - events_.push_back(event->type());
|
| - }
|
| -
|
| virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
|
| - events_.push_back(event->type());
|
| - }
|
| -
|
| - virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
|
| - events_.push_back(event->type());
|
| + touch_locations_.push_back(event->location());
|
| }
|
|
|
| private:
|
| Events events_;
|
| - MouseEventLocations mouse_locations_;
|
| + EventLocations mouse_locations_;
|
| + EventLocations touch_locations_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(EventFilterRecorder);
|
| };
|
| @@ -595,7 +595,7 @@ TEST_F(RootWindowTest, MouseMovesHeld) {
|
| dispatcher()->AsWindowTreeHostDelegate()->OnHostMouseEvent(
|
| &mouse_move_event);
|
| // Discard MOUSE_ENTER.
|
| - filter->events().clear();
|
| + filter->Reset();
|
|
|
| dispatcher()->HoldPointerMoves();
|
|
|
| @@ -614,7 +614,7 @@ TEST_F(RootWindowTest, MouseMovesHeld) {
|
| &mouse_pressed_event);
|
| EXPECT_EQ("MOUSE_DRAGGED MOUSE_PRESSED",
|
| EventTypesToString(filter->events()));
|
| - filter->events().clear();
|
| + filter->Reset();
|
|
|
| // Check that we coalesce held MOUSE_DRAGGED events.
|
| ui::MouseEvent mouse_dragged_event2(ui::ET_MOUSE_DRAGGED, gfx::Point(1, 1),
|
| @@ -628,7 +628,7 @@ TEST_F(RootWindowTest, MouseMovesHeld) {
|
| &mouse_pressed_event);
|
| EXPECT_EQ("MOUSE_DRAGGED MOUSE_PRESSED",
|
| EventTypesToString(filter->events()));
|
| - filter->events().clear();
|
| + filter->Reset();
|
|
|
| // Check that on ReleasePointerMoves, held events are not dispatched
|
| // immediately, but posted instead.
|
| @@ -638,7 +638,7 @@ TEST_F(RootWindowTest, MouseMovesHeld) {
|
| EXPECT_TRUE(filter->events().empty());
|
| RunAllPendingInMessageLoop();
|
| EXPECT_EQ("MOUSE_DRAGGED", EventTypesToString(filter->events()));
|
| - filter->events().clear();
|
| + filter->Reset();
|
|
|
| // However if another message comes in before the dispatch of the posted
|
| // event, check that the posted event is dispatched before this new event.
|
| @@ -650,7 +650,7 @@ TEST_F(RootWindowTest, MouseMovesHeld) {
|
| &mouse_pressed_event);
|
| EXPECT_EQ("MOUSE_DRAGGED MOUSE_PRESSED",
|
| EventTypesToString(filter->events()));
|
| - filter->events().clear();
|
| + filter->Reset();
|
| RunAllPendingInMessageLoop();
|
| EXPECT_TRUE(filter->events().empty());
|
|
|
| @@ -663,7 +663,7 @@ TEST_F(RootWindowTest, MouseMovesHeld) {
|
| dispatcher()->AsWindowTreeHostDelegate()->OnHostMouseEvent(
|
| &mouse_dragged_event2);
|
| EXPECT_EQ("MOUSE_DRAGGED", EventTypesToString(filter->events()));
|
| - filter->events().clear();
|
| + filter->Reset();
|
| RunAllPendingInMessageLoop();
|
| EXPECT_TRUE(filter->events().empty());
|
| }
|
| @@ -674,22 +674,23 @@ TEST_F(RootWindowTest, TouchMovesHeld) {
|
|
|
| test::TestWindowDelegate delegate;
|
| scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
|
| - &delegate, 1, gfx::Rect(0, 0, 100, 100), root_window()));
|
| + &delegate, 1, gfx::Rect(50, 50, 100, 100), root_window()));
|
|
|
| + const gfx::Point touch_location(60, 60);
|
| // Starting the touch and throwing out the first few events, since the system
|
| // is going to generate synthetic mouse events that are not relevant to the
|
| // test.
|
| - ui::TouchEvent touch_pressed_event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0),
|
| + ui::TouchEvent touch_pressed_event(ui::ET_TOUCH_PRESSED, touch_location,
|
| 0, base::TimeDelta());
|
| dispatcher()->AsWindowTreeHostDelegate()->OnHostTouchEvent(
|
| &touch_pressed_event);
|
| RunAllPendingInMessageLoop();
|
| - filter->events().clear();
|
| + filter->Reset();
|
|
|
| dispatcher()->HoldPointerMoves();
|
|
|
| // Check that we don't immediately dispatch the TOUCH_MOVED event.
|
| - ui::TouchEvent touch_moved_event(ui::ET_TOUCH_MOVED, gfx::Point(0, 0),
|
| + ui::TouchEvent touch_moved_event(ui::ET_TOUCH_MOVED, touch_location,
|
| 0, base::TimeDelta());
|
| dispatcher()->AsWindowTreeHostDelegate()->OnHostTouchEvent(
|
| &touch_moved_event);
|
| @@ -701,15 +702,16 @@ TEST_F(RootWindowTest, TouchMovesHeld) {
|
| &touch_moved_event);
|
| dispatcher()->ReleasePointerMoves();
|
| EXPECT_TRUE(filter->events().empty());
|
| +
|
| RunAllPendingInMessageLoop();
|
| EXPECT_EQ("TOUCH_MOVED", EventTypesToString(filter->events()));
|
| - filter->events().clear();
|
| + filter->Reset();
|
|
|
| // If another touch event occurs then the held touch should be dispatched
|
| // immediately before it.
|
| - ui::TouchEvent touch_released_event(ui::ET_TOUCH_RELEASED, gfx::Point(0, 0),
|
| + ui::TouchEvent touch_released_event(ui::ET_TOUCH_RELEASED, touch_location,
|
| 0, base::TimeDelta());
|
| - filter->events().clear();
|
| + filter->Reset();
|
| dispatcher()->HoldPointerMoves();
|
| dispatcher()->AsWindowTreeHostDelegate()->OnHostTouchEvent(
|
| &touch_moved_event);
|
| @@ -717,12 +719,73 @@ TEST_F(RootWindowTest, TouchMovesHeld) {
|
| &touch_released_event);
|
| EXPECT_EQ("TOUCH_MOVED TOUCH_RELEASED GESTURE_TAP_CANCEL GESTURE_END",
|
| EventTypesToString(filter->events()));
|
| - filter->events().clear();
|
| + filter->Reset();
|
| dispatcher()->ReleasePointerMoves();
|
| RunAllPendingInMessageLoop();
|
| EXPECT_TRUE(filter->events().empty());
|
| }
|
|
|
| +class HoldPointerOnScrollHandler : public test::TestEventHandler {
|
| + public:
|
| + HoldPointerOnScrollHandler(WindowEventDispatcher* dispatcher,
|
| + EventFilterRecorder* filter)
|
| + : dispatcher_(dispatcher),
|
| + filter_(filter),
|
| + holding_moves_(false) {
|
| + }
|
| + virtual ~HoldPointerOnScrollHandler() {}
|
| +
|
| + private:
|
| + virtual void OnGestureEvent(ui::GestureEvent* gesture) OVERRIDE {
|
| + if (gesture->type() == ui::ET_GESTURE_SCROLL_UPDATE) {
|
| + CHECK(!holding_moves_);
|
| + holding_moves_ = true;
|
| + dispatcher_->HoldPointerMoves();
|
| + filter_->Reset();
|
| + } else if (gesture->type() == ui::ET_GESTURE_SCROLL_END) {
|
| + dispatcher_->ReleasePointerMoves();
|
| + holding_moves_ = false;
|
| + }
|
| + }
|
| +
|
| + WindowEventDispatcher* dispatcher_;
|
| + EventFilterRecorder* filter_;
|
| + bool holding_moves_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(HoldPointerOnScrollHandler);
|
| +};
|
| +
|
| +// Tests that touch-move events don't contribute to an in-progress scroll
|
| +// gesture if touch-move events are being held by the dispatcher.
|
| +TEST_F(RootWindowTest, TouchMovesHeldOnScroll) {
|
| + EventFilterRecorder* filter = new EventFilterRecorder;
|
| + root_window()->SetEventFilter(filter);
|
| + test::TestWindowDelegate delegate;
|
| + HoldPointerOnScrollHandler handler(dispatcher(), filter);
|
| + scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate(
|
| + &delegate, 1, gfx::Rect(50, 50, 100, 100), root_window()));
|
| + window->AddPreTargetHandler(&handler);
|
| +
|
| + test::EventGenerator generator(root_window());
|
| + generator.GestureScrollSequence(
|
| + gfx::Point(60, 60), gfx::Point(10, 60),
|
| + base::TimeDelta::FromMilliseconds(100), 25);
|
| +
|
| + // |handler| will have reset |filter| and started holding the touch-move
|
| + // events when scrolling started. At the end of the scroll (i.e. upon
|
| + // touch-release), the held touch-move event will have been dispatched first,
|
| + // along with the subsequent events (i.e. touch-release, scroll-end, and
|
| + // gesture-end).
|
| + const EventFilterRecorder::Events& events = filter->events();
|
| + EXPECT_EQ("TOUCH_MOVED TOUCH_RELEASED GESTURE_SCROLL_END GESTURE_END",
|
| + EventTypesToString(events));
|
| + ASSERT_EQ(2u, filter->touch_locations().size());
|
| + EXPECT_EQ(gfx::Point(-40, 10).ToString(),
|
| + filter->touch_locations()[0].ToString());
|
| + EXPECT_EQ(gfx::Point(-40, 10).ToString(),
|
| + filter->touch_locations()[1].ToString());
|
| +}
|
| +
|
| // Tests that synthetic mouse events are ignored when mouse
|
| // events are disabled.
|
| TEST_F(RootWindowTest, DispatchSyntheticMouseEvents) {
|
| @@ -742,14 +805,14 @@ TEST_F(RootWindowTest, DispatchSyntheticMouseEvents) {
|
| gfx::Point(10, 10), 0, 0);
|
| dispatcher()->AsWindowTreeHostDelegate()->OnHostMouseEvent(&mouse1);
|
| EXPECT_FALSE(filter->events().empty());
|
| - filter->events().clear();
|
| + filter->Reset();
|
|
|
| // Dispatch a synthetic mouse event when mouse events are enabled.
|
| ui::MouseEvent mouse2(ui::ET_MOUSE_MOVED, gfx::Point(10, 10),
|
| gfx::Point(10, 10), ui::EF_IS_SYNTHESIZED, 0);
|
| dispatcher()->AsWindowTreeHostDelegate()->OnHostMouseEvent(&mouse2);
|
| EXPECT_FALSE(filter->events().empty());
|
| - filter->events().clear();
|
| + filter->Reset();
|
|
|
| // Dispatch a synthetic mouse event when mouse events are disabled.
|
| cursor_client.DisableMouseEvents();
|
| @@ -777,7 +840,7 @@ TEST_F(RootWindowTest, DispatchMouseExitWhenCursorHidden) {
|
| EXPECT_TRUE(filter->events().empty());
|
| dispatcher()->AsWindowTreeHostDelegate()->OnHostMouseEvent(&mouse1);
|
| EXPECT_FALSE(filter->events().empty());
|
| - filter->events().clear();
|
| + filter->Reset();
|
|
|
| // Hide the cursor and verify a mouse exit was dispatched.
|
| dispatcher()->OnCursorVisibilityChanged(false);
|
| @@ -1019,7 +1082,7 @@ TEST_F(RootWindowTest, RepostTapdownGestureTest) {
|
| // TODO(rbyers): Currently disabled - crbug.com/170987
|
| EXPECT_FALSE(EventTypesToString(filter->events()).find("GESTURE_TAP_DOWN") !=
|
| std::string::npos);
|
| - filter->events().clear();
|
| + filter->Reset();
|
| }
|
|
|
| // This class inherits from the EventFilterRecorder class which provides a
|
| @@ -1040,7 +1103,7 @@ class RepostGestureEventRecorder : public EventFilterRecorder {
|
| virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
|
| if (reposted_ && event->type() == ui::ET_TOUCH_PRESSED) {
|
| done_cleanup_ = true;
|
| - events().clear();
|
| + Reset();
|
| }
|
| EventFilterRecorder::OnTouchEvent(event);
|
| }
|
|
|