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

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

Issue 2147263003: Send got/lostpointercapture immediately if possible (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 4 years, 5 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 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

Powered by Google App Engine
This is Rietveld 408576698