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 |