| Index: ui/events/gesture_detection/gesture_provider.cc
|
| diff --git a/ui/events/gesture_detection/gesture_provider.cc b/ui/events/gesture_detection/gesture_provider.cc
|
| index 23d092a2082d5770ab82e24433c75aa78b487afb..5cbe56fac43f21dc8c6ac9b3131ebe668447d874 100644
|
| --- a/ui/events/gesture_detection/gesture_provider.cc
|
| +++ b/ui/events/gesture_detection/gesture_provider.cc
|
| @@ -11,6 +11,7 @@
|
| #include "ui/events/event_constants.h"
|
| #include "ui/events/gesture_detection/gesture_event_data.h"
|
| #include "ui/events/gesture_detection/motion_event.h"
|
| +#include "ui/gfx/geometry/point_f.h"
|
|
|
| namespace ui {
|
| namespace {
|
| @@ -36,93 +37,6 @@ const char* GetMotionEventActionName(MotionEvent::Action action) {
|
| return "";
|
| }
|
|
|
| -gfx::RectF GetBoundingBox(const MotionEvent& event) {
|
| - // Can't use gfx::RectF::Union, as it ignores touches with a radius of 0.
|
| - float left = std::numeric_limits<float>::max();
|
| - float top = std::numeric_limits<float>::max();
|
| - float right = -std::numeric_limits<float>::max();
|
| - float bottom = -std::numeric_limits<float>::max();
|
| - for (size_t i = 0; i < event.GetPointerCount(); ++i) {
|
| - float diameter = event.GetTouchMajor(i);
|
| - float x = event.GetX(i) - diameter / 2;
|
| - float y = event.GetY(i) - diameter / 2;
|
| - left = std::min(left, x);
|
| - right = std::max(right, x + diameter);
|
| - top = std::min(top, y);
|
| - bottom = std::max(bottom, y + diameter);
|
| - }
|
| - return gfx::RectF(left, top, right - left, bottom - top);
|
| -}
|
| -
|
| -GestureEventData CreateGesture(const GestureEventDetails& details,
|
| - int motion_event_id,
|
| - MotionEvent::ToolType primary_tool_type,
|
| - base::TimeTicks time,
|
| - float x,
|
| - float y,
|
| - float raw_x,
|
| - float raw_y,
|
| - size_t touch_point_count,
|
| - const gfx::RectF& bounding_box) {
|
| - return GestureEventData(details,
|
| - motion_event_id,
|
| - primary_tool_type,
|
| - time,
|
| - x,
|
| - y,
|
| - raw_x,
|
| - raw_y,
|
| - touch_point_count,
|
| - bounding_box);
|
| -}
|
| -
|
| -GestureEventData CreateGesture(EventType type,
|
| - int motion_event_id,
|
| - MotionEvent::ToolType primary_tool_type,
|
| - base::TimeTicks time,
|
| - float x,
|
| - float y,
|
| - float raw_x,
|
| - float raw_y,
|
| - size_t touch_point_count,
|
| - const gfx::RectF& bounding_box) {
|
| - return GestureEventData(GestureEventDetails(type, 0, 0),
|
| - motion_event_id,
|
| - primary_tool_type,
|
| - time,
|
| - x,
|
| - y,
|
| - raw_x,
|
| - raw_y,
|
| - touch_point_count,
|
| - bounding_box);
|
| -}
|
| -
|
| -GestureEventData CreateGesture(const GestureEventDetails& details,
|
| - const MotionEvent& event) {
|
| - return GestureEventData(details,
|
| - event.GetId(),
|
| - event.GetToolType(),
|
| - event.GetEventTime(),
|
| - event.GetX(),
|
| - event.GetY(),
|
| - event.GetRawX(),
|
| - event.GetRawY(),
|
| - event.GetPointerCount(),
|
| - GetBoundingBox(event));
|
| -}
|
| -
|
| -GestureEventData CreateGesture(EventType type, const MotionEvent& event) {
|
| - return CreateGesture(GestureEventDetails(type, 0, 0), event);
|
| -}
|
| -
|
| -GestureEventData CreateTapGesture(EventType type, const MotionEvent& event) {
|
| - // Set the tap count to 1 even for ET_GESTURE_DOUBLE_TAP, in order to be
|
| - // consistent with double tap behavior on a mobile viewport. See
|
| - // crbug.com/234986 for context.
|
| - return CreateGesture(GestureEventDetails(type, 1, 0), event);
|
| -}
|
| -
|
| gfx::RectF ClampBoundingBox(const gfx::RectF& bounds,
|
| float min_length,
|
| float max_length) {
|
| @@ -173,7 +87,9 @@ class GestureProvider::GestureListenerImpl
|
| ignore_multitouch_zoom_events_(false),
|
| ignore_single_tap_(false),
|
| pinch_event_sent_(false),
|
| - scroll_event_sent_(false) {}
|
| + scroll_event_sent_(false),
|
| + max_diameter_before_show_press_(0),
|
| + show_press_event_sent_(false) {}
|
|
|
| void OnTouchEvent(const MotionEvent& event) {
|
| const bool in_scale_gesture = IsScaleGestureDetectionInProgress();
|
| @@ -188,7 +104,10 @@ class GestureProvider::GestureListenerImpl
|
| ignore_single_tap_ = false;
|
| scroll_event_sent_ = false;
|
| pinch_event_sent_ = false;
|
| + show_press_event_sent_ = false;
|
| gesture_detector_.set_longpress_enabled(true);
|
| + tap_down_point_ = gfx::PointF(event.GetX(), event.GetY());
|
| + max_diameter_before_show_press_ = event.GetTouchMajor();
|
| }
|
|
|
| gesture_detector_.OnTouchEvent(event);
|
| @@ -201,6 +120,11 @@ class GestureProvider::GestureListenerImpl
|
| if (scroll_event_sent_)
|
| Send(CreateGesture(ET_GESTURE_SCROLL_END, event));
|
| current_down_time_ = base::TimeTicks();
|
| + } else if (action == MotionEvent::ACTION_MOVE) {
|
| + if (!show_press_event_sent_ && !scroll_event_sent_) {
|
| + max_diameter_before_show_press_ =
|
| + std::max(max_diameter_before_show_press_, event.GetTouchMajor());
|
| + }
|
| }
|
| }
|
|
|
| @@ -297,7 +221,7 @@ class GestureProvider::GestureListenerImpl
|
| detector.GetFocusX() + e.GetRawOffsetX(),
|
| detector.GetFocusY() + e.GetRawOffsetY(),
|
| e.GetPointerCount(),
|
| - GetBoundingBox(e)));
|
| + GetBoundingBox(e, ET_GESTURE_PINCH_BEGIN)));
|
| }
|
|
|
| if (std::abs(detector.GetCurrentSpan() - detector.GetPreviousSpan()) <
|
| @@ -331,7 +255,7 @@ class GestureProvider::GestureListenerImpl
|
| detector.GetFocusX() + e.GetRawOffsetX(),
|
| detector.GetFocusY() + e.GetRawOffsetY(),
|
| e.GetPointerCount(),
|
| - GetBoundingBox(e)));
|
| + GetBoundingBox(e, pinch_details.type())));
|
| return true;
|
| }
|
|
|
| @@ -381,7 +305,7 @@ class GestureProvider::GestureListenerImpl
|
| e1.GetRawX(),
|
| e1.GetRawY(),
|
| e2.GetPointerCount(),
|
| - GetBoundingBox(e2)));
|
| + GetBoundingBox(e2, scroll_details.type())));
|
| DCHECK(scroll_event_sent_);
|
| }
|
|
|
| @@ -394,12 +318,12 @@ class GestureProvider::GestureListenerImpl
|
| }
|
|
|
| if (distance_x || distance_y) {
|
| - const gfx::RectF bounding_box = GetBoundingBox(e2);
|
| + GestureEventDetails scroll_details(
|
| + ET_GESTURE_SCROLL_UPDATE, -distance_x, -distance_y);
|
| + const gfx::RectF bounding_box = GetBoundingBox(e2, scroll_details.type());
|
| const gfx::PointF center = bounding_box.CenterPoint();
|
| const gfx::PointF raw_center =
|
| center + gfx::Vector2dF(e2.GetRawOffsetX(), e2.GetRawOffsetY());
|
| - GestureEventDetails scroll_details(
|
| - ET_GESTURE_SCROLL_UPDATE, -distance_x, -distance_y);
|
| Send(CreateGesture(scroll_details,
|
| e2.GetId(),
|
| e2.GetToolType(),
|
| @@ -469,12 +393,13 @@ class GestureProvider::GestureListenerImpl
|
| e1.GetRawX(),
|
| e1.GetRawY(),
|
| e2.GetPointerCount(),
|
| - GetBoundingBox(e2)));
|
| + GetBoundingBox(e2, two_finger_tap_details.type())));
|
| return true;
|
| }
|
|
|
| virtual void OnShowPress(const MotionEvent& e) OVERRIDE {
|
| GestureEventDetails show_press_details(ET_GESTURE_SHOW_PRESS, 0, 0);
|
| + show_press_event_sent_ = true;
|
| Send(CreateGesture(show_press_details, e));
|
| }
|
|
|
| @@ -556,6 +481,107 @@ class GestureProvider::GestureListenerImpl
|
| Send(CreateGesture(long_press_details, e));
|
| }
|
|
|
| + GestureEventData CreateGesture(const GestureEventDetails& details,
|
| + int motion_event_id,
|
| + MotionEvent::ToolType primary_tool_type,
|
| + base::TimeTicks time,
|
| + float x,
|
| + float y,
|
| + float raw_x,
|
| + float raw_y,
|
| + size_t touch_point_count,
|
| + const gfx::RectF& bounding_box) {
|
| + return GestureEventData(details,
|
| + motion_event_id,
|
| + primary_tool_type,
|
| + time,
|
| + x,
|
| + y,
|
| + raw_x,
|
| + raw_y,
|
| + touch_point_count,
|
| + bounding_box);
|
| + }
|
| +
|
| + GestureEventData CreateGesture(EventType type,
|
| + int motion_event_id,
|
| + MotionEvent::ToolType primary_tool_type,
|
| + base::TimeTicks time,
|
| + float x,
|
| + float y,
|
| + float raw_x,
|
| + float raw_y,
|
| + size_t touch_point_count,
|
| + const gfx::RectF& bounding_box) {
|
| + return GestureEventData(GestureEventDetails(type, 0, 0),
|
| + motion_event_id,
|
| + primary_tool_type,
|
| + time,
|
| + x,
|
| + y,
|
| + raw_x,
|
| + raw_y,
|
| + touch_point_count,
|
| + bounding_box);
|
| + }
|
| +
|
| + GestureEventData CreateGesture(const GestureEventDetails& details,
|
| + const MotionEvent& event) {
|
| + return GestureEventData(details,
|
| + event.GetId(),
|
| + event.GetToolType(),
|
| + event.GetEventTime(),
|
| + event.GetX(),
|
| + event.GetY(),
|
| + event.GetRawX(),
|
| + event.GetRawY(),
|
| + event.GetPointerCount(),
|
| + GetBoundingBox(event, details.type()));
|
| + }
|
| +
|
| + GestureEventData CreateGesture(EventType type, const MotionEvent& event) {
|
| + return CreateGesture(GestureEventDetails(type, 0, 0), event);
|
| + }
|
| +
|
| + GestureEventData CreateTapGesture(EventType type, const MotionEvent& event) {
|
| + // Set the tap count to 1 even for ET_GESTURE_DOUBLE_TAP, in order to be
|
| + // consistent with double tap behavior on a mobile viewport. See
|
| + // crbug.com/234986 for context.
|
| + return CreateGesture(GestureEventDetails(type, 1, 0), event);
|
| + }
|
| +
|
| + gfx::RectF GetBoundingBox(const MotionEvent& event, EventType type) {
|
| + // Can't use gfx::RectF::Union, as it ignores touches with a radius of 0.
|
| + float left = std::numeric_limits<float>::max();
|
| + float top = std::numeric_limits<float>::max();
|
| + float right = -std::numeric_limits<float>::max();
|
| + float bottom = -std::numeric_limits<float>::max();
|
| + for (size_t i = 0; i < event.GetPointerCount(); ++i) {
|
| + float x, y, diameter;
|
| + // Only for the show press and tap events, the bounding box is calculated
|
| + // based on the touch start point and the maximum diameter before the
|
| + // show press event is sent.
|
| + if (type == ET_GESTURE_SHOW_PRESS || type == ET_GESTURE_TAP ||
|
| + type == ET_GESTURE_TAP_UNCONFIRMED) {
|
| + DCHECK_EQ(0U, i);
|
| + diameter = max_diameter_before_show_press_;
|
| + x = tap_down_point_.x();
|
| + y = tap_down_point_.y();
|
| + } else {
|
| + diameter = event.GetTouchMajor(i);
|
| + x = event.GetX(i);
|
| + y = event.GetY(i);
|
| + }
|
| + x = x - diameter / 2;
|
| + y = y - diameter / 2;
|
| + left = std::min(left, x);
|
| + right = std::max(right, x + diameter);
|
| + top = std::min(top, y);
|
| + bottom = std::max(bottom, y + diameter);
|
| + }
|
| + return gfx::RectF(left, top, right - left, bottom - top);
|
| + }
|
| +
|
| void SetDoubleTapEnabled(bool enabled) {
|
| DCHECK(!IsDoubleTapInProgress());
|
| gesture_detector_.SetDoubleTapListener(enabled ? this : NULL);
|
| @@ -621,6 +647,16 @@ class GestureProvider::GestureListenerImpl
|
| bool pinch_event_sent_;
|
| bool scroll_event_sent_;
|
|
|
| + // Only track the maximum diameter before the show press event has been
|
| + // sent and a tap must still be possible for this touch sequence.
|
| + float max_diameter_before_show_press_;
|
| +
|
| + gfx::PointF tap_down_point_;
|
| +
|
| + // Tracks whether an ET_GESTURE_SHOW_PRESS event has been sent for this touch
|
| + // sequence.
|
| + bool show_press_event_sent_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(GestureListenerImpl);
|
| };
|
|
|
| @@ -704,21 +740,23 @@ void GestureProvider::OnTouchEventHandlingBegin(const MotionEvent& event) {
|
| case MotionEvent::ACTION_DOWN:
|
| current_down_event_ = event.Clone();
|
| if (gesture_begin_end_types_enabled_)
|
| - gesture_listener_->Send(CreateGesture(ET_GESTURE_BEGIN, event));
|
| + gesture_listener_->Send(
|
| + gesture_listener_->CreateGesture(ET_GESTURE_BEGIN, event));
|
| break;
|
| case MotionEvent::ACTION_POINTER_DOWN:
|
| if (gesture_begin_end_types_enabled_) {
|
| const int action_index = event.GetActionIndex();
|
| - gesture_listener_->Send(CreateGesture(ET_GESTURE_BEGIN,
|
| - event.GetId(),
|
| - event.GetToolType(),
|
| - event.GetEventTime(),
|
| - event.GetX(action_index),
|
| - event.GetY(action_index),
|
| - event.GetRawX(action_index),
|
| - event.GetRawY(action_index),
|
| - event.GetPointerCount(),
|
| - GetBoundingBox(event)));
|
| + gesture_listener_->Send(gesture_listener_->CreateGesture(
|
| + ET_GESTURE_BEGIN,
|
| + event.GetId(),
|
| + event.GetToolType(),
|
| + event.GetEventTime(),
|
| + event.GetX(action_index),
|
| + event.GetY(action_index),
|
| + event.GetRawX(action_index),
|
| + event.GetRawY(action_index),
|
| + event.GetPointerCount(),
|
| + gesture_listener_->GetBoundingBox(event, ET_GESTURE_BEGIN)));
|
| }
|
| break;
|
| case MotionEvent::ACTION_POINTER_UP:
|
| @@ -734,7 +772,8 @@ void GestureProvider::OnTouchEventHandlingEnd(const MotionEvent& event) {
|
| case MotionEvent::ACTION_UP:
|
| case MotionEvent::ACTION_CANCEL: {
|
| if (gesture_begin_end_types_enabled_)
|
| - gesture_listener_->Send(CreateGesture(ET_GESTURE_END, event));
|
| + gesture_listener_->Send(
|
| + gesture_listener_->CreateGesture(ET_GESTURE_END, event));
|
|
|
| current_down_event_.reset();
|
|
|
| @@ -743,7 +782,8 @@ void GestureProvider::OnTouchEventHandlingEnd(const MotionEvent& event) {
|
| }
|
| case MotionEvent::ACTION_POINTER_UP:
|
| if (gesture_begin_end_types_enabled_)
|
| - gesture_listener_->Send(CreateGesture(ET_GESTURE_END, event));
|
| + gesture_listener_->Send(
|
| + gesture_listener_->CreateGesture(ET_GESTURE_END, event));
|
| break;
|
| case MotionEvent::ACTION_DOWN:
|
| case MotionEvent::ACTION_POINTER_DOWN:
|
|
|