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

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: Appling the comments and adding extra test 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 if (isFrameBoundaryTransition && pointerEvent->buttons() == 0) {
mustaq 2016/03/23 18:49:07 Add a comment why we can't omit |isFrameBoundary..
Navid Zolghadr 2016/03/23 19:47:48 Done.
132 true); 120 m_preventMouseEventForPointerTypeMouse = false;
121 }
122
123 processCaptureAndPositionOfPointerEvent(pointerEvent, enteredNode,
124 exitedNode, mouseEvent, true, isFrameBoundaryTransition);
133 } 125 }
134 126
135 void PointerEventManager::sendNodeTransitionEvents( 127 void PointerEventManager::sendNodeTransitionEvents(
136 PassRefPtrWillBeRawPtr<EventTarget> prpExitedTarget, 128 PassRefPtrWillBeRawPtr<EventTarget> prpExitedTarget,
137 PassRefPtrWillBeRawPtr<EventTarget> prpEnteredTarget, 129 PassRefPtrWillBeRawPtr<EventTarget> prpEnteredTarget,
138 PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent, 130 PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent,
139 const PlatformMouseEvent& mouseEvent, bool sendMouseEvent) 131 const PlatformMouseEvent& mouseEvent, bool sendMouseEvent)
140 { 132 {
141 RefPtrWillBeRawPtr<EventTarget> exitedTarget = prpExitedTarget; 133 RefPtrWillBeRawPtr<EventTarget> exitedTarget = prpExitedTarget;
142 RefPtrWillBeRawPtr<EventTarget> enteredTarget = prpEnteredTarget; 134 RefPtrWillBeRawPtr<EventTarget> enteredTarget = prpEnteredTarget;
143 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent; 135 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent;
136
144 if (exitedTarget == enteredTarget) 137 if (exitedTarget == enteredTarget)
145 return; 138 return;
146 139
147 if (EventTarget* capturingTarget = getCapturingNode(pointerEvent->pointerId( ))) { 140 if (EventTarget* capturingTarget = getCapturingNode(pointerEvent->pointerId( ))) {
148 if (capturingTarget == exitedTarget) 141 if (capturingTarget == exitedTarget)
149 enteredTarget = nullptr; 142 enteredTarget = nullptr;
150 else if (capturingTarget == enteredTarget) 143 else if (capturingTarget == enteredTarget)
151 exitedTarget = nullptr; 144 exitedTarget = nullptr;
152 else 145 else
153 return; 146 return;
154 } 147 }
155 148
156 // Dispatch pointerout/mouseout events 149 // Dispatch pointerout/mouseout events
157 if (isInDocument(exitedTarget)) { 150 if (isInDocument(exitedTarget)) {
158 dispatchPointerEvent(exitedTarget, m_pointerEventFactory.createPointerTr ansitionEvent( 151 if (!sendMouseEvent) {
159 pointerEvent, EventTypeNames::pointerout, enteredTarget)); 152 dispatchPointerEvent(exitedTarget, m_pointerEventFactory.createPoint erTransitionEvent(
160 if (sendMouseEvent) { 153 pointerEvent, EventTypeNames::pointerout, enteredTarget));
154 } else {
161 dispatchMouseEvent(exitedTarget, 155 dispatchMouseEvent(exitedTarget,
162 EventTypeNames::mouseout, mouseEvent, enteredTarget); 156 EventTypeNames::mouseout, mouseEvent, enteredTarget);
163 } 157 }
164 } 158 }
165 159
166 // Create lists of all exited/entered ancestors, locate the common ancestor 160 // Create lists of all exited/entered ancestors, locate the common ancestor
167 WillBeHeapVector<RefPtrWillBeMember<Node>, 32> exitedAncestors; 161 WillBeHeapVector<RefPtrWillBeMember<Node>, 32> exitedAncestors;
168 WillBeHeapVector<RefPtrWillBeMember<Node>, 32> enteredAncestors; 162 WillBeHeapVector<RefPtrWillBeMember<Node>, 32> enteredAncestors;
169 if (isInDocument(exitedTarget)) { 163 if (isInDocument(exitedTarget)) {
170 RefPtrWillBeRawPtr<Node> exitedNode = exitedTarget->toNode(); 164 RefPtrWillBeRawPtr<Node> exitedNode = exitedTarget->toNode();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 bool exitedNodeHasCapturingAncestor = false; 208 bool exitedNodeHasCapturingAncestor = false;
215 for (size_t j = 0; j < exitedAncestors.size(); j++) { 209 for (size_t j = 0; j < exitedAncestors.size(); j++) {
216 if (exitedAncestors[j]->hasCapturingEventListeners(EventTypeNames::mouse leave) 210 if (exitedAncestors[j]->hasCapturingEventListeners(EventTypeNames::mouse leave)
217 || (RuntimeEnabledFeatures::pointerEventEnabled() 211 || (RuntimeEnabledFeatures::pointerEventEnabled()
218 && exitedAncestors[j]->hasCapturingEventListeners(EventTypeNames::po interleave))) 212 && exitedAncestors[j]->hasCapturingEventListeners(EventTypeNames::po interleave)))
219 exitedNodeHasCapturingAncestor = true; 213 exitedNodeHasCapturingAncestor = true;
220 } 214 }
221 215
222 // Dispatch pointerleave/mouseleave events, in child-to-parent order. 216 // Dispatch pointerleave/mouseleave events, in child-to-parent order.
223 for (size_t j = 0; j < exitedAncestorIndex; j++) { 217 for (size_t j = 0; j < exitedAncestorIndex; j++) {
224 dispatchPointerEvent(exitedAncestors[j].get(), 218 if (!sendMouseEvent) {
225 m_pointerEventFactory.createPointerTransitionEvent( 219 dispatchPointerEvent(exitedAncestors[j].get(),
226 pointerEvent, EventTypeNames::pointerleave, enteredTarget), 220 m_pointerEventFactory.createPointerTransitionEvent(
227 !exitedNodeHasCapturingAncestor); 221 pointerEvent, EventTypeNames::pointerleave, enteredTarget),
228 if (sendMouseEvent) { 222 !exitedNodeHasCapturingAncestor);
223 } else {
229 dispatchMouseEvent(exitedAncestors[j].get(), 224 dispatchMouseEvent(exitedAncestors[j].get(),
230 EventTypeNames::mouseleave, mouseEvent, enteredTarget, 225 EventTypeNames::mouseleave, mouseEvent, enteredTarget,
231 0, !exitedNodeHasCapturingAncestor); 226 0, !exitedNodeHasCapturingAncestor);
232 } 227 }
233 } 228 }
234 229
235 // Dispatch pointerover/mouseover. 230 // Dispatch pointerover/mouseover.
236 if (isInDocument(enteredTarget)) { 231 if (isInDocument(enteredTarget)) {
237 dispatchPointerEvent(enteredTarget, m_pointerEventFactory.createPointerT ransitionEvent( 232 if (!sendMouseEvent) {
238 pointerEvent, EventTypeNames::pointerover, exitedTarget)); 233 dispatchPointerEvent(enteredTarget, m_pointerEventFactory.createPoin terTransitionEvent(
239 if (sendMouseEvent) { 234 pointerEvent, EventTypeNames::pointerover, exitedTarget));
235 } else {
240 dispatchMouseEvent(enteredTarget, 236 dispatchMouseEvent(enteredTarget,
241 EventTypeNames::mouseover, mouseEvent, exitedTarget); 237 EventTypeNames::mouseover, mouseEvent, exitedTarget);
242 } 238 }
243 } 239 }
244 240
245 // Defer locating capturing pointeenter/mouseenter listener until /after/ di spatching the leave events because 241 // Defer locating capturing pointeenter/mouseenter listener until /after/ di spatching the leave events because
246 // the leave handlers might set a capturing enter handler. 242 // the leave handlers might set a capturing enter handler.
247 bool enteredNodeHasCapturingAncestor = false; 243 bool enteredNodeHasCapturingAncestor = false;
248 for (size_t i = 0; i < enteredAncestors.size(); i++) { 244 for (size_t i = 0; i < enteredAncestors.size(); i++) {
249 if (enteredAncestors[i]->hasCapturingEventListeners(EventTypeNames::mous eenter) 245 if (enteredAncestors[i]->hasCapturingEventListeners(EventTypeNames::mous eenter)
250 || (RuntimeEnabledFeatures::pointerEventEnabled() 246 || (RuntimeEnabledFeatures::pointerEventEnabled()
251 && enteredAncestors[i]->hasCapturingEventListeners(EventTypeNames::p ointerenter))) 247 && enteredAncestors[i]->hasCapturingEventListeners(EventTypeNames::p ointerenter)))
252 enteredNodeHasCapturingAncestor = true; 248 enteredNodeHasCapturingAncestor = true;
253 } 249 }
254 250
255 // Dispatch pointerenter/mouseenter events, in parent-to-child order. 251 // Dispatch pointerenter/mouseenter events, in parent-to-child order.
256 for (size_t i = enteredAncestorIndex; i > 0; i--) { 252 for (size_t i = enteredAncestorIndex; i > 0; i--) {
257 dispatchPointerEvent(enteredAncestors[i-1].get(), 253 if (!sendMouseEvent) {
258 m_pointerEventFactory.createPointerTransitionEvent( 254 dispatchPointerEvent(enteredAncestors[i-1].get(),
259 pointerEvent, EventTypeNames::pointerenter, exitedTarget), 255 m_pointerEventFactory.createPointerTransitionEvent(
260 !enteredNodeHasCapturingAncestor); 256 pointerEvent, EventTypeNames::pointerenter, exitedTarget),
261 if (sendMouseEvent) { 257 !enteredNodeHasCapturingAncestor);
258 } else {
262 dispatchMouseEvent(enteredAncestors[i-1].get(), 259 dispatchMouseEvent(enteredAncestors[i-1].get(),
263 EventTypeNames::mouseenter, mouseEvent, exitedTarget, 260 EventTypeNames::mouseenter, mouseEvent, exitedTarget,
264 0, !enteredNodeHasCapturingAncestor); 261 0, !enteredNodeHasCapturingAncestor);
265 } 262 }
266 } 263 }
267 } 264 }
268 265
269 void PointerEventManager::setNodeUnderPointer( 266 void PointerEventManager::setNodeUnderPointer(
270 PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent, 267 PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent,
271 PassRefPtrWillBeRawPtr<EventTarget> prpTarget) 268 PassRefPtrWillBeRawPtr<EventTarget> prpTarget,
269 bool sendEvent)
272 { 270 {
273 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent; 271 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent;
274 RefPtrWillBeRawPtr<EventTarget> target = prpTarget; 272 RefPtrWillBeRawPtr<EventTarget> target = prpTarget;
275 if (m_nodeUnderPointer.contains(pointerEvent->pointerId())) { 273 if (m_nodeUnderPointer.contains(pointerEvent->pointerId())) {
276 EventTargetAttributes node = m_nodeUnderPointer.get( 274 EventTargetAttributes node = m_nodeUnderPointer.get(
277 pointerEvent->pointerId()); 275 pointerEvent->pointerId());
278 if (!target) { 276 if (!target) {
279 m_nodeUnderPointer.remove(pointerEvent->pointerId()); 277 m_nodeUnderPointer.remove(pointerEvent->pointerId());
280 } else if (target 278 } else if (target
281 != m_nodeUnderPointer.get(pointerEvent->pointerId()).target) { 279 != m_nodeUnderPointer.get(pointerEvent->pointerId()).target) {
282 m_nodeUnderPointer.set(pointerEvent->pointerId(), 280 m_nodeUnderPointer.set(pointerEvent->pointerId(),
283 EventTargetAttributes(target, false)); 281 EventTargetAttributes(target, false));
284 } 282 }
285 sendNodeTransitionEvents(node.target, target, pointerEvent); 283 if (sendEvent)
284 sendNodeTransitionEvents(node.target, target, pointerEvent);
286 } else if (target) { 285 } else if (target) {
287 m_nodeUnderPointer.add(pointerEvent->pointerId(), 286 m_nodeUnderPointer.add(pointerEvent->pointerId(),
288 EventTargetAttributes(target, false)); 287 EventTargetAttributes(target, false));
289 sendNodeTransitionEvents(nullptr, target, pointerEvent); 288 if (sendEvent)
289 sendNodeTransitionEvents(nullptr, target, pointerEvent);
290 } 290 }
291 } 291 }
292 292
293 void PointerEventManager::sendTouchCancelPointerEvent(PassRefPtrWillBeRawPtr<Eve ntTarget> prpTarget, const PlatformTouchPoint& point) 293 void PointerEventManager::sendTouchCancelPointerEvent(PassRefPtrWillBeRawPtr<Eve ntTarget> prpTarget, const PlatformTouchPoint& point)
294 { 294 {
295 RefPtrWillBeRawPtr<EventTarget> target = prpTarget; 295 RefPtrWillBeRawPtr<EventTarget> target = prpTarget;
296 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = m_pointerEventFactory.create PointerCancelEvent(point); 296 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = m_pointerEventFactory.create PointerCancelEvent(point);
297 297
298 processPendingPointerCapture(pointerEvent, target); 298
299 processCaptureAndPositionOfPointerEvent(pointerEvent, target);
299 300
300 // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing v s pointer event capturing 301 // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing v s pointer event capturing
301 dispatchPointerEvent( 302 dispatchPointerEvent(
302 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()), 303 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()),
303 pointerEvent.get()); 304 pointerEvent.get());
304 305
305 setNodeUnderPointer(pointerEvent, nullptr); 306 setNodeUnderPointer(pointerEvent, nullptr);
306 307
307 removePointer(pointerEvent); 308 removePointer(pointerEvent);
308 } 309 }
309 310
310 WebInputEventResult PointerEventManager::sendTouchPointerEvent( 311 WebInputEventResult PointerEventManager::sendTouchPointerEvent(
311 PassRefPtrWillBeRawPtr<EventTarget> prpTarget, 312 PassRefPtrWillBeRawPtr<EventTarget> prpTarget,
312 const PlatformTouchPoint& touchPoint, PlatformEvent::Modifiers modifiers, 313 const PlatformTouchPoint& touchPoint, PlatformEvent::Modifiers modifiers,
313 const double width, const double height, 314 const double width, const double height,
314 const double clientX, const double clientY) 315 const double clientX, const double clientY)
315 { 316 {
316 RefPtrWillBeRawPtr<EventTarget> target = prpTarget; 317 RefPtrWillBeRawPtr<EventTarget> target = prpTarget;
317 318
318 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = 319 RefPtrWillBeRawPtr<PointerEvent> pointerEvent =
319 m_pointerEventFactory.create( 320 m_pointerEventFactory.create(
320 pointerEventNameForTouchPointState(touchPoint.state()), 321 pointerEventNameForTouchPointState(touchPoint.state()),
321 touchPoint, modifiers, width, height, clientX, clientY); 322 touchPoint, modifiers, width, height, clientX, clientY);
322 323
323 processPendingPointerCapture(pointerEvent, target); 324 processCaptureAndPositionOfPointerEvent(pointerEvent, target);
324
325 setNodeUnderPointer(pointerEvent, target);
326 325
327 // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing v s pointer event capturing 326 // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing v s pointer event capturing
328 WebInputEventResult result = dispatchPointerEvent( 327 WebInputEventResult result = dispatchPointerEvent(
329 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()), 328 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()),
330 pointerEvent.get()); 329 pointerEvent.get());
331 330
332 if (touchPoint.state() == PlatformTouchPoint::TouchReleased 331 if (touchPoint.state() == PlatformTouchPoint::TouchReleased
333 || touchPoint.state() == PlatformTouchPoint::TouchCancelled) { 332 || touchPoint.state() == PlatformTouchPoint::TouchCancelled) {
334 setNodeUnderPointer(pointerEvent, nullptr); 333 setNodeUnderPointer(pointerEvent, nullptr);
335 removePointer(pointerEvent); 334 removePointer(pointerEvent);
336 } 335 }
337 336
338 return result; 337 return result;
339 } 338 }
340 339
341 WebInputEventResult PointerEventManager::sendMousePointerEvent( 340 WebInputEventResult PointerEventManager::sendMousePointerEvent(
342 PassRefPtrWillBeRawPtr<Node> prpTarget, const AtomicString& mouseEventType, 341 PassRefPtrWillBeRawPtr<Node> prpTarget, const AtomicString& mouseEventType,
343 int clickCount, const PlatformMouseEvent& mouseEvent, 342 int clickCount, const PlatformMouseEvent& mouseEvent,
344 PassRefPtrWillBeRawPtr<Node> relatedTarget, 343 PassRefPtrWillBeRawPtr<Node> relatedTarget,
345 PassRefPtrWillBeRawPtr<AbstractView> view) 344 PassRefPtrWillBeRawPtr<AbstractView> view,
345 PassRefPtrWillBeRawPtr<Node> lastNodeUnderMouse)
346 { 346 {
347 RefPtrWillBeRawPtr<Node> target = prpTarget; 347 RefPtrWillBeRawPtr<Node> target = prpTarget;
348
348 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = 349 RefPtrWillBeRawPtr<PointerEvent> pointerEvent =
349 m_pointerEventFactory.create(mouseEventType, mouseEvent, 350 m_pointerEventFactory.create(mouseEventType, mouseEvent,
350 relatedTarget, view); 351 relatedTarget, view);
351 352
352 processPendingPointerCapture(pointerEvent, target, mouseEvent, true); 353 // This is for when the mouse is released outside of the page.
354 if (pointerEvent->type() == EventTypeNames::pointermove
355 && !pointerEvent->buttons()) {
356 m_preventMouseEventForPointerTypeMouse = false;
357 }
353 358
354 // TODO(crbug.com/587955): We should call setNodeUnderPointer here but it ca uses sending 359 processCaptureAndPositionOfPointerEvent(pointerEvent, target,
355 // transition events that should be first removed from EventHandler. 360 lastNodeUnderMouse, mouseEvent, true, true);
356 // setNodeUnderPointer(pointerEvent, target);
357 361
358 RefPtrWillBeRawPtr<EventTarget> effectiveTarget = 362 RefPtrWillBeRawPtr<EventTarget> effectiveTarget =
359 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()); 363 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId());
360 364
361 WebInputEventResult result = 365 WebInputEventResult result =
362 dispatchPointerEvent(effectiveTarget, pointerEvent); 366 dispatchPointerEvent(effectiveTarget, pointerEvent);
363 367
364 if (result != WebInputEventResult::NotHandled 368 if (result != WebInputEventResult::NotHandled
365 && pointerEvent->type() == EventTypeNames::pointerdown) 369 && pointerEvent->type() == EventTypeNames::pointerdown)
366 m_preventMouseEventForPointerTypeMouse = true; 370 m_preventMouseEventForPointerTypeMouse = true;
367 371
368 if (!m_preventMouseEventForPointerTypeMouse) { 372 if (!m_preventMouseEventForPointerTypeMouse) {
369 result = EventHandler::mergeEventResult(result, 373 result = EventHandler::mergeEventResult(result,
370 dispatchMouseEvent(effectiveTarget, mouseEventType, mouseEvent, 374 dispatchMouseEvent(effectiveTarget, mouseEventType, mouseEvent,
371 nullptr, clickCount)); 375 nullptr, clickCount));
372 } 376 }
373 377
374 if (pointerEvent->buttons() == 0) 378 if (pointerEvent->buttons() == 0) {
375 releasePointerCapture(pointerEvent->pointerId()); 379 releasePointerCapture(pointerEvent->pointerId());
380 m_preventMouseEventForPointerTypeMouse = false;
381 }
376 382
377 return result; 383 return result;
378 } 384 }
379 385
380 PointerEventManager::PointerEventManager() 386 PointerEventManager::PointerEventManager()
381 { 387 {
382 clear(); 388 clear();
383 } 389 }
384 390
385 PointerEventManager::~PointerEventManager() 391 PointerEventManager::~PointerEventManager()
386 { 392 {
387 } 393 }
388 394
389 void PointerEventManager::clear() 395 void PointerEventManager::clear()
390 { 396 {
391 m_preventMouseEventForPointerTypeMouse = false; 397 m_preventMouseEventForPointerTypeMouse = false;
392 m_pointerEventFactory.clear(); 398 m_pointerEventFactory.clear();
393 m_nodeUnderPointer.clear(); 399 m_nodeUnderPointer.clear();
394 } 400 }
395 401
396 void PointerEventManager::conditionallyEnableMouseEventForPointerTypeMouse( 402 void PointerEventManager::processCaptureAndPositionOfPointerEvent(
397 unsigned modifiers) 403 const PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent,
404 const PassRefPtrWillBeRawPtr<EventTarget> prpHitTestTarget,
405 const PassRefPtrWillBeRawPtr<EventTarget> lastNodeUnderMouse,
406 const PlatformMouseEvent& mouseEvent,
407 bool sendMouseEvent, bool setPointerPosition)
398 { 408 {
399 409 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent;
400 if (MouseEvent::platformModifiersToButtons(modifiers) == 410 RefPtrWillBeRawPtr<EventTarget> hitTestTarget = prpHitTestTarget;
401 static_cast<unsigned short>(MouseEvent::Buttons::None)) 411 bool isCaptureChanged = processPendingPointerCapture(pointerEvent,
402 m_preventMouseEventForPointerTypeMouse = false; 412 hitTestTarget, mouseEvent, sendMouseEvent);
413 if (setPointerPosition) {
414 // If there was a change in capturing processPendingPointerCapture has
415 // already taken care of transition events. So we don't need to send the
416 // transition events here.
417 setNodeUnderPointer(pointerEvent, hitTestTarget, !isCaptureChanged);
418 }
419 if (sendMouseEvent && !isCaptureChanged) {
420 // lastNodeUnderMouse is needed here because it is still stored in Event Handler.
421 sendNodeTransitionEvents(lastNodeUnderMouse, hitTestTarget,
422 pointerEvent, mouseEvent, true);
423 }
403 } 424 }
404 425
405 void PointerEventManager::processPendingPointerCapture( 426 bool PointerEventManager::processPendingPointerCapture(
406 const PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent, 427 const PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent,
407 const PassRefPtrWillBeRawPtr<EventTarget> prpHitTestTarget, 428 const PassRefPtrWillBeRawPtr<EventTarget> prpHitTestTarget,
408 const PlatformMouseEvent& mouseEvent, bool sendMouseEvent) 429 const PlatformMouseEvent& mouseEvent, bool sendMouseEvent)
409 { 430 {
410 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent; 431 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent;
411 RefPtrWillBeRawPtr<EventTarget> hitTestTarget = prpHitTestTarget; 432 RefPtrWillBeRawPtr<EventTarget> hitTestTarget = prpHitTestTarget;
412 int pointerId = pointerEvent->pointerId(); 433 int pointerId = pointerEvent->pointerId();
413 const RefPtrWillBeRawPtr<EventTarget> pointerCaptureTarget = 434 const RefPtrWillBeRawPtr<EventTarget> pointerCaptureTarget =
414 m_pointerCaptureTarget.contains(pointerId) 435 m_pointerCaptureTarget.contains(pointerId)
415 ? m_pointerCaptureTarget.get(pointerId) : nullptr; 436 ? m_pointerCaptureTarget.get(pointerId) : nullptr;
416 const RefPtrWillBeRawPtr<EventTarget> pendingPointerCaptureTarget = 437 const RefPtrWillBeRawPtr<EventTarget> pendingPointerCaptureTarget =
417 m_pendingPointerCaptureTarget.contains(pointerId) 438 m_pendingPointerCaptureTarget.contains(pointerId)
418 ? m_pendingPointerCaptureTarget.get(pointerId) : nullptr; 439 ? m_pendingPointerCaptureTarget.get(pointerId) : nullptr;
419 const EventTargetAttributes &nodeUnderPointerAtt = 440 const EventTargetAttributes &nodeUnderPointerAtt =
420 m_nodeUnderPointer.contains(pointerId) 441 m_nodeUnderPointer.contains(pointerId)
421 ? m_nodeUnderPointer.get(pointerId) : EventTargetAttributes(); 442 ? m_nodeUnderPointer.get(pointerId) : EventTargetAttributes();
443 const bool isCaptureChanged =
444 pointerCaptureTarget != pendingPointerCaptureTarget;
422 445
423 if (pointerCaptureTarget != pendingPointerCaptureTarget) { 446 if (isCaptureChanged) {
424 if (pendingPointerCaptureTarget != nodeUnderPointerAtt.target 447 if ((hitTestTarget != nodeUnderPointerAtt.target
448 || (pendingPointerCaptureTarget
449 && pendingPointerCaptureTarget != nodeUnderPointerAtt.target))
425 && nodeUnderPointerAtt.hasRecievedOverEvent) { 450 && nodeUnderPointerAtt.hasRecievedOverEvent) {
451 if (sendMouseEvent) {
452 // Send pointer event transitions as the line after this if
453 // block sends the mouse events
454 sendNodeTransitionEvents(nodeUnderPointerAtt.target, nullptr,
455 pointerEvent);
456 }
426 sendNodeTransitionEvents(nodeUnderPointerAtt.target, nullptr, 457 sendNodeTransitionEvents(nodeUnderPointerAtt.target, nullptr,
427 pointerEvent, mouseEvent, sendMouseEvent); 458 pointerEvent, mouseEvent, sendMouseEvent);
428 } 459 }
429 if (pointerCaptureTarget) { 460 if (pointerCaptureTarget) {
430 // Re-target lostpointercapture to the document when the element is 461 // Re-target lostpointercapture to the document when the element is
431 // no longer participating in the tree. 462 // no longer participating in the tree.
432 EventTarget* target = pointerCaptureTarget.get(); 463 EventTarget* target = pointerCaptureTarget.get();
433 if (target->toNode() 464 if (target->toNode()
434 && !target->toNode()->inDocument()) { 465 && !target->toNode()->inDocument()) {
435 target = target->toNode()->ownerDocument(); 466 target = target->toNode()->ownerDocument();
436 } 467 }
437 if (target) { 468 dispatchPointerEvent(target,
438 dispatchPointerEvent(target, 469 m_pointerEventFactory.createPointerCaptureEvent(
439 m_pointerEventFactory.createPointerCaptureEvent( 470 pointerEvent, EventTypeNames::lostpointercapture));
440 pointerEvent, EventTypeNames::lostpointercapture));
441 }
442 } 471 }
443 } 472 }
444 473
445 // Set pointerCaptureTarget from pendingPointerCaptureTarget. This does 474 // Set pointerCaptureTarget from pendingPointerCaptureTarget. This does
446 // affect the behavior of sendNodeTransitionEvents function. So the 475 // affect the behavior of sendNodeTransitionEvents function. So the
447 // ordering of the surrounding blocks of code for sending transition events 476 // ordering of the surrounding blocks of code for sending transition events
448 // are important. 477 // are important.
449 if (pendingPointerCaptureTarget) 478 if (pendingPointerCaptureTarget)
450 m_pointerCaptureTarget.set(pointerId, pendingPointerCaptureTarget); 479 m_pointerCaptureTarget.set(pointerId, pendingPointerCaptureTarget);
451 else 480 else
452 m_pointerCaptureTarget.remove(pointerId); 481 m_pointerCaptureTarget.remove(pointerId);
453 482
454 if (pointerCaptureTarget != pendingPointerCaptureTarget) { 483 if (isCaptureChanged) {
455 if (pendingPointerCaptureTarget) { 484 dispatchPointerEvent(pendingPointerCaptureTarget,
456 dispatchPointerEvent(pendingPointerCaptureTarget, 485 m_pointerEventFactory.createPointerCaptureEvent(
457 m_pointerEventFactory.createPointerCaptureEvent( 486 pointerEvent, EventTypeNames::gotpointercapture));
458 pointerEvent, EventTypeNames::gotpointercapture));
459 }
460 if ((pendingPointerCaptureTarget == hitTestTarget 487 if ((pendingPointerCaptureTarget == hitTestTarget
461 || !pendingPointerCaptureTarget) 488 || !pendingPointerCaptureTarget)
462 && (nodeUnderPointerAtt.target != hitTestTarget 489 && (nodeUnderPointerAtt.target != hitTestTarget
463 || !nodeUnderPointerAtt.hasRecievedOverEvent)) { 490 || !nodeUnderPointerAtt.hasRecievedOverEvent)) {
491 if (sendMouseEvent) {
492 // Send pointer event transitions as the line after this if
493 // block sends the mouse events
494 sendNodeTransitionEvents(nullptr, hitTestTarget, pointerEvent);
495 }
464 sendNodeTransitionEvents(nullptr, hitTestTarget, pointerEvent, 496 sendNodeTransitionEvents(nullptr, hitTestTarget, pointerEvent,
465 mouseEvent, sendMouseEvent); 497 mouseEvent, sendMouseEvent);
466 } 498 }
467 } 499 }
500 return isCaptureChanged;
468 } 501 }
469 502
470 void PointerEventManager::removeTargetFromPointerCapturingMapping( 503 void PointerEventManager::removeTargetFromPointerCapturingMapping(
471 PointerCapturingMap& map, const EventTarget* target) 504 PointerCapturingMap& map, const EventTarget* target)
472 { 505 {
473 // We could have kept a reverse mapping to make this deletion possibly 506 // 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 507 // 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 508 // the performance improvement considering there might not be a lot of
476 // active pointer or pointer captures at the same time. 509 // active pointer or pointer captures at the same time.
477 PointerCapturingMap tmp = map; 510 PointerCapturingMap tmp = map;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 { 564 {
532 #if ENABLE(OILPAN) 565 #if ENABLE(OILPAN)
533 visitor->trace(m_nodeUnderPointer); 566 visitor->trace(m_nodeUnderPointer);
534 visitor->trace(m_pointerCaptureTarget); 567 visitor->trace(m_pointerCaptureTarget);
535 visitor->trace(m_pendingPointerCaptureTarget); 568 visitor->trace(m_pendingPointerCaptureTarget);
536 #endif 569 #endif
537 } 570 }
538 571
539 572
540 } // namespace blink 573 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698