| 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 5db66be1a2ed0bb42e5eace9f5d66fa8c1c843f8..d29460a36dc3b0638fc7b8ba8e8938e377db387c 100644
|
| --- a/ui/events/gesture_detection/gesture_provider.cc
|
| +++ b/ui/events/gesture_detection/gesture_provider.cc
|
| @@ -18,6 +18,7 @@
|
| #include "ui/events/gesture_detection/motion_event_generic.h"
|
| #include "ui/events/gesture_detection/scale_gesture_listeners.h"
|
| #include "ui/gfx/geometry/point_f.h"
|
| +#include "ui/gfx/geometry/vector2d_f.h"
|
|
|
| namespace ui {
|
| namespace {
|
| @@ -118,7 +119,6 @@ class GestureProvider::GestureListenerImpl : public ScaleGestureListener,
|
| tap_down_point_ = gfx::PointF(event.GetX(), event.GetY());
|
| max_diameter_before_show_press_ = event.GetTouchMajor();
|
| }
|
| -
|
| gesture_detector_.OnTouchEvent(event);
|
| scale_gesture_detector_.OnTouchEvent(event);
|
|
|
| @@ -284,25 +284,19 @@ class GestureProvider::GestureListenerImpl : public ScaleGestureListener,
|
|
|
| bool OnScroll(const MotionEvent& e1,
|
| const MotionEvent& e2,
|
| + const MotionEvent& secondary_pointer_down,
|
| float raw_distance_x,
|
| float raw_distance_y) override {
|
| float distance_x = raw_distance_x;
|
| float distance_y = raw_distance_y;
|
| - if (!scroll_event_sent_ && e2.GetPointerCount() == 1) {
|
| - // Remove the touch slop region from the first scroll event to
|
| - // avoid a jump. Touch slop isn't used for multi-finger
|
| - // gestures, so in those cases we don't subtract the slop.
|
| - float distance =
|
| - std::sqrt(distance_x * distance_x + distance_y * distance_y);
|
| - float epsilon = 1e-3f;
|
| - if (distance > epsilon) {
|
| - float ratio =
|
| - std::max(0.f,
|
| - distance - config_.gesture_detector_config.touch_slop) /
|
| - distance;
|
| - distance_x *= ratio;
|
| - distance_y *= ratio;
|
| - }
|
| + if (!scroll_event_sent_ && e2.GetPointerCount() < 3) {
|
| + // Remove the touch slop region from the first scroll event to avoid a
|
| + // jump. Touch slop isn't used for scroll gestures with greater than 2
|
| + // pointers down, in those cases we don't subtract the slop.
|
| + gfx::Vector2dF delta =
|
| + ComputeFirstScrollDelta(e1, e2, secondary_pointer_down);
|
| + distance_x = delta.x();
|
| + distance_y = delta.y();
|
| }
|
|
|
| snap_scroll_controller_.UpdateSnapScrollMode(distance_x, distance_y);
|
| @@ -656,6 +650,55 @@ class GestureProvider::GestureListenerImpl : public ScaleGestureListener,
|
|
|
| void SetIgnoreSingleTap(bool value) { ignore_single_tap_ = value; }
|
|
|
| + gfx::Vector2dF SubtractSlopRegion(const float dx, const float dy) {
|
| + float distance = std::sqrt(dx * dx + dy * dy);
|
| + float epsilon = 1e-3f;
|
| + if (distance > epsilon) {
|
| + float ratio =
|
| + std::max(0.f, distance - config_.gesture_detector_config.touch_slop) /
|
| + distance;
|
| + gfx::Vector2dF delta(dx * ratio, dy * ratio);
|
| + return delta;
|
| + }
|
| + gfx::Vector2dF delta(dx, dy);
|
| + return delta;
|
| + }
|
| +
|
| + // When any of the currently down pointers exceeds its slop region
|
| + // for the first time, scroll delta is adjusted.
|
| + // The new deltas are calculated for each pointer individually,
|
| + // and the final scroll delta is the average over all delta values.
|
| + gfx::Vector2dF ComputeFirstScrollDelta(
|
| + const MotionEvent& ev1,
|
| + const MotionEvent& ev2,
|
| + const MotionEvent& secondary_pointer_down) {
|
| + // If there are more than two down pointers, tapping is not possible,
|
| + // so Slop region is not deducted.
|
| + DCHECK(ev2.GetPointerCount() < 3);
|
| +
|
| + const int id0 = ev1.GetPointerId(0);
|
| + const int ev_idx0 = ev2.GetPointerId(0) == id0 ? 0 : 1;
|
| +
|
| + // Subtract the slop region from the first pointer move.
|
| + float dx0 = ev1.GetX() - ev2.GetX(ev_idx0);
|
| + float dy0 = ev1.GetY() - ev2.GetY(ev_idx0);
|
| + gfx::Vector2dF first_pointer_delta = SubtractSlopRegion(dx0, dy0);
|
| +
|
| + gfx::Vector2dF second_pointer_delta(0, 0);
|
| + // Subtract the slop region from the second pointer move.
|
| + if (ev2.GetPointerCount() == 2) {
|
| + const int ev_idx1 = ev_idx0 == 0 ? 1 : 0;
|
| + const int idx1 = secondary_pointer_down.GetActionIndex();
|
| + float dx1 = secondary_pointer_down.GetX(idx1) - ev2.GetX(ev_idx1);
|
| + float dy1 = secondary_pointer_down.GetY(idx1) - ev2.GetY(ev_idx1);
|
| + second_pointer_delta = SubtractSlopRegion(dx1, dy1);
|
| + }
|
| +
|
| + gfx::Vector2dF delta = first_pointer_delta + second_pointer_delta;
|
| + delta.Scale(1.0 / ev2.GetPointerCount());
|
| + return delta;
|
| + }
|
| +
|
| const GestureProvider::Config config_;
|
| GestureProviderClient* const client_;
|
|
|
|
|