summaryrefslogtreecommitdiffstats
path: root/chromium/content/common/input/web_input_event_traits.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/common/input/web_input_event_traits.cc')
-rw-r--r--chromium/content/common/input/web_input_event_traits.cc103
1 files changed, 85 insertions, 18 deletions
diff --git a/chromium/content/common/input/web_input_event_traits.cc b/chromium/content/common/input/web_input_event_traits.cc
index 5da4d9a833e..fa9f433a1d7 100644
--- a/chromium/content/common/input/web_input_event_traits.cc
+++ b/chromium/content/common/input/web_input_event_traits.cc
@@ -4,6 +4,9 @@
#include "content/common/input/web_input_event_traits.h"
+#include <bitset>
+#include <limits>
+
#include "base/logging.h"
using blink::WebGestureEvent;
@@ -12,10 +15,13 @@ using blink::WebKeyboardEvent;
using blink::WebMouseEvent;
using blink::WebMouseWheelEvent;
using blink::WebTouchEvent;
+using std::numeric_limits;
namespace content {
namespace {
+const int kInvalidTouchIndex = -1;
+
bool CanCoalesce(const WebKeyboardEvent& event_to_coalesce,
const WebKeyboardEvent& event) {
return false;
@@ -87,12 +93,39 @@ void Coalesce(const WebMouseWheelEvent& event_to_coalesce,
event->timeStampSeconds = event_to_coalesce.timeStampSeconds;
}
+// Returns |kInvalidTouchIndex| iff |event| lacks a touch with an ID of |id|.
+int GetIndexOfTouchID(const WebTouchEvent& event, int id) {
+ for (unsigned i = 0; i < event.touchesLength; ++i) {
+ if (event.touches[i].id == id)
+ return i;
+ }
+ return kInvalidTouchIndex;
+}
+
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;
+ if (event.type != event_to_coalesce.type ||
+ event.type != WebInputEvent::TouchMove ||
+ event.modifiers != event_to_coalesce.modifiers ||
+ event.touchesLength != event_to_coalesce.touchesLength ||
+ event.touchesLength > WebTouchEvent::touchesLengthCap)
+ return false;
+
+ COMPILE_ASSERT(WebTouchEvent::touchesLengthCap <= sizeof(int32_t) * 8U,
+ suboptimal_touches_length_cap_size);
+ // Ensure that we have a 1-to-1 mapping of pointer ids between touches.
+ std::bitset<WebTouchEvent::touchesLengthCap> unmatched_event_touches(
+ (1 << event.touchesLength) - 1);
+ for (unsigned i = 0; i < event_to_coalesce.touchesLength; ++i) {
+ int event_touch_index =
+ GetIndexOfTouchID(event, event_to_coalesce.touches[i].id);
+ if (event_touch_index == kInvalidTouchIndex)
+ return false;
+ if (!unmatched_event_touches[event_touch_index])
+ return false;
+ unmatched_event_touches[event_touch_index] = false;
+ }
+ return unmatched_event_touches.none();
}
void Coalesce(const WebTouchEvent& event_to_coalesce, WebTouchEvent* event) {
@@ -106,23 +139,49 @@ void Coalesce(const WebTouchEvent& event_to_coalesce, WebTouchEvent* event) {
WebTouchEvent old_event = *event;
*event = event_to_coalesce;
for (unsigned i = 0; i < event->touchesLength; ++i) {
- if (old_event.touches[i].state == blink::WebTouchPoint::StateMoved)
+ int i_old = GetIndexOfTouchID(old_event, event->touches[i].id);
+ if (old_event.touches[i_old].state == blink::WebTouchPoint::StateMoved)
event->touches[i].state = blink::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;
+ if (event.type != event_to_coalesce.type ||
+ event.sourceDevice != event_to_coalesce.sourceDevice ||
+ event.modifiers != event_to_coalesce.modifiers)
+ return false;
+
+ if (event.type == WebInputEvent::GestureScrollUpdate)
+ return true;
+
+ // GesturePinchUpdate scales can be combined only if they share a focal point,
+ // e.g., with double-tap drag zoom.
+ if (event.type == WebInputEvent::GesturePinchUpdate &&
+ event.x == event_to_coalesce.x &&
+ event.y == event_to_coalesce.y)
+ return true;
+
+ return false;
}
void Coalesce(const WebGestureEvent& event_to_coalesce,
WebGestureEvent* event) {
DCHECK(CanCoalesce(event_to_coalesce, *event));
- event->data.scrollUpdate.deltaX += event_to_coalesce.data.scrollUpdate.deltaX;
- event->data.scrollUpdate.deltaY += event_to_coalesce.data.scrollUpdate.deltaY;
+ if (event->type == WebInputEvent::GestureScrollUpdate) {
+ event->data.scrollUpdate.deltaX +=
+ event_to_coalesce.data.scrollUpdate.deltaX;
+ event->data.scrollUpdate.deltaY +=
+ event_to_coalesce.data.scrollUpdate.deltaY;
+ } else if (event->type == WebInputEvent::GesturePinchUpdate) {
+ event->data.pinchUpdate.scale *= event_to_coalesce.data.pinchUpdate.scale;
+ // Ensure the scale remains bounded above 0 and below Infinity so that
+ // we can reliably perform operations like log on the values.
+ if (event->data.pinchUpdate.scale < numeric_limits<float>::min())
+ event->data.pinchUpdate.scale = numeric_limits<float>::min();
+ else if (event->data.pinchUpdate.scale > numeric_limits<float>::max())
+ event->data.pinchUpdate.scale = numeric_limits<float>::max();
+ }
}
struct WebInputEventSize {
@@ -283,22 +342,30 @@ void WebInputEventTraits::Coalesce(const WebInputEvent& event_to_coalesce,
Apply(WebInputEventCoalesce(), event->type, event_to_coalesce, event);
}
-bool WebInputEventTraits::IgnoresAckDisposition(
- blink::WebInputEvent::Type type) {
- switch (type) {
- case WebInputEvent::GestureTapDown:
+bool WebInputEventTraits::IgnoresAckDisposition(const WebInputEvent& event) {
+ switch (event.type) {
+ case WebInputEvent::MouseDown:
+ case WebInputEvent::MouseUp:
+ case WebInputEvent::MouseEnter:
+ case WebInputEvent::MouseLeave:
+ case WebInputEvent::ContextMenu:
+ case WebInputEvent::GestureScrollBegin:
+ case WebInputEvent::GestureScrollEnd:
case WebInputEvent::GestureShowPress:
+ case WebInputEvent::GestureTapUnconfirmed:
+ case WebInputEvent::GestureTapDown:
case WebInputEvent::GestureTapCancel:
case WebInputEvent::GesturePinchBegin:
case WebInputEvent::GesturePinchEnd:
- case WebInputEvent::GestureScrollBegin:
- case WebInputEvent::GestureScrollEnd:
case WebInputEvent::TouchCancel:
return true;
+ case WebInputEvent::TouchStart:
+ case WebInputEvent::TouchMove:
+ case WebInputEvent::TouchEnd:
+ return !static_cast<const WebTouchEvent&>(event).cancelable;
default:
- break;
+ return false;
}
- return false;
}
} // namespace content