| Index: ui/touch_selection/longpress_drag_selector.cc
|
| diff --git a/ui/touch_selection/longpress_drag_selector.cc b/ui/touch_selection/longpress_drag_selector.cc
|
| index ad68171a61910f198ed457e0003466b8895cf967..b84c90da9e137cc9f5c068ae75941aa8aaededa6 100644
|
| --- a/ui/touch_selection/longpress_drag_selector.cc
|
| +++ b/ui/touch_selection/longpress_drag_selector.cc
|
| @@ -8,6 +8,13 @@
|
| #include "ui/events/gesture_detection/motion_event.h"
|
|
|
| namespace ui {
|
| +namespace {
|
| +
|
| +gfx::Vector2dF SafeNormalize(const gfx::Vector2dF& v) {
|
| + return v.IsZero() ? v : ScaleVector2d(v, 1.f / v.Length());
|
| +}
|
| +
|
| +} // namespace
|
|
|
| LongPressDragSelector::LongPressDragSelector(
|
| LongPressDragSelectorClient* client)
|
| @@ -70,21 +77,27 @@ bool LongPressDragSelector::WillHandleTouchEvent(const MotionEvent& event) {
|
| // If initial motion is up/down, extend the start/end selection bound.
|
| extend_selection_start = delta.y() < 0;
|
| } else {
|
| - // Otherwise extend the selection bound toward which we're moving.
|
| + // Otherwise extend the selection bound toward which we're moving, or
|
| + // the closest bound if motion is already away from both bounds.
|
| // Note that, for mixed RTL text, or for multiline selections triggered
|
| // by longpress, this may not pick the most suitable drag target
|
| - gfx::Vector2dF start_delta = selection_start - position;
|
| + gfx::Vector2dF start_delta = selection_start - longpress_drag_start_anchor_;
|
| + gfx::Vector2dF end_delta = selection_end - longpress_drag_start_anchor_;
|
|
|
| // The vectors must be normalized to make dot product comparison meaningful.
|
| - if (!start_delta.IsZero())
|
| - start_delta.Scale(1.f / start_delta.Length());
|
| - gfx::Vector2dF end_delta = selection_end - position;
|
| - if (!end_delta.IsZero())
|
| - end_delta.Scale(1.f / start_delta.Length());
|
| -
|
| - // The larger the dot product the more similar the direction.
|
| - extend_selection_start =
|
| - gfx::DotProduct(start_delta, delta) > gfx::DotProduct(end_delta, delta);
|
| + gfx::Vector2dF normalized_start_delta = SafeNormalize(start_delta);
|
| + gfx::Vector2dF normalized_end_delta = SafeNormalize(end_delta);
|
| + double start_dot_product = gfx::DotProduct(normalized_start_delta, delta);
|
| + double end_dot_product = gfx::DotProduct(normalized_end_delta, delta);
|
| +
|
| + if (start_dot_product >= 0 || end_dot_product >= 0) {
|
| + // The greater the dot product the more similar the direction.
|
| + extend_selection_start = start_dot_product > end_dot_product;
|
| + } else {
|
| + // If we're already moving away from both endpoints, pick the closest.
|
| + extend_selection_start =
|
| + start_delta.LengthSquared() < end_delta.LengthSquared();
|
| + }
|
| }
|
|
|
| gfx::PointF extent = extend_selection_start ? selection_start : selection_end;
|
|
|