Chromium Code Reviews| Index: content/common/input/web_input_event_traits.cc |
| diff --git a/content/common/input/web_input_event_traits.cc b/content/common/input/web_input_event_traits.cc |
| index 15c334bc01da7497e640a03c3f7427a7ec86169c..c4e908fc6bc0e3c656f8fd0640ffa90209072e31 100644 |
| --- a/content/common/input/web_input_event_traits.cc |
| +++ b/content/common/input/web_input_event_traits.cc |
| @@ -16,50 +16,185 @@ using WebKit::WebTouchEvent; |
| namespace content { |
| namespace { |
| +float GetUnacceleratedDelta(float accelerated_delta, float acceleration_ratio) { |
| + return accelerated_delta * acceleration_ratio; |
| +} |
| + |
| +float GetAccelerationRatio(float accelerated_delta, float unaccelerated_delta) { |
| + if (unaccelerated_delta == 0.f || accelerated_delta == 0.f) |
|
aelias_OOO_until_Jul13
2013/10/14 03:38:57
I know you're just moving this, but this kind of d
jdduke (slow)
2013/10/14 17:03:18
Hmm, normally I'd agree, but it looks like they're
|
| + return 1.f; |
| + return unaccelerated_delta / accelerated_delta; |
| +} |
| + |
| +bool TryCoalesce(const WebKeyboardEvent& event_to_coalesce, |
| + WebKeyboardEvent* event) { |
| + return false; |
| +} |
| + |
| +bool TryCoalesce(const WebMouseEvent& event_to_coalesce, WebMouseEvent* event) { |
| + if (event->type != event_to_coalesce.type) |
| + return false; |
| + |
| + if (event->type != WebInputEvent::MouseMove) |
| + return false; |
| + |
| + // Accumulate movement deltas. |
| + int x = event->movementX; |
| + int y = event->movementY; |
| + *event = event_to_coalesce; |
| + event->movementX += x; |
| + event->movementY += y; |
| + return true; |
| +} |
| + |
| +bool TryCoalesce(const WebMouseWheelEvent& event_to_coalesce, |
| + WebMouseWheelEvent* event) { |
| + if (event->modifiers != event_to_coalesce.modifiers) |
| + return false; |
| + |
| + if (event->scrollByPage != event_to_coalesce.scrollByPage) |
| + return false; |
| + |
| + if (event->hasPreciseScrollingDeltas != |
| + event_to_coalesce.hasPreciseScrollingDeltas) |
| + return false; |
| + |
| + if (event->phase != event_to_coalesce.phase) |
| + return false; |
| + |
| + if (event->momentumPhase != event_to_coalesce.momentumPhase) |
| + return false; |
| + |
| + float unaccelerated_x = |
| + GetUnacceleratedDelta(event->deltaX, |
| + event->accelerationRatioX) + |
| + GetUnacceleratedDelta(event_to_coalesce.deltaX, |
| + event_to_coalesce.accelerationRatioX); |
| + float unaccelerated_y = |
| + GetUnacceleratedDelta(event->deltaY, |
| + event->accelerationRatioY) + |
| + GetUnacceleratedDelta(event_to_coalesce.deltaY, |
| + event_to_coalesce.accelerationRatioY); |
| + event->deltaX += event_to_coalesce.deltaX; |
| + event->deltaY += event_to_coalesce.deltaY; |
| + event->wheelTicksX += event_to_coalesce.wheelTicksX; |
| + event->wheelTicksY += event_to_coalesce.wheelTicksY; |
| + event->accelerationRatioX = |
| + GetAccelerationRatio(event->deltaX, unaccelerated_x); |
| + event->accelerationRatioY = |
| + GetAccelerationRatio(event->deltaY, unaccelerated_y); |
| + DCHECK_GE(event_to_coalesce.timeStampSeconds, event->timeStampSeconds); |
| + event->timeStampSeconds = event_to_coalesce.timeStampSeconds; |
| + return true; |
| +} |
| + |
| +bool TryCoalesce(const WebTouchEvent& event_to_coalesce, WebTouchEvent* event) { |
| + if (event->type != event_to_coalesce.type) |
| + return false; |
| + |
| + if (event->type != WebInputEvent::TouchMove) |
| + return false; |
| + |
| + if (event->modifiers != event_to_coalesce.modifiers) |
| + return false; |
| + |
| + if (event->touchesLength != event_to_coalesce.touchesLength) |
| + return false; |
| + |
| + // The WebTouchPoints include absolute position information. So it is |
| + // sufficient to simply replace the previous event with the new event-> |
| + // However, it is necessary to make sure that all the points have the |
| + // correct state, i.e. the touch-points that moved in the last event, but |
| + // didn't change in the current event, will have Stationary state. It is |
| + // necessary to change them back to Moved state. |
| + WebTouchEvent old_event = *event; |
| + *event = event_to_coalesce; |
| + for (unsigned i = 0; i < event->touchesLength; ++i) { |
| + if (old_event.touches[i].state == WebKit::WebTouchPoint::StateMoved) |
| + event->touches[i].state = WebKit::WebTouchPoint::StateMoved; |
| + } |
| + return true; |
| +} |
| + |
| +bool TryCoalesce(const WebGestureEvent& event_to_coalesce, |
| + WebGestureEvent* event) { |
| + if (event->type != event_to_coalesce.type) |
| + return false; |
| + |
| + if (event->type == WebInputEvent::GestureScrollUpdate) { |
| + if (event->modifiers != event_to_coalesce.modifiers) |
| + return false; |
| + event->data.scrollUpdate.deltaX += |
| + event_to_coalesce.data.scrollUpdate.deltaX; |
| + event->data.scrollUpdate.deltaY += |
| + event_to_coalesce.data.scrollUpdate.deltaY; |
| + return true; |
| + } |
| + |
| + // TODO(jdduke): Add support for pinch gesture coalescing. |
| + return false; |
| +} |
| + |
| struct WebInputEventSize { |
| template <class EventType> |
| - void Execute(WebInputEvent::Type /* type */, size_t* type_size) const { |
| + bool Execute(WebInputEvent::Type /* type */, size_t* type_size) const { |
| *type_size = sizeof(EventType); |
| + return true; |
| } |
| }; |
| struct WebInputEventClone { |
| template <class EventType> |
| - void Execute(const WebInputEvent& event, |
| + bool Execute(const WebInputEvent& event, |
| ScopedWebInputEvent* scoped_event) const { |
| DCHECK_EQ(sizeof(EventType), event.size); |
| *scoped_event = ScopedWebInputEvent( |
| new EventType(static_cast<const EventType&>(event))); |
| + return true; |
| } |
| }; |
| struct WebInputEventDelete { |
| template <class EventType> |
| - void Execute(WebInputEvent* event, bool* /* dummy_var */) const { |
| + bool Execute(WebInputEvent* event, bool* /* dummy_var */) const { |
| if (!event) |
| - return; |
| + return false; |
| DCHECK_EQ(sizeof(EventType), event->size); |
| delete static_cast<EventType*>(event); |
| + return true; |
| + } |
| +}; |
| + |
| +struct WebInputEventCoalesce { |
| + tempalte <class EventType> |
| + bool Execute(const WebInputEvent& event_to_coalesce, |
| + WebInputEvent* event) const { |
| + DCHECK_EQ(event_to_coalesce.type, event->type) |
| + DCHECK_EQ(sizeof(EventType), event->size); |
| + DCHECK_EQ(sizeof(EventType), event_to_coalesce.size); |
| + return TryCoalesce(static_cast<const EventType&>(event_to_coalesce), |
| + static_cast<EventType*>(event)); |
| } |
| }; |
| template <typename Operator, typename ArgIn, typename ArgOut> |
| -void Apply(Operator op, |
| +bool Apply(Operator op, |
| WebInputEvent::Type type, |
| const ArgIn& arg_in, |
| ArgOut* arg_out) { |
| if (WebInputEvent::isMouseEventType(type)) |
| - op.template Execute<WebMouseEvent>(arg_in, arg_out); |
| + return op.template Execute<WebMouseEvent>(arg_in, arg_out); |
| else if (type == WebInputEvent::MouseWheel) |
| - op.template Execute<WebMouseWheelEvent>(arg_in, arg_out); |
| + return op.template Execute<WebMouseWheelEvent>(arg_in, arg_out); |
| else if (WebInputEvent::isKeyboardEventType(type)) |
| - op.template Execute<WebKeyboardEvent>(arg_in, arg_out); |
| + return op.template Execute<WebKeyboardEvent>(arg_in, arg_out); |
| else if (WebInputEvent::isTouchEventType(type)) |
| - op.template Execute<WebTouchEvent>(arg_in, arg_out); |
| + return op.template Execute<WebTouchEvent>(arg_in, arg_out); |
| else if (WebInputEvent::isGestureEventType(type)) |
| - op.template Execute<WebGestureEvent>(arg_in, arg_out); |
| - else |
| - NOTREACHED() << "Unknown webkit event type " << type; |
| + return op.template Execute<WebGestureEvent>(arg_in, arg_out); |
| + |
| + NOTREACHED() << "Unknown webkit event type " << type; |
| + return false; |
| } |
| } // namespace |
| @@ -83,4 +218,11 @@ void WebInputEventTraits::Delete(WebInputEvent* event) { |
| Apply(WebInputEventDelete(), event->type, event, &dummy_var); |
| } |
| +bool WebInputEventTraits::TryCoalesce(const WebInputEvent& event_to_coalesce, |
| + WebInputEvent* event) { |
| + if (!event || event_to_coalesce.type != event->type) |
| + return false; |
| + return Apply(WebInputEventCoalesce(), event->type, event_to_coalesce, event); |
| +} |
| + |
| } // namespace content |