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

Unified Diff: third_party/WebKit/Source/core/input/EventHandler.cpp

Issue 1425053002: Fire pointermoves for mousemove events. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: TestExpectations Created 5 years, 1 month 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
« no previous file with comments | « third_party/WebKit/Source/core/input/EventHandler.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/input/EventHandler.cpp
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp
index 1e4b1d430ed9d5f5d9450f80e88803bd3cb6507d..dbad22913a2a7336501d50ca12cfd0876a9f2c0c 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.cpp
+++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -108,8 +108,67 @@ bool isNodeInDocument(Node* n)
return n && n->inDocument();
}
+const AtomicString& touchEventNameForTouchPointState(PlatformTouchPoint::State state)
+{
+ switch (state) {
+ case PlatformTouchPoint::TouchReleased:
+ return EventTypeNames::touchend;
+ case PlatformTouchPoint::TouchCancelled:
+ return EventTypeNames::touchcancel;
+ case PlatformTouchPoint::TouchPressed:
+ return EventTypeNames::touchstart;
+ case PlatformTouchPoint::TouchMoved:
+ return EventTypeNames::touchmove;
+ case PlatformTouchPoint::TouchStationary:
+ // Fall through to default
+ default:
+ ASSERT_NOT_REACHED();
+ return emptyAtom;
+ }
}
+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:
+ // Fall through to default
+ default:
+ ASSERT_NOT_REACHED();
+ return emptyAtom;
+ }
+}
+
+const AtomicString& pointerEventNameForMouseEventName(const AtomicString& mouseEventName)
+{
+#define RETURN_CORRESPONDING_PE_NAME(eventSuffix) \
+ if (mouseEventName == EventTypeNames::mouse##eventSuffix) {\
+ return EventTypeNames::pointer##eventSuffix;\
+ }
+
+ RETURN_CORRESPONDING_PE_NAME(down);
+ RETURN_CORRESPONDING_PE_NAME(enter);
+ RETURN_CORRESPONDING_PE_NAME(leave);
+ RETURN_CORRESPONDING_PE_NAME(move);
+ RETURN_CORRESPONDING_PE_NAME(out);
+ RETURN_CORRESPONDING_PE_NAME(over);
+ RETURN_CORRESPONDING_PE_NAME(up);
+
+#undef RETURN_CORRESPONDING_PE_NAME
+
+ ASSERT_NOT_REACHED();
+ return emptyAtom;
+}
+
+} // namespace
+
using namespace HTMLNames;
// The link drag hysteresis is much larger than the others because there
@@ -971,13 +1030,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
m_frame->selection().setCaretBlinkingSuspended(true);
- bool swallowEvent = dispatchPointerEventForMouseEvent(mev.innerNode(), EventTypeNames::pointerdown, mouseEvent);
-
- if (swallowEvent) {
- m_preventMouseEventForPointerTypeMouse = true;
- }
- if (!m_preventMouseEventForPointerTypeMouse)
- swallowEvent = swallowEvent || !dispatchMouseEvent(EventTypeNames::mousedown, mev.innerNode(), m_clickCount, mouseEvent);
+ bool swallowEvent = updatePointerTargetAndDispatchEvents(EventTypeNames::mousedown, mev.innerNode(), m_clickCount, mouseEvent);
// m_selectionInitiationState is initialized after dispatching mousedown
// event in order not to keep the selection by DOM APIs Because we can't
@@ -1111,7 +1164,7 @@ bool EventHandler::handleMouseMoveOrLeaveEvent(const PlatformMouseEvent& mouseEv
}
if (m_frameSetBeingResized)
- return !dispatchMouseEvent(EventTypeNames::mousemove, m_frameSetBeingResized.get(), 0, mouseEvent);
+ return updatePointerTargetAndDispatchEvents(EventTypeNames::mousemove, m_frameSetBeingResized.get(), 0, mouseEvent);
// Send events right to a scrollbar if the mouse is pressed.
if (m_lastScrollbarUnderMouse && m_mousePressed) {
@@ -1193,7 +1246,8 @@ bool EventHandler::handleMouseMoveOrLeaveEvent(const PlatformMouseEvent& mouseEv
if (swallowEvent)
return true;
- swallowEvent = !dispatchMouseEvent(EventTypeNames::mousemove, mev.innerNode(), 0, mouseEvent);
+ swallowEvent = updatePointerTargetAndDispatchEvents(EventTypeNames::mousemove, mev.innerNode(), 0, mouseEvent);
+
if (!swallowEvent)
swallowEvent = handleMouseDraggedEvent(mev);
@@ -1246,12 +1300,12 @@ bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
}
if (m_frameSetBeingResized)
- return !dispatchMouseEvent(EventTypeNames::mouseup, m_frameSetBeingResized.get(), m_clickCount, mouseEvent);
+ return dispatchMouseEvent(EventTypeNames::mouseup, m_frameSetBeingResized.get(), m_clickCount, mouseEvent);
if (m_lastScrollbarUnderMouse) {
invalidateClick();
m_lastScrollbarUnderMouse->mouseUp(mouseEvent);
- return !dispatchMouseEvent(EventTypeNames::mouseup, m_nodeUnderMouse.get(), m_clickCount, mouseEvent);
+ return dispatchMouseEvent(EventTypeNames::mouseup, m_nodeUnderMouse.get(), m_clickCount, mouseEvent);
}
// Mouse events simulated from touch should not hit-test again.
@@ -1266,14 +1320,10 @@ bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
if (subframe && passMouseReleaseEventToSubframe(mev, subframe))
return true;
- bool swallowPointerUpEvent = dispatchPointerEventForMouseEvent(mev.innerNode(), EventTypeNames::pointerup, mouseEvent);
- bool swallowMouseUpEvent = false;
- if (!m_preventMouseEventForPointerTypeMouse) {
- swallowMouseUpEvent = !dispatchMouseEvent(EventTypeNames::mouseup, mev.innerNode(), m_clickCount, mouseEvent);
- } else {
- // TODO(crbug/545647): This state should reset with pointercancel too.
- m_preventMouseEventForPointerTypeMouse = false;
- }
+ bool swallowUpEvent = updatePointerTargetAndDispatchEvents(EventTypeNames::mouseup, mev.innerNode(), m_clickCount, mouseEvent);
+
+ // TODO(crbug/545647): This state should reset with pointercancel too.
+ m_preventMouseEventForPointerTypeMouse = false;
bool contextMenuEvent = mouseEvent.button() == RightButton;
#if OS(MACOSX)
@@ -1308,12 +1358,12 @@ bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
}
bool swallowMouseReleaseEvent = false;
- if (!swallowPointerUpEvent && !swallowMouseUpEvent)
+ if (!swallowUpEvent)
swallowMouseReleaseEvent = handleMouseReleaseEvent(mev);
invalidateClick();
- return swallowPointerUpEvent || swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
+ return swallowUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
}
bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTarget, const PlatformMouseEvent& event, DataTransfer* dataTransfer)
@@ -1562,7 +1612,7 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
sendMouseEventsForNodeTransition(lastNodeUnderMouse.get(), m_nodeUnderMouse.get(), mouseEvent);
}
-bool EventHandler::dispatchPointerEventForMouseEvent(Node* target, const AtomicString& eventType,
+bool EventHandler::dispatchPointerEvent(Node* target, const AtomicString& eventType,
const PlatformMouseEvent& mouseEvent, Node* relatedTarget)
{
if (!RuntimeEnabledFeatures::pointerEventEnabled())
@@ -1581,7 +1631,7 @@ void EventHandler::sendMouseEventsForNodeTransition(Node* exitedNode, Node* ente
// Dispatch pointerout/mouseout events
if (isNodeInDocument(exitedNode)) {
- dispatchPointerEventForMouseEvent(exitedNode, EventTypeNames::pointerout, mouseEvent, enteredNode);
+ dispatchPointerEvent(exitedNode, EventTypeNames::pointerout, mouseEvent, enteredNode);
exitedNode->dispatchMouseEvent(mouseEvent, EventTypeNames::mouseout, 0, enteredNode);
}
@@ -1643,7 +1693,7 @@ void EventHandler::sendMouseEventsForNodeTransition(Node* exitedNode, Node* ente
// Dispatch pointerleave/mouseleave events, in child-to-parent order.
for (size_t j = 0; j < exitedAncestorIndex; j++) {
if (exitedNodeHasCapturingAncestor || exitedAncestors[j]->hasEventListeners(EventTypeNames::pointerleave)) {
- dispatchPointerEventForMouseEvent(exitedAncestors[j].get(), EventTypeNames::pointerleave, mouseEvent,
+ dispatchPointerEvent(exitedAncestors[j].get(), EventTypeNames::pointerleave, mouseEvent,
enteredNode);
}
if (exitedNodeHasCapturingAncestor || exitedAncestors[j]->hasEventListeners(EventTypeNames::mouseleave))
@@ -1652,7 +1702,7 @@ void EventHandler::sendMouseEventsForNodeTransition(Node* exitedNode, Node* ente
// Dispatch pointerover/mouseover.
if (isNodeInDocument(enteredNode)) {
- dispatchPointerEventForMouseEvent(enteredNode, EventTypeNames::pointerover, mouseEvent, exitedNode);
+ dispatchPointerEvent(enteredNode, EventTypeNames::pointerover, mouseEvent, exitedNode);
enteredNode->dispatchMouseEvent(mouseEvent, EventTypeNames::mouseover, 0, exitedNode);
}
@@ -1669,7 +1719,7 @@ void EventHandler::sendMouseEventsForNodeTransition(Node* exitedNode, Node* ente
// Dispatch pointerenter/mouseenter events, in parent-to-child order.
for (size_t i = enteredAncestorIndex; i > 0; i--) {
if (enteredNodeHasCapturingAncestor || enteredAncestors[i-1]->hasEventListeners(EventTypeNames::pointerenter)) {
- dispatchPointerEventForMouseEvent(enteredAncestors[i-1].get(), EventTypeNames::pointerenter, mouseEvent,
+ dispatchPointerEvent(enteredAncestors[i-1].get(), EventTypeNames::pointerenter, mouseEvent,
exitedNode);
}
if (enteredNodeHasCapturingAncestor || enteredAncestors[i-1]->hasEventListeners(EventTypeNames::mouseenter))
@@ -1677,14 +1727,38 @@ void EventHandler::sendMouseEventsForNodeTransition(Node* exitedNode, Node* ente
}
}
-// The return value means 'continue default handling.'
bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targetNode, int clickCount, const PlatformMouseEvent& mouseEvent)
{
updateMouseEventTargetNode(targetNode, mouseEvent);
- return !m_nodeUnderMouse || m_nodeUnderMouse->dispatchMouseEvent(mouseEvent, eventType, clickCount);
+ return m_nodeUnderMouse && !m_nodeUnderMouse->dispatchMouseEvent(mouseEvent, eventType, clickCount);
+}
+
+// TODO(mustaq): Make PE drive ME dispatch & bookkeeping in EventHandler.
+bool EventHandler::updatePointerTargetAndDispatchEvents(const AtomicString& mouseEventType, Node* targetNode, int clickCount, const PlatformMouseEvent& mouseEvent)
+{
+ ASSERT(mouseEventType == EventTypeNames::mousedown
+ || mouseEventType == EventTypeNames::mousemove
+ || mouseEventType == EventTypeNames::mouseup);
+
+ updateMouseEventTargetNode(targetNode, mouseEvent);
+ if (!m_nodeUnderMouse)
+ return false;
+
+ bool swallowEvent = dispatchPointerEvent(m_nodeUnderMouse.get(),
+ pointerEventNameForMouseEventName(mouseEventType),
+ mouseEvent);
+
+ if (swallowEvent && mouseEventType == EventTypeNames::mousedown) {
+ m_preventMouseEventForPointerTypeMouse = true;
+ }
+
+ if (!m_preventMouseEventForPointerTypeMouse) {
+ swallowEvent |= !m_nodeUnderMouse->dispatchMouseEvent(mouseEvent, mouseEventType, clickCount);
+ }
+
+ return swallowEvent;
}
-// The return value means 'swallow event' (was handled), as for other handle* functions.
bool EventHandler::handleMouseFocus(const MouseEventWithHitTestResults& targetedEvent, InputDeviceCapabilities* sourceCapabilities)
{
// If clicking on a frame scrollbar, do not mess up with content focus.
@@ -2126,7 +2200,7 @@ bool EventHandler::handleGestureTap(const GestureEventWithHitTestResults& target
LeftButton, PlatformEvent::MousePressed, gestureEvent.tapCount(),
static_cast<PlatformEvent::Modifiers>(modifiers | PlatformEvent::LeftButtonDown),
PlatformMouseEvent::FromTouch, gestureEvent.timestamp());
- bool swallowMouseDownEvent = !dispatchMouseEvent(EventTypeNames::mousedown, currentHitTest.innerNode(), gestureEvent.tapCount(), fakeMouseDown);
+ bool swallowMouseDownEvent = dispatchMouseEvent(EventTypeNames::mousedown, currentHitTest.innerNode(), gestureEvent.tapCount(), fakeMouseDown);
selectionController().initializeSelectionState();
if (!swallowMouseDownEvent)
swallowMouseDownEvent = handleMouseFocus(MouseEventWithHitTestResults(fakeMouseDown, currentHitTest), InputDeviceCapabilities::firesTouchEventsSourceCapabilities());
@@ -2152,7 +2226,7 @@ bool EventHandler::handleGestureTap(const GestureEventWithHitTestResults& target
LeftButton, PlatformEvent::MouseReleased, gestureEvent.tapCount(),
static_cast<PlatformEvent::Modifiers>(modifiers),
PlatformMouseEvent::FromTouch, gestureEvent.timestamp());
- bool swallowMouseUpEvent = !dispatchMouseEvent(EventTypeNames::mouseup, currentHitTest.innerNode(), gestureEvent.tapCount(), fakeMouseUp);
+ bool swallowMouseUpEvent = dispatchMouseEvent(EventTypeNames::mouseup, currentHitTest.innerNode(), gestureEvent.tapCount(), fakeMouseUp);
bool swallowClickEvent = false;
if (m_clickNode) {
@@ -2164,7 +2238,7 @@ bool EventHandler::handleGestureTap(const GestureEventWithHitTestResults& target
// because commonAncestor() will exit early if their documents are different.
m_clickNode->updateDistribution();
Node* clickTargetNode = currentHitTest.innerNode()->commonAncestor(*m_clickNode, parentForClickEvent);
- swallowClickEvent = !dispatchMouseEvent(EventTypeNames::click, clickTargetNode, gestureEvent.tapCount(), fakeMouseUp);
+ swallowClickEvent = dispatchMouseEvent(EventTypeNames::click, clickTargetNode, gestureEvent.tapCount(), fakeMouseUp);
}
m_clickNode = nullptr;
}
@@ -2811,7 +2885,7 @@ bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event, Node* o
selectionController().sendContextMenuEvent(mev, positionInContents);
Node* targetNode = overrideTargetNode ? overrideTargetNode : mev.innerNode();
- return !dispatchMouseEvent(EventTypeNames::contextmenu, targetNode, 0, event);
+ return dispatchMouseEvent(EventTypeNames::contextmenu, targetNode, 0, event);
}
bool EventHandler::sendContextMenuEventForKey(Element* overrideTargetElement)
@@ -3271,7 +3345,7 @@ void EventHandler::updateDragStateAfterEditDragIfNeeded(Element* rootEditableEle
// returns if we should continue "default processing", i.e., whether eventhandler canceled
bool EventHandler::dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent& event)
{
- return !dispatchDragEvent(eventType, dragState().m_dragSrc.get(), event, dragState().m_dragDataTransfer.get());
+ return dispatchDragEvent(eventType, dragState().m_dragSrc.get(), event, dragState().m_dragDataTransfer.get());
}
bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, DragInitiator initiator)
@@ -3358,7 +3432,7 @@ bool EventHandler::tryStartDrag(const MouseEventWithHitTestResults& event)
// reset. Hence, need to check if this particular drag operation can
// continue even if dispatchEvent() indicates no (direct) cancellation.
// Do that by checking if m_dragSrc is still set.
- m_mouseDownMayStartDrag = dispatchDragSrcEvent(EventTypeNames::dragstart, m_mouseDown)
+ m_mouseDownMayStartDrag = !dispatchDragSrcEvent(EventTypeNames::dragstart, m_mouseDown)
&& !m_frame->selection().isInPasswordField() && dragState().m_dragSrc;
// Invalidate clipboard here against anymore pasteboard writing for security. The drag
@@ -3554,44 +3628,6 @@ void EventHandler::updateLastScrollbarUnderMouse(Scrollbar* scrollbar, bool setL
}
}
-static const AtomicString& touchEventNameForTouchPointState(PlatformTouchPoint::State state)
-{
- switch (state) {
- case PlatformTouchPoint::TouchReleased:
- return EventTypeNames::touchend;
- case PlatformTouchPoint::TouchCancelled:
- return EventTypeNames::touchcancel;
- case PlatformTouchPoint::TouchPressed:
- return EventTypeNames::touchstart;
- case PlatformTouchPoint::TouchMoved:
- return EventTypeNames::touchmove;
- case PlatformTouchPoint::TouchStationary:
- // Fall through to default
- default:
- ASSERT_NOT_REACHED();
- return emptyAtom;
- }
-}
-
-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:
- // Fall through to default
- default:
- ASSERT_NOT_REACHED();
- return emptyAtom;
- }
-}
-
HitTestResult EventHandler::hitTestResultInFrame(LocalFrame* frame, const LayoutPoint& point, HitTestRequest::HitTestRequestType hitType)
{
HitTestResult result(HitTestRequest(hitType), point);
@@ -3607,9 +3643,12 @@ HitTestResult EventHandler::hitTestResultInFrame(LocalFrame* frame, const Layout
return result;
}
-void EventHandler::dispatchPointerEventsForTouchEvent(const PlatformTouchEvent& event,
+void EventHandler::dispatchPointerEvents(const PlatformTouchEvent& event,
WillBeHeapVector<TouchInfo>& touchInfos)
{
+ if (!RuntimeEnabledFeatures::pointerEventEnabled())
+ return;
+
// Iterate through the touch points, sending PointerEvents to the targets as required.
for (unsigned i = 0; i < touchInfos.size(); ++i) {
TouchInfo& touchInfo = touchInfos[i];
@@ -3645,6 +3684,9 @@ void EventHandler::dispatchPointerEventsForTouchEvent(const PlatformTouchEvent&
void EventHandler::sendPointerCancels(WillBeHeapVector<TouchInfo>& touchInfos)
{
+ if (!RuntimeEnabledFeatures::pointerEventEnabled())
+ return;
+
for (unsigned i = 0; i < touchInfos.size(); ++i) {
TouchInfo& touchInfo = touchInfos[i];
const PlatformTouchPoint& point = touchInfo.point;
@@ -3941,14 +3983,12 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
touchInfo.consumed = false;
}
- if (RuntimeEnabledFeatures::pointerEventEnabled()) {
- if (!m_inPointerCanceledState) {
- dispatchPointerEventsForTouchEvent(event, touchInfos);
- // Note that the disposition of any pointer events affects only the generation of touch
- // events. If all pointer events were handled (and hence no touch events were fired), that
- // is still equivalent to the touch events going unhandled because pointer event handler
- // don't block scroll gesture generation.
- }
+ if (!m_inPointerCanceledState) {
+ dispatchPointerEvents(event, touchInfos);
+ // Note that the disposition of any pointer events affects only the generation of touch
+ // events. If all pointer events were handled (and hence no touch events were fired), that
+ // is still equivalent to the touch events going unhandled because pointer event handler
+ // don't block scroll gesture generation.
}
// TODO(crbug.com/507408): If PE handlers always call preventDefault, we won't see TEs until after
@@ -3958,17 +3998,15 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
bool swallowedTouchEvent = dispatchTouchEvents(event, touchInfos, freshTouchEvents,
allTouchReleased);
- if (RuntimeEnabledFeatures::pointerEventEnabled()) {
- if (!m_inPointerCanceledState) {
- // Check if we need to stop firing pointer events because of a touch action.
- // See: www.w3.org/TR/pointerevents/#declaring-candidate-regions-for-default-touch-behaviors
- if (event.causesScrollingIfUncanceled() && !swallowedTouchEvent) {
- m_inPointerCanceledState = true;
- sendPointerCancels(touchInfos);
- }
- } else if (allTouchReleased) {
- m_inPointerCanceledState = false;
+ if (!m_inPointerCanceledState) {
+ // Check if we need to stop firing pointer events because of a touch action.
+ // See: www.w3.org/TR/pointerevents/#declaring-candidate-regions-for-default-touch-behaviors
+ if (event.causesScrollingIfUncanceled() && !swallowedTouchEvent) {
+ m_inPointerCanceledState = true;
+ sendPointerCancels(touchInfos);
}
+ } else if (allTouchReleased) {
+ m_inPointerCanceledState = false;
}
return swallowedTouchEvent;
« no previous file with comments | « third_party/WebKit/Source/core/input/EventHandler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698