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

Side by Side Diff: third_party/WebKit/Source/core/input/PointerEventManager.cpp

Issue 1809603003: Separate mouse transition events from pointerevent (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Applying the comments 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/input/PointerEventManager.h" 5 #include "core/input/PointerEventManager.h"
6 6
7 #include "core/dom/shadow/FlatTreeTraversal.h" 7 #include "core/dom/shadow/FlatTreeTraversal.h"
8 #include "core/events/MouseEvent.h" 8 #include "core/events/MouseEvent.h"
9 #include "core/input/EventHandler.h" 9 #include "core/input/EventHandler.h"
10 10
(...skipping 28 matching lines...) Expand all
39 WebInputEventResult dispatchMouseEvent( 39 WebInputEventResult dispatchMouseEvent(
40 PassRefPtrWillBeRawPtr<EventTarget> prpTarget, 40 PassRefPtrWillBeRawPtr<EventTarget> prpTarget,
41 const AtomicString& mouseEventType, 41 const AtomicString& mouseEventType,
42 const PlatformMouseEvent& mouseEvent, 42 const PlatformMouseEvent& mouseEvent,
43 PassRefPtrWillBeRawPtr<EventTarget> prpRelatedTarget, 43 PassRefPtrWillBeRawPtr<EventTarget> prpRelatedTarget,
44 int detail = 0, 44 int detail = 0,
45 bool checkForListener = false) 45 bool checkForListener = false)
46 { 46 {
47 RefPtrWillBeRawPtr<EventTarget> target = prpTarget; 47 RefPtrWillBeRawPtr<EventTarget> target = prpTarget;
48 RefPtrWillBeRawPtr<EventTarget> relatedTarget = prpRelatedTarget; 48 RefPtrWillBeRawPtr<EventTarget> relatedTarget = prpRelatedTarget;
49 if (target->toNode() 49 if (target && target->toNode()
50 && (!checkForListener || target->hasEventListeners(mouseEventType))) { 50 && (!checkForListener || target->hasEventListeners(mouseEventType))) {
51 RefPtrWillBeRawPtr<Node> targetNode = target->toNode(); 51 RefPtrWillBeRawPtr<Node> targetNode = target->toNode();
52 RefPtrWillBeRawPtr<MouseEvent> event = MouseEvent::create(mouseEventType , 52 RefPtrWillBeRawPtr<MouseEvent> event = MouseEvent::create(mouseEventType ,
53 targetNode->document().domWindow(), mouseEvent, detail, 53 targetNode->document().domWindow(), mouseEvent, detail,
54 relatedTarget ? relatedTarget->toNode() : nullptr); 54 relatedTarget ? relatedTarget->toNode() : nullptr);
55 DispatchEventResult dispatchResult = target->dispatchEvent(event); 55 DispatchEventResult dispatchResult = target->dispatchEvent(event);
56 return EventHandler::toWebInputEventResult(dispatchResult); 56 return EventHandler::toWebInputEventResult(dispatchResult);
57 } 57 }
58 return WebInputEventResult::NotHandled; 58 return WebInputEventResult::NotHandled;
59 } 59 }
60 60
61 } // namespace 61 } // namespace
62 62
63 WebInputEventResult PointerEventManager::dispatchPointerEvent( 63 WebInputEventResult PointerEventManager::dispatchPointerEvent(
64 PassRefPtrWillBeRawPtr<EventTarget> prpTarget, 64 PassRefPtrWillBeRawPtr<EventTarget> prpTarget,
65 PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent, 65 PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent,
66 bool checkForListener) 66 bool checkForListener)
67 { 67 {
68 RefPtrWillBeRawPtr<EventTarget> target = prpTarget; 68 RefPtrWillBeRawPtr<EventTarget> target = prpTarget;
69 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent; 69 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent;
70 70
71 if (!target)
72 return WebInputEventResult::NotHandled;
73
71 // Set whether node under pointer has received pointerover or not. 74 // Set whether node under pointer has received pointerover or not.
72 const int pointerId = pointerEvent->pointerId(); 75 const int pointerId = pointerEvent->pointerId();
73 const AtomicString& eventType = pointerEvent->type(); 76 const AtomicString& eventType = pointerEvent->type();
74 if ((eventType == EventTypeNames::pointerout 77 if ((eventType == EventTypeNames::pointerout
75 || eventType == EventTypeNames::pointerover) 78 || eventType == EventTypeNames::pointerover)
76 && m_nodeUnderPointer.contains(pointerId)) { 79 && m_nodeUnderPointer.contains(pointerId)) {
77 RefPtrWillBeRawPtr<EventTarget> targetUnderPointer = 80 RefPtrWillBeRawPtr<EventTarget> targetUnderPointer =
78 m_nodeUnderPointer.get(pointerId).target; 81 m_nodeUnderPointer.get(pointerId).target;
79 if (targetUnderPointer == target) { 82 if (targetUnderPointer == target) {
80 m_nodeUnderPointer.set(pointerId, EventTargetAttributes 83 m_nodeUnderPointer.set(pointerId, EventTargetAttributes
81 (targetUnderPointer, 84 (targetUnderPointer,
82 eventType == EventTypeNames::pointerover)); 85 eventType == EventTypeNames::pointerover));
83 } 86 }
84 } 87 }
85 88
86 // TODO(crbug.com/587955): The following is a hack to work around this bug
87 if (pointerId == 1) {
88 if (eventType == EventTypeNames::pointerover) {
89 m_nodeUnderPointer.set(pointerId, EventTargetAttributes
90 (target, true));
91 }
92 if (eventType == EventTypeNames::pointerout
93 && m_nodeUnderPointer.get(pointerId).target == target) {
94 m_nodeUnderPointer.set(pointerId, EventTargetAttributes
95 (target, false));
96 }
97 }
98
99 if (!RuntimeEnabledFeatures::pointerEventEnabled()) 89 if (!RuntimeEnabledFeatures::pointerEventEnabled())
100 return WebInputEventResult::NotHandled; 90 return WebInputEventResult::NotHandled;
101 if (!checkForListener || target->hasEventListeners(eventType)) { 91 if (!checkForListener || target->hasEventListeners(eventType)) {
102 DispatchEventResult dispatchResult = target->dispatchEvent(pointerEvent) ; 92 DispatchEventResult dispatchResult = target->dispatchEvent(pointerEvent) ;
103 return EventHandler::toWebInputEventResult(dispatchResult); 93 return EventHandler::toWebInputEventResult(dispatchResult);
104 } 94 }
105 return WebInputEventResult::NotHandled; 95 return WebInputEventResult::NotHandled;
106 } 96 }
107 97
108 PassRefPtrWillBeRawPtr<EventTarget> PointerEventManager::getEffectiveTargetForPo interEvent( 98 PassRefPtrWillBeRawPtr<EventTarget> PointerEventManager::getEffectiveTargetForPo interEvent(
109 PassRefPtrWillBeRawPtr<EventTarget> target, int pointerId) 99 PassRefPtrWillBeRawPtr<EventTarget> target, int pointerId)
110 { 100 {
111 if (EventTarget* capturingTarget = getCapturingNode(pointerId)) 101 if (EventTarget* capturingTarget = getCapturingNode(pointerId))
112 return capturingTarget; 102 return capturingTarget;
113 return target; 103 return target;
114 } 104 }
115 105
116 // Sends node transition events (pointer|mouse)(out|leave|over|enter) to the cor responding targets 106 void PointerEventManager::sendMouseAndPossiblyPointerNodeTransitionEvents(
117 void PointerEventManager::sendNodeTransitionEvents( 107 PassRefPtrWillBeRawPtr<Node> exitedNode,
118 PassRefPtrWillBeRawPtr<Node> prpExitedNode, 108 PassRefPtrWillBeRawPtr<Node> enteredNode,
119 PassRefPtrWillBeRawPtr<Node> prpEnteredNode,
120 const PlatformMouseEvent& mouseEvent, 109 const PlatformMouseEvent& mouseEvent,
121 PassRefPtrWillBeRawPtr<AbstractView> view) 110 PassRefPtrWillBeRawPtr<AbstractView> view,
111 bool isFrameBoundaryTransition)
122 { 112 {
123 RefPtrWillBeRawPtr<Node> exitedNode = prpExitedNode; 113 // Pointer event type does not matter as it will be overridden in the sendNo deTransitionEvents
124 RefPtrWillBeRawPtr<Node> enteredNode = prpEnteredNode;
125 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = 114 RefPtrWillBeRawPtr<PointerEvent> pointerEvent =
126 m_pointerEventFactory.create(EventTypeNames::mouseout, mouseEvent, 115 m_pointerEventFactory.create(EventTypeNames::mouseout, mouseEvent,
127 nullptr, view); 116 nullptr, view);
128 processPendingPointerCapture(pointerEvent, enteredNode, mouseEvent, true);
129 117
130 // Pointer event type does not matter as it will be overridden in the sendNo deTransitionEvents 118 // TODO(crbug/545647): This state should reset with pointercancel too.
131 sendNodeTransitionEvents(exitedNode, enteredNode, pointerEvent, mouseEvent, 119 // This function also gets called for compat mouse events of touch at this
132 true); 120 // stage. So if the event is not frame boundary transition it is only a
121 // compatibility mouse event and we do not need to change pointer event
122 // behavior regarding preventMouseEvent state in that case.
123 if (isFrameBoundaryTransition && pointerEvent->buttons() == 0) {
124 m_preventMouseEventForPointerTypeMouse = false;
125 }
126
127 processCaptureAndPositionOfPointerEvent(pointerEvent, enteredNode,
128 exitedNode, mouseEvent, true, isFrameBoundaryTransition);
133 } 129 }
134 130
135 void PointerEventManager::sendNodeTransitionEvents( 131 void PointerEventManager::sendNodeTransitionEvents(
136 PassRefPtrWillBeRawPtr<EventTarget> prpExitedTarget, 132 PassRefPtrWillBeRawPtr<EventTarget> prpExitedTarget,
137 PassRefPtrWillBeRawPtr<EventTarget> prpEnteredTarget, 133 PassRefPtrWillBeRawPtr<EventTarget> prpEnteredTarget,
138 PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent, 134 PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent,
139 const PlatformMouseEvent& mouseEvent, bool sendMouseEvent) 135 const PlatformMouseEvent& mouseEvent, bool sendMouseEvent)
140 { 136 {
141 RefPtrWillBeRawPtr<EventTarget> exitedTarget = prpExitedTarget; 137 RefPtrWillBeRawPtr<EventTarget> exitedTarget = prpExitedTarget;
142 RefPtrWillBeRawPtr<EventTarget> enteredTarget = prpEnteredTarget; 138 RefPtrWillBeRawPtr<EventTarget> enteredTarget = prpEnteredTarget;
143 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent; 139 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent;
140
144 if (exitedTarget == enteredTarget) 141 if (exitedTarget == enteredTarget)
145 return; 142 return;
146 143
147 if (EventTarget* capturingTarget = getCapturingNode(pointerEvent->pointerId( ))) { 144 if (EventTarget* capturingTarget = getCapturingNode(pointerEvent->pointerId( ))) {
148 if (capturingTarget == exitedTarget) 145 if (capturingTarget == exitedTarget)
149 enteredTarget = nullptr; 146 enteredTarget = nullptr;
150 else if (capturingTarget == enteredTarget) 147 else if (capturingTarget == enteredTarget)
151 exitedTarget = nullptr; 148 exitedTarget = nullptr;
152 else 149 else
153 return; 150 return;
154 } 151 }
155 152
156 // Dispatch pointerout/mouseout events 153 // Dispatch pointerout/mouseout events
157 if (isInDocument(exitedTarget)) { 154 if (isInDocument(exitedTarget)) {
158 dispatchPointerEvent(exitedTarget, m_pointerEventFactory.createPointerTr ansitionEvent( 155 if (!sendMouseEvent) {
159 pointerEvent, EventTypeNames::pointerout, enteredTarget)); 156 dispatchPointerEvent(exitedTarget, m_pointerEventFactory.createPoint erTransitionEvent(
160 if (sendMouseEvent) { 157 pointerEvent, EventTypeNames::pointerout, enteredTarget));
158 } else {
161 dispatchMouseEvent(exitedTarget, 159 dispatchMouseEvent(exitedTarget,
162 EventTypeNames::mouseout, mouseEvent, enteredTarget); 160 EventTypeNames::mouseout, mouseEvent, enteredTarget);
163 } 161 }
164 } 162 }
165 163
166 // Create lists of all exited/entered ancestors, locate the common ancestor 164 // Create lists of all exited/entered ancestors, locate the common ancestor
167 WillBeHeapVector<RefPtrWillBeMember<Node>, 32> exitedAncestors; 165 WillBeHeapVector<RefPtrWillBeMember<Node>, 32> exitedAncestors;
168 WillBeHeapVector<RefPtrWillBeMember<Node>, 32> enteredAncestors; 166 WillBeHeapVector<RefPtrWillBeMember<Node>, 32> enteredAncestors;
169 if (isInDocument(exitedTarget)) { 167 if (isInDocument(exitedTarget)) {
170 RefPtrWillBeRawPtr<Node> exitedNode = exitedTarget->toNode(); 168 RefPtrWillBeRawPtr<Node> exitedNode = exitedTarget->toNode();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 bool exitedNodeHasCapturingAncestor = false; 212 bool exitedNodeHasCapturingAncestor = false;
215 for (size_t j = 0; j < exitedAncestors.size(); j++) { 213 for (size_t j = 0; j < exitedAncestors.size(); j++) {
216 if (exitedAncestors[j]->hasCapturingEventListeners(EventTypeNames::mouse leave) 214 if (exitedAncestors[j]->hasCapturingEventListeners(EventTypeNames::mouse leave)
217 || (RuntimeEnabledFeatures::pointerEventEnabled() 215 || (RuntimeEnabledFeatures::pointerEventEnabled()
218 && exitedAncestors[j]->hasCapturingEventListeners(EventTypeNames::po interleave))) 216 && exitedAncestors[j]->hasCapturingEventListeners(EventTypeNames::po interleave)))
219 exitedNodeHasCapturingAncestor = true; 217 exitedNodeHasCapturingAncestor = true;
220 } 218 }
221 219
222 // Dispatch pointerleave/mouseleave events, in child-to-parent order. 220 // Dispatch pointerleave/mouseleave events, in child-to-parent order.
223 for (size_t j = 0; j < exitedAncestorIndex; j++) { 221 for (size_t j = 0; j < exitedAncestorIndex; j++) {
224 dispatchPointerEvent(exitedAncestors[j].get(), 222 if (!sendMouseEvent) {
225 m_pointerEventFactory.createPointerTransitionEvent( 223 dispatchPointerEvent(exitedAncestors[j].get(),
226 pointerEvent, EventTypeNames::pointerleave, enteredTarget), 224 m_pointerEventFactory.createPointerTransitionEvent(
227 !exitedNodeHasCapturingAncestor); 225 pointerEvent, EventTypeNames::pointerleave, enteredTarget),
228 if (sendMouseEvent) { 226 !exitedNodeHasCapturingAncestor);
227 } else {
229 dispatchMouseEvent(exitedAncestors[j].get(), 228 dispatchMouseEvent(exitedAncestors[j].get(),
230 EventTypeNames::mouseleave, mouseEvent, enteredTarget, 229 EventTypeNames::mouseleave, mouseEvent, enteredTarget,
231 0, !exitedNodeHasCapturingAncestor); 230 0, !exitedNodeHasCapturingAncestor);
232 } 231 }
233 } 232 }
234 233
235 // Dispatch pointerover/mouseover. 234 // Dispatch pointerover/mouseover.
236 if (isInDocument(enteredTarget)) { 235 if (isInDocument(enteredTarget)) {
237 dispatchPointerEvent(enteredTarget, m_pointerEventFactory.createPointerT ransitionEvent( 236 if (!sendMouseEvent) {
238 pointerEvent, EventTypeNames::pointerover, exitedTarget)); 237 dispatchPointerEvent(enteredTarget, m_pointerEventFactory.createPoin terTransitionEvent(
239 if (sendMouseEvent) { 238 pointerEvent, EventTypeNames::pointerover, exitedTarget));
239 } else {
240 dispatchMouseEvent(enteredTarget, 240 dispatchMouseEvent(enteredTarget,
241 EventTypeNames::mouseover, mouseEvent, exitedTarget); 241 EventTypeNames::mouseover, mouseEvent, exitedTarget);
242 } 242 }
243 } 243 }
244 244
245 // Defer locating capturing pointeenter/mouseenter listener until /after/ di spatching the leave events because 245 // Defer locating capturing pointeenter/mouseenter listener until /after/ di spatching the leave events because
246 // the leave handlers might set a capturing enter handler. 246 // the leave handlers might set a capturing enter handler.
247 bool enteredNodeHasCapturingAncestor = false; 247 bool enteredNodeHasCapturingAncestor = false;
248 for (size_t i = 0; i < enteredAncestors.size(); i++) { 248 for (size_t i = 0; i < enteredAncestors.size(); i++) {
249 if (enteredAncestors[i]->hasCapturingEventListeners(EventTypeNames::mous eenter) 249 if (enteredAncestors[i]->hasCapturingEventListeners(EventTypeNames::mous eenter)
250 || (RuntimeEnabledFeatures::pointerEventEnabled() 250 || (RuntimeEnabledFeatures::pointerEventEnabled()
251 && enteredAncestors[i]->hasCapturingEventListeners(EventTypeNames::p ointerenter))) 251 && enteredAncestors[i]->hasCapturingEventListeners(EventTypeNames::p ointerenter)))
252 enteredNodeHasCapturingAncestor = true; 252 enteredNodeHasCapturingAncestor = true;
253 } 253 }
254 254
255 // Dispatch pointerenter/mouseenter events, in parent-to-child order. 255 // Dispatch pointerenter/mouseenter events, in parent-to-child order.
256 for (size_t i = enteredAncestorIndex; i > 0; i--) { 256 for (size_t i = enteredAncestorIndex; i > 0; i--) {
257 dispatchPointerEvent(enteredAncestors[i-1].get(), 257 if (!sendMouseEvent) {
258 m_pointerEventFactory.createPointerTransitionEvent( 258 dispatchPointerEvent(enteredAncestors[i-1].get(),
259 pointerEvent, EventTypeNames::pointerenter, exitedTarget), 259 m_pointerEventFactory.createPointerTransitionEvent(
260 !enteredNodeHasCapturingAncestor); 260 pointerEvent, EventTypeNames::pointerenter, exitedTarget),
261 if (sendMouseEvent) { 261 !enteredNodeHasCapturingAncestor);
262 } else {
262 dispatchMouseEvent(enteredAncestors[i-1].get(), 263 dispatchMouseEvent(enteredAncestors[i-1].get(),
263 EventTypeNames::mouseenter, mouseEvent, exitedTarget, 264 EventTypeNames::mouseenter, mouseEvent, exitedTarget,
264 0, !enteredNodeHasCapturingAncestor); 265 0, !enteredNodeHasCapturingAncestor);
265 } 266 }
266 } 267 }
267 } 268 }
268 269
269 void PointerEventManager::setNodeUnderPointer( 270 void PointerEventManager::setNodeUnderPointer(
270 PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent, 271 PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent,
271 PassRefPtrWillBeRawPtr<EventTarget> prpTarget) 272 PassRefPtrWillBeRawPtr<EventTarget> prpTarget,
273 bool sendEvent)
272 { 274 {
273 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent; 275 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent;
274 RefPtrWillBeRawPtr<EventTarget> target = prpTarget; 276 RefPtrWillBeRawPtr<EventTarget> target = prpTarget;
275 if (m_nodeUnderPointer.contains(pointerEvent->pointerId())) { 277 if (m_nodeUnderPointer.contains(pointerEvent->pointerId())) {
276 EventTargetAttributes node = m_nodeUnderPointer.get( 278 EventTargetAttributes node = m_nodeUnderPointer.get(
277 pointerEvent->pointerId()); 279 pointerEvent->pointerId());
278 if (!target) { 280 if (!target) {
279 m_nodeUnderPointer.remove(pointerEvent->pointerId()); 281 m_nodeUnderPointer.remove(pointerEvent->pointerId());
280 } else if (target 282 } else if (target
281 != m_nodeUnderPointer.get(pointerEvent->pointerId()).target) { 283 != m_nodeUnderPointer.get(pointerEvent->pointerId()).target) {
282 m_nodeUnderPointer.set(pointerEvent->pointerId(), 284 m_nodeUnderPointer.set(pointerEvent->pointerId(),
283 EventTargetAttributes(target, false)); 285 EventTargetAttributes(target, false));
284 } 286 }
285 sendNodeTransitionEvents(node.target, target, pointerEvent); 287 if (sendEvent)
288 sendNodeTransitionEvents(node.target, target, pointerEvent);
286 } else if (target) { 289 } else if (target) {
287 m_nodeUnderPointer.add(pointerEvent->pointerId(), 290 m_nodeUnderPointer.add(pointerEvent->pointerId(),
288 EventTargetAttributes(target, false)); 291 EventTargetAttributes(target, false));
289 sendNodeTransitionEvents(nullptr, target, pointerEvent); 292 if (sendEvent)
293 sendNodeTransitionEvents(nullptr, target, pointerEvent);
290 } 294 }
291 } 295 }
292 296
293 void PointerEventManager::sendTouchCancelPointerEvent(PassRefPtrWillBeRawPtr<Eve ntTarget> prpTarget, const PlatformTouchPoint& point) 297 void PointerEventManager::sendTouchCancelPointerEvent(PassRefPtrWillBeRawPtr<Eve ntTarget> prpTarget, const PlatformTouchPoint& point)
294 { 298 {
295 RefPtrWillBeRawPtr<EventTarget> target = prpTarget; 299 RefPtrWillBeRawPtr<EventTarget> target = prpTarget;
296 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = m_pointerEventFactory.create PointerCancelEvent(point); 300 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = m_pointerEventFactory.create PointerCancelEvent(point);
297 301
298 processPendingPointerCapture(pointerEvent, target); 302
303 processCaptureAndPositionOfPointerEvent(pointerEvent, target);
299 304
300 // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing v s pointer event capturing 305 // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing v s pointer event capturing
301 dispatchPointerEvent( 306 dispatchPointerEvent(
302 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()), 307 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()),
303 pointerEvent.get()); 308 pointerEvent.get());
304 309
305 setNodeUnderPointer(pointerEvent, nullptr); 310 setNodeUnderPointer(pointerEvent, nullptr);
306 311
307 removePointer(pointerEvent); 312 removePointer(pointerEvent);
308 } 313 }
309 314
310 WebInputEventResult PointerEventManager::sendTouchPointerEvent( 315 WebInputEventResult PointerEventManager::sendTouchPointerEvent(
311 PassRefPtrWillBeRawPtr<EventTarget> prpTarget, 316 PassRefPtrWillBeRawPtr<EventTarget> prpTarget,
312 const PlatformTouchPoint& touchPoint, PlatformEvent::Modifiers modifiers, 317 const PlatformTouchPoint& touchPoint, PlatformEvent::Modifiers modifiers,
313 const double width, const double height, 318 const double width, const double height,
314 const double clientX, const double clientY) 319 const double clientX, const double clientY)
315 { 320 {
316 RefPtrWillBeRawPtr<EventTarget> target = prpTarget; 321 RefPtrWillBeRawPtr<EventTarget> target = prpTarget;
317 322
318 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = 323 RefPtrWillBeRawPtr<PointerEvent> pointerEvent =
319 m_pointerEventFactory.create( 324 m_pointerEventFactory.create(
320 pointerEventNameForTouchPointState(touchPoint.state()), 325 pointerEventNameForTouchPointState(touchPoint.state()),
321 touchPoint, modifiers, width, height, clientX, clientY); 326 touchPoint, modifiers, width, height, clientX, clientY);
322 327
323 processPendingPointerCapture(pointerEvent, target); 328 processCaptureAndPositionOfPointerEvent(pointerEvent, target);
324
325 setNodeUnderPointer(pointerEvent, target);
326 329
327 // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing v s pointer event capturing 330 // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing v s pointer event capturing
328 WebInputEventResult result = dispatchPointerEvent( 331 WebInputEventResult result = dispatchPointerEvent(
329 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()), 332 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()),
330 pointerEvent.get()); 333 pointerEvent.get());
331 334
332 if (touchPoint.state() == PlatformTouchPoint::TouchReleased 335 if (touchPoint.state() == PlatformTouchPoint::TouchReleased
333 || touchPoint.state() == PlatformTouchPoint::TouchCancelled) { 336 || touchPoint.state() == PlatformTouchPoint::TouchCancelled) {
334 setNodeUnderPointer(pointerEvent, nullptr); 337 setNodeUnderPointer(pointerEvent, nullptr);
335 removePointer(pointerEvent); 338 removePointer(pointerEvent);
336 } 339 }
337 340
338 return result; 341 return result;
339 } 342 }
340 343
341 WebInputEventResult PointerEventManager::sendMousePointerEvent( 344 WebInputEventResult PointerEventManager::sendMousePointerEvent(
342 PassRefPtrWillBeRawPtr<Node> prpTarget, const AtomicString& mouseEventType, 345 PassRefPtrWillBeRawPtr<Node> prpTarget, const AtomicString& mouseEventType,
343 int clickCount, const PlatformMouseEvent& mouseEvent, 346 int clickCount, const PlatformMouseEvent& mouseEvent,
344 PassRefPtrWillBeRawPtr<Node> relatedTarget, 347 PassRefPtrWillBeRawPtr<Node> relatedTarget,
345 PassRefPtrWillBeRawPtr<AbstractView> view) 348 PassRefPtrWillBeRawPtr<AbstractView> view,
349 PassRefPtrWillBeRawPtr<Node> lastNodeUnderMouse)
346 { 350 {
347 RefPtrWillBeRawPtr<Node> target = prpTarget; 351 RefPtrWillBeRawPtr<Node> target = prpTarget;
352
348 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = 353 RefPtrWillBeRawPtr<PointerEvent> pointerEvent =
349 m_pointerEventFactory.create(mouseEventType, mouseEvent, 354 m_pointerEventFactory.create(mouseEventType, mouseEvent,
350 relatedTarget, view); 355 relatedTarget, view);
351 356
352 processPendingPointerCapture(pointerEvent, target, mouseEvent, true); 357 // This is for when the mouse is released outside of the page.
358 if (pointerEvent->type() == EventTypeNames::pointermove
359 && !pointerEvent->buttons()) {
360 m_preventMouseEventForPointerTypeMouse = false;
361 }
353 362
354 // TODO(crbug.com/587955): We should call setNodeUnderPointer here but it ca uses sending 363 processCaptureAndPositionOfPointerEvent(pointerEvent, target,
355 // transition events that should be first removed from EventHandler. 364 lastNodeUnderMouse, mouseEvent, true, true);
356 // setNodeUnderPointer(pointerEvent, target);
357 365
358 RefPtrWillBeRawPtr<EventTarget> effectiveTarget = 366 RefPtrWillBeRawPtr<EventTarget> effectiveTarget =
359 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()); 367 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId());
360 368
361 WebInputEventResult result = 369 WebInputEventResult result =
362 dispatchPointerEvent(effectiveTarget, pointerEvent); 370 dispatchPointerEvent(effectiveTarget, pointerEvent);
363 371
364 if (result != WebInputEventResult::NotHandled 372 if (result != WebInputEventResult::NotHandled
365 && pointerEvent->type() == EventTypeNames::pointerdown) 373 && pointerEvent->type() == EventTypeNames::pointerdown)
366 m_preventMouseEventForPointerTypeMouse = true; 374 m_preventMouseEventForPointerTypeMouse = true;
367 375
368 if (!m_preventMouseEventForPointerTypeMouse) { 376 if (!m_preventMouseEventForPointerTypeMouse) {
369 result = EventHandler::mergeEventResult(result, 377 result = EventHandler::mergeEventResult(result,
370 dispatchMouseEvent(effectiveTarget, mouseEventType, mouseEvent, 378 dispatchMouseEvent(effectiveTarget, mouseEventType, mouseEvent,
371 nullptr, clickCount)); 379 nullptr, clickCount));
372 } 380 }
373 381
374 if (pointerEvent->buttons() == 0) 382 if (pointerEvent->buttons() == 0) {
375 releasePointerCapture(pointerEvent->pointerId()); 383 releasePointerCapture(pointerEvent->pointerId());
384 m_preventMouseEventForPointerTypeMouse = false;
385 }
376 386
377 return result; 387 return result;
378 } 388 }
379 389
380 PointerEventManager::PointerEventManager() 390 PointerEventManager::PointerEventManager()
381 { 391 {
382 clear(); 392 clear();
383 } 393 }
384 394
385 PointerEventManager::~PointerEventManager() 395 PointerEventManager::~PointerEventManager()
386 { 396 {
387 } 397 }
388 398
389 void PointerEventManager::clear() 399 void PointerEventManager::clear()
390 { 400 {
391 m_preventMouseEventForPointerTypeMouse = false; 401 m_preventMouseEventForPointerTypeMouse = false;
392 m_pointerEventFactory.clear(); 402 m_pointerEventFactory.clear();
393 m_nodeUnderPointer.clear(); 403 m_nodeUnderPointer.clear();
394 } 404 }
395 405
396 void PointerEventManager::conditionallyEnableMouseEventForPointerTypeMouse( 406 void PointerEventManager::processCaptureAndPositionOfPointerEvent(
397 unsigned modifiers) 407 const PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent,
408 const PassRefPtrWillBeRawPtr<EventTarget> prpHitTestTarget,
409 const PassRefPtrWillBeRawPtr<EventTarget> lastNodeUnderMouse,
410 const PlatformMouseEvent& mouseEvent,
411 bool sendMouseEvent, bool setPointerPosition)
398 { 412 {
413 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent;
414 RefPtrWillBeRawPtr<EventTarget> hitTestTarget = prpHitTestTarget;
415 bool isCaptureChanged = false;
399 416
400 if (MouseEvent::platformModifiersToButtons(modifiers) == 417 if (setPointerPosition) {
401 static_cast<unsigned short>(MouseEvent::Buttons::None)) 418 isCaptureChanged = processPendingPointerCapture(pointerEvent,
402 m_preventMouseEventForPointerTypeMouse = false; 419 hitTestTarget, mouseEvent, sendMouseEvent);
420 // If there was a change in capturing processPendingPointerCapture has
421 // already taken care of transition events. So we don't need to send the
422 // transition events here.
423 setNodeUnderPointer(pointerEvent, hitTestTarget, !isCaptureChanged);
424 }
425 if (sendMouseEvent && !isCaptureChanged) {
426 // lastNodeUnderMouse is needed here because it is still stored in Event Handler.
427 sendNodeTransitionEvents(lastNodeUnderMouse, hitTestTarget,
428 pointerEvent, mouseEvent, true);
429 }
403 } 430 }
404 431
405 void PointerEventManager::processPendingPointerCapture( 432 bool PointerEventManager::processPendingPointerCapture(
406 const PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent, 433 const PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent,
407 const PassRefPtrWillBeRawPtr<EventTarget> prpHitTestTarget, 434 const PassRefPtrWillBeRawPtr<EventTarget> prpHitTestTarget,
408 const PlatformMouseEvent& mouseEvent, bool sendMouseEvent) 435 const PlatformMouseEvent& mouseEvent, bool sendMouseEvent)
409 { 436 {
410 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent; 437 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent;
411 RefPtrWillBeRawPtr<EventTarget> hitTestTarget = prpHitTestTarget; 438 RefPtrWillBeRawPtr<EventTarget> hitTestTarget = prpHitTestTarget;
412 int pointerId = pointerEvent->pointerId(); 439 int pointerId = pointerEvent->pointerId();
413 const RefPtrWillBeRawPtr<EventTarget> pointerCaptureTarget = 440 const RefPtrWillBeRawPtr<EventTarget> pointerCaptureTarget =
414 m_pointerCaptureTarget.contains(pointerId) 441 m_pointerCaptureTarget.contains(pointerId)
415 ? m_pointerCaptureTarget.get(pointerId) : nullptr; 442 ? m_pointerCaptureTarget.get(pointerId) : nullptr;
416 const RefPtrWillBeRawPtr<EventTarget> pendingPointerCaptureTarget = 443 const RefPtrWillBeRawPtr<EventTarget> pendingPointerCaptureTarget =
417 m_pendingPointerCaptureTarget.contains(pointerId) 444 m_pendingPointerCaptureTarget.contains(pointerId)
418 ? m_pendingPointerCaptureTarget.get(pointerId) : nullptr; 445 ? m_pendingPointerCaptureTarget.get(pointerId) : nullptr;
419 const EventTargetAttributes &nodeUnderPointerAtt = 446 const EventTargetAttributes &nodeUnderPointerAtt =
420 m_nodeUnderPointer.contains(pointerId) 447 m_nodeUnderPointer.contains(pointerId)
421 ? m_nodeUnderPointer.get(pointerId) : EventTargetAttributes(); 448 ? m_nodeUnderPointer.get(pointerId) : EventTargetAttributes();
449 const bool isCaptureChanged =
450 pointerCaptureTarget != pendingPointerCaptureTarget;
422 451
423 if (pointerCaptureTarget != pendingPointerCaptureTarget) { 452 if (isCaptureChanged) {
424 if (pendingPointerCaptureTarget != nodeUnderPointerAtt.target 453 if ((hitTestTarget != nodeUnderPointerAtt.target
454 || (pendingPointerCaptureTarget
455 && pendingPointerCaptureTarget != nodeUnderPointerAtt.target))
425 && nodeUnderPointerAtt.hasRecievedOverEvent) { 456 && nodeUnderPointerAtt.hasRecievedOverEvent) {
457 if (sendMouseEvent) {
458 // Send pointer event transitions as the line after this if
459 // block sends the mouse events
460 sendNodeTransitionEvents(nodeUnderPointerAtt.target, nullptr,
461 pointerEvent);
462 }
426 sendNodeTransitionEvents(nodeUnderPointerAtt.target, nullptr, 463 sendNodeTransitionEvents(nodeUnderPointerAtt.target, nullptr,
427 pointerEvent, mouseEvent, sendMouseEvent); 464 pointerEvent, mouseEvent, sendMouseEvent);
428 } 465 }
429 if (pointerCaptureTarget) { 466 if (pointerCaptureTarget) {
430 // Re-target lostpointercapture to the document when the element is 467 // Re-target lostpointercapture to the document when the element is
431 // no longer participating in the tree. 468 // no longer participating in the tree.
432 EventTarget* target = pointerCaptureTarget.get(); 469 EventTarget* target = pointerCaptureTarget.get();
433 if (target->toNode() 470 if (target->toNode()
434 && !target->toNode()->inDocument()) { 471 && !target->toNode()->inDocument()) {
435 target = target->toNode()->ownerDocument(); 472 target = target->toNode()->ownerDocument();
436 } 473 }
437 if (target) { 474 dispatchPointerEvent(target,
438 dispatchPointerEvent(target, 475 m_pointerEventFactory.createPointerCaptureEvent(
439 m_pointerEventFactory.createPointerCaptureEvent( 476 pointerEvent, EventTypeNames::lostpointercapture));
440 pointerEvent, EventTypeNames::lostpointercapture));
441 }
442 } 477 }
443 } 478 }
444 479
445 // Set pointerCaptureTarget from pendingPointerCaptureTarget. This does 480 // Set pointerCaptureTarget from pendingPointerCaptureTarget. This does
446 // affect the behavior of sendNodeTransitionEvents function. So the 481 // affect the behavior of sendNodeTransitionEvents function. So the
447 // ordering of the surrounding blocks of code for sending transition events 482 // ordering of the surrounding blocks of code for sending transition events
448 // are important. 483 // are important.
449 if (pendingPointerCaptureTarget) 484 if (pendingPointerCaptureTarget)
450 m_pointerCaptureTarget.set(pointerId, pendingPointerCaptureTarget); 485 m_pointerCaptureTarget.set(pointerId, pendingPointerCaptureTarget);
451 else 486 else
452 m_pointerCaptureTarget.remove(pointerId); 487 m_pointerCaptureTarget.remove(pointerId);
453 488
454 if (pointerCaptureTarget != pendingPointerCaptureTarget) { 489 if (isCaptureChanged) {
455 if (pendingPointerCaptureTarget) { 490 dispatchPointerEvent(pendingPointerCaptureTarget,
456 dispatchPointerEvent(pendingPointerCaptureTarget, 491 m_pointerEventFactory.createPointerCaptureEvent(
457 m_pointerEventFactory.createPointerCaptureEvent( 492 pointerEvent, EventTypeNames::gotpointercapture));
458 pointerEvent, EventTypeNames::gotpointercapture));
459 }
460 if ((pendingPointerCaptureTarget == hitTestTarget 493 if ((pendingPointerCaptureTarget == hitTestTarget
461 || !pendingPointerCaptureTarget) 494 || !pendingPointerCaptureTarget)
462 && (nodeUnderPointerAtt.target != hitTestTarget 495 && (nodeUnderPointerAtt.target != hitTestTarget
463 || !nodeUnderPointerAtt.hasRecievedOverEvent)) { 496 || !nodeUnderPointerAtt.hasRecievedOverEvent)) {
497 if (sendMouseEvent) {
498 // Send pointer event transitions as the line after this if
499 // block sends the mouse events
500 sendNodeTransitionEvents(nullptr, hitTestTarget, pointerEvent);
501 }
464 sendNodeTransitionEvents(nullptr, hitTestTarget, pointerEvent, 502 sendNodeTransitionEvents(nullptr, hitTestTarget, pointerEvent,
465 mouseEvent, sendMouseEvent); 503 mouseEvent, sendMouseEvent);
466 } 504 }
467 } 505 }
506 return isCaptureChanged;
468 } 507 }
469 508
470 void PointerEventManager::removeTargetFromPointerCapturingMapping( 509 void PointerEventManager::removeTargetFromPointerCapturingMapping(
471 PointerCapturingMap& map, const EventTarget* target) 510 PointerCapturingMap& map, const EventTarget* target)
472 { 511 {
473 // We could have kept a reverse mapping to make this deletion possibly 512 // We could have kept a reverse mapping to make this deletion possibly
474 // faster but it adds some code complication which might not be worth of 513 // faster but it adds some code complication which might not be worth of
475 // the performance improvement considering there might not be a lot of 514 // the performance improvement considering there might not be a lot of
476 // active pointer or pointer captures at the same time. 515 // active pointer or pointer captures at the same time.
477 PointerCapturingMap tmp = map; 516 PointerCapturingMap tmp = map;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 { 570 {
532 #if ENABLE(OILPAN) 571 #if ENABLE(OILPAN)
533 visitor->trace(m_nodeUnderPointer); 572 visitor->trace(m_nodeUnderPointer);
534 visitor->trace(m_pointerCaptureTarget); 573 visitor->trace(m_pointerCaptureTarget);
535 visitor->trace(m_pendingPointerCaptureTarget); 574 visitor->trace(m_pendingPointerCaptureTarget);
536 #endif 575 #endif
537 } 576 }
538 577
539 578
540 } // namespace blink 579 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698