| Index: content/browser/renderer_host/input/mouse_wheel_event_queue.cc
|
| diff --git a/content/browser/renderer_host/input/mouse_wheel_event_queue.cc b/content/browser/renderer_host/input/mouse_wheel_event_queue.cc
|
| index 48dbad231bb553d57a13efc79263eecab3a69f64..5e56e9b821ec1e90d46749752c8dac920b5efe7f 100644
|
| --- a/content/browser/renderer_host/input/mouse_wheel_event_queue.cc
|
| +++ b/content/browser/renderer_host/input/mouse_wheel_event_queue.cc
|
| @@ -37,6 +37,7 @@ MouseWheelEventQueue::MouseWheelEventQueue(MouseWheelEventQueueClient* client,
|
| int64_t scroll_transaction_ms)
|
| : client_(client),
|
| needs_scroll_begin_(true),
|
| + needs_scroll_end_(false),
|
| send_gestures_(send_gestures),
|
| scroll_transaction_ms_(scroll_transaction_ms),
|
| scrolling_device_(blink::WebGestureDeviceUninitialized) {
|
| @@ -85,6 +86,9 @@ void MouseWheelEventQueue::ProcessMouseWheelAck(
|
| (scrolling_device_ == blink::WebGestureDeviceUninitialized ||
|
| scrolling_device_ == blink::WebGestureDeviceTouchpad)) {
|
| GestureEventWithLatencyInfo scroll_update;
|
| + scroll_update.event.timeStampSeconds =
|
| + event_sent_for_gesture_ack_->event.timeStampSeconds;
|
| +
|
| scroll_update.event.x = event_sent_for_gesture_ack_->event.x;
|
| scroll_update.event.y = event_sent_for_gesture_ack_->event.y;
|
| scroll_update.event.globalX = event_sent_for_gesture_ack_->event.globalX;
|
| @@ -96,6 +100,11 @@ void MouseWheelEventQueue::ProcessMouseWheelAck(
|
| event_sent_for_gesture_ack_->event.deltaX;
|
| scroll_update.event.data.scrollUpdate.deltaY =
|
| event_sent_for_gesture_ack_->event.deltaY;
|
| + // Only OSX populates the momentumPhase; so expect this to
|
| + // always be PhaseNone on all other platforms.
|
| + scroll_update.event.data.scrollUpdate.inertial =
|
| + event_sent_for_gesture_ack_->event.momentumPhase !=
|
| + blink::WebMouseWheelEvent::PhaseNone;
|
| if (event_sent_for_gesture_ack_->event.scrollByPage) {
|
| scroll_update.event.data.scrollUpdate.deltaUnits =
|
| blink::WebGestureEvent::Page;
|
| @@ -114,7 +123,67 @@ void MouseWheelEventQueue::ProcessMouseWheelAck(
|
| ? blink::WebGestureEvent::PrecisePixels
|
| : blink::WebGestureEvent::Pixels;
|
| }
|
| - SendGesture(scroll_update);
|
| +
|
| + bool current_phase_ended = false;
|
| + bool has_phase_info = false;
|
| +
|
| + if (event_sent_for_gesture_ack_->event.phase !=
|
| + blink::WebMouseWheelEvent::PhaseNone ||
|
| + event_sent_for_gesture_ack_->event.momentumPhase !=
|
| + blink::WebMouseWheelEvent::PhaseNone) {
|
| + has_phase_info = true;
|
| + current_phase_ended = event_sent_for_gesture_ack_->event.phase ==
|
| + blink::WebMouseWheelEvent::PhaseEnded ||
|
| + event_sent_for_gesture_ack_->event.phase ==
|
| + blink::WebMouseWheelEvent::PhaseCancelled ||
|
| + event_sent_for_gesture_ack_->event.momentumPhase ==
|
| + blink::WebMouseWheelEvent::PhaseEnded ||
|
| + event_sent_for_gesture_ack_->event.momentumPhase ==
|
| + blink::WebMouseWheelEvent::PhaseCancelled;
|
| + }
|
| +
|
| + bool needs_update = scroll_update.event.data.scrollUpdate.deltaX != 0 ||
|
| + scroll_update.event.data.scrollUpdate.deltaY != 0;
|
| +
|
| + // If there is no update to send and the current phase is ended yet a GSB
|
| + // needs to be sent, this event sequence doesn't need to be generated
|
| + // because the events generated will be a GSB (non-synthetic) and GSE
|
| + // (non-synthetic). This situation arises when OSX generates double
|
| + // phase end information.
|
| + bool empty_sequence =
|
| + !needs_update && needs_scroll_begin_ && current_phase_ended;
|
| +
|
| + if (needs_update || !empty_sequence) {
|
| + if (needs_scroll_begin_) {
|
| + // If no GSB has been sent, it will be a non-synthetic GSB.
|
| + SendScrollBegin(scroll_update, false);
|
| + } else if (has_phase_info) {
|
| + // If a GSB has been sent, generate a synthetic GSB if we have phase
|
| + // information. This should be removed once crbug.com/526463 is fully
|
| + // implemented.
|
| + SendScrollBegin(scroll_update, true);
|
| + }
|
| +
|
| + if (needs_update)
|
| + client_->SendGestureEvent(scroll_update);
|
| +
|
| + if (current_phase_ended) {
|
| + // Non-synthetic GSEs are sent when the current phase is canceled or
|
| + // ended.
|
| + SendScrollEnd(scroll_update.event, false);
|
| + } else if (has_phase_info) {
|
| + // Generate a synthetic GSE for every update to force hit testing so
|
| + // that the non-latching behavior is preserved. Remove once
|
| + // crbug.com/526463 is fully implemented.
|
| + SendScrollEnd(scroll_update.event, true);
|
| + } else {
|
| + scroll_end_timer_.Start(
|
| + FROM_HERE,
|
| + base::TimeDelta::FromMilliseconds(scroll_transaction_ms_),
|
| + base::Bind(&MouseWheelEventQueue::SendScrollEnd,
|
| + base::Unretained(this), scroll_update.event, false));
|
| + }
|
| + }
|
| }
|
|
|
| event_sent_for_gesture_ack_.reset();
|
| @@ -158,62 +227,52 @@ void MouseWheelEventQueue::TryForwardNextEventToRenderer() {
|
| client_->SendMouseWheelEventImmediately(send_event);
|
| }
|
|
|
| -void MouseWheelEventQueue::SendScrollEnd(blink::WebGestureEvent update_event) {
|
| - GestureEventWithLatencyInfo scroll_end;
|
| +void MouseWheelEventQueue::SendScrollEnd(blink::WebGestureEvent update_event,
|
| + bool synthetic) {
|
| + DCHECK((synthetic && !needs_scroll_end_) || needs_scroll_end_);
|
| +
|
| + GestureEventWithLatencyInfo scroll_end(update_event);
|
| + scroll_end.event.timeStampSeconds =
|
| + (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
|
| scroll_end.event.type = WebInputEvent::GestureScrollEnd;
|
| - scroll_end.event.sourceDevice = blink::WebGestureDeviceTouchpad;
|
| scroll_end.event.resendingPluginId = -1;
|
| + scroll_end.event.data.scrollEnd.synthetic = synthetic;
|
| + scroll_end.event.data.scrollEnd.inertial =
|
| + update_event.data.scrollUpdate.inertial;
|
| scroll_end.event.data.scrollEnd.deltaUnits =
|
| update_event.data.scrollUpdate.deltaUnits;
|
| - scroll_end.event.x = update_event.x;
|
| - scroll_end.event.y = update_event.y;
|
| - scroll_end.event.globalX = update_event.globalX;
|
| - scroll_end.event.globalY = update_event.globalY;
|
|
|
| - SendGesture(scroll_end);
|
| -}
|
| + if (!synthetic) {
|
| + needs_scroll_begin_ = true;
|
| + needs_scroll_end_ = false;
|
|
|
| -void MouseWheelEventQueue::SendGesture(
|
| - const GestureEventWithLatencyInfo& gesture) {
|
| - switch (gesture.event.type) {
|
| - case WebInputEvent::GestureScrollUpdate:
|
| - if (needs_scroll_begin_) {
|
| - GestureEventWithLatencyInfo scroll_begin(gesture);
|
| - scroll_begin.event.x = gesture.event.x;
|
| - scroll_begin.event.y = gesture.event.y;
|
| - scroll_begin.event.globalX = gesture.event.globalX;
|
| - scroll_begin.event.globalY = gesture.event.globalY;
|
| - scroll_begin.event.type = WebInputEvent::GestureScrollBegin;
|
| - scroll_begin.event.data.scrollBegin.deltaXHint =
|
| - gesture.event.data.scrollUpdate.deltaX;
|
| - scroll_begin.event.data.scrollBegin.deltaYHint =
|
| - gesture.event.data.scrollUpdate.deltaY;
|
| - scroll_begin.event.data.scrollBegin.targetViewport = false;
|
| - scroll_begin.event.data.scrollBegin.deltaHintUnits =
|
| - gesture.event.data.scrollUpdate.deltaUnits;
|
| -
|
| - SendGesture(scroll_begin);
|
| - }
|
| - if (scroll_end_timer_.IsRunning()) {
|
| - scroll_end_timer_.Reset();
|
| - } else {
|
| - scroll_end_timer_.Start(
|
| - FROM_HERE,
|
| - base::TimeDelta::FromMilliseconds(scroll_transaction_ms_),
|
| - base::Bind(&MouseWheelEventQueue::SendScrollEnd,
|
| - base::Unretained(this), gesture.event));
|
| - }
|
| - break;
|
| - case WebInputEvent::GestureScrollEnd:
|
| - needs_scroll_begin_ = true;
|
| - break;
|
| - case WebInputEvent::GestureScrollBegin:
|
| - needs_scroll_begin_ = false;
|
| - break;
|
| - default:
|
| - return;
|
| + if (scroll_end_timer_.IsRunning())
|
| + scroll_end_timer_.Reset();
|
| }
|
| - client_->SendGestureEvent(gesture);
|
| + client_->SendGestureEvent(scroll_end);
|
| +}
|
| +
|
| +void MouseWheelEventQueue::SendScrollBegin(
|
| + const GestureEventWithLatencyInfo& gesture_update,
|
| + bool synthetic) {
|
| + DCHECK((synthetic && !needs_scroll_begin_) || needs_scroll_begin_);
|
| +
|
| + GestureEventWithLatencyInfo scroll_begin(gesture_update);
|
| + scroll_begin.event.type = WebInputEvent::GestureScrollBegin;
|
| + scroll_begin.event.data.scrollBegin.synthetic = synthetic;
|
| + scroll_begin.event.data.scrollBegin.inertial =
|
| + gesture_update.event.data.scrollUpdate.inertial;
|
| + scroll_begin.event.data.scrollBegin.deltaXHint =
|
| + gesture_update.event.data.scrollUpdate.deltaX;
|
| + scroll_begin.event.data.scrollBegin.deltaYHint =
|
| + gesture_update.event.data.scrollUpdate.deltaY;
|
| + scroll_begin.event.data.scrollBegin.targetViewport = false;
|
| + scroll_begin.event.data.scrollBegin.deltaHintUnits =
|
| + gesture_update.event.data.scrollUpdate.deltaUnits;
|
| +
|
| + needs_scroll_begin_ = false;
|
| + needs_scroll_end_ = true;
|
| + client_->SendGestureEvent(scroll_begin);
|
| }
|
|
|
| } // namespace content
|
|
|