Index: content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc |
diff --git a/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc b/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc |
index b2fb4bb7eb3bf82487025edf9b3e0b3e3d6bfda1..77304dc3191d2798ebd96368c3658b6f97cb51d6 100644 |
--- a/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc |
+++ b/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.cc |
@@ -35,7 +35,7 @@ SyntheticSmoothScrollGesture::SyntheticSmoothScrollGesture( |
SyntheticSmoothScrollGesture::~SyntheticSmoothScrollGesture() {} |
SyntheticGesture::Result SyntheticSmoothScrollGesture::ForwardInputEvents( |
- const base::TimeDelta& interval, SyntheticGestureTarget* target) { |
+ const base::TimeTicks& timestamp, SyntheticGestureTarget* target) { |
if (state_ == SETUP) { |
gesture_source_type_ = params_.gesture_source_type; |
if (gesture_source_type_ == SyntheticGestureParams::DEFAULT_INPUT) |
@@ -45,13 +45,14 @@ SyntheticGesture::Result SyntheticSmoothScrollGesture::ForwardInputEvents( |
return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_SUPPORTED_BY_PLATFORM; |
state_ = STARTED; |
+ start_time_ = timestamp; |
} |
DCHECK_NE(gesture_source_type_, SyntheticGestureParams::DEFAULT_INPUT); |
if (gesture_source_type_ == SyntheticGestureParams::TOUCH_INPUT) |
- ForwardTouchInputEvents(interval, target); |
+ ForwardTouchInputEvents(timestamp, target); |
else if (gesture_source_type_ == SyntheticGestureParams::MOUSE_INPUT) |
- ForwardMouseInputEvents(interval, target); |
+ ForwardMouseInputEvents(timestamp, target); |
else |
return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_IMPLEMENTED; |
@@ -60,7 +61,8 @@ SyntheticGesture::Result SyntheticSmoothScrollGesture::ForwardInputEvents( |
} |
void SyntheticSmoothScrollGesture::ForwardTouchInputEvents( |
- const base::TimeDelta& interval, SyntheticGestureTarget* target) { |
+ const base::TimeTicks& timestamp, SyntheticGestureTarget* target) { |
+ base::TimeTicks event_timestamp = timestamp; |
switch (state_) { |
case STARTED: |
// Check for an early finish. |
@@ -69,29 +71,33 @@ void SyntheticSmoothScrollGesture::ForwardTouchInputEvents( |
break; |
} |
AddTouchSlopToDistance(target); |
- PressTouchPoint(target); |
+ PressTouchPoint(target, event_timestamp); |
state_ = MOVING; |
break; |
- case MOVING: |
- total_delta_ += GetPositionDelta(interval); |
- MoveTouchPoint(target); |
+ case MOVING: { |
+ gfx::Vector2dF delta = |
+ GetPositionDeltaAndUpdateTimestamp(&event_timestamp); |
+ MoveTouchPoint(target, delta, event_timestamp); |
- if (HasScrolledEntireDistance()) { |
+ if (HasScrolledEntireDistance(delta)) { |
if (params_.prevent_fling) { |
+ stopping_start_time_ = event_timestamp; |
state_ = STOPPING; |
} else { |
- ReleaseTouchPoint(target); |
+ ReleaseTouchPoint(target, event_timestamp); |
state_ = DONE; |
} |
} |
- break; |
+ } break; |
case STOPPING: |
- total_stopping_wait_time_ += interval; |
- if (total_stopping_wait_time_ >= target->PointerAssumedStoppedTime()) { |
+ if (timestamp - stopping_start_time_ >= |
+ target->PointerAssumedStoppedTime()) { |
+ event_timestamp = |
+ stopping_start_time_ + target->PointerAssumedStoppedTime(); |
// Send one last move event, but don't change the location. Without this |
// we'd still sometimes cause a fling on Android. |
- MoveTouchPoint(target); |
- ReleaseTouchPoint(target); |
+ ForwardTouchEvent(target, event_timestamp); |
+ ReleaseTouchPoint(target, event_timestamp); |
state_ = DONE; |
} |
break; |
@@ -105,7 +111,7 @@ void SyntheticSmoothScrollGesture::ForwardTouchInputEvents( |
} |
void SyntheticSmoothScrollGesture::ForwardMouseInputEvents( |
- const base::TimeDelta& interval, SyntheticGestureTarget* target) { |
+ const base::TimeTicks& timestamp, SyntheticGestureTarget* target) { |
switch (state_) { |
case STARTED: |
// Check for an early finish. |
@@ -115,22 +121,23 @@ void SyntheticSmoothScrollGesture::ForwardMouseInputEvents( |
} |
state_ = MOVING; |
// Fall through to forward the first event. |
- case MOVING: |
- { |
- // Even though WebMouseWheelEvents take floating point deltas, |
- // internally the scroll position is stored as an integer. We therefore |
- // keep track of the discrete delta which is consistent with the |
- // internal scrolling state. This ensures that when the gesture has |
- // finished we've scrolled exactly the specified distance. |
- total_delta_ += GetPositionDelta(interval); |
- gfx::Vector2d delta_discrete = |
- FloorTowardZero(total_delta_ - total_delta_discrete_); |
- ForwardMouseWheelEvent(target, delta_discrete); |
- total_delta_discrete_ += delta_discrete; |
- } |
- if (HasScrolledEntireDistance()) |
+ case MOVING: { |
+ // Even though WebMouseWheelEvents take floating point deltas, |
+ // internally the scroll position is stored as an integer. We therefore |
+ // keep track of the discrete delta which is consistent with the |
+ // internal scrolling state. This ensures that when the gesture has |
+ // finished we've scrolled exactly the specified distance. |
+ base::TimeTicks event_timestamp = timestamp; |
+ gfx::Vector2dF total_delta = |
+ GetPositionDeltaAndUpdateTimestamp(&event_timestamp); |
+ gfx::Vector2d delta_discrete = |
+ FloorTowardZero(total_delta - total_delta_discrete_); |
+ ForwardMouseWheelEvent(target, delta_discrete, event_timestamp); |
+ total_delta_discrete_ += delta_discrete; |
+ |
+ if (HasScrolledEntireDistance(total_delta)) |
state_ = DONE; |
- break; |
+ } break; |
case SETUP: |
NOTREACHED() |
<< "State STARTED invalid for synthetic scroll using touch input."; |
@@ -140,44 +147,52 @@ void SyntheticSmoothScrollGesture::ForwardMouseInputEvents( |
case DONE: |
NOTREACHED() |
<< "State DONE invalid for synthetic scroll using touch input."; |
- } |
+ } |
} |
void SyntheticSmoothScrollGesture::ForwardTouchEvent( |
- SyntheticGestureTarget* target) const { |
+ SyntheticGestureTarget* target, const base::TimeTicks& timestamp) { |
+ touch_event_.timeStampSeconds = ConvertTimestampToSeconds(timestamp); |
+ |
target->DispatchInputEventToPlatform( |
InputEvent(touch_event_, ui::LatencyInfo(), false)); |
} |
void SyntheticSmoothScrollGesture::ForwardMouseWheelEvent( |
- SyntheticGestureTarget* target, const gfx::Vector2dF& delta) const { |
+ SyntheticGestureTarget* target, |
+ const gfx::Vector2dF& delta, |
+ const base::TimeTicks& timestamp) const { |
blink::WebMouseWheelEvent mouse_wheel_event = |
SyntheticWebMouseWheelEventBuilder::Build(delta.x(), delta.y(), 0, false); |
mouse_wheel_event.x = params_.anchor.x(); |
mouse_wheel_event.y = params_.anchor.y(); |
+ mouse_wheel_event.timeStampSeconds = ConvertTimestampToSeconds(timestamp); |
+ |
target->DispatchInputEventToPlatform( |
InputEvent(mouse_wheel_event, ui::LatencyInfo(), false)); |
} |
void SyntheticSmoothScrollGesture::PressTouchPoint( |
- SyntheticGestureTarget* target) { |
+ SyntheticGestureTarget* target, const base::TimeTicks& timestamp) { |
touch_event_.PressPoint(params_.anchor.x(), params_.anchor.y()); |
- ForwardTouchEvent(target); |
+ ForwardTouchEvent(target, timestamp); |
} |
void SyntheticSmoothScrollGesture::MoveTouchPoint( |
- SyntheticGestureTarget* target) { |
- gfx::PointF touch_position = params_.anchor + total_delta_; |
+ SyntheticGestureTarget* target, |
+ const gfx::Vector2dF& delta, |
+ const base::TimeTicks& timestamp) { |
+ gfx::PointF touch_position = params_.anchor + delta; |
touch_event_.MovePoint(0, touch_position.x(), touch_position.y()); |
- ForwardTouchEvent(target); |
+ ForwardTouchEvent(target, timestamp); |
} |
void SyntheticSmoothScrollGesture::ReleaseTouchPoint( |
- SyntheticGestureTarget* target) { |
+ SyntheticGestureTarget* target, const base::TimeTicks& timestamp) { |
touch_event_.ReleasePoint(0); |
- ForwardTouchEvent(target); |
+ ForwardTouchEvent(target, timestamp); |
} |
void SyntheticSmoothScrollGesture::AddTouchSlopToDistance( |
@@ -187,23 +202,30 @@ void SyntheticSmoothScrollGesture::AddTouchSlopToDistance( |
// distance and round up to the nearest integer. |
// For vertical and horizontal scrolls (the common case), both methods produce |
// the same result. |
- gfx::Vector2dF touch_slop_delta = ProjectLengthOntoScrollDirection( |
- target->GetTouchSlopInDips()); |
+ gfx::Vector2dF touch_slop_delta = |
+ ProjectLengthOntoScrollDirection(target->GetTouchSlopInDips()); |
params_.distance += CeilFromZero(touch_slop_delta); |
} |
-gfx::Vector2dF SyntheticSmoothScrollGesture::GetPositionDelta( |
- const base::TimeDelta& interval) const { |
- float delta_length = params_.speed_in_pixels_s * interval.InSecondsF(); |
+gfx::Vector2dF SyntheticSmoothScrollGesture::GetPositionDeltaAndUpdateTimestamp( |
+ base::TimeTicks* timestamp) const { |
jdduke (slow)
2014/01/03 18:24:30
DCHECK(timestamp);
Dominik Grewe
2014/01/06 11:46:07
Done.
|
+ float delta_length = |
+ params_.speed_in_pixels_s * (*timestamp - start_time_).InSecondsF(); |
// Make sure we're not scrolling too far. |
- gfx::Vector2dF remaining_delta = ComputeRemainingDelta(); |
- if (delta_length > remaining_delta.Length()) |
+ if (delta_length > params_.distance.Length()) { |
+ // Update the timestamp to match the end of the scroll. |
+ int total_duration_in_ms = |
+ (1000 * params_.distance.Length()) / params_.speed_in_pixels_s; |
jdduke (slow)
2014/01/03 18:24:30
Same as above, multiplying the time scale by the d
Dominik Grewe
2014/01/06 11:46:07
Done.
|
+ *timestamp = |
+ start_time_ + base::TimeDelta::FromMilliseconds(total_duration_in_ms); |
+ |
// In order to scroll in a certain direction we need to move the |
// touch pointer/mouse wheel in the opposite direction. |
- return -remaining_delta; |
- else |
+ return -params_.distance; |
+ } else { |
return -ProjectLengthOntoScrollDirection(delta_length); |
+ } |
} |
gfx::Vector2dF SyntheticSmoothScrollGesture::ProjectLengthOntoScrollDirection( |
@@ -212,12 +234,9 @@ gfx::Vector2dF SyntheticSmoothScrollGesture::ProjectLengthOntoScrollDirection( |
return ScaleVector2d(params_.distance, delta_length / kTotalLength); |
} |
-gfx::Vector2dF SyntheticSmoothScrollGesture::ComputeRemainingDelta() const { |
- return params_.distance + total_delta_; |
-} |
- |
-bool SyntheticSmoothScrollGesture::HasScrolledEntireDistance() const { |
- return ComputeRemainingDelta().IsZero(); |
+bool SyntheticSmoothScrollGesture::HasScrolledEntireDistance( |
+ const gfx::Vector2dF& delta) const { |
+ return delta == -params_.distance; |
} |
} // namespace content |