Chromium Code Reviews| 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..ea0a0d8d2495a76cd28382e269e861922cad235e 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,58 @@ class GestureProvider::GestureListenerImpl : public ScaleGestureListener, |
| void SetIgnoreSingleTap(bool value) { ignore_single_tap_ = value; } |
| + // 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); |
| + float distance0 = std::sqrt(dx0 * dx0 + dy0 * dy0); |
| + float epsilon = 1e-3f; |
| + if (distance0 > epsilon) { |
| + float ratio = |
| + std::max(0.f, |
| + distance0 - config_.gesture_detector_config.touch_slop) / |
| + distance0; |
| + dx0 *= ratio; |
| + dy0 *= ratio; |
| + } |
| + float dx1 = 0; |
| + float dy1 = 0; |
| + // Subtract the slop region from the second pointer move. |
| + if (ev2.GetPointerCount() == 2) { |
|
tdresser
2016/07/01 14:29:15
Could we factor out the slop subtraction here?
Li
sahel
2016/07/05 20:36:35
Done.
|
| + const int ev_idx1 = ev_idx0 == 0 ? 1 : 0; |
| + const int idx1 = secondary_pointer_down.GetActionIndex(); |
| + dx1 = secondary_pointer_down.GetX(idx1) - ev2.GetX(ev_idx1); |
| + dy1 = secondary_pointer_down.GetY(idx1) - ev2.GetY(ev_idx1); |
| + float distance1 = std::sqrt(dx1 * dx1 + dy1 * dy1); |
| + if (distance1 > epsilon) { |
| + float ratio = |
| + std::max(0.f, |
| + distance1 - config_.gesture_detector_config.touch_slop) / |
| + distance1; |
| + dx1 *= ratio; |
| + dy1 *= ratio; |
| + } |
| + } |
| + float delta_x = (dx0 + dx1) / ev2.GetPointerCount(); |
| + float delta_y = (dy0 + dy1) / ev2.GetPointerCount(); |
| + gfx::Vector2dF delta(delta_x, delta_y); |
| + return delta; |
| + } |
| + |
| const GestureProvider::Config config_; |
| GestureProviderClient* const client_; |