Commit b8c15ec6 authored by rbyers@chromium.org's avatar rbyers@chromium.org

Pass tap count (1 or 2) with tap gesture events

This is necessary to support the generation of the correct dblclick event sequence in WebKit.

Remove evil generic_x/generic_y from GestureEventDetails (some event types have data other than floats in that position of the union, this wasn't typesafe).

Adds missing double tap gesture recognizer unit tests.

This makes ET_GESTURE_DOUBLE_TAP pretty pointless now.  I've filed crbug.com/140382 to track removing it.

BUG=115486


Review URL: https://chromiumcodereview.appspot.com/10824158

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149935 0039d316-1c4b-4281-b951-d872f2087c98
parent 87d59ad8
...@@ -415,10 +415,27 @@ class LocalGestureEvent : ...@@ -415,10 +415,27 @@ class LocalGestureEvent :
data().y = client_point.y; data().y = client_point.y;
data().globalX = screen_point.x; data().globalX = screen_point.x;
data().globalY = screen_point.y; data().globalY = screen_point.y;
data().deltaX = details.generic_x();
data().deltaY = details.generic_y();
data().type = ConvertToWebInputEvent(type_); data().type = ConvertToWebInputEvent(type_);
data().boundingBox = details.bounding_box(); data().boundingBox = details.bounding_box();
// Copy any event-type specific data.
switch (type_) {
case ui::ET_GESTURE_TAP:
data().deltaX = details.tap_count();
break;
case ui::ET_GESTURE_SCROLL_UPDATE:
data().deltaX = details.scroll_x();
data().deltaY = details.scroll_y();
break;
case ui::ET_GESTURE_PINCH_UPDATE:
data().deltaX = details.scale();
break;
case ui::ET_SCROLL_FLING_START:
data().deltaX = details.velocity_x();
data().deltaY = details.velocity_y();
default:
break;
}
} }
virtual int GetLowestTouchId() const OVERRIDE { virtual int GetLowestTouchId() const OVERRIDE {
......
...@@ -364,6 +364,7 @@ WebKit::WebGestureEvent MakeWebGestureEventFromAuraEvent( ...@@ -364,6 +364,7 @@ WebKit::WebGestureEvent MakeWebGestureEventFromAuraEvent(
switch (event->type()) { switch (event->type()) {
case ui::ET_GESTURE_TAP: case ui::ET_GESTURE_TAP:
gesture_event.type = WebKit::WebInputEvent::GestureTap; gesture_event.type = WebKit::WebInputEvent::GestureTap;
gesture_event.deltaX = event->details().tap_count();
break; break;
case ui::ET_GESTURE_TAP_DOWN: case ui::ET_GESTURE_TAP_DOWN:
gesture_event.type = WebKit::WebInputEvent::GestureTapDown; gesture_event.type = WebKit::WebInputEvent::GestureTapDown;
...@@ -376,6 +377,8 @@ WebKit::WebGestureEvent MakeWebGestureEventFromAuraEvent( ...@@ -376,6 +377,8 @@ WebKit::WebGestureEvent MakeWebGestureEventFromAuraEvent(
break; break;
case ui::ET_GESTURE_SCROLL_UPDATE: case ui::ET_GESTURE_SCROLL_UPDATE:
gesture_event.type = WebKit::WebInputEvent::GestureScrollUpdate; gesture_event.type = WebKit::WebInputEvent::GestureScrollUpdate;
gesture_event.deltaX = event->details().scroll_x();
gesture_event.deltaY = event->details().scroll_y();
break; break;
case ui::ET_GESTURE_SCROLL_END: case ui::ET_GESTURE_SCROLL_END:
gesture_event.type = WebKit::WebInputEvent::GestureScrollEnd; gesture_event.type = WebKit::WebInputEvent::GestureScrollEnd;
...@@ -385,12 +388,15 @@ WebKit::WebGestureEvent MakeWebGestureEventFromAuraEvent( ...@@ -385,12 +388,15 @@ WebKit::WebGestureEvent MakeWebGestureEventFromAuraEvent(
break; break;
case ui::ET_GESTURE_PINCH_UPDATE: case ui::ET_GESTURE_PINCH_UPDATE:
gesture_event.type = WebKit::WebInputEvent::GesturePinchUpdate; gesture_event.type = WebKit::WebInputEvent::GesturePinchUpdate;
gesture_event.deltaX = event->details().scale();
break; break;
case ui::ET_GESTURE_PINCH_END: case ui::ET_GESTURE_PINCH_END:
gesture_event.type = WebKit::WebInputEvent::GesturePinchEnd; gesture_event.type = WebKit::WebInputEvent::GesturePinchEnd;
break; break;
case ui::ET_SCROLL_FLING_START: case ui::ET_SCROLL_FLING_START:
gesture_event.type = WebKit::WebInputEvent::GestureFlingStart; gesture_event.type = WebKit::WebInputEvent::GestureFlingStart;
gesture_event.deltaX = event->details().velocity_x();
gesture_event.deltaY = event->details().velocity_y();
break; break;
case ui::ET_SCROLL_FLING_CANCEL: case ui::ET_SCROLL_FLING_CANCEL:
gesture_event.type = WebKit::WebInputEvent::GestureFlingCancel; gesture_event.type = WebKit::WebInputEvent::GestureFlingCancel;
...@@ -410,8 +416,6 @@ WebKit::WebGestureEvent MakeWebGestureEventFromAuraEvent( ...@@ -410,8 +416,6 @@ WebKit::WebGestureEvent MakeWebGestureEventFromAuraEvent(
} }
gesture_event.boundingBox = event->details().bounding_box(); gesture_event.boundingBox = event->details().bounding_box();
gesture_event.deltaX = event->details().generic_x();
gesture_event.deltaY = event->details().generic_y();
gesture_event.modifiers = EventFlagsToWebEventModifiers(event->flags()); gesture_event.modifiers = EventFlagsToWebEventModifiers(event->flags());
return gesture_event; return gesture_event;
......
...@@ -51,7 +51,8 @@ class GestureEventConsumeDelegate : public TestWindowDelegate { ...@@ -51,7 +51,8 @@ class GestureEventConsumeDelegate : public TestWindowDelegate {
scroll_x_(0), scroll_x_(0),
scroll_y_(0), scroll_y_(0),
velocity_x_(0), velocity_x_(0),
velocity_y_(0) { velocity_y_(0),
tap_count_(0) {
} }
virtual ~GestureEventConsumeDelegate() {} virtual ~GestureEventConsumeDelegate() {}
...@@ -79,6 +80,7 @@ class GestureEventConsumeDelegate : public TestWindowDelegate { ...@@ -79,6 +80,7 @@ class GestureEventConsumeDelegate : public TestWindowDelegate {
scroll_y_ = 0; scroll_y_ = 0;
velocity_x_ = 0; velocity_x_ = 0;
velocity_y_ = 0; velocity_y_ = 0;
tap_count_ = 0;
} }
bool tap() const { return tap_; } bool tap() const { return tap_; }
...@@ -110,12 +112,14 @@ class GestureEventConsumeDelegate : public TestWindowDelegate { ...@@ -110,12 +112,14 @@ class GestureEventConsumeDelegate : public TestWindowDelegate {
float velocity_x() const { return velocity_x_; } float velocity_x() const { return velocity_x_; }
float velocity_y() const { return velocity_y_; } float velocity_y() const { return velocity_y_; }
const gfx::Rect& bounding_box() const { return bounding_box_; } const gfx::Rect& bounding_box() const { return bounding_box_; }
int tap_count() const { return tap_count_; }
virtual ui::GestureStatus OnGestureEvent(GestureEvent* gesture) OVERRIDE { virtual ui::GestureStatus OnGestureEvent(GestureEvent* gesture) OVERRIDE {
bounding_box_ = gesture->details().bounding_box(); bounding_box_ = gesture->details().bounding_box();
switch (gesture->type()) { switch (gesture->type()) {
case ui::ET_GESTURE_TAP: case ui::ET_GESTURE_TAP:
tap_location_ = gesture->location(); tap_location_ = gesture->location();
tap_count_ = gesture->details().tap_count();
tap_ = true; tap_ = true;
break; break;
case ui::ET_GESTURE_TAP_DOWN: case ui::ET_GESTURE_TAP_DOWN:
...@@ -196,6 +200,7 @@ class GestureEventConsumeDelegate : public TestWindowDelegate { ...@@ -196,6 +200,7 @@ class GestureEventConsumeDelegate : public TestWindowDelegate {
float velocity_y_; float velocity_y_;
int touch_id_; int touch_id_;
gfx::Rect bounding_box_; gfx::Rect bounding_box_;
int tap_count_;
DISALLOW_COPY_AND_ASSIGN(GestureEventConsumeDelegate); DISALLOW_COPY_AND_ASSIGN(GestureEventConsumeDelegate);
}; };
...@@ -431,6 +436,8 @@ TEST_F(GestureRecognizerTest, GestureEventTap) { ...@@ -431,6 +436,8 @@ TEST_F(GestureRecognizerTest, GestureEventTap) {
EXPECT_FALSE(delegate->scroll_begin()); EXPECT_FALSE(delegate->scroll_begin());
EXPECT_FALSE(delegate->scroll_update()); EXPECT_FALSE(delegate->scroll_update());
EXPECT_FALSE(delegate->scroll_end()); EXPECT_FALSE(delegate->scroll_end());
EXPECT_EQ(1, delegate->tap_count());
} }
// Check that appropriate touch events generate tap gesture events // Check that appropriate touch events generate tap gesture events
...@@ -481,6 +488,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) { ...@@ -481,6 +488,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) {
EXPECT_FALSE(delegate->scroll_update()); EXPECT_FALSE(delegate->scroll_update());
EXPECT_FALSE(delegate->scroll_end()); EXPECT_FALSE(delegate->scroll_end());
EXPECT_EQ(1, delegate->tap_count());
gfx::Point actual_point(delegate->tap_location()); gfx::Point actual_point(delegate->tap_location());
EXPECT_EQ(24, delegate->bounding_box().width()); EXPECT_EQ(24, delegate->bounding_box().width());
EXPECT_EQ(24, delegate->bounding_box().height()); EXPECT_EQ(24, delegate->bounding_box().height());
...@@ -522,6 +530,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) { ...@@ -522,6 +530,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) {
EXPECT_FALSE(delegate->scroll_update()); EXPECT_FALSE(delegate->scroll_update());
EXPECT_FALSE(delegate->scroll_end()); EXPECT_FALSE(delegate->scroll_end());
EXPECT_EQ(1, delegate->tap_count());
gfx::Point actual_point(delegate->tap_location()); gfx::Point actual_point(delegate->tap_location());
EXPECT_EQ(46, delegate->bounding_box().width()); EXPECT_EQ(46, delegate->bounding_box().width());
EXPECT_EQ(40, delegate->bounding_box().height()); EXPECT_EQ(40, delegate->bounding_box().height());
...@@ -579,6 +588,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) { ...@@ -579,6 +588,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) {
EXPECT_FALSE(delegate->scroll_update()); EXPECT_FALSE(delegate->scroll_update());
EXPECT_FALSE(delegate->scroll_end()); EXPECT_FALSE(delegate->scroll_end());
EXPECT_EQ(1, delegate->tap_count());
gfx::Point actual_point(delegate->tap_location()); gfx::Point actual_point(delegate->tap_location());
EXPECT_EQ(28, delegate->bounding_box().width()); EXPECT_EQ(28, delegate->bounding_box().width());
EXPECT_EQ(28, delegate->bounding_box().height()); EXPECT_EQ(28, delegate->bounding_box().height());
...@@ -668,6 +678,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) { ...@@ -668,6 +678,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) {
EXPECT_FALSE(delegate->scroll_update()); EXPECT_FALSE(delegate->scroll_update());
EXPECT_FALSE(delegate->scroll_end()); EXPECT_FALSE(delegate->scroll_end());
EXPECT_EQ(1, delegate->tap_count());
gfx::Point actual_point(delegate->tap_location()); gfx::Point actual_point(delegate->tap_location());
EXPECT_EQ(35, delegate->bounding_box().width()); EXPECT_EQ(35, delegate->bounding_box().width());
EXPECT_EQ(36, delegate->bounding_box().height()); EXPECT_EQ(36, delegate->bounding_box().height());
...@@ -2375,5 +2386,135 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTouchMoveConsumed) { ...@@ -2375,5 +2386,135 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTouchMoveConsumed) {
EXPECT_TRUE(delegate->scroll_end()); EXPECT_TRUE(delegate->scroll_end());
} }
// Check that appropriate touch events generate double tap gesture events.
TEST_F(GestureRecognizerTest, GestureEventDoubleTap) {
scoped_ptr<GestureEventConsumeDelegate> delegate(
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));
// First tap (tested in GestureEventTap)
TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(104, 201),
kTouchId, GetTime());
root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1);
TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(104, 201),
kTouchId, press1.time_stamp() +
base::TimeDelta::FromMilliseconds(50));
root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release1);
delegate->Reset();
// Second tap
TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(101, 203),
kTouchId, release1.time_stamp() +
base::TimeDelta::FromMilliseconds(200));
root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2);
TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(102, 206),
kTouchId, press2.time_stamp() +
base::TimeDelta::FromMilliseconds(50));
root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release2);
EXPECT_TRUE(delegate->tap());
EXPECT_TRUE(delegate->tap_down());
EXPECT_TRUE(delegate->begin());
EXPECT_TRUE(delegate->end());
EXPECT_TRUE(delegate->double_tap());
EXPECT_FALSE(delegate->scroll_begin());
EXPECT_FALSE(delegate->scroll_update());
EXPECT_FALSE(delegate->scroll_end());
EXPECT_EQ(2, delegate->tap_count());
}
// Check that we don't get a double tap when the two taps are far apart.
TEST_F(GestureRecognizerTest, TwoTapsFarApart) {
scoped_ptr<GestureEventConsumeDelegate> delegate(
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));
// First tap (tested in GestureEventTap)
TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201),
kTouchId, GetTime());
root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1);
TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201),
kTouchId, press1.time_stamp() +
base::TimeDelta::FromMilliseconds(50));
root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release1);
delegate->Reset();
// Second tap, close in time but far in distance
TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(201, 201),
kTouchId, release1.time_stamp() +
base::TimeDelta::FromMilliseconds(200));
root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2);
TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(201, 201),
kTouchId, press2.time_stamp() +
base::TimeDelta::FromMilliseconds(50));
root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release2);
EXPECT_TRUE(delegate->tap());
EXPECT_TRUE(delegate->tap_down());
EXPECT_TRUE(delegate->begin());
EXPECT_TRUE(delegate->end());
EXPECT_FALSE(delegate->double_tap());
EXPECT_FALSE(delegate->scroll_begin());
EXPECT_FALSE(delegate->scroll_update());
EXPECT_FALSE(delegate->scroll_end());
EXPECT_EQ(1, delegate->tap_count());
}
// Check that we don't get a double tap when the two taps have a long enough
// delay in between.
TEST_F(GestureRecognizerTest, TwoTapsWithDelayBetween) {
scoped_ptr<GestureEventConsumeDelegate> delegate(
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));
// First tap (tested in GestureEventTap)
TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201),
kTouchId, GetTime());
root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1);
TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201),
kTouchId, press1.time_stamp() +
base::TimeDelta::FromMilliseconds(50));
root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release1);
delegate->Reset();
// Second tap, close in distance but after some delay
TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201),
kTouchId, release1.time_stamp() +
base::TimeDelta::FromMilliseconds(2000));
root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2);
TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201),
kTouchId, press2.time_stamp() +
base::TimeDelta::FromMilliseconds(50));
root_window()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release2);
EXPECT_TRUE(delegate->tap());
EXPECT_TRUE(delegate->tap_down());
EXPECT_TRUE(delegate->begin());
EXPECT_TRUE(delegate->end());
EXPECT_FALSE(delegate->double_tap());
EXPECT_FALSE(delegate->scroll_begin());
EXPECT_FALSE(delegate->scroll_update());
EXPECT_FALSE(delegate->scroll_end());
EXPECT_EQ(1, delegate->tap_count());
}
} // namespace test } // namespace test
} // namespace aura } // namespace aura
...@@ -596,11 +596,12 @@ void GestureSequence::AppendEndGestureEvent(const GesturePoint& point, ...@@ -596,11 +596,12 @@ void GestureSequence::AppendEndGestureEvent(const GesturePoint& point,
} }
void GestureSequence::AppendClickGestureEvent(const GesturePoint& point, void GestureSequence::AppendClickGestureEvent(const GesturePoint& point,
int tap_count,
Gestures* gestures) { Gestures* gestures) {
gfx::Rect er = point.enclosing_rectangle(); gfx::Rect er = point.enclosing_rectangle();
gfx::Point center = er.CenterPoint(); gfx::Point center = er.CenterPoint();
gestures->push_back(CreateGestureEvent( gestures->push_back(CreateGestureEvent(
GestureEventDetails(ui::ET_GESTURE_TAP, 0, 0), GestureEventDetails(ui::ET_GESTURE_TAP, tap_count, 0),
center, center,
flags_, flags_,
base::Time::FromDoubleT(point.last_touch_time()), base::Time::FromDoubleT(point.last_touch_time()),
...@@ -753,8 +754,9 @@ bool GestureSequence::Click(const TouchEvent& event, ...@@ -753,8 +754,9 @@ bool GestureSequence::Click(const TouchEvent& event,
const GesturePoint& point, Gestures* gestures) { const GesturePoint& point, Gestures* gestures) {
DCHECK(state_ == GS_PENDING_SYNTHETIC_CLICK); DCHECK(state_ == GS_PENDING_SYNTHETIC_CLICK);
if (point.IsInClickWindow(event)) { if (point.IsInClickWindow(event)) {
AppendClickGestureEvent(point, gestures); bool double_tap = point.IsInDoubleClickWindow(event);
if (point.IsInDoubleClickWindow(event)) AppendClickGestureEvent(point, double_tap ? 2 : 1, gestures);
if (double_tap)
AppendDoubleClickGestureEvent(point, gestures); AppendDoubleClickGestureEvent(point, gestures);
return true; return true;
} }
......
...@@ -90,7 +90,9 @@ class UI_EXPORT GestureSequence { ...@@ -90,7 +90,9 @@ class UI_EXPORT GestureSequence {
void AppendTapDownGestureEvent(const GesturePoint& point, Gestures* gestures); void AppendTapDownGestureEvent(const GesturePoint& point, Gestures* gestures);
void AppendBeginGestureEvent(const GesturePoint& point, Gestures* gestures); void AppendBeginGestureEvent(const GesturePoint& point, Gestures* gestures);
void AppendEndGestureEvent(const GesturePoint& point, Gestures* gestures); void AppendEndGestureEvent(const GesturePoint& point, Gestures* gestures);
void AppendClickGestureEvent(const GesturePoint& point, Gestures* gestures); void AppendClickGestureEvent(const GesturePoint& point,
int tap_count,
Gestures* gestures);
void AppendDoubleClickGestureEvent(const GesturePoint& point, void AppendDoubleClickGestureEvent(const GesturePoint& point,
Gestures* gestures); Gestures* gestures);
void AppendLongPressGestureEvent(); void AppendLongPressGestureEvent();
......
...@@ -39,6 +39,11 @@ GestureEventDetails::GestureEventDetails(ui::EventType type, ...@@ -39,6 +39,11 @@ GestureEventDetails::GestureEventDetails(ui::EventType type,
data.swipe.down = delta_y > 0; data.swipe.down = delta_y > 0;
break; break;
case ui::ET_GESTURE_TAP:
data.tap_count = static_cast<int>(delta_x);
CHECK_EQ(0.f, delta_y) << "Unknown data in delta_y for tap.";
break;
default: default:
data.generic.delta_x = delta_x; data.generic.delta_x = delta_x;
data.generic.delta_y = delta_y; data.generic.delta_y = delta_y;
......
...@@ -69,12 +69,9 @@ struct UI_EXPORT GestureEventDetails { ...@@ -69,12 +69,9 @@ struct UI_EXPORT GestureEventDetails {
return data.swipe.down; return data.swipe.down;
} }
float generic_x() const { int tap_count() const {
return data.generic.delta_x; CHECK_EQ(ui::ET_GESTURE_TAP, type_);
} return data.tap_count;
float generic_y() const {
return data.generic.delta_y;
} }
private: private:
...@@ -101,6 +98,8 @@ struct UI_EXPORT GestureEventDetails { ...@@ -101,6 +98,8 @@ struct UI_EXPORT GestureEventDetails {
bool down; bool down;
} swipe; } swipe;
int tap_count; // TAP repeat count.
struct { struct {
float delta_x; float delta_x;
float delta_y; float delta_y;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment