Chromium Code Reviews| Index: third_party/WebKit/Source/core/input/PointerEventManager.cpp |
| diff --git a/third_party/WebKit/Source/core/input/PointerEventManager.cpp b/third_party/WebKit/Source/core/input/PointerEventManager.cpp |
| index 7e47ca1262db223305a146c552435bad1dd47e56..4422b3498bc3caff965beb8ec904a54da69b7412 100644 |
| --- a/third_party/WebKit/Source/core/input/PointerEventManager.cpp |
| +++ b/third_party/WebKit/Source/core/input/PointerEventManager.cpp |
| @@ -46,7 +46,7 @@ WebInputEventResult dispatchMouseEvent( |
| { |
| RefPtrWillBeRawPtr<EventTarget> target = prpTarget; |
| RefPtrWillBeRawPtr<EventTarget> relatedTarget = prpRelatedTarget; |
| - if (target->toNode() |
| + if (target && target->toNode() |
| && (!checkForListener || target->hasEventListeners(mouseEventType))) { |
| RefPtrWillBeRawPtr<Node> targetNode = target->toNode(); |
| RefPtrWillBeRawPtr<MouseEvent> event = MouseEvent::create(mouseEventType, |
| @@ -68,6 +68,9 @@ WebInputEventResult PointerEventManager::dispatchPointerEvent( |
| RefPtrWillBeRawPtr<EventTarget> target = prpTarget; |
| RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent; |
| + if (!target) |
| + return WebInputEventResult::NotHandled; |
| + |
| // Set whether node under pointer has received pointerover or not. |
| const int pointerId = pointerEvent->pointerId(); |
| const AtomicString& eventType = pointerEvent->type(); |
| @@ -83,19 +86,6 @@ WebInputEventResult PointerEventManager::dispatchPointerEvent( |
| } |
| } |
| - // TODO(crbug.com/587955): The following is a hack to work around this bug |
| - if (pointerId == 1) { |
| - if (eventType == EventTypeNames::pointerover) { |
| - m_nodeUnderPointer.set(pointerId, EventTargetAttributes |
| - (target, true)); |
| - } |
| - if (eventType == EventTypeNames::pointerout |
| - && m_nodeUnderPointer.get(pointerId).target == target) { |
| - m_nodeUnderPointer.set(pointerId, EventTargetAttributes |
| - (target, false)); |
| - } |
| - } |
| - |
| if (!RuntimeEnabledFeatures::pointerEventEnabled()) |
| return WebInputEventResult::NotHandled; |
| if (!checkForListener || target->hasEventListeners(eventType)) { |
| @@ -118,18 +108,24 @@ void PointerEventManager::sendNodeTransitionEvents( |
| PassRefPtrWillBeRawPtr<Node> prpExitedNode, |
| PassRefPtrWillBeRawPtr<Node> prpEnteredNode, |
| const PlatformMouseEvent& mouseEvent, |
| - PassRefPtrWillBeRawPtr<AbstractView> view) |
| + PassRefPtrWillBeRawPtr<AbstractView> view, |
| + bool isFrameBoundaryTransition) |
| { |
| RefPtrWillBeRawPtr<Node> exitedNode = prpExitedNode; |
| RefPtrWillBeRawPtr<Node> enteredNode = prpEnteredNode; |
| + |
| + // Pointer event type does not matter as it will be overridden in the sendNodeTransitionEvents |
| RefPtrWillBeRawPtr<PointerEvent> pointerEvent = |
| m_pointerEventFactory.create(EventTypeNames::mouseout, mouseEvent, |
| nullptr, view); |
| - processPendingPointerCapture(pointerEvent, enteredNode, mouseEvent, true); |
| - // Pointer event type does not matter as it will be overridden in the sendNodeTransitionEvents |
| - sendNodeTransitionEvents(exitedNode, enteredNode, pointerEvent, mouseEvent, |
| - true); |
| + // TODO(crbug/545647): This state should reset with pointercancel too. |
| + if (isFrameBoundaryTransition && pointerEvent->buttons() == 0) { |
| + m_preventMouseEventForPointerTypeMouse = false; |
| + } |
| + |
| + prepareForFiringPointerEvent(pointerEvent, enteredNode, |
| + exitedNode, mouseEvent, true, isFrameBoundaryTransition); |
| } |
| void PointerEventManager::sendNodeTransitionEvents( |
| @@ -141,6 +137,7 @@ void PointerEventManager::sendNodeTransitionEvents( |
| RefPtrWillBeRawPtr<EventTarget> exitedTarget = prpExitedTarget; |
| RefPtrWillBeRawPtr<EventTarget> enteredTarget = prpEnteredTarget; |
| RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent; |
| + |
| if (exitedTarget == enteredTarget) |
| return; |
| @@ -155,9 +152,10 @@ void PointerEventManager::sendNodeTransitionEvents( |
| // Dispatch pointerout/mouseout events |
| if (isInDocument(exitedTarget)) { |
| - dispatchPointerEvent(exitedTarget, m_pointerEventFactory.createPointerTransitionEvent( |
| - pointerEvent, EventTypeNames::pointerout, enteredTarget)); |
| - if (sendMouseEvent) { |
| + if (!sendMouseEvent) { |
| + dispatchPointerEvent(exitedTarget, m_pointerEventFactory.createPointerTransitionEvent( |
| + pointerEvent, EventTypeNames::pointerout, enteredTarget)); |
| + } else { |
| dispatchMouseEvent(exitedTarget, |
| EventTypeNames::mouseout, mouseEvent, enteredTarget); |
| } |
| @@ -221,11 +219,12 @@ void PointerEventManager::sendNodeTransitionEvents( |
| // Dispatch pointerleave/mouseleave events, in child-to-parent order. |
| for (size_t j = 0; j < exitedAncestorIndex; j++) { |
| - dispatchPointerEvent(exitedAncestors[j].get(), |
| - m_pointerEventFactory.createPointerTransitionEvent( |
| - pointerEvent, EventTypeNames::pointerleave, enteredTarget), |
| - !exitedNodeHasCapturingAncestor); |
| - if (sendMouseEvent) { |
| + if (!sendMouseEvent) { |
| + dispatchPointerEvent(exitedAncestors[j].get(), |
| + m_pointerEventFactory.createPointerTransitionEvent( |
| + pointerEvent, EventTypeNames::pointerleave, enteredTarget), |
| + !exitedNodeHasCapturingAncestor); |
| + } else { |
| dispatchMouseEvent(exitedAncestors[j].get(), |
| EventTypeNames::mouseleave, mouseEvent, enteredTarget, |
| 0, !exitedNodeHasCapturingAncestor); |
| @@ -234,9 +233,10 @@ void PointerEventManager::sendNodeTransitionEvents( |
| // Dispatch pointerover/mouseover. |
| if (isInDocument(enteredTarget)) { |
| - dispatchPointerEvent(enteredTarget, m_pointerEventFactory.createPointerTransitionEvent( |
| - pointerEvent, EventTypeNames::pointerover, exitedTarget)); |
| - if (sendMouseEvent) { |
| + if (!sendMouseEvent) { |
| + dispatchPointerEvent(enteredTarget, m_pointerEventFactory.createPointerTransitionEvent( |
| + pointerEvent, EventTypeNames::pointerover, exitedTarget)); |
| + } else { |
| dispatchMouseEvent(enteredTarget, |
| EventTypeNames::mouseover, mouseEvent, exitedTarget); |
| } |
| @@ -254,11 +254,12 @@ void PointerEventManager::sendNodeTransitionEvents( |
| // Dispatch pointerenter/mouseenter events, in parent-to-child order. |
| for (size_t i = enteredAncestorIndex; i > 0; i--) { |
| - dispatchPointerEvent(enteredAncestors[i-1].get(), |
| - m_pointerEventFactory.createPointerTransitionEvent( |
| - pointerEvent, EventTypeNames::pointerenter, exitedTarget), |
| - !enteredNodeHasCapturingAncestor); |
| - if (sendMouseEvent) { |
| + if (!sendMouseEvent) { |
| + dispatchPointerEvent(enteredAncestors[i-1].get(), |
| + m_pointerEventFactory.createPointerTransitionEvent( |
| + pointerEvent, EventTypeNames::pointerenter, exitedTarget), |
| + !enteredNodeHasCapturingAncestor); |
| + } else { |
| dispatchMouseEvent(enteredAncestors[i-1].get(), |
| EventTypeNames::mouseenter, mouseEvent, exitedTarget, |
| 0, !enteredNodeHasCapturingAncestor); |
| @@ -268,7 +269,8 @@ void PointerEventManager::sendNodeTransitionEvents( |
| void PointerEventManager::setNodeUnderPointer( |
| PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent, |
| - PassRefPtrWillBeRawPtr<EventTarget> prpTarget) |
| + PassRefPtrWillBeRawPtr<EventTarget> prpTarget, |
| + bool sendEvent) |
| { |
| RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent; |
| RefPtrWillBeRawPtr<EventTarget> target = prpTarget; |
| @@ -282,11 +284,13 @@ void PointerEventManager::setNodeUnderPointer( |
| m_nodeUnderPointer.set(pointerEvent->pointerId(), |
| EventTargetAttributes(target, false)); |
| } |
| - sendNodeTransitionEvents(node.target, target, pointerEvent); |
| + if (sendEvent) |
| + sendNodeTransitionEvents(node.target, target, pointerEvent); |
| } else if (target) { |
| m_nodeUnderPointer.add(pointerEvent->pointerId(), |
| EventTargetAttributes(target, false)); |
| - sendNodeTransitionEvents(nullptr, target, pointerEvent); |
| + if (sendEvent) |
| + sendNodeTransitionEvents(nullptr, target, pointerEvent); |
| } |
| } |
| @@ -295,7 +299,8 @@ void PointerEventManager::sendTouchCancelPointerEvent(PassRefPtrWillBeRawPtr<Eve |
| RefPtrWillBeRawPtr<EventTarget> target = prpTarget; |
| RefPtrWillBeRawPtr<PointerEvent> pointerEvent = m_pointerEventFactory.createPointerCancelEvent(point); |
| - processPendingPointerCapture(pointerEvent, target); |
| + |
| + prepareForFiringPointerEvent(pointerEvent, target); |
| // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing vs pointer event capturing |
| dispatchPointerEvent( |
| @@ -320,9 +325,7 @@ WebInputEventResult PointerEventManager::sendTouchPointerEvent( |
| pointerEventNameForTouchPointState(touchPoint.state()), |
| touchPoint, modifiers, width, height, clientX, clientY); |
| - processPendingPointerCapture(pointerEvent, target); |
| - |
| - setNodeUnderPointer(pointerEvent, target); |
| + prepareForFiringPointerEvent(pointerEvent, target); |
| // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing vs pointer event capturing |
| WebInputEventResult result = dispatchPointerEvent( |
| @@ -342,18 +345,22 @@ WebInputEventResult PointerEventManager::sendMousePointerEvent( |
| PassRefPtrWillBeRawPtr<Node> prpTarget, const AtomicString& mouseEventType, |
| int clickCount, const PlatformMouseEvent& mouseEvent, |
| PassRefPtrWillBeRawPtr<Node> relatedTarget, |
| - PassRefPtrWillBeRawPtr<AbstractView> view) |
| + PassRefPtrWillBeRawPtr<AbstractView> view, |
| + PassRefPtrWillBeRawPtr<Node> lastNodeUnderMouse) |
| { |
| RefPtrWillBeRawPtr<Node> target = prpTarget; |
| + |
| RefPtrWillBeRawPtr<PointerEvent> pointerEvent = |
| m_pointerEventFactory.create(mouseEventType, mouseEvent, |
| relatedTarget, view); |
| - processPendingPointerCapture(pointerEvent, target, mouseEvent, true); |
| + if (pointerEvent->type() == EventTypeNames::pointermove |
| + && !pointerEvent->buttons()) { |
| + m_preventMouseEventForPointerTypeMouse = false; |
|
mustaq
2016/03/22 15:28:43
Resetting m_preventMouseEventForPointerTypeMouse t
Navid Zolghadr
2016/03/22 18:00:24
Following our discussion offline, this is still ne
|
| + } |
| - // TODO(crbug.com/587955): We should call setNodeUnderPointer here but it causes sending |
| - // transition events that should be first removed from EventHandler. |
| - // setNodeUnderPointer(pointerEvent, target); |
| + prepareForFiringPointerEvent(pointerEvent, target, |
| + lastNodeUnderMouse, mouseEvent, true, true); |
|
mustaq
2016/03/22 15:28:43
I guess this is okay to pass the PassRefPtr lastNo
Navid Zolghadr
2016/03/22 18:00:24
I believe you are right. I remember I was told tha
|
| RefPtrWillBeRawPtr<EventTarget> effectiveTarget = |
| getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()); |
| @@ -371,8 +378,10 @@ WebInputEventResult PointerEventManager::sendMousePointerEvent( |
| nullptr, clickCount)); |
| } |
| - if (pointerEvent->buttons() == 0) |
| + if (pointerEvent->buttons() == 0) { |
| releasePointerCapture(pointerEvent->pointerId()); |
| + m_preventMouseEventForPointerTypeMouse = false; |
| + } |
| return result; |
| } |
| @@ -393,16 +402,31 @@ void PointerEventManager::clear() |
| m_nodeUnderPointer.clear(); |
| } |
| -void PointerEventManager::conditionallyEnableMouseEventForPointerTypeMouse( |
| - unsigned modifiers) |
| +void PointerEventManager::prepareForFiringPointerEvent( |
|
mustaq
2016/03/22 15:28:43
Please consider a more specific name here. Also ad
Navid Zolghadr
2016/03/22 18:00:24
I used processCaptureAndPositionOfPointerEvent. Is
mustaq
2016/03/23 18:49:07
Yes, thanks. Is |updateCaptureAndPosition| better?
|
| + const PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent, |
| + const PassRefPtrWillBeRawPtr<EventTarget> prpHitTestTarget, |
| + const PassRefPtrWillBeRawPtr<EventTarget> lastNodeUnderMouse, |
| + const PlatformMouseEvent& mouseEvent, |
| + bool sendMouseEvent, bool isFrameBoundaryTransition) |
| { |
| - |
| - if (MouseEvent::platformModifiersToButtons(modifiers) == |
| - static_cast<unsigned short>(MouseEvent::Buttons::None)) |
| - m_preventMouseEventForPointerTypeMouse = false; |
| + RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent; |
| + RefPtrWillBeRawPtr<EventTarget> hitTestTarget = prpHitTestTarget; |
| + bool isCaptureChanged = processPendingPointerCapture(pointerEvent, |
| + hitTestTarget, mouseEvent, sendMouseEvent); |
| + if (isFrameBoundaryTransition) { |
| + // If there was a change in capturing processPendingPointerCapture has |
| + // already taken care of transition events. So we don't need to send the |
| + // transition events here. |
| + setNodeUnderPointer(pointerEvent, hitTestTarget, !isCaptureChanged); |
| + } |
| + if (sendMouseEvent && !isCaptureChanged) { |
| + // lastNodeUnderMouse is needed here because it is still stored in EventHandler. |
| + sendNodeTransitionEvents(lastNodeUnderMouse, hitTestTarget, |
| + pointerEvent, mouseEvent, true); |
| + } |
| } |
| -void PointerEventManager::processPendingPointerCapture( |
| +bool PointerEventManager::processPendingPointerCapture( |
| const PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent, |
| const PassRefPtrWillBeRawPtr<EventTarget> prpHitTestTarget, |
| const PlatformMouseEvent& mouseEvent, bool sendMouseEvent) |
| @@ -419,10 +443,19 @@ void PointerEventManager::processPendingPointerCapture( |
| const EventTargetAttributes &nodeUnderPointerAtt = |
| m_nodeUnderPointer.contains(pointerId) |
| ? m_nodeUnderPointer.get(pointerId) : EventTargetAttributes(); |
| + const bool isCaptureChanged = |
| + pointerCaptureTarget != pendingPointerCaptureTarget; |
| - if (pointerCaptureTarget != pendingPointerCaptureTarget) { |
| - if (pendingPointerCaptureTarget != nodeUnderPointerAtt.target |
| + if (isCaptureChanged) { |
| + if ((hitTestTarget != nodeUnderPointerAtt.target |
| + || pendingPointerCaptureTarget != nodeUnderPointerAtt.target) |
| && nodeUnderPointerAtt.hasRecievedOverEvent) { |
| + if (sendMouseEvent) { |
| + // Send pointer event transitions as the line after this if |
| + // block sends the mouse events |
| + sendNodeTransitionEvents(nodeUnderPointerAtt.target, nullptr, |
| + pointerEvent); |
| + } |
| sendNodeTransitionEvents(nodeUnderPointerAtt.target, nullptr, |
| pointerEvent, mouseEvent, sendMouseEvent); |
| } |
| @@ -434,11 +467,9 @@ void PointerEventManager::processPendingPointerCapture( |
| && !target->toNode()->inDocument()) { |
| target = target->toNode()->ownerDocument(); |
| } |
| - if (target) { |
| - dispatchPointerEvent(target, |
| - m_pointerEventFactory.createPointerCaptureEvent( |
| - pointerEvent, EventTypeNames::lostpointercapture)); |
| - } |
| + dispatchPointerEvent(target, |
| + m_pointerEventFactory.createPointerCaptureEvent( |
| + pointerEvent, EventTypeNames::lostpointercapture)); |
| } |
| } |
| @@ -451,20 +482,24 @@ void PointerEventManager::processPendingPointerCapture( |
| else |
| m_pointerCaptureTarget.remove(pointerId); |
| - if (pointerCaptureTarget != pendingPointerCaptureTarget) { |
| - if (pendingPointerCaptureTarget) { |
| - dispatchPointerEvent(pendingPointerCaptureTarget, |
| - m_pointerEventFactory.createPointerCaptureEvent( |
| - pointerEvent, EventTypeNames::gotpointercapture)); |
| - } |
| + if (isCaptureChanged) { |
| + dispatchPointerEvent(pendingPointerCaptureTarget, |
| + m_pointerEventFactory.createPointerCaptureEvent( |
| + pointerEvent, EventTypeNames::gotpointercapture)); |
| if ((pendingPointerCaptureTarget == hitTestTarget |
| || !pendingPointerCaptureTarget) |
| && (nodeUnderPointerAtt.target != hitTestTarget |
| || !nodeUnderPointerAtt.hasRecievedOverEvent)) { |
| + if (sendMouseEvent) { |
| + // Send pointer event transitions as the line after this if |
| + // block sends the mouse events |
| + sendNodeTransitionEvents(nullptr, hitTestTarget, pointerEvent); |
| + } |
| sendNodeTransitionEvents(nullptr, hitTestTarget, pointerEvent, |
| mouseEvent, sendMouseEvent); |
| } |
| } |
| + return isCaptureChanged; |
| } |
| void PointerEventManager::removeTargetFromPointerCapturingMapping( |