Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1410)

Unified Diff: Source/core/page/EventHandler.cpp

Issue 1144313003: Added PointerEvent firing on touch events. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« Source/core/events/TouchEvent.cpp ('K') | « Source/core/page/EventHandler.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/page/EventHandler.cpp
diff --git a/Source/core/page/EventHandler.cpp b/Source/core/page/EventHandler.cpp
index d26cd614a18903911ad11f4746158ee73bb540f4..e6f3638ca43c15d221843eb900419d2ab8182821 100644
--- a/Source/core/page/EventHandler.cpp
+++ b/Source/core/page/EventHandler.cpp
@@ -45,6 +45,7 @@
#include "core/events/EventPath.h"
#include "core/events/KeyboardEvent.h"
#include "core/events/MouseEvent.h"
+#include "core/events/PointerEvent.h"
#include "core/events/TextEvent.h"
#include "core/events/TouchEvent.h"
#include "core/events/WheelEvent.h"
@@ -237,6 +238,7 @@ EventHandler::EventHandler(LocalFrame* frame)
, m_mouseDownTimestamp(0)
, m_widgetIsLatched(false)
, m_touchPressed(false)
+ , m_primaryPointerId(0)
, m_scrollGestureHandlingNode(nullptr)
, m_lastGestureScrollOverWidget(false)
, m_maxMouseMovedDuration(0)
@@ -317,6 +319,7 @@ void EventHandler::clear()
m_scrollbarHandlingScrollGesture = nullptr;
m_maxMouseMovedDuration = 0;
m_touchPressed = false;
+ m_primaryPointerId = 0;
m_mouseDownMayStartSelect = false;
m_mouseDownMayStartDrag = false;
m_lastShowPressTimestamp = 0;
@@ -3776,7 +3779,7 @@ void EventHandler::updateLastScrollbarUnderMouse(Scrollbar* scrollbar, bool setL
}
}
-static const AtomicString& eventNameForTouchPointState(PlatformTouchPoint::State state)
+static const AtomicString& touchEventNameForTouchPointState(PlatformTouchPoint::State state)
{
switch (state) {
case PlatformTouchPoint::TouchReleased:
@@ -3795,6 +3798,25 @@ static const AtomicString& eventNameForTouchPointState(PlatformTouchPoint::State
}
}
+static const AtomicString& pointerEventNameForTouchPointState(PlatformTouchPoint::State state)
+{
+ switch (state) {
+ case PlatformTouchPoint::TouchReleased:
+ return EventTypeNames::pointerup;
+ case PlatformTouchPoint::TouchCancelled:
+ return EventTypeNames::pointercancel;
+ case PlatformTouchPoint::TouchPressed:
+ return EventTypeNames::pointerdown;
+ case PlatformTouchPoint::TouchMoved:
+ return EventTypeNames::pointermove;
+ case PlatformTouchPoint::TouchStationary:
+ // TouchStationary state is not converted to touch events, so fall through to assert.
+ default:
+ ASSERT_NOT_REACHED();
+ return emptyAtom;
+ }
+}
+
HitTestResult EventHandler::hitTestResultInFrame(LocalFrame* frame, const LayoutPoint& point, HitTestRequest::HitTestRequestType hitType)
{
HitTestResult result(HitTestRequest(hitType), point);
@@ -3816,10 +3838,9 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
const Vector<PlatformTouchPoint>& points = event.touchPoints();
- unsigned i;
bool freshTouchEvents = true;
bool allTouchReleased = true;
- for (i = 0; i < points.size(); ++i) {
+ for (unsigned i = 0; i < points.size(); ++i) {
const PlatformTouchPoint& point = points[i];
if (point.state() != PlatformTouchPoint::TouchPressed)
freshTouchEvents = false;
@@ -3853,7 +3874,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
}
// First do hit tests for any new touch points.
- for (i = 0; i < points.size(); ++i) {
+ for (unsigned i = 0; i < points.size(); ++i) {
const PlatformTouchPoint& point = points[i];
// Touch events implicitly capture to the touched node, and don't change
@@ -3888,6 +3909,10 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
ASSERT(m_touchSequenceDocument->frame()->view());
}
+ // If it is the first TouchPressed we have seen so far, we will consider it primary.
+ if (!m_primaryPointerId)
+ m_primaryPointerId = point.id();
+
// Ideally we'd ASSERT(!m_targetForTouchID.contains(point.id())
// since we shouldn't get a touchstart for a touch that's already
// down. However EventSender allows this to be violated and there's
@@ -3904,6 +3929,10 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
m_touchPressed = !allTouchReleased;
+ unsigned lastPrimaryPointerId = m_primaryPointerId;
+ if (allTouchReleased)
+ m_primaryPointerId = 0;
+
// If there's no document receiving touch events, or no handlers on the
// document set to receive the events, then we can skip all the rest of
// this work.
@@ -3938,7 +3967,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
EventTargetSet m_targets;
} changedTouches[PlatformTouchPoint::TouchStateEnd];
- for (i = 0; i < points.size(); ++i) {
+ for (unsigned i = 0; i < points.size(); ++i) {
const PlatformTouchPoint& point = points[i];
PlatformTouchPoint::State pointState = point.state();
RefPtrWillBeRawPtr<EventTarget> touchTarget = nullptr;
@@ -4031,20 +4060,57 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
m_touchSequenceUserGestureToken.clear();
}
- // Now iterate the changedTouches list and m_targets within it, sending
- // events to the targets as required.
bool swallowedEvent = false;
+
+ // Iterate the changedTouches list and m_targets within it, sending PointerEvents
+ // to the targets as required.
Rick Byers 2015/05/25 18:24:26 I think you'll want to skip all this if your Runti
mustaq 2015/05/26 15:00:09 Done. See my next comment on cleanup.
+ for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state) {
+ if (!changedTouches[state].m_touches)
+ continue;
+
+ const AtomicString& eventName(pointerEventNameForTouchPointState(static_cast<PlatformTouchPoint::State>(state)));
+ const EventTargetSet& targetsForState = changedTouches[state].m_targets;
+
+ for (const RefPtrWillBeMember<EventTarget>& eventTarget : targetsForState) {
+ EventTarget* pointerEventTarget = eventTarget.get();
+ TouchList* touchesForTarget = touchesByTarget.get(pointerEventTarget);
Rick Byers 2015/05/25 18:24:26 I think this would be simpler if you didn't use th
mustaq 2015/05/26 15:00:09 I agree on your first point. I will isolate the in
+ for (unsigned i = 0; i < touchesForTarget->length(); i++) {
+ Touch* touch = touchesForTarget->item(i);
+
+ PointerEventInit pointerEventInit;
+ pointerEventInit.setPointerId(touch->identifier());
+ pointerEventInit.setWidth(touch->radiusX());
+ pointerEventInit.setHeight(touch->radiusY());
+ pointerEventInit.setPressure(touch->force());
+ pointerEventInit.setTiltX(0.0);
+ pointerEventInit.setTiltY(0.0);
+ pointerEventInit.setPointerType(eventName);
+ pointerEventInit.setIsPrimary(lastPrimaryPointerId == touch->identifier());
+
+ RefPtrWillBeRawPtr<PointerEvent> pointerEvent = PointerEvent::create(eventName, pointerEventInit);
+ pointerEventTarget->toNode()->dispatchPointerEvent(pointerEvent.get());
+ swallowedEvent = swallowedEvent || pointerEvent->defaultPrevented() || pointerEvent->defaultHandled();
+ }
+ }
+ }
+
+ // Skip firing TouchEvent's if any PointerEvent was consumed.
+ if (swallowedEvent)
+ return true;
+
+ // Now iterate the changedTouches list and m_targets within it, sending
+ // TouchEvents to the targets as required.
for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state) {
if (!changedTouches[state].m_touches)
continue;
- const AtomicString& stateName(eventNameForTouchPointState(static_cast<PlatformTouchPoint::State>(state)));
+ const AtomicString& eventName(touchEventNameForTouchPointState(static_cast<PlatformTouchPoint::State>(state)));
const EventTargetSet& targetsForState = changedTouches[state].m_targets;
for (const RefPtrWillBeMember<EventTarget>& eventTarget : targetsForState) {
EventTarget* touchEventTarget = eventTarget.get();
RefPtrWillBeRawPtr<TouchEvent> touchEvent = TouchEvent::create(
touches.get(), touchesByTarget.get(touchEventTarget), changedTouches[state].m_touches.get(),
- stateName, touchEventTarget->toNode()->document().domWindow(),
+ eventName, touchEventTarget->toNode()->document().domWindow(),
event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(), event.cancelable(), event.causesScrollingIfUncanceled(), event.timestamp());
touchEventTarget->toNode()->dispatchTouchEvent(touchEvent.get());
swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() || touchEvent->defaultHandled();
« Source/core/events/TouchEvent.cpp ('K') | « Source/core/page/EventHandler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698