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..e7406c8cb86c085bf233bb39da4340b1d4025c85 100644 |
--- a/content/common/input/web_input_event_traits.cc |
+++ b/content/common/input/web_input_event_traits.cc |
@@ -16,50 +16,182 @@ using WebKit::WebTouchEvent; |
namespace content { |
namespace { |
+bool CanCoalesce(const WebKeyboardEvent& event_to_coalesce, |
+ const WebKeyboardEvent& event) { |
+ return false; |
+} |
+ |
+void Coalesce(const WebKeyboardEvent& event_to_coalesce, |
+ WebKeyboardEvent* event) { |
+ NOTREACHED() << "Keyboard coalescing not possible."; |
+} |
+ |
+bool CanCoalesce(const WebMouseEvent& event_to_coalesce, |
+ const WebMouseEvent& event) { |
+ return event.type == event_to_coalesce.type && |
+ event.type == WebInputEvent::MouseMove; |
+} |
+ |
+void Coalesce(const WebMouseEvent& event_to_coalesce, WebMouseEvent* event) { |
+ // Accumulate movement deltas. |
+ int x = event->movementX; |
aelias_OOO_until_Jul13
2013/10/14 19:05:58
Please add DCHECK(CanCoalesce(event_to_coalsece, *
jdduke (slow)
2013/10/14 19:10:12
OK. I had the DCHECK in WebInputEventTraits::Coal
|
+ int y = event->movementY; |
+ *event = event_to_coalesce; |
+ event->movementX += x; |
+ event->movementY += y; |
+} |
+ |
+bool CanCoalesce(const WebMouseWheelEvent& event_to_coalesce, |
+ const WebMouseWheelEvent& event) { |
+ return event.modifiers == event_to_coalesce.modifiers && |
+ event.scrollByPage == event_to_coalesce.scrollByPage && |
+ event.phase == event_to_coalesce.phase && |
+ event.momentumPhase == event_to_coalesce.momentumPhase && |
+ event.hasPreciseScrollingDeltas == |
+ event_to_coalesce.hasPreciseScrollingDeltas; |
+} |
+ |
+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) |
+ return 1.f; |
+ return unaccelerated_delta / accelerated_delta; |
+} |
+ |
+void Coalesce(const WebMouseWheelEvent& event_to_coalesce, |
+ WebMouseWheelEvent* event) { |
+ 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; |
+} |
+ |
+bool CanCoalesce(const WebTouchEvent& event_to_coalesce, |
+ const WebTouchEvent& event) { |
+ return event.type == event_to_coalesce.type && |
+ event.type == WebInputEvent::TouchMove && |
+ event.modifiers == event_to_coalesce.modifiers && |
+ event.touchesLength == event_to_coalesce.touchesLength; |
+} |
+ |
+void Coalesce(const WebTouchEvent& event_to_coalesce, WebTouchEvent* event) { |
+ // 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; |
+ } |
+} |
+ |
+bool CanCoalesce(const WebGestureEvent& event_to_coalesce, |
+ const WebGestureEvent& event) { |
+ return event.type == event_to_coalesce.type && |
+ event.type == WebInputEvent::GestureScrollUpdate && |
+ event.modifiers == event_to_coalesce.modifiers; |
+} |
+ |
+void Coalesce(const WebGestureEvent& event_to_coalesce, |
+ WebGestureEvent* event) { |
+ event->data.scrollUpdate.deltaX += event_to_coalesce.data.scrollUpdate.deltaX; |
+ event->data.scrollUpdate.deltaY += event_to_coalesce.data.scrollUpdate.deltaY; |
+} |
+ |
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 WebInputEventCanCoalesce { |
+ template <class EventType> |
+ bool Execute(const WebInputEvent& event_to_coalesce, |
+ const WebInputEvent* event) const { |
+ if (event_to_coalesce.type != event->type) |
+ return false; |
+ DCHECK_EQ(sizeof(EventType), event->size); |
+ DCHECK_EQ(sizeof(EventType), event_to_coalesce.size); |
+ return CanCoalesce(static_cast<const EventType&>(event_to_coalesce), |
+ *static_cast<const EventType*>(event)); |
+ } |
+}; |
+ |
+struct WebInputEventCoalesce { |
+ template <class EventType> |
+ bool Execute(const WebInputEvent& event_to_coalesce, |
+ WebInputEvent* event) const { |
+ Coalesce(static_cast<const EventType&>(event_to_coalesce), |
+ static_cast<EventType*>(event)); |
+ return true; |
} |
}; |
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 +215,22 @@ void WebInputEventTraits::Delete(WebInputEvent* event) { |
Apply(WebInputEventDelete(), event->type, event, &dummy_var); |
} |
+bool WebInputEventTraits::CanCoalesce(const WebInputEvent& event_to_coalesce, |
+ const WebInputEvent& event) { |
+ // Early out before casting. |
+ if (event_to_coalesce.type != event.type) |
+ return false; |
+ return Apply(WebInputEventCanCoalesce(), |
+ event.type, |
+ event_to_coalesce, |
+ &event); |
+} |
+ |
+void WebInputEventTraits::Coalesce(const WebInputEvent& event_to_coalesce, |
+ WebInputEvent* event) { |
+ DCHECK(event); |
+ DCHECK(CanCoalesce(event_to_coalesce, *event)); |
+ Apply(WebInputEventCoalesce(), event->type, event_to_coalesce, event); |
+} |
+ |
} // namespace content |