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

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

Issue 1774913004: Firing got/lost pointer capture events (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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
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 3ae14e61187fa7b9a7916fb8f9338dd2a3585e76..01782a8c6f072b7461130a07d66e41d45411bd68 100644
--- a/third_party/WebKit/Source/core/input/PointerEventManager.cpp
+++ b/third_party/WebKit/Source/core/input/PointerEventManager.cpp
@@ -69,21 +69,29 @@ WebInputEventResult PointerEventManager::dispatchPointerEvent(
RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent;
// Set whether node under pointer has received pointerover or not.
- int pointerId = pointerEvent->pointerId();
- if ((pointerEvent->type() == EventTypeNames::pointerout
- || pointerEvent->type() == EventTypeNames::pointerover)
+ const int pointerId = pointerEvent->pointerId();
+ const AtomicString& pointerType = pointerEvent->type();
+ if ((pointerType == EventTypeNames::pointerout
+ || pointerType == EventTypeNames::pointerover)
&& m_nodeUnderPointer.contains(pointerId)) {
RefPtrWillBeRawPtr<EventTarget> targetUnderPointer =
m_nodeUnderPointer.get(pointerId).target;
if (targetUnderPointer == target) {
m_nodeUnderPointer.set(pointerId, EventTargetAttributes
(targetUnderPointer,
- pointerEvent->type() == EventTypeNames::pointerover));
+ pointerType == EventTypeNames::pointerover));
}
}
+
+ // TODO(crbug.com/587955): The following if is a hack to work around this bug
mustaq 2016/03/10 19:28:19 nit: remove "if"
Navid Zolghadr 2016/03/10 20:27:35 Sure.
+ if (pointerType == EventTypeNames::pointerover && pointerId == 1) {
+ m_nodeUnderPointer.set(pointerId, EventTargetAttributes
+ (target, true));
+ }
mustaq 2016/03/10 19:28:19 This deserves a comment: why not resetting the bit
Navid Zolghadr 2016/03/10 20:27:35 Since it was a hack anyways and should be removed
mustaq 2016/03/10 21:06:57 This is significant enough to call for a test. I u
+
if (!RuntimeEnabledFeatures::pointerEventEnabled())
return WebInputEventResult::NotHandled;
- if (!checkForListener || target->hasEventListeners(pointerEvent->type())) {
+ if (!checkForListener || target->hasEventListeners(pointerType)) {
DispatchEventResult dispatchResult = target->dispatchEvent(pointerEvent);
return EventHandler::toWebInputEventResult(dispatchResult);
}
@@ -140,7 +148,7 @@ void PointerEventManager::sendNodeTransitionEvents(
// Dispatch pointerout/mouseout events
if (isInDocument(exitedTarget)) {
- dispatchPointerEvent(exitedTarget, m_pointerEventFactory.create(
+ dispatchPointerEvent(exitedTarget, m_pointerEventFactory.createPointerTransition(
pointerEvent, EventTypeNames::pointerout, enteredTarget));
if (sendMouseEvent) {
dispatchMouseEvent(exitedTarget,
@@ -207,7 +215,7 @@ 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.create(
+ m_pointerEventFactory.createPointerTransition(
pointerEvent, EventTypeNames::pointerleave, enteredTarget),
!exitedNodeHasCapturingAncestor);
if (sendMouseEvent) {
@@ -219,7 +227,7 @@ void PointerEventManager::sendNodeTransitionEvents(
// Dispatch pointerover/mouseover.
if (isInDocument(enteredTarget)) {
- dispatchPointerEvent(enteredTarget, m_pointerEventFactory.create(
+ dispatchPointerEvent(enteredTarget, m_pointerEventFactory.createPointerTransition(
pointerEvent, EventTypeNames::pointerover, exitedTarget));
if (sendMouseEvent) {
dispatchMouseEvent(enteredTarget,
@@ -240,7 +248,7 @@ 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.create(
+ m_pointerEventFactory.createPointerTransition(
pointerEvent, EventTypeNames::pointerenter, exitedTarget),
!enteredNodeHasCapturingAncestor);
if (sendMouseEvent) {
@@ -262,7 +270,8 @@ void PointerEventManager::setNodeUnderPointer(
pointerEvent->pointerId());
if (!target) {
m_nodeUnderPointer.remove(pointerEvent->pointerId());
- } else {
+ } else if (target
+ != m_nodeUnderPointer.get(pointerEvent->pointerId()).target) {
m_nodeUnderPointer.set(pointerEvent->pointerId(),
EventTargetAttributes(target, false));
}
@@ -337,6 +346,7 @@ WebInputEventResult PointerEventManager::sendMousePointerEvent(
// 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);
RefPtrWillBeRawPtr<EventTarget> effectiveTarget =
getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId());
@@ -390,43 +400,64 @@ void PointerEventManager::processPendingPointerCapture(
const PassRefPtrWillBeRawPtr<EventTarget> prpHitTestTarget,
const PlatformMouseEvent& mouseEvent, bool sendMouseEvent)
{
- // TODO(nzolghadr): Process sending got/lostpointercapture
RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent;
RefPtrWillBeRawPtr<EventTarget> hitTestTarget = prpHitTestTarget;
int pointerId = pointerEvent->pointerId();
- bool hasPointerCaptureTarget = m_pointerCaptureTarget.contains(pointerId);
- bool hasPendingPointerCaptureTarget = m_pendingPointerCaptureTarget.contains(pointerId);
const RefPtrWillBeRawPtr<EventTarget> pointerCaptureTarget =
- hasPointerCaptureTarget ? m_pointerCaptureTarget.get(pointerId) : nullptr;
+ m_pointerCaptureTarget.contains(pointerId)
+ ? m_pointerCaptureTarget.get(pointerId) : nullptr;
const RefPtrWillBeRawPtr<EventTarget> pendingPointerCaptureTarget =
- hasPendingPointerCaptureTarget ? m_pendingPointerCaptureTarget.get(pointerId) : nullptr;
-
- if (hasPendingPointerCaptureTarget
- && (pointerCaptureTarget != pendingPointerCaptureTarget)) {
- if (!hasPointerCaptureTarget
- && pendingPointerCaptureTarget != hitTestTarget
- && m_nodeUnderPointer.contains(pointerId)
- && m_nodeUnderPointer.get(pointerId).hasRecievedOverEvent) {
- sendNodeTransitionEvents(hitTestTarget, nullptr, pointerEvent,
- mouseEvent, sendMouseEvent);
+ m_pendingPointerCaptureTarget.contains(pointerId)
+ ? m_pendingPointerCaptureTarget.get(pointerId) : nullptr;
+ const EventTargetAttributes &nodeUnderPointerAtt =
+ m_nodeUnderPointer.contains(pointerId)
+ ? m_nodeUnderPointer.get(pointerId) : EventTargetAttributes();
+
+ if (pointerCaptureTarget != pendingPointerCaptureTarget) {
+ if (pendingPointerCaptureTarget != nodeUnderPointerAtt.target
+ && nodeUnderPointerAtt.hasRecievedOverEvent) {
+ sendNodeTransitionEvents(nodeUnderPointerAtt.target, nullptr,
+ pointerEvent, mouseEvent, sendMouseEvent);
+ }
+ if (pointerCaptureTarget) {
+ // Re-target lostpointercapture to the document when the element is
+ // no longer participating in the tree.
+ EventTarget* target = pointerCaptureTarget.get();
+ if (target->toNode()
+ && !target->toNode()->inDocument()) {
+ target = target->toNode()->ownerDocument();
+ }
+ if (target) {
+ dispatchPointerEvent(target,
+ m_pointerEventFactory.createPointerCapture(
+ pointerEvent, EventTypeNames::lostpointercapture));
+ }
}
}
// Set pointerCaptureTarget from pendingPointerCaptureTarget. This does
// affect the behavior of sendNodeTransitionEvents function. So the
- // ordering of the surrounding blocks of code is important.
- if (!hasPendingPointerCaptureTarget)
- m_pointerCaptureTarget.remove(pointerId);
+ // ordering of the surrounding blocks of code for sending transition events
+ // are important.
+ if (pendingPointerCaptureTarget)
+ m_pointerCaptureTarget.set(pointerId, pendingPointerCaptureTarget);
else
- m_pointerCaptureTarget.set(pointerId, m_pendingPointerCaptureTarget.get(pointerId));
+ m_pointerCaptureTarget.remove(pointerId);
- if (hasPointerCaptureTarget && (pointerCaptureTarget != pendingPointerCaptureTarget)) {
- if (!hasPendingPointerCaptureTarget && pointerCaptureTarget != hitTestTarget) {
+ if (pointerCaptureTarget != pendingPointerCaptureTarget) {
+ if (pendingPointerCaptureTarget) {
+ dispatchPointerEvent(pendingPointerCaptureTarget,
+ m_pointerEventFactory.createPointerCapture(
+ pointerEvent, EventTypeNames::gotpointercapture));
+ }
+ if ((pendingPointerCaptureTarget == hitTestTarget
+ || !pendingPointerCaptureTarget)
+ && (nodeUnderPointerAtt.target != hitTestTarget
+ || !nodeUnderPointerAtt.hasRecievedOverEvent)) {
sendNodeTransitionEvents(nullptr, hitTestTarget, pointerEvent,
mouseEvent, sendMouseEvent);
}
}
-
}
void PointerEventManager::removeTargetFromPointerCapturingMapping(
@@ -464,9 +495,7 @@ void PointerEventManager::removePointer(
void PointerEventManager::elementRemoved(EventTarget* target)
{
- removeTargetFromPointerCapturingMapping(m_pointerCaptureTarget, target);
removeTargetFromPointerCapturingMapping(m_pendingPointerCaptureTarget, target);
- // TODO(nzolghadr): Process sending lostpointercapture to the document
}
void PointerEventManager::setPointerCapture(int pointerId, EventTarget* target)

Powered by Google App Engine
This is Rietveld 408576698