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 c3cb5b770a9521f9937ea289373426c9127a9dcf..b5ce0949f095f7dacb8d7f2c893df88dd3169161 100644 |
| --- a/third_party/WebKit/Source/core/input/PointerEventManager.cpp |
| +++ b/third_party/WebKit/Source/core/input/PointerEventManager.cpp |
| @@ -5,6 +5,7 @@ |
| #include "core/input/PointerEventManager.h" |
| #include "core/dom/ElementTraversal.h" |
| +#include "core/dom/ExecutionContextTask.h" |
| #include "core/dom/shadow/FlatTreeTraversal.h" |
| #include "core/events/MouseEvent.h" |
| #include "core/frame/FrameView.h" |
| @@ -612,6 +613,25 @@ void PointerEventManager::clear() |
| m_pendingPointerCaptureTarget.clear(); |
| } |
| +bool PointerEventManager::getPointerCaptureState(int pointerId, |
| + EventTarget** pointerCaptureTarget, |
| + EventTarget** pendingPointerCaptureTarget) |
| +{ |
| + EventTarget* pct = m_pointerCaptureTarget.contains(pointerId) |
|
Rick Byers
2016/07/15 17:35:32
nit: HashMap::find is the efficient way to do cont
Navid Zolghadr
2016/07/15 20:41:01
Done.
|
| + ? m_pointerCaptureTarget.get(pointerId) |
| + : nullptr; |
| + EventTarget* ppct = m_pendingPointerCaptureTarget.contains(pointerId) |
| + ? m_pendingPointerCaptureTarget.get(pointerId) |
| + : nullptr; |
| + |
| + if (pointerCaptureTarget) |
| + *pointerCaptureTarget = pct; |
| + if (pendingPointerCaptureTarget) |
| + *pendingPointerCaptureTarget = ppct; |
| + |
| + return pct != ppct; |
| +} |
| + |
| void PointerEventManager::processCaptureAndPositionOfPointerEvent( |
| PointerEvent* pointerEvent, |
| EventTarget* hitTestTarget, |
| @@ -636,23 +656,54 @@ void PointerEventManager::processCaptureAndPositionOfPointerEvent( |
| } |
| } |
| +void PointerEventManager::immediateProcessPendingPointerCapture(int pointerId) |
|
mustaq
2016/07/15 19:35:43
Nit: s/immediate/immediately/
Navid Zolghadr
2016/07/15 20:41:01
Done.
|
| +{ |
| + EventTarget* pointerCaptureTarget; |
| + EventTarget* pendingPointerCaptureTarget; |
| + const bool isCaptureChanged = getPointerCaptureState(pointerId, |
| + &pointerCaptureTarget, &pendingPointerCaptureTarget); |
| + |
| + if (!isCaptureChanged) |
| + return; |
| + |
| + if (pointerCaptureTarget) { |
| + // Re-target lostpointercapture to the document when the element is |
|
Rick Byers
2016/07/15 17:35:32
is this behavior specified somewhere? It seems re
Navid Zolghadr
2016/07/15 20:41:01
Yes. It is here the second paragraph.
https://w3c.
|
| + // no longer participating in the tree. |
| + EventTarget* target = pointerCaptureTarget; |
| + if (target->toNode() |
| + && !target->toNode()->inShadowIncludingDocument()) { |
| + target = target->toNode()->ownerDocument(); |
| + } |
| + dispatchPointerEvent(target, |
| + m_pointerEventFactory.createPointerCaptureEvent( |
| + pointerId, EventTypeNames::lostpointercapture)); |
| + } |
| + dispatchPointerEvent(pendingPointerCaptureTarget, |
|
Rick Byers
2016/07/15 17:35:32
Don't you need to check for null here too - eg. fo
mustaq
2016/07/15 19:35:43
Yes, pendingPointerCaptureTarget would be null aft
Navid Zolghadr
2016/07/15 20:41:01
Since there was a lot of those checks around every
|
| + m_pointerEventFactory.createPointerCaptureEvent( |
| + pointerId, EventTypeNames::gotpointercapture)); |
| + |
| + // Setting |m_pointerCaptureTarget| comes at the end to prevent the infinite |
| + // loop if js calls set/releasepointercapture in got/lostpointercapture |
| + // handlers. |
| + if (pendingPointerCaptureTarget) |
| + m_pointerCaptureTarget.set(pointerId, pendingPointerCaptureTarget); |
| + else |
| + m_pointerCaptureTarget.remove(pointerId); |
| +} |
| + |
| bool PointerEventManager::processPendingPointerCapture( |
|
Rick Byers
2016/07/15 17:35:31
once we make the other changes here (eg. not firin
Navid Zolghadr
2016/07/15 20:41:01
That is correct. I added the TODO.
mustaq
2016/07/15 21:06:14
"Not firing the boundary events": we still need to
|
| PointerEvent* pointerEvent, |
| EventTarget* hitTestTarget, |
| const PlatformMouseEvent& mouseEvent, bool sendMouseEvent) |
| { |
| int pointerId = pointerEvent->pointerId(); |
| - EventTarget* pointerCaptureTarget = |
| - m_pointerCaptureTarget.contains(pointerId) |
| - ? m_pointerCaptureTarget.get(pointerId) : nullptr; |
| - EventTarget* pendingPointerCaptureTarget = |
| - m_pendingPointerCaptureTarget.contains(pointerId) |
| - ? m_pendingPointerCaptureTarget.get(pointerId) : nullptr; |
| + EventTarget* pointerCaptureTarget; |
| + EventTarget* pendingPointerCaptureTarget; |
| + const bool isCaptureChanged = getPointerCaptureState(pointerId, |
| + &pointerCaptureTarget, &pendingPointerCaptureTarget); |
| const EventTargetAttributes &nodeUnderPointerAtt = |
| m_nodeUnderPointer.contains(pointerId) |
| ? m_nodeUnderPointer.get(pointerId) : EventTargetAttributes(); |
| - const bool isCaptureChanged = |
| - pointerCaptureTarget != pendingPointerCaptureTarget; |
| if (isCaptureChanged) { |
| if ((hitTestTarget != nodeUnderPointerAtt.target |
| @@ -678,7 +729,7 @@ bool PointerEventManager::processPendingPointerCapture( |
| } |
| dispatchPointerEvent(target, |
| m_pointerEventFactory.createPointerCaptureEvent( |
| - pointerEvent, EventTypeNames::lostpointercapture)); |
| + pointerId, EventTypeNames::lostpointercapture)); |
| } |
| } |
| @@ -694,7 +745,7 @@ bool PointerEventManager::processPendingPointerCapture( |
| if (isCaptureChanged) { |
| dispatchPointerEvent(pendingPointerCaptureTarget, |
| m_pointerEventFactory.createPointerCaptureEvent( |
| - pointerEvent, EventTypeNames::gotpointercapture)); |
| + pointerId, EventTypeNames::gotpointercapture)); |
| if ((pendingPointerCaptureTarget == hitTestTarget |
| || !pendingPointerCaptureTarget) |
| && (nodeUnderPointerAtt.target != hitTestTarget |
| @@ -751,8 +802,20 @@ void PointerEventManager::elementRemoved(EventTarget* target) |
| void PointerEventManager::setPointerCapture(int pointerId, EventTarget* target) |
|
mustaq
2016/07/15 19:35:43
It's not clear to me what happens in case of a jan
Navid Zolghadr
2016/07/15 20:41:01
Nothing I guess. Actually before we fire every poi
|
| { |
| UseCounter::count(m_frame->document(), UseCounter::PointerEventSetCapture); |
| - if (m_pointerEventFactory.isActiveButtonsState(pointerId)) |
| + if (m_pointerEventFactory.isActiveButtonsState(pointerId)) { |
| + bool wasCaptureStationary = !getPointerCaptureState(pointerId, nullptr, nullptr); |
| m_pendingPointerCaptureTarget.set(pointerId, target); |
| + // Only queue the processing pending pointer capture if the pending |
|
Rick Byers
2016/07/15 17:35:32
nit: Add a comment referencing the github issue wh
Navid Zolghadr
2016/07/15 20:41:01
Done.
|
| + // capture target and capture target were the same to prevent infinite |
| + // got/lostpointercapture event sequence. |
| + if (wasCaptureStationary) { |
| + m_frame->document()->getExecutionContext()->postTask( |
|
Rick Byers
2016/07/15 17:35:31
Looking at this more, I think you probably should
Navid Zolghadr
2016/07/15 20:41:01
Done.
|
| + BLINK_FROM_HERE, |
| + createSameThreadTask( |
| + &PointerEventManager::immediateProcessPendingPointerCapture, |
| + WTF::unretained(this), pointerId)); |
| + } |
| + } |
| } |
| void PointerEventManager::releasePointerCapture(int pointerId, EventTarget* target) |
| @@ -770,7 +833,18 @@ void PointerEventManager::releasePointerCapture(int pointerId, EventTarget* targ |
| void PointerEventManager::releasePointerCapture(int pointerId) |
| { |
| + bool wasCaptureStationary = !getPointerCaptureState(pointerId, nullptr, nullptr); |
| m_pendingPointerCaptureTarget.remove(pointerId); |
| + // Only queue the processing pending pointer capture if the pending |
|
Rick Byers
2016/07/15 17:35:32
please avoid copy/paste - share this code
Navid Zolghadr
2016/07/15 20:41:01
Done.
|
| + // capture target and capture target were the same to prevent infinite |
| + // got/lostpointercapture event sequence. |
| + if (wasCaptureStationary) { |
| + m_frame->document()->getExecutionContext()->postTask( |
| + BLINK_FROM_HERE, |
| + createSameThreadTask( |
| + &PointerEventManager::immediateProcessPendingPointerCapture, |
| + WTF::unretained(this), pointerId)); |
| + } |
| } |
| bool PointerEventManager::isActive(const int pointerId) const |