diff options
-rw-r--r-- | ash/wm/root_window_event_filter_unittest.cc | 10 | ||||
-rw-r--r-- | ui/aura/gestures/gesture_point.cc | 4 | ||||
-rw-r--r-- | ui/aura/gestures/gesture_point.h | 14 | ||||
-rw-r--r-- | ui/aura/gestures/gesture_recognizer_unittest.cc | 228 | ||||
-rw-r--r-- | ui/aura/gestures/gesture_sequence.cc | 116 | ||||
-rw-r--r-- | ui/aura/gestures/gesture_sequence.h | 6 | ||||
-rw-r--r-- | ui/aura/window_unittest.cc | 3 |
7 files changed, 258 insertions, 123 deletions
diff --git a/ash/wm/root_window_event_filter_unittest.cc b/ash/wm/root_window_event_filter_unittest.cc index c4e41bd..efc2820 100644 --- a/ash/wm/root_window_event_filter_unittest.cc +++ b/ash/wm/root_window_event_filter_unittest.cc @@ -325,7 +325,7 @@ TEST_F(RootWindowEventFilterTest, ActivateOnTouch) { press_point = w1->bounds().CenterPoint(); aura::Window::ConvertPointToWindow(w1->parent(), root_window, &press_point); d1.set_activate(false); - aura::TouchEvent touchev2(ui::ET_TOUCH_PRESSED, press_point, 0); + aura::TouchEvent touchev2(ui::ET_TOUCH_PRESSED, press_point, 1); root_window->DispatchTouchEvent(&touchev2); // Window2 should still be active and focused. @@ -547,13 +547,15 @@ TEST_F(RootWindowEventFilterTest, UpdateCursorVisibility) { aura::MouseEvent mouse_moved( ui::ET_MOUSE_MOVED, gfx::Point(0, 0), gfx::Point(0, 0), 0x0); - aura::TouchEvent touch_pressed( + aura::TouchEvent touch_pressed1( ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), 0); + aura::TouchEvent touch_pressed2( + ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), 1); root_window_filter->set_update_cursor_visibility(true); root_window->DispatchMouseEvent(&mouse_moved); EXPECT_TRUE(root_window->cursor_shown()); - root_window->DispatchTouchEvent(&touch_pressed); + root_window->DispatchTouchEvent(&touch_pressed1); EXPECT_FALSE(root_window->cursor_shown()); root_window->DispatchMouseEvent(&mouse_moved); EXPECT_TRUE(root_window->cursor_shown()); @@ -563,7 +565,7 @@ TEST_F(RootWindowEventFilterTest, UpdateCursorVisibility) { root_window->DispatchMouseEvent(&mouse_moved); EXPECT_FALSE(root_window->cursor_shown()); root_window->ShowCursor(true); - root_window->DispatchTouchEvent(&touch_pressed); + root_window->DispatchTouchEvent(&touch_pressed2); EXPECT_TRUE(root_window->cursor_shown()); } diff --git a/ui/aura/gestures/gesture_point.cc b/ui/aura/gestures/gesture_point.cc index be72be1..a531f70 100644 --- a/ui/aura/gestures/gesture_point.cc +++ b/ui/aura/gestures/gesture_point.cc @@ -27,7 +27,8 @@ GesturePoint::GesturePoint() : first_touch_time_(0.0), last_touch_time_(0.0), last_tap_time_(0.0), - velocity_calculator_(kBufferedPoints) { + velocity_calculator_(kBufferedPoints), + point_id_(-1) { } GesturePoint::~GesturePoint() {} @@ -35,6 +36,7 @@ GesturePoint::~GesturePoint() {} void GesturePoint::Reset() { first_touch_time_ = last_touch_time_ = 0.0; velocity_calculator_.ClearHistory(); + point_id_ = -1; } void GesturePoint::UpdateValues(const TouchEvent& event) { diff --git a/ui/aura/gestures/gesture_point.h b/ui/aura/gestures/gesture_point.h index b04ffbd..906ba48 100644 --- a/ui/aura/gestures/gesture_point.h +++ b/ui/aura/gestures/gesture_point.h @@ -53,8 +53,16 @@ class GesturePoint { double last_touch_time() const { return last_touch_time_; } const gfx::Point& last_touch_position() const { return last_touch_position_; } - void set_touch_id(unsigned int touch_id) { touch_id_ = touch_id; } - unsigned int touch_id() const { return touch_id_; } + // point_id_ is used to drive GestureSequence::ProcessTouchEventForGesture. + // point_ids are maintained such that the set of point_ids is always + // contiguous, from 0 to the number of current touches. + // A lower point_id indicates that a touch occurred first. + // A negative point_id indicates that the GesturePoint is not currently + // associated with a touch. + void set_point_id(int point_id) { point_id_ = point_id; } + const int point_id() const { return point_id_; } + + const bool in_use() const { return point_id_ >= 0; } double x_delta() const { return last_touch_position_.x() - first_touch_position_.x(); @@ -87,7 +95,7 @@ class GesturePoint { VelocityCalculator velocity_calculator_; - unsigned int touch_id_; + int point_id_; DISALLOW_COPY_AND_ASSIGN(GesturePoint); }; diff --git a/ui/aura/gestures/gesture_recognizer_unittest.cc b/ui/aura/gestures/gesture_recognizer_unittest.cc index 518f3dd..3ee9ac5 100644 --- a/ui/aura/gestures/gesture_recognizer_unittest.cc +++ b/ui/aura/gestures/gesture_recognizer_unittest.cc @@ -75,7 +75,7 @@ class GestureEventConsumeDelegate : public TestWindowDelegate { float scroll_x() const { return scroll_x_; } float scroll_y() const { return scroll_y_; } - unsigned int touch_id() const { return touch_id_; } + int touch_id() const { return touch_id_; } virtual ui::GestureStatus OnGestureEvent(GestureEvent* gesture) OVERRIDE { switch (gesture->type()) { @@ -135,7 +135,7 @@ class GestureEventConsumeDelegate : public TestWindowDelegate { float scroll_x_; float scroll_y_; - unsigned int touch_id_; + int touch_id_; DISALLOW_COPY_AND_ASSIGN(GestureEventConsumeDelegate); }; @@ -241,7 +241,7 @@ class TestOneShotGestureSequenceTimer class TimerTestGestureSequence : public GestureSequence { public: - TimerTestGestureSequence(RootWindow* root_window) + explicit TimerTestGestureSequence(RootWindow* root_window) : GestureSequence(root_window) { } @@ -257,7 +257,7 @@ class TimerTestGestureSequence : public GestureSequence { class TestGestureRecognizer : public GestureRecognizerAura { public: - TestGestureRecognizer(RootWindow* root_window) + explicit TestGestureRecognizer(RootWindow* root_window) : GestureRecognizerAura(root_window) { } @@ -276,6 +276,7 @@ void SendScrollEvents(RootWindow* root_window, base::TimeDelta time_start, int dx, int dy, + int touch_id, int time_step, int num_steps, GestureEventConsumeDelegate* delegate) { @@ -285,22 +286,23 @@ void SendScrollEvents(RootWindow* root_window, for (int i = 0; i < num_steps; i++) { delegate->Reset(); - TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(x, y), 0); - Event::TestApi test_move(&move); - test_move.set_time_stamp(time); - root_window->DispatchTouchEvent(&move); x += dx; y += dy; time = time + base::TimeDelta::FromMilliseconds(time_step); + TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(x, y), touch_id); + Event::TestApi test_move(&move); + test_move.set_time_stamp(time); + root_window->DispatchTouchEvent(&move); } } void SendScrollEvent(RootWindow* root_window, int x, int y, + int touch_id, GestureEventConsumeDelegate* delegate) { delegate->Reset(); - TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(x, y), 0); + TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(x, y), touch_id); root_window->DispatchTouchEvent(&move); } @@ -316,12 +318,13 @@ TEST_F(GestureRecognizerTest, GestureEventTap) { new GestureEventConsumeDelegate()); const int kWindowWidth = 123; const int kWindowHeight = 45; + const int kTouchId = 2; gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( delegate.get(), -1234, bounds, NULL)); delegate->Reset(); - TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), 0); + TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId); root_window()->DispatchTouchEvent(&press); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); @@ -334,7 +337,7 @@ TEST_F(GestureRecognizerTest, GestureEventTap) { // Make sure there is enough delay before the touch is released so that it is // recognized as a tap. delegate->Reset(); - TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), 0); + TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId); Event::TestApi test_release(&release); test_release.set_time_stamp(press.time_stamp() + base::TimeDelta::FromMilliseconds(50)); @@ -353,12 +356,13 @@ TEST_F(GestureRecognizerTest, GestureEventScroll) { new GestureEventConsumeDelegate()); const int kWindowWidth = 123; const int kWindowHeight = 45; + const int kTouchId = 5; gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( delegate.get(), -1234, bounds, NULL)); delegate->Reset(); - TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), 0); + TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId); root_window()->DispatchTouchEvent(&press); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); @@ -371,7 +375,7 @@ TEST_F(GestureRecognizerTest, GestureEventScroll) { // should generate both SCROLL_BEGIN and SCROLL_UPDATE gestures. // The first movement is diagonal, to ensure that we have a free scroll, // and not a rail scroll. - SendScrollEvent(root_window(), 130, 230, delegate.get()); + SendScrollEvent(root_window(), 130, 230, kTouchId, delegate.get()); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->double_tap()); @@ -384,7 +388,7 @@ TEST_F(GestureRecognizerTest, GestureEventScroll) { delegate->scroll_begin_position().ToString()); // Move some more to generate a few more scroll updates. - SendScrollEvent(root_window(), 110, 211, delegate.get()); + SendScrollEvent(root_window(), 110, 211, kTouchId, delegate.get()); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->double_tap()); @@ -394,7 +398,7 @@ TEST_F(GestureRecognizerTest, GestureEventScroll) { EXPECT_EQ(-20, delegate->scroll_x()); EXPECT_EQ(-19, delegate->scroll_y()); - SendScrollEvent(root_window(), 140, 215, delegate.get()); + SendScrollEvent(root_window(), 140, 215, kTouchId, delegate.get()); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->double_tap()); @@ -406,7 +410,7 @@ TEST_F(GestureRecognizerTest, GestureEventScroll) { // Release the touch. This should end the scroll. delegate->Reset(); - TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), 0); + TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId); Event::TestApi test_release(&release); test_release.set_time_stamp(press.time_stamp() + base::TimeDelta::FromMilliseconds(50)); @@ -425,6 +429,7 @@ TEST_F(GestureRecognizerTest, GestureEventLongPress) { new GestureEventConsumeDelegate()); const int kWindowWidth = 123; const int kWindowHeight = 45; + const int kTouchId = 2; gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( delegate.get(), -1234, bounds, NULL)); @@ -439,7 +444,7 @@ TEST_F(GestureRecognizerTest, GestureEventLongPress) { root_window()->SetGestureRecognizerForTesting(gesture_recognizer); - TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), 0); + TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId); root_window()->DispatchTouchEvent(&press1); EXPECT_TRUE(delegate->tap_down()); @@ -449,10 +454,10 @@ TEST_F(GestureRecognizerTest, GestureEventLongPress) { // Wait until the timer runs out gesture_sequence->ForceTimeout(); EXPECT_TRUE(delegate->long_press()); - EXPECT_EQ(0u, delegate->touch_id()); + EXPECT_EQ(0, delegate->touch_id()); delegate->Reset(); - TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), 0); + TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId); root_window()->DispatchTouchEvent(&release1); EXPECT_FALSE(delegate->long_press()); } @@ -463,6 +468,7 @@ TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledByScroll) { new GestureEventConsumeDelegate()); const int kWindowWidth = 123; const int kWindowHeight = 45; + const int kTouchId = 6; gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( delegate.get(), -1234, bounds, NULL)); @@ -477,7 +483,7 @@ TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledByScroll) { root_window()->SetGestureRecognizerForTesting(gesture_recognizer); - TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), 0); + TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId); root_window()->DispatchTouchEvent(&press1); EXPECT_TRUE(delegate->tap_down()); @@ -485,13 +491,13 @@ TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledByScroll) { EXPECT_FALSE(delegate->long_press()); // Scroll around, to cancel the long press - SendScrollEvent(root_window(), 130, 230, delegate.get()); + SendScrollEvent(root_window(), 130, 230, kTouchId, delegate.get()); // Wait until the timer runs out gesture_sequence->ForceTimeout(); EXPECT_FALSE(delegate->long_press()); delegate->Reset(); - TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), 0); + TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId); root_window()->DispatchTouchEvent(&release1); EXPECT_FALSE(delegate->long_press()); } @@ -502,6 +508,8 @@ TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledByPinch) { new GestureEventConsumeDelegate()); const int kWindowWidth = 300; const int kWindowHeight = 400; + const int kTouchId1 = 8; + const int kTouchId2 = 2; gfx::Rect bounds(5, 5, kWindowWidth, kWindowHeight); scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( delegate.get(), -1234, bounds, NULL)); @@ -515,7 +523,7 @@ TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledByPinch) { root_window()->SetGestureRecognizerForTesting(gesture_recognizer); delegate->Reset(); - TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), 0); + TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1); root_window()->DispatchTouchEvent(&press); EXPECT_TRUE(delegate->tap_down()); @@ -524,7 +532,7 @@ TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledByPinch) { // Pinch, to cancel the long press delegate->Reset(); - TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1); + TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), kTouchId2); root_window()->DispatchTouchEvent(&press2); EXPECT_TRUE(delegate->tap_down()); EXPECT_TRUE(delegate->pinch_begin()); @@ -536,7 +544,7 @@ TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledByPinch) { EXPECT_FALSE(delegate->long_press()); delegate->Reset(); - TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), 0); + TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId1); root_window()->DispatchTouchEvent(&release1); EXPECT_FALSE(delegate->long_press()); } @@ -546,20 +554,21 @@ TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledByPinch) { TEST_F(GestureRecognizerTest, GestureEventHorizontalRailScroll) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); + const int kTouchId = 7; gfx::Rect bounds(0, 0, 1000, 1000); scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( delegate.get(), -1234, bounds, NULL)); - TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), 0); + TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), kTouchId); root_window()->DispatchTouchEvent(&press); // Move the touch-point horizontally enough that it is considered a // horizontal scroll. - SendScrollEvent(root_window(), 20, 1, delegate.get()); + SendScrollEvent(root_window(), 20, 1, kTouchId, delegate.get()); EXPECT_EQ(0, delegate->scroll_y()); EXPECT_EQ(20, delegate->scroll_x()); - SendScrollEvent(root_window(), 25, 6, delegate.get()); + SendScrollEvent(root_window(), 25, 6, kTouchId, delegate.get()); EXPECT_TRUE(delegate->scroll_update()); EXPECT_EQ(5, delegate->scroll_x()); // y shouldn't change, as we're on a horizontal rail. @@ -568,10 +577,10 @@ TEST_F(GestureRecognizerTest, GestureEventHorizontalRailScroll) { // Send enough information that a velocity can be calculated for the gesture, // and we can break the rail SendScrollEvents(root_window(), 1, 1, press.time_stamp(), - 1, 100, 1, kBufferedPoints, delegate.get()); + 1, 100, kTouchId, 1, kBufferedPoints, delegate.get()); - SendScrollEvent(root_window(), 0, 0, delegate.get()); - SendScrollEvent(root_window(), 5, 5, delegate.get()); + SendScrollEvent(root_window(), 0, 0, kTouchId, delegate.get()); + SendScrollEvent(root_window(), 5, 5, kTouchId, delegate.get()); // The rail should be broken EXPECT_TRUE(delegate->scroll_update()); @@ -584,20 +593,21 @@ TEST_F(GestureRecognizerTest, GestureEventHorizontalRailScroll) { TEST_F(GestureRecognizerTest, GestureEventVerticalRailScroll) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); + const int kTouchId = 7; gfx::Rect bounds(0, 0, 1000, 1000); scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( delegate.get(), -1234, bounds, NULL)); - TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), 0); + TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), kTouchId); root_window()->DispatchTouchEvent(&press); // Move the touch-point vertically enough that it is considered a // vertical scroll. - SendScrollEvent(root_window(), 1, 20, delegate.get()); + SendScrollEvent(root_window(), 1, 20, kTouchId, delegate.get()); EXPECT_EQ(0, delegate->scroll_x()); EXPECT_EQ(20, delegate->scroll_y()); - SendScrollEvent(root_window(), 6, 25, delegate.get()); + SendScrollEvent(root_window(), 6, 25, kTouchId, delegate.get()); EXPECT_TRUE(delegate->scroll_update()); EXPECT_EQ(5, delegate->scroll_y()); // x shouldn't change, as we're on a vertical rail. @@ -606,10 +616,10 @@ TEST_F(GestureRecognizerTest, GestureEventVerticalRailScroll) { // Send enough information that a velocity can be calculated for the gesture, // and we can break the rail SendScrollEvents(root_window(), 1, 1, press.time_stamp(), - 100, 1, 1, kBufferedPoints, delegate.get()); + 100, 1, kTouchId, 1, kBufferedPoints, delegate.get()); - SendScrollEvent(root_window(), 0, 0, delegate.get()); - SendScrollEvent(root_window(), 5, 5, delegate.get()); + SendScrollEvent(root_window(), 0, 0, kTouchId, delegate.get()); + SendScrollEvent(root_window(), 5, 5, kTouchId, delegate.get()); // The rail should be broken EXPECT_TRUE(delegate->scroll_update()); @@ -623,12 +633,13 @@ TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) { new GestureEventConsumeDelegate()); const int kWindowWidth = 123; const int kWindowHeight = 45; + const int kTouchId = 3; gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( delegate.get(), -1234, bounds, NULL)); delegate->Reset(); - TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), 0); + TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId); root_window()->DispatchTouchEvent(&press); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); @@ -640,7 +651,7 @@ TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) { // Make sure there is enough delay before the touch is released so that it is // recognized as a tap. delegate->Reset(); - TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), 0); + TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId); Event::TestApi test_release(&release); test_release.set_time_stamp(press.time_stamp() + base::TimeDelta::FromMilliseconds(50)); @@ -655,7 +666,7 @@ TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) { // Now, do a scroll gesture. Delay it sufficiently so that it doesn't trigger // a double-tap. delegate->Reset(); - TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), 0); + TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId); Event::TestApi test_release1(&press1); test_release1.set_time_stamp(release.time_stamp() + base::TimeDelta::FromMilliseconds(1000)); @@ -672,7 +683,7 @@ TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) { // The first movement is diagonal, to ensure that we have a free scroll, // and not a rail scroll. delegate->Reset(); - TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(130, 230), 0); + TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(130, 230), kTouchId); root_window()->DispatchTouchEvent(&move); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); @@ -685,7 +696,7 @@ TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) { // Move some more to generate a few more scroll updates. delegate->Reset(); - TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(110, 211), 0); + TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(110, 211), kTouchId); root_window()->DispatchTouchEvent(&move1); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); @@ -697,7 +708,7 @@ TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) { EXPECT_EQ(-19, delegate->scroll_y()); delegate->Reset(); - TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(140, 215), 0); + TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(140, 215), kTouchId); root_window()->DispatchTouchEvent(&move2); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); @@ -710,7 +721,7 @@ TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) { // Release the touch. This should end the scroll. delegate->Reset(); - TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), 0); + TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId); root_window()->DispatchTouchEvent(&release1); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); @@ -729,7 +740,7 @@ TEST_F(GestureRecognizerTest, GestureTapSyntheticMouse) { gfx::Rect(0, 0, 123, 45), NULL)); delegate->Reset(); - GestureEvent tap(ui::ET_GESTURE_TAP, 20, 20, 0, base::Time::Now(), 0, 0); + GestureEvent tap(ui::ET_GESTURE_TAP, 20, 20, 0, base::Time::Now(), 0, 6); root_window()->DispatchGestureEvent(&tap); EXPECT_TRUE(delegate->mouse_enter()); EXPECT_TRUE(delegate->mouse_press()); @@ -753,6 +764,8 @@ TEST_F(GestureRecognizerTest, AsynchronousGestureRecognition) { new QueueTouchEventDelegate(root_window())); const int kWindowWidth = 123; const int kWindowHeight = 45; + const int kTouchId1 = 6; + const int kTouchId2 = 4; gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); scoped_ptr<aura::Window> queue(CreateTestWindowWithDelegate( queued_delegate.get(), -1234, bounds, NULL)); @@ -761,7 +774,7 @@ TEST_F(GestureRecognizerTest, AsynchronousGestureRecognition) { // Touch down on the window. This should not generate any gesture event. queued_delegate->Reset(); - TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), 0); + TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1); root_window()->DispatchTouchEvent(&press); EXPECT_FALSE(queued_delegate->tap()); EXPECT_FALSE(queued_delegate->tap_down()); @@ -773,7 +786,7 @@ TEST_F(GestureRecognizerTest, AsynchronousGestureRecognition) { // Introduce some delay before the touch is released so that it is recognized // as a tap. However, this still should not create any gesture events. queued_delegate->Reset(); - TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), 0); + TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId1); Event::TestApi test_release(&release); test_release.set_time_stamp(press.time_stamp() + base::TimeDelta::FromMilliseconds(50)); @@ -792,7 +805,7 @@ TEST_F(GestureRecognizerTest, AsynchronousGestureRecognition) { scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( delegate.get(), -2345, gfx::Rect(0, 0, 50, 50), NULL)); delegate->Reset(); - TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 20), 0); + TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 20), kTouchId2); root_window()->DispatchTouchEvent(&press2); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); @@ -801,7 +814,7 @@ TEST_F(GestureRecognizerTest, AsynchronousGestureRecognition) { EXPECT_FALSE(delegate->scroll_update()); EXPECT_FALSE(delegate->scroll_end()); - TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), 0); + TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), kTouchId2); root_window()->DispatchTouchEvent(&release2); // Process the first queued event. @@ -827,7 +840,7 @@ TEST_F(GestureRecognizerTest, AsynchronousGestureRecognition) { // Start all over. Press on the first window, then press again on the second // window. The second press should still go to the first window. queued_delegate->Reset(); - TouchEvent press3(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), 0); + TouchEvent press3(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1); root_window()->DispatchTouchEvent(&press3); EXPECT_FALSE(queued_delegate->tap()); EXPECT_FALSE(queued_delegate->tap_down()); @@ -838,7 +851,7 @@ TEST_F(GestureRecognizerTest, AsynchronousGestureRecognition) { queued_delegate->Reset(); delegate->Reset(); - TouchEvent press4(ui::ET_TOUCH_PRESSED, gfx::Point(10, 20), 1); + TouchEvent press4(ui::ET_TOUCH_PRESSED, gfx::Point(10, 20), kTouchId2); root_window()->DispatchTouchEvent(&press4); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); @@ -881,6 +894,8 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromScroll) { new GestureEventConsumeDelegate()); const int kWindowWidth = 300; const int kWindowHeight = 400; + const int kTouchId1 = 5; + const int kTouchId2 = 3; gfx::Rect bounds(5, 5, kWindowWidth, kWindowHeight); scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( delegate.get(), -1234, bounds, NULL)); @@ -888,7 +903,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromScroll) { aura::RootWindow* root = root_window(); delegate->Reset(); - TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), 0); + TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1); root->DispatchTouchEvent(&press); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); @@ -900,7 +915,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromScroll) { // Move the touch-point enough so that it is considered as a scroll. This // should generate both SCROLL_BEGIN and SCROLL_UPDATE gestures. delegate->Reset(); - TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(130, 201), 0); + TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(130, 201), kTouchId1); root->DispatchTouchEvent(&move); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); @@ -911,7 +926,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromScroll) { // Press the second finger. It should cause both a tap-down and pinch-begin. delegate->Reset(); - TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1); + TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), kTouchId2); root->DispatchTouchEvent(&press2); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); @@ -923,7 +938,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromScroll) { // Move the first finger. delegate->Reset(); - TouchEvent move3(ui::ET_TOUCH_MOVED, gfx::Point(95, 201), 0); + TouchEvent move3(ui::ET_TOUCH_MOVED, gfx::Point(95, 201), kTouchId1); root->DispatchTouchEvent(&move3); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); @@ -936,7 +951,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromScroll) { // Now move the second finger. delegate->Reset(); - TouchEvent move4(ui::ET_TOUCH_MOVED, gfx::Point(55, 15), 1); + TouchEvent move4(ui::ET_TOUCH_MOVED, gfx::Point(55, 15), kTouchId2); root->DispatchTouchEvent(&move4); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); @@ -949,7 +964,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromScroll) { // Release the first finger. This should end pinch. delegate->Reset(); - TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), 0); + TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId1); Event::TestApi test_release(&release); test_release.set_time_stamp(press.time_stamp() + base::TimeDelta::FromMilliseconds(50)); @@ -964,7 +979,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromScroll) { // Move the second finger. This should still generate a scroll. delegate->Reset(); - TouchEvent move5(ui::ET_TOUCH_MOVED, gfx::Point(25, 10), 1); + TouchEvent move5(ui::ET_TOUCH_MOVED, gfx::Point(25, 10), kTouchId2); root->DispatchTouchEvent(&move5); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); @@ -976,11 +991,53 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromScroll) { EXPECT_FALSE(delegate->pinch_update()); } +TEST_F(GestureRecognizerTest, GestureEventPinchFromScrollFromPinch) { +scoped_ptr<GestureEventConsumeDelegate> delegate( + new GestureEventConsumeDelegate()); + const int kWindowWidth = 300; + const int kWindowHeight = 400; + const int kTouchId1 = 5; + const int kTouchId2 = 3; + gfx::Rect bounds(5, 5, kWindowWidth, kWindowHeight); + scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( + delegate.get(), -1234, bounds, NULL)); + + TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1); + root_window()->DispatchTouchEvent(&press); + delegate->Reset(); + TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), kTouchId2); + root_window()->DispatchTouchEvent(&press2); + EXPECT_TRUE(delegate->pinch_begin()); + + SendScrollEvent(root_window(), 130, 230, kTouchId1, delegate.get()); + EXPECT_TRUE(delegate->pinch_update()); + + // Pinch has started, now release the second finger + delegate->Reset(); + TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId1); + root_window()->DispatchTouchEvent(&release); + EXPECT_TRUE(delegate->pinch_end()); + + SendScrollEvent(root_window(), 130, 230, kTouchId2, delegate.get()); + EXPECT_TRUE(delegate->scroll_update()); + + // Pinch again + delegate->Reset(); + TouchEvent press3(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), kTouchId1); + root_window()->DispatchTouchEvent(&press3); + EXPECT_TRUE(delegate->pinch_begin()); + + SendScrollEvent(root_window(), 130, 230, kTouchId1, delegate.get()); + EXPECT_TRUE(delegate->pinch_update()); +} + TEST_F(GestureRecognizerTest, GestureEventPinchFromTap) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); const int kWindowWidth = 300; const int kWindowHeight = 400; + const int kTouchId1 = 3; + const int kTouchId2 = 5; gfx::Rect bounds(5, 5, kWindowWidth, kWindowHeight); scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( delegate.get(), -1234, bounds, NULL)); @@ -988,7 +1045,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromTap) { aura::RootWindow* root = root_window(); delegate->Reset(); - TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), 0); + TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1); root->DispatchTouchEvent(&press); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); @@ -1000,7 +1057,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromTap) { // Press the second finger. It should cause a tap-down, scroll-begin and // pinch-begin. delegate->Reset(); - TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1); + TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), kTouchId2); root->DispatchTouchEvent(&press2); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); @@ -1012,7 +1069,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromTap) { // Move the first finger. delegate->Reset(); - TouchEvent move3(ui::ET_TOUCH_MOVED, gfx::Point(65, 201), 0); + TouchEvent move3(ui::ET_TOUCH_MOVED, gfx::Point(65, 201), kTouchId1); root->DispatchTouchEvent(&move3); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); @@ -1025,7 +1082,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromTap) { // Now move the second finger. delegate->Reset(); - TouchEvent move4(ui::ET_TOUCH_MOVED, gfx::Point(55, 15), 1); + TouchEvent move4(ui::ET_TOUCH_MOVED, gfx::Point(55, 15), kTouchId2); root->DispatchTouchEvent(&move4); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); @@ -1038,7 +1095,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromTap) { // Release the first finger. This should end pinch. delegate->Reset(); - TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), 0); + TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId1); Event::TestApi test_release(&release); test_release.set_time_stamp(press.time_stamp() + base::TimeDelta::FromMilliseconds(50)); @@ -1053,7 +1110,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromTap) { // Move the second finger. This should still generate a scroll. delegate->Reset(); - TouchEvent move5(ui::ET_TOUCH_MOVED, gfx::Point(25, 10), 1); + TouchEvent move5(ui::ET_TOUCH_MOVED, gfx::Point(25, 10), kTouchId2); root->DispatchTouchEvent(&move5); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); @@ -1065,5 +1122,48 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromTap) { EXPECT_FALSE(delegate->pinch_update()); } +TEST_F(GestureRecognizerTest, GestureEventPinchScrollOnlyWhenBothFingersMove) { + scoped_ptr<GestureEventConsumeDelegate> delegate( + new GestureEventConsumeDelegate()); + const int kWindowWidth = 1000; + const int kWindowHeight = 1000; + const int kTouchId1 = 3; + const int kTouchId2 = 5; + gfx::Rect bounds(0, 0, kWindowWidth, kWindowHeight); + scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( + delegate.get(), -1234, bounds, NULL)); + + delegate->Reset(); + TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(100, 100), kTouchId1); + + root_window()->DispatchTouchEvent(&press1); + + delegate->Reset(); + TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(110, 110), kTouchId2); + root_window()->DispatchTouchEvent(&press2); + + SendScrollEvents(root_window(), 100, 100, press1.time_stamp(), + 1, 10, kTouchId1, 1, kBufferedPoints, delegate.get()); + + SendScrollEvents(root_window(), 110, 110, press1.time_stamp() + + base::TimeDelta::FromMilliseconds(1000), + 1, 10, kTouchId2, 1, kBufferedPoints, delegate.get()); + // At no point were both fingers moving at the same time, + // so no scrolling should have occurred + + EXPECT_EQ(0, delegate->scroll_x()); + EXPECT_EQ(0, delegate->scroll_y()); +} + +TEST_F(GestureRecognizerTest, GestureEventIgnoresDisconnectedEvents) { + scoped_ptr<GestureEventConsumeDelegate> delegate( + new GestureEventConsumeDelegate()); + + TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), 6); + root_window()->DispatchTouchEvent(&release1); + EXPECT_FALSE(delegate->tap()); + EXPECT_FALSE(delegate->tap_down()); +} + } // namespace test } // namespace aura diff --git a/ui/aura/gestures/gesture_sequence.cc b/ui/aura/gestures/gesture_sequence.cc index 554cf10..a31f9ef 100644 --- a/ui/aura/gestures/gesture_sequence.cc +++ b/ui/aura/gestures/gesture_sequence.cc @@ -12,11 +12,6 @@ #include "ui/aura/gestures/gesture_configuration.h" #include "ui/base/events.h" -// TODO(sad): Pinch gestures currently always assume that the first two -// touch-points (i.e. at indices 0 and 1) are involved. This may not -// always be the case. This needs to be fixed eventually. -// http://crbug.com/113144 - namespace { // TODO(girard): Make these configurable in sync with this CL @@ -99,18 +94,6 @@ enum EdgeStateSignatureType { GST_SCROLL_FIRST_CANCELLED = G(GS_SCROLL, 0, TS_CANCELLED, false), - GST_SCROLL_FIRST_PRESSED = - G(GS_SCROLL, 0, TS_PRESSED, false), - - GST_SCROLL_SECOND_RELEASED = - G(GS_SCROLL, 1, TS_RELEASED, false), - - GST_SCROLL_SECOND_MOVED = - G(GS_SCROLL, 1, TS_MOVED, false), - - GST_SCROLL_SECOND_CANCELLED = - G(GS_SCROLL, 1, TS_CANCELLED, false), - GST_SCROLL_SECOND_PRESSED = G(GS_SCROLL, 1, TS_PRESSED, false), @@ -164,9 +147,6 @@ GestureSequence::GestureSequence(RootWindow* root_window) long_press_timer_(CreateTimer()), point_count_(0), root_window_(root_window) { - for (int i = 0; i < kMaxGesturePoints; ++i) { - points_[i].set_touch_id(i); - } } GestureSequence::~GestureSequence() { @@ -185,7 +165,14 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( if (event.type() == ui::ET_TOUCH_PRESSED) { if (point_count_ == kMaxGesturePoints) return NULL; - ++point_count_; + GesturePoint* new_point = &points_[event.touch_id()]; + // Eventually, we shouldn't be able to get two PRESSED events without either + // a RELEASE or CANCEL. Currently if a RELEASE is preventDefaulted, + // this could occur: crbug.com/116537 + // TODO(tdresser): Enable this DCHECK, and remove the following condition + // DCHECK(!points_[event.touch_id()].in_use()); + if (!points_[event.touch_id()].in_use()) + new_point->set_point_id(point_count_++); } GestureState last_state = state_; @@ -195,7 +182,10 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( GesturePoint& point = GesturePointForEvent(event); point.UpdateValues(event); flags_ = event.flags(); - switch (Signature(state_, event.touch_id(), event.type(), false)) { + const int point_id = points_[event.touch_id()].point_id(); + if (point_id < 0) + return NULL; + switch (Signature(state_, point_id, event.type(), false)) { case GST_NO_GESTURE_FIRST_PRESSED: TouchDown(event, point, gestures.get()); set_state(GS_PENDING_SYNTHETIC_CLICK); @@ -217,7 +207,6 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( NoGesture(event, point, gestures.get()); break; case GST_SCROLL_FIRST_MOVED: - case GST_SCROLL_SECOND_MOVED: if (scroll_type_ == ST_VERTICAL || scroll_type_ == ST_HORIZONTAL) BreakRailScroll(event, point, gestures.get()); @@ -226,12 +215,9 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( break; case GST_SCROLL_FIRST_RELEASED: case GST_SCROLL_FIRST_CANCELLED: - case GST_SCROLL_SECOND_RELEASED: - case GST_SCROLL_SECOND_CANCELLED: ScrollEnd(event, point, gestures.get()); set_state(GS_NO_GESTURE); break; - case GST_SCROLL_FIRST_PRESSED: case GST_SCROLL_SECOND_PRESSED: case GST_PENDING_SYNTHETIC_CLICK_SECOND_PRESSED: PinchStart(event, point, gestures.get()); @@ -240,8 +226,8 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( case GST_PINCH_FIRST_MOVED: case GST_PINCH_SECOND_MOVED: if (PinchUpdate(event, point, gestures.get())) { - points_[0].UpdateForScroll(); - points_[1].UpdateForScroll(); + GetPointByPointId(0)->UpdateForScroll(); + GetPointByPointId(1)->UpdateForScroll(); } break; case GST_PINCH_FIRST_RELEASED: @@ -265,15 +251,27 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( if (last_state == GS_PENDING_SYNTHETIC_CLICK && state_ != last_state) long_press_timer_->Stop(); - if (event.type() == ui::ET_TOUCH_RELEASED) + // The set of point_ids must be contiguous and include 0. + // When a touch point is released, all points with ids greater than the + // released point must have their ids decremented, or the set of point_ids + // could end up with gaps. + if (event.type() == ui::ET_TOUCH_RELEASED) { + GesturePoint& old_point = points_[event.touch_id()]; + for (int i = 0; i < kMaxGesturePoints; ++i) { + GesturePoint& point = points_[i]; + if (point.point_id() > old_point.point_id()) + point.set_point_id(point.point_id() - 1); + } + old_point.Reset(); --point_count_; + } return gestures.release(); } void GestureSequence::Reset() { set_state(GS_NO_GESTURE); - for (int i = 0; i < point_count_; ++i) + for (int i = 0; i < kMaxGesturePoints; ++i) points_[i].Reset(); } @@ -292,6 +290,17 @@ GesturePoint& GestureSequence::GesturePointForEvent( return points_[event.touch_id()]; } +GesturePoint* GestureSequence::GetPointByPointId(int point_id) { + DCHECK(0 <= point_id && point_id < kMaxGesturePoints); + for (int i = 0; i < kMaxGesturePoints; ++i) { + GesturePoint& point = points_[i]; + if (point.in_use() && point.point_id() == point_id) + return &point; + } + NOTREACHED(); + return NULL; +} + void GestureSequence::AppendTapDownGestureEvent(const GesturePoint& point, Gestures* gestures) { gestures->push_back(linked_ptr<GestureEvent>(new GestureEvent( @@ -482,16 +491,14 @@ bool GestureSequence::TouchDown(const TouchEvent& event, } void GestureSequence::AppendLongPressGestureEvent() { - // TODO(tdresser) - this may not always be the first point - const GesturePoint& point = points_[0]; + const GesturePoint* point = GetPointByPointId(0); GestureEvent* gesture = new GestureEvent( ui::ET_GESTURE_LONG_PRESS, - point.first_touch_position().x(), - point.first_touch_position().y(), + point->first_touch_position().x(), + point->first_touch_position().y(), flags_, - base::Time::FromDoubleT(point.last_touch_time()), - point.touch_id(), 0.f); - + base::Time::FromDoubleT(point->last_touch_time()), + point->point_id(), 0.f); root_window_->DispatchGestureEvent(gesture); } @@ -514,13 +521,16 @@ bool GestureSequence::PinchStart(const TouchEvent& event, state_ == GS_PENDING_SYNTHETIC_CLICK); AppendTapDownGestureEvent(point, gestures); - pinch_distance_current_ = points_[0].Distance(points_[1]); + const GesturePoint* point1 = GetPointByPointId(0); + const GesturePoint* point2 = GetPointByPointId(1); + + pinch_distance_current_ = point1->Distance(*point2); pinch_distance_start_ = pinch_distance_current_; - AppendPinchGestureBegin(points_[0], points_[1], gestures); + AppendPinchGestureBegin(*point1, *point2, gestures); if (state_ == GS_PENDING_SYNTHETIC_CLICK) { - gfx::Point center = points_[0].last_touch_position().Middle( - points_[1].last_touch_position()); + gfx::Point center = point1->last_touch_position().Middle( + point2->last_touch_position()); AppendScrollGestureBegin(point, center, gestures); } @@ -530,23 +540,27 @@ bool GestureSequence::PinchStart(const TouchEvent& event, bool GestureSequence::PinchUpdate(const TouchEvent& event, const GesturePoint& point, Gestures* gestures) { DCHECK(state_ == GS_PINCH); - float distance = points_[0].Distance(points_[1]); + + const GesturePoint* point1 = GetPointByPointId(0); + const GesturePoint* point2 = GetPointByPointId(1); + + float distance = point1->Distance(*point2); if (abs(distance - pinch_distance_current_) < GestureConfiguration::minimum_pinch_update_distance_in_pixels()) { // The fingers didn't move towards each other, or away from each other, // enough to constitute a pinch. But perhaps they moved enough in the same // direction to do a two-finger scroll. - if (!points_[0].DidScroll(event, + if (!point1->DidScroll(event, GestureConfiguration::minimum_distance_for_pinch_scroll_in_pixels()) || - !points_[1].DidScroll(event, + !point2->DidScroll(event, GestureConfiguration::minimum_distance_for_pinch_scroll_in_pixels())) return false; - gfx::Point center = points_[0].last_touch_position().Middle( - points_[1].last_touch_position()); + gfx::Point center = point1->last_touch_position().Middle( + point2->last_touch_position()); AppendScrollGestureUpdate(point, center, gestures); } else { - AppendPinchGestureUpdate(points_[0], points_[1], + AppendPinchGestureUpdate(*point1, *point2, distance / pinch_distance_current_, gestures); pinch_distance_current_ = distance; } @@ -556,8 +570,12 @@ bool GestureSequence::PinchUpdate(const TouchEvent& event, bool GestureSequence::PinchEnd(const TouchEvent& event, const GesturePoint& point, Gestures* gestures) { DCHECK(state_ == GS_PINCH); - float distance = points_[0].Distance(points_[1]); - AppendPinchGestureEnd(points_[0], points_[1], + + const GesturePoint* point1 = GetPointByPointId(0); + const GesturePoint* point2 = GetPointByPointId(1); + + float distance = point1->Distance(*point2); + AppendPinchGestureEnd(*point1, *point2, distance / pinch_distance_start_, gestures); pinch_distance_start_ = 0; diff --git a/ui/aura/gestures/gesture_sequence.h b/ui/aura/gestures/gesture_sequence.h index 95ed63c..709d8a5 100644 --- a/ui/aura/gestures/gesture_sequence.h +++ b/ui/aura/gestures/gesture_sequence.h @@ -55,7 +55,11 @@ class AURA_EXPORT GestureSequence { GesturePoint& GesturePointForEvent(const TouchEvent& event); - // Functions to be called to add GestureEvents, after succesful recognition. + // Do a linear scan through points_ to find the GesturePoint + // with id |point_id|. + GesturePoint* GetPointByPointId(int point_id); + + // Functions to be called to add GestureEvents, after successful recognition. // Tap gestures. void AppendTapDownGestureEvent(const GesturePoint& point, Gestures* gestures); diff --git a/ui/aura/window_unittest.cc b/ui/aura/window_unittest.cc index d3779df..f78ed7c 100644 --- a/ui/aura/window_unittest.cc +++ b/ui/aura/window_unittest.cc @@ -518,7 +518,8 @@ TEST_F(WindowTest, CaptureTests) { generator.PressLeftButton(); EXPECT_EQ(1, delegate.mouse_event_count()); - root_window()->DispatchTouchEvent(&touchev); + TouchEvent touchev2(ui::ET_TOUCH_PRESSED, gfx::Point(50, 50), 1); + root_window()->DispatchTouchEvent(&touchev2); EXPECT_EQ(0, delegate.touch_event_count()); // Removing the capture window from parent should reset the capture window |