Commit c99767e0 authored by jdduke@chromium.org's avatar jdduke@chromium.org

Support minimum gesture bounds in GestureProvider

Some touch devices report either zero or unreasonably small touch sizes. While
this doesn't present a problem for gesture detection, it does affect the
behavior of the touch-derived gestures. For example, tap disambiguation is
prevented if the tap gesture's size is sufficiently small. As a workaround,
provide a platform-specific minimum gesture bounds length in GestureProvider.
On Android, this value is the same as was used before the unified gesture
detector, and on Aura we simply use half the default touch size.

BUG=379876

Review URL: https://codereview.chromium.org/321563002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@276550 0039d316-1c4b-4281-b951-d872f2087c98
parent a8360f2a
......@@ -241,7 +241,7 @@ WebGestureEvent CreateWebGestureEventFromGestureEventData(
gesture.timeStampSeconds = (data.time - base::TimeTicks()).InSecondsF();
gesture.sourceDevice = blink::WebGestureDeviceTouchscreen;
switch (data.type) {
switch (data.type()) {
case ui::ET_GESTURE_SHOW_PRESS:
gesture.type = WebInputEvent::GestureShowPress;
gesture.data.showPress.width = data.details.bounding_box_f().width();
......
......@@ -13,6 +13,10 @@ namespace ui {
namespace {
// TODO(jdduke): Adopt GestureConfiguration on Android, crbug/339203.
// This was the minimum tap/press size used on Android before the new gesture
// detection pipeline.
const float kMinGestureBoundsLengthDips = 24.f;
GestureDetector::Config DefaultGestureDetectorConfig(
const gfx::Display& display) {
GestureDetector::Config config;
......@@ -62,6 +66,7 @@ GestureProvider::Config DefaultGestureProviderConfig() {
config.scale_gesture_detector_config =
DefaultScaleGestureDetectorConfig(config.display);
config.gesture_begin_end_types_enabled = false;
config.min_gesture_bounds_length = kMinGestureBoundsLengthDips;
return config;
}
......
......@@ -65,6 +65,8 @@ GestureProvider::Config DefaultGestureProviderConfig() {
config.gesture_detector_config = DefaultGestureDetectorConfig();
config.scale_gesture_detector_config = DefaultScaleGestureDetectorConfig();
config.gesture_begin_end_types_enabled = true;
// Half the size of the default touch length is a reasonable minimum.
config.min_gesture_bounds_length = GestureConfiguration::default_radius();
return config;
}
......
......@@ -8,25 +8,20 @@
namespace ui {
GestureEventData::GestureEventData(EventType type,
GestureEventData::GestureEventData(const GestureEventDetails& details,
int motion_event_id,
base::TimeTicks time,
float x,
float y,
int touch_point_count,
const gfx::RectF& bounding_box,
const GestureEventDetails& details)
: type(type),
const gfx::RectF& bounding_box)
: details(details),
motion_event_id(motion_event_id),
time(time),
x(x),
y(y),
details(details) {
y(y) {
DCHECK_GE(motion_event_id, 0);
DCHECK_NE(0, touch_point_count);
DCHECK_GE(type, ET_GESTURE_TYPE_START);
DCHECK_LE(type, ET_GESTURE_TYPE_END);
DCHECK_EQ(type, details.type());
this->details.set_touch_points(touch_point_count);
this->details.set_bounding_box(bounding_box);
}
......@@ -38,20 +33,17 @@ GestureEventData::GestureEventData(EventType type,
float y,
int touch_point_count,
const gfx::RectF& bounding_box)
: type(type),
: details(GestureEventDetails(type, 0, 0)),
motion_event_id(motion_event_id),
time(time),
x(x),
y(y),
details(GestureEventDetails(type, 0, 0)) {
y(y) {
DCHECK_GE(motion_event_id, 0);
DCHECK_NE(0, touch_point_count);
DCHECK_GE(type, ET_GESTURE_TYPE_START);
DCHECK_LE(type, ET_GESTURE_TYPE_END);
details.set_touch_points(touch_point_count);
details.set_bounding_box(bounding_box);
}
GestureEventData::GestureEventData() : type(ET_UNKNOWN), x(0), y(0) {}
GestureEventData::GestureEventData() : x(0), y(0) {
}
} // namespace ui
......@@ -15,14 +15,13 @@ namespace ui {
class GestureEventDataPacket;
struct GESTURE_DETECTION_EXPORT GestureEventData {
GestureEventData(EventType type,
GestureEventData(const GestureEventDetails&,
int motion_event_id,
base::TimeTicks time,
float x,
float y,
int touch_point_count,
const gfx::RectF& bounding_box,
const GestureEventDetails& details);
const gfx::RectF& bounding_box);
GestureEventData(EventType type,
int motion_event_id,
......@@ -32,14 +31,14 @@ struct GESTURE_DETECTION_EXPORT GestureEventData {
int touch_point_count,
const gfx::RectF& bounding_box);
EventType type;
EventType type() const { return details.type(); }
GestureEventDetails details;
int motion_event_id;
base::TimeTicks time;
float x;
float y;
GestureEventDetails details;
private:
friend class GestureEventDataPacket;
......
......@@ -67,7 +67,7 @@ GestureEventDataPacket& GestureEventDataPacket::operator=(
}
void GestureEventDataPacket::Push(const GestureEventData& gesture) {
DCHECK_NE(ET_UNKNOWN, gesture.type);
DCHECK_NE(ET_UNKNOWN, gesture.type());
CHECK_LT(gesture_count_, static_cast<size_t>(kMaxGesturesPerTouch));
gestures_[gesture_count_++] = gesture;
}
......
......@@ -9,14 +9,13 @@
#include "base/memory/scoped_ptr.h"
#include "ui/events/gesture_detection/gesture_detection_export.h"
#include "ui/events/gesture_detection/gesture_detector.h"
#include "ui/events/gesture_detection/gesture_event_data.h"
#include "ui/events/gesture_detection/scale_gesture_detector.h"
#include "ui/events/gesture_detection/snap_scroll_controller.h"
#include "ui/gfx/display.h"
namespace ui {
struct GestureEventData;
class GESTURE_DETECTION_EXPORT GestureProviderClient {
public:
virtual ~GestureProviderClient() {}
......@@ -45,6 +44,12 @@ class GESTURE_DETECTION_EXPORT GestureProvider {
// event for every added touch point, and an ET_GESTURE_END event for every
// removed touch point. Defaults to false.
bool gesture_begin_end_types_enabled;
// The minimum size (both length and width, in dips) of the generated
// bounding box for all gesture types. This is useful for touch streams
// that may report zero or unreasonably small touch sizes.
// Defaults to 0.
float min_gesture_bounds_length;
};
GestureProvider(const Config& config, GestureProviderClient* client);
......@@ -87,7 +92,7 @@ class GESTURE_DETECTION_EXPORT GestureProvider {
bool CanHandle(const MotionEvent& event) const;
void Fling(const MotionEvent& e, float velocity_x, float velocity_y);
void Send(const GestureEventData& gesture);
void Send(GestureEventData gesture);
bool SendLongTapIfNecessary(const MotionEvent& event);
void EndTouchScrollIfNecessary(const MotionEvent& event,
bool send_scroll_end_event);
......@@ -121,7 +126,9 @@ class GESTURE_DETECTION_EXPORT GestureProvider {
// GESTURE_TAP_CANCEL for removing any ::active styling.
base::TimeTicks current_longpress_time_;
bool gesture_begin_end_types_enabled_;
const bool gesture_begin_end_types_enabled_;
const float min_gesture_bounds_length_;
};
} // namespace ui
......
......@@ -130,7 +130,7 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
// GestureProviderClient
virtual void OnGestureEvent(const GestureEventData& gesture) OVERRIDE {
if (gesture.type == ET_GESTURE_SCROLL_BEGIN)
if (gesture.type() == ET_GESTURE_SCROLL_BEGIN)
active_scroll_begin_event_.reset(new GestureEventData(gesture));
gestures_.push_back(gesture);
}
......@@ -153,7 +153,7 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
bool HasReceivedGesture(EventType type) const {
for (size_t i = 0; i < gestures_.size(); ++i) {
if (gestures_[i].type == type)
if (gestures_[i].type() == type)
return true;
}
return false;
......@@ -166,7 +166,7 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
EventType GetMostRecentGestureEventType() const {
EXPECT_FALSE(gestures_.empty());
return gestures_.back().type;
return gestures_.back().type();
}
size_t GetReceivedGestureCount() const { return gestures_.size(); }
......@@ -235,6 +235,12 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
SetUpWithConfig(config);
}
void SetMinGestureBoundsLength(float min_gesture_bound_length) {
GestureProvider::Config config = GetDefaultConfig();
config.min_gesture_bounds_length = min_gesture_bound_length;
SetUpWithConfig(config);
}
bool HasDownEvent() const { return gesture_provider_->current_down_event(); }
protected:
......@@ -268,7 +274,7 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
"ScrollBegin and ScrollBy "
"should have been sent";
EXPECT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(1).type);
EXPECT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(1).type());
EXPECT_EQ(motion_event_id, GetReceivedGesture(1).motion_event_id);
EXPECT_EQ(event_time + kOneSecond, GetReceivedGesture(1).time)
<< "ScrollBegin should have the time of the ACTION_MOVE";
......@@ -372,7 +378,7 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
};
// Verify that a DOWN followed shortly by an UP will trigger a single tap.
TEST_F(GestureProviderTest, GestureTapTap) {
TEST_F(GestureProviderTest, GestureTap) {
base::TimeTicks event_time = base::TimeTicks::Now();
int motion_event_id = 0;
......@@ -404,7 +410,7 @@ TEST_F(GestureProviderTest, GestureTapTap) {
// Verify that a DOWN followed shortly by an UP will trigger
// a ET_GESTURE_TAP_UNCONFIRMED event if double-tap is enabled.
TEST_F(GestureProviderTest, GestureTapTapWithDelay) {
TEST_F(GestureProviderTest, GestureTapWithDelay) {
base::TimeTicks event_time = base::TimeTicks::Now();
int motion_event_id = 0;
......@@ -520,7 +526,7 @@ TEST_F(GestureProviderTest, FlingEventSequence) {
EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
ASSERT_EQ(3U, GetReceivedGestureCount());
ASSERT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(1).type);
ASSERT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(1).type());
EXPECT_EQ(motion_event_id, GetReceivedGesture(1).motion_event_id);
// We don't want to take a dependency here on exactly how hints are calculated
......@@ -638,7 +644,7 @@ TEST_F(GestureProviderTest, DoubleTap) {
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
const GestureEventData& double_tap = GetMostRecentGestureEvent();
EXPECT_EQ(ET_GESTURE_DOUBLE_TAP, double_tap.type);
EXPECT_EQ(ET_GESTURE_DOUBLE_TAP, double_tap.type());
// Ensure tap details have been set.
EXPECT_EQ(10, double_tap.details.bounding_box().width());
EXPECT_EQ(10, double_tap.details.bounding_box().height());
......@@ -737,7 +743,7 @@ TEST_F(GestureProviderTest, ScrollUpdateValues) {
// Make sure the reported gesture event has all the expected details.
ASSERT_LT(0U, GetReceivedGestureCount());
GestureEventData gesture = GetMostRecentGestureEvent();
EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, gesture.type);
EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, gesture.type());
EXPECT_EQ(event_time + kOneMicrosecond * 2, gesture.time);
EXPECT_EQ(kFakeCoordX - delta_x, gesture.x);
EXPECT_EQ(kFakeCoordY - delta_y, gesture.y);
......@@ -781,7 +787,7 @@ TEST_F(GestureProviderTest, FractionalScroll) {
ASSERT_LT(0U, GetReceivedGestureCount());
GestureEventData gesture = GetMostRecentGestureEvent();
EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, gesture.type);
EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, gesture.type());
EXPECT_EQ(event_time + kOneMicrosecond * i, gesture.time);
EXPECT_EQ(1, gesture.details.touch_points());
......@@ -1732,7 +1738,7 @@ TEST_F(GestureProviderTest, GestureBeginAndEnd) {
ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, 1, 1);
event.pointer_count = 1;
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_BEGIN, GetReceivedGesture(0).type);
EXPECT_EQ(ET_GESTURE_BEGIN, GetReceivedGesture(0).type());
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(2U, GetReceivedGestureCount());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
......@@ -1826,7 +1832,7 @@ TEST_F(GestureProviderTest, GestureBeginAndEndOnCancel) {
ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, 1, 1);
event.pointer_count = 1;
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_BEGIN, GetReceivedGesture(0).type);
EXPECT_EQ(ET_GESTURE_BEGIN, GetReceivedGesture(0).type());
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(2U, GetReceivedGestureCount());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
......@@ -1865,11 +1871,11 @@ TEST_F(GestureProviderTest, GestureBeginAndEndOnCancel) {
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(7U, GetReceivedGestureCount());
EXPECT_EQ(3, GetReceivedGesture(4).details.touch_points());
EXPECT_EQ(ET_GESTURE_END, GetReceivedGesture(4).details.type());
EXPECT_EQ(ET_GESTURE_END, GetReceivedGesture(4).type());
EXPECT_EQ(2, GetReceivedGesture(5).details.touch_points());
EXPECT_EQ(ET_GESTURE_END, GetReceivedGesture(5).details.type());
EXPECT_EQ(ET_GESTURE_END, GetReceivedGesture(5).type());
EXPECT_EQ(1, GetReceivedGesture(6).details.touch_points());
EXPECT_EQ(ET_GESTURE_END, GetReceivedGesture(6).details.type());
EXPECT_EQ(ET_GESTURE_END, GetReceivedGesture(6).type());
EXPECT_EQ(1, GetReceivedGesture(4).x);
EXPECT_EQ(1, GetReceivedGesture(4).y);
EXPECT_EQ(2, GetReceivedGesture(5).x);
......@@ -1921,9 +1927,9 @@ TEST_F(GestureProviderTest, TwoFingerTap) {
0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type);
EXPECT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(1).type);
EXPECT_EQ(ET_GESTURE_TWO_FINGER_TAP, GetReceivedGesture(2).type);
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type());
EXPECT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(1).type());
EXPECT_EQ(ET_GESTURE_TWO_FINGER_TAP, GetReceivedGesture(2).type());
EXPECT_EQ(3U, GetReceivedGestureCount());
EXPECT_EQ(kMockTouchRadius * 2,
......@@ -1966,8 +1972,8 @@ TEST_F(GestureProviderTest, TwoFingerTapCancelledByFingerMovement) {
kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type);
EXPECT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(1).type);
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type());
EXPECT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(1).type());
EXPECT_EQ(2U, GetReceivedGestureCount());
}
......@@ -2003,7 +2009,7 @@ TEST_F(GestureProviderTest, TwoFingerTapCancelledByDelay) {
kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type);
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type());
EXPECT_EQ(1U, GetReceivedGestureCount());
}
......@@ -2033,7 +2039,7 @@ TEST_F(GestureProviderTest, TwoFingerTapCancelledByDistanceBetweenPointers) {
kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type);
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type());
EXPECT_EQ(1U, GetReceivedGestureCount());
}
......@@ -2118,4 +2124,31 @@ TEST_F(GestureProviderTest, PinchZoomWithThreshold) {
EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
}
// Verify that the min gesture bound setting is honored.
TEST_F(GestureProviderTest, MinGestureBoundsLength) {
const float kMinGestureBoundsLength = 10.f * kMockTouchRadius;
SetMinGestureBoundsLength(kMinGestureBoundsLength);
gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(kMinGestureBoundsLength,
GetMostRecentGestureEvent().details.bounding_box_f().width());
EXPECT_EQ(kMinGestureBoundsLength,
GetMostRecentGestureEvent().details.bounding_box_f().height());
event =
ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::ACTION_UP);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
EXPECT_EQ(kMinGestureBoundsLength,
GetMostRecentGestureEvent().details.bounding_box_f().width());
EXPECT_EQ(kMinGestureBoundsLength,
GetMostRecentGestureEvent().details.bounding_box_f().height());
}
} // namespace ui
......@@ -20,14 +20,13 @@ GestureEventData CreateGesture(EventType type,
const base::TimeTicks& timestamp,
const gfx::PointF& location) {
GestureEventDetails details(type, 0, 0);
return GestureEventData(type,
return GestureEventData(details,
motion_event_id,
timestamp,
location.x(),
location.y(),
1,
gfx::RectF(location.x(), location.y(), 0, 0),
details);
gfx::RectF(location.x(), location.y(), 0, 0));
}
enum RequiredTouches {
......@@ -223,9 +222,9 @@ void TouchDispositionGestureFilter::FilterAndSendPacket(
for (size_t i = 0; i < packet.gesture_count(); ++i) {
const GestureEventData& gesture = packet.gesture(i);
DCHECK(ET_GESTURE_TYPE_START <= gesture.type &&
gesture.type <= ET_GESTURE_TYPE_END);
if (state_.Filter(gesture.type)) {
DCHECK_GE(gesture.details.type(), ET_GESTURE_TYPE_START);
DCHECK_LE(gesture.details.type(), ET_GESTURE_TYPE_END);
if (state_.Filter(gesture.details.type())) {
CancelTapIfNecessary();
continue;
}
......@@ -245,7 +244,7 @@ void TouchDispositionGestureFilter::FilterAndSendPacket(
void TouchDispositionGestureFilter::SendGesture(const GestureEventData& event) {
// TODO(jdduke): Factor out gesture stream reparation code into a standalone
// utility class.
switch (event.type) {
switch (event.type()) {
case ET_GESTURE_LONG_TAP:
if (!needs_tap_ending_event_)
return;
......@@ -270,8 +269,13 @@ void TouchDispositionGestureFilter::SendGesture(const GestureEventData& event) {
case ET_GESTURE_TAP:
DCHECK(needs_tap_ending_event_);
if (needs_show_press_event_) {
GestureEventData show_press_event(event);
show_press_event.type = ET_GESTURE_SHOW_PRESS;
GestureEventData show_press_event(ET_GESTURE_SHOW_PRESS,
event.motion_event_id,
event.time,
event.x,
event.y,
event.details.touch_points(),
event.details.bounding_box_f());
SendGesture(show_press_event);
DCHECK(!needs_show_press_event_);
}
......
......@@ -31,7 +31,7 @@ class TouchDispositionGestureFilterTest
virtual void ForwardGestureEvent(const GestureEventData& event) OVERRIDE {
++sent_gesture_count_;
last_sent_gesture_time_ = event.time;
sent_gestures_.push_back(event.type);
sent_gestures_.push_back(event.type());
last_sent_gesture_location_ = gfx::PointF(event.x, event.y);
if (cancel_after_next_gesture_) {
CancelTouchPoint();
......
......@@ -13,6 +13,8 @@ GestureEventDetails::GestureEventDetails(ui::EventType type,
float delta_y)
: type_(type),
touch_points_(1) {
DCHECK_GE(type, ET_GESTURE_TYPE_START);
DCHECK_LE(type, ET_GESTURE_TYPE_END);
switch (type_) {
case ui::ET_GESTURE_SCROLL_BEGIN:
data.scroll_begin.x_hint = delta_x;
......
......@@ -21,7 +21,10 @@ struct EVENTS_BASE_EXPORT GestureEventDetails {
EventType type() const { return type_; }
int touch_points() const { return touch_points_; }
void set_touch_points(int touch_points) { touch_points_ = touch_points; }
void set_touch_points(int touch_points) {
DCHECK_GT(touch_points, 0);
touch_points_ = touch_points;
}
// TODO(tdresser): Return RectF. See crbug.com/337824.
const gfx::Rect bounding_box() const {
......@@ -107,6 +110,7 @@ struct EVENTS_BASE_EXPORT GestureEventDetails {
}
void set_tap_count(int tap_count) {
DCHECK_GE(tap_count, 0);
DCHECK(type_ == ET_GESTURE_TAP ||
type_ == ET_GESTURE_TAP_UNCONFIRMED ||
type_ == ET_GESTURE_DOUBLE_TAP);
......
......@@ -62,7 +62,7 @@ void GestureProviderAura::OnGestureEvent(
const GestureEventData& gesture) {
GestureEventDetails details = gesture.details;
if (gesture.type == ET_GESTURE_TAP) {
if (gesture.type() == ET_GESTURE_TAP) {
int tap_count = 1;
if (previous_tap_ && IsConsideredDoubleTap(*previous_tap_, gesture))
tap_count = 1 + (previous_tap_->details.tap_count() % 3);
......@@ -72,12 +72,12 @@ void GestureProviderAura::OnGestureEvent(
else
*previous_tap_ = gesture;
previous_tap_->details = details;
} else if (gesture.type == ET_GESTURE_TAP_CANCEL) {
} else if (gesture.type() == ET_GESTURE_TAP_CANCEL) {
previous_tap_.reset();
}
scoped_ptr<ui::GestureEvent> event(
new ui::GestureEvent(gesture.type,
new ui::GestureEvent(gesture.type(),
gesture.x,
gesture.y,
last_touch_event_flags_,
......
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