OLD | NEW |
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/DocumentUserGestureToken.h" | 7 #include "core/dom/DocumentUserGestureToken.h" |
8 #include "core/dom/ElementTraversal.h" | 8 #include "core/dom/ElementTraversal.h" |
9 #include "core/dom/shadow/FlatTreeTraversal.h" | 9 #include "core/dom/shadow/FlatTreeTraversal.h" |
10 #include "core/events/MouseEvent.h" | 10 #include "core/events/MouseEvent.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 #include "platform/PlatformTouchEvent.h" | 21 #include "platform/PlatformTouchEvent.h" |
22 | 22 |
23 namespace blink { | 23 namespace blink { |
24 | 24 |
25 namespace { | 25 namespace { |
26 | 26 |
27 size_t toPointerTypeIndex(WebPointerProperties::PointerType t) { | 27 size_t toPointerTypeIndex(WebPointerProperties::PointerType t) { |
28 return static_cast<size_t>(t); | 28 return static_cast<size_t>(t); |
29 } | 29 } |
30 | 30 |
31 const AtomicString& pointerEventNameForTouchPointState( | |
32 PlatformTouchPoint::TouchState state) { | |
33 switch (state) { | |
34 case PlatformTouchPoint::TouchReleased: | |
35 return EventTypeNames::pointerup; | |
36 case PlatformTouchPoint::TouchCancelled: | |
37 return EventTypeNames::pointercancel; | |
38 case PlatformTouchPoint::TouchPressed: | |
39 return EventTypeNames::pointerdown; | |
40 case PlatformTouchPoint::TouchMoved: | |
41 return EventTypeNames::pointermove; | |
42 case PlatformTouchPoint::TouchStationary: | |
43 // Fall through to default | |
44 default: | |
45 NOTREACHED(); | |
46 return emptyAtom; | |
47 } | |
48 } | |
49 | |
50 bool isInDocument(EventTarget* n) { | 31 bool isInDocument(EventTarget* n) { |
51 return n && n->toNode() && n->toNode()->isConnected(); | 32 return n && n->toNode() && n->toNode()->isConnected(); |
52 } | 33 } |
53 | 34 |
| 35 Vector<PlatformTouchPoint> getCoalescedPoints( |
| 36 const Vector<PlatformTouchEvent>& coalescedEvents, |
| 37 int id) { |
| 38 Vector<PlatformTouchPoint> relatedPoints; |
| 39 for (const auto& touchEvent : coalescedEvents) { |
| 40 for (auto& point : touchEvent.touchPoints()) { |
| 41 // TODO(nzolghadr): Need to filter out stationary points |
| 42 if (point.id() == id) |
| 43 relatedPoints.append(point); |
| 44 } |
| 45 } |
| 46 return relatedPoints; |
| 47 } |
| 48 |
54 } // namespace | 49 } // namespace |
55 | 50 |
56 PointerEventManager::PointerEventManager(LocalFrame* frame, | 51 PointerEventManager::PointerEventManager(LocalFrame* frame, |
57 MouseEventManager* mouseEventManager) | 52 MouseEventManager* mouseEventManager) |
58 : m_frame(frame), | 53 : m_frame(frame), |
59 m_touchEventManager(new TouchEventManager(frame)), | 54 m_touchEventManager(new TouchEventManager(frame)), |
60 m_mouseEventManager(mouseEventManager) { | 55 m_mouseEventManager(mouseEventManager) { |
61 clear(); | 56 clear(); |
62 } | 57 } |
63 | 58 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 return target; | 178 return target; |
184 } | 179 } |
185 | 180 |
186 void PointerEventManager::sendMouseAndPointerBoundaryEvents( | 181 void PointerEventManager::sendMouseAndPointerBoundaryEvents( |
187 Node* enteredNode, | 182 Node* enteredNode, |
188 const PlatformMouseEvent& mouseEvent) { | 183 const PlatformMouseEvent& mouseEvent) { |
189 // Mouse event type does not matter as this pointerevent will only be used | 184 // Mouse event type does not matter as this pointerevent will only be used |
190 // to create boundary pointer events and its type will be overridden in | 185 // to create boundary pointer events and its type will be overridden in |
191 // |sendBoundaryEvents| function. | 186 // |sendBoundaryEvents| function. |
192 PointerEvent* dummyPointerEvent = m_pointerEventFactory.create( | 187 PointerEvent* dummyPointerEvent = m_pointerEventFactory.create( |
193 EventTypeNames::mousedown, mouseEvent, m_frame->document()->domWindow()); | 188 EventTypeNames::mousedown, mouseEvent, Vector<PlatformMouseEvent>(), |
| 189 m_frame->document()->domWindow()); |
194 | 190 |
195 // TODO(crbug/545647): This state should reset with pointercancel too. | 191 // TODO(crbug/545647): This state should reset with pointercancel too. |
196 // This function also gets called for compat mouse events of touch at this | 192 // This function also gets called for compat mouse events of touch at this |
197 // stage. So if the event is not frame boundary transition it is only a | 193 // stage. So if the event is not frame boundary transition it is only a |
198 // compatibility mouse event and we do not need to change pointer event | 194 // compatibility mouse event and we do not need to change pointer event |
199 // behavior regarding preventMouseEvent state in that case. | 195 // behavior regarding preventMouseEvent state in that case. |
200 if (dummyPointerEvent->buttons() == 0 && dummyPointerEvent->isPrimary()) { | 196 if (dummyPointerEvent->buttons() == 0 && dummyPointerEvent->isPrimary()) { |
201 m_preventMouseEventForPointerType[toPointerTypeIndex( | 197 m_preventMouseEventForPointerType[toPointerTypeIndex( |
202 mouseEvent.pointerProperties().pointerType)] = false; | 198 mouseEvent.pointerProperties().pointerType)] = false; |
203 } | 199 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 | 276 |
281 removePointer(pointerEvent); | 277 removePointer(pointerEvent); |
282 } | 278 } |
283 } | 279 } |
284 | 280 |
285 void PointerEventManager::unblockTouchPointers() { | 281 void PointerEventManager::unblockTouchPointers() { |
286 m_inCanceledStateForPointerTypeTouch = false; | 282 m_inCanceledStateForPointerTypeTouch = false; |
287 } | 283 } |
288 | 284 |
289 WebInputEventResult PointerEventManager::handleTouchEvents( | 285 WebInputEventResult PointerEventManager::handleTouchEvents( |
290 const PlatformTouchEvent& event) { | 286 const PlatformTouchEvent& event, |
| 287 const Vector<PlatformTouchEvent>& coalescedEvents) { |
291 if (event.type() == PlatformEvent::TouchScrollStarted) { | 288 if (event.type() == PlatformEvent::TouchScrollStarted) { |
292 blockTouchPointers(); | 289 blockTouchPointers(); |
293 return WebInputEventResult::HandledSystem; | 290 return WebInputEventResult::HandledSystem; |
294 } | 291 } |
295 | 292 |
296 bool newTouchSequence = true; | 293 bool newTouchSequence = true; |
297 for (const auto& touchPoint : event.touchPoints()) { | 294 for (const auto& touchPoint : event.touchPoints()) { |
298 if (touchPoint.state() != PlatformTouchPoint::TouchPressed) { | 295 if (touchPoint.state() != PlatformTouchPoint::TouchPressed) { |
299 newTouchSequence = false; | 296 newTouchSequence = false; |
300 break; | 297 break; |
(...skipping 17 matching lines...) Expand all Loading... |
318 // associated with so just pick the first finger. | 315 // associated with so just pick the first finger. |
319 RefPtr<UserGestureToken> possibleGestureToken; | 316 RefPtr<UserGestureToken> possibleGestureToken; |
320 if (event.type() == PlatformEvent::TouchEnd && | 317 if (event.type() == PlatformEvent::TouchEnd && |
321 !m_inCanceledStateForPointerTypeTouch && !touchInfos.isEmpty() && | 318 !m_inCanceledStateForPointerTypeTouch && !touchInfos.isEmpty() && |
322 touchInfos[0].targetFrame) { | 319 touchInfos[0].targetFrame) { |
323 possibleGestureToken = | 320 possibleGestureToken = |
324 DocumentUserGestureToken::create(touchInfos[0].targetFrame->document()); | 321 DocumentUserGestureToken::create(touchInfos[0].targetFrame->document()); |
325 } | 322 } |
326 UserGestureIndicator holder(possibleGestureToken); | 323 UserGestureIndicator holder(possibleGestureToken); |
327 | 324 |
328 dispatchTouchPointerEvents(event, touchInfos); | 325 dispatchTouchPointerEvents(event, coalescedEvents, touchInfos); |
329 | 326 |
330 return m_touchEventManager->handleTouchEvent(event, touchInfos); | 327 return m_touchEventManager->handleTouchEvent(event, touchInfos); |
331 } | 328 } |
332 | 329 |
333 void PointerEventManager::computeTouchTargets( | 330 void PointerEventManager::computeTouchTargets( |
334 const PlatformTouchEvent& event, | 331 const PlatformTouchEvent& event, |
335 HeapVector<TouchEventManager::TouchInfo>& touchInfos) { | 332 HeapVector<TouchEventManager::TouchInfo>& touchInfos) { |
336 for (const auto& touchPoint : event.touchPoints()) { | 333 for (const auto& touchPoint : event.touchPoints()) { |
337 TouchEventManager::TouchInfo touchInfo; | 334 TouchEventManager::TouchInfo touchInfo; |
338 touchInfo.point = touchPoint; | 335 touchInfo.point = touchPoint; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 m_pendingPointerCaptureTarget.get(pointerId)->toNode(); | 379 m_pendingPointerCaptureTarget.get(pointerId)->toNode(); |
383 touchInfo.targetFrame = touchInfo.touchNode->document().frame(); | 380 touchInfo.targetFrame = touchInfo.touchNode->document().frame(); |
384 } | 381 } |
385 | 382 |
386 touchInfos.append(touchInfo); | 383 touchInfos.append(touchInfo); |
387 } | 384 } |
388 } | 385 } |
389 | 386 |
390 void PointerEventManager::dispatchTouchPointerEvents( | 387 void PointerEventManager::dispatchTouchPointerEvents( |
391 const PlatformTouchEvent& event, | 388 const PlatformTouchEvent& event, |
| 389 const Vector<PlatformTouchEvent>& coalescedEvents, |
392 HeapVector<TouchEventManager::TouchInfo>& touchInfos) { | 390 HeapVector<TouchEventManager::TouchInfo>& touchInfos) { |
393 // Iterate through the touch points, sending PointerEvents to the targets as | 391 // Iterate through the touch points, sending PointerEvents to the targets as |
394 // required. | 392 // required. |
395 for (auto touchInfo : touchInfos) { | 393 for (auto touchInfo : touchInfos) { |
396 const PlatformTouchPoint& touchPoint = touchInfo.point; | 394 const PlatformTouchPoint& touchPoint = touchInfo.point; |
397 // Do not send pointer events for stationary touches or null targetFrame | 395 // Do not send pointer events for stationary touches or null targetFrame |
398 if (touchInfo.touchNode && touchInfo.targetFrame && | 396 if (touchInfo.touchNode && touchInfo.targetFrame && |
399 touchPoint.state() != PlatformTouchPoint::TouchStationary && | 397 touchPoint.state() != PlatformTouchPoint::TouchStationary && |
400 !m_inCanceledStateForPointerTypeTouch) { | 398 !m_inCanceledStateForPointerTypeTouch) { |
401 FloatPoint pagePoint = touchInfo.targetFrame->view()->rootFrameToContents( | |
402 touchInfo.point.pos()); | |
403 float scaleFactor = 1.0f / touchInfo.targetFrame->pageZoomFactor(); | |
404 FloatPoint scrollPosition(touchInfo.targetFrame->view()->scrollOffset()); | |
405 FloatPoint framePoint = pagePoint.scaledBy(scaleFactor); | |
406 framePoint.moveBy(scrollPosition.scaledBy(-scaleFactor)); | |
407 PointerEvent* pointerEvent = m_pointerEventFactory.create( | 399 PointerEvent* pointerEvent = m_pointerEventFactory.create( |
408 pointerEventNameForTouchPointState(touchPoint.state()), touchPoint, | 400 touchPoint, getCoalescedPoints(coalescedEvents, touchPoint.id()), |
409 event.getModifiers(), touchPoint.radius().scaledBy(scaleFactor), | 401 event.getModifiers(), touchInfo.targetFrame, |
410 framePoint, | |
411 touchInfo.touchNode ? touchInfo.touchNode->document().domWindow() | 402 touchInfo.touchNode ? touchInfo.touchNode->document().domWindow() |
412 : nullptr); | 403 : nullptr); |
413 | 404 |
414 WebInputEventResult result = | 405 WebInputEventResult result = |
415 sendTouchPointerEvent(touchInfo.touchNode, pointerEvent); | 406 sendTouchPointerEvent(touchInfo.touchNode, pointerEvent); |
416 | 407 |
417 // If a pointerdown has been canceled, queue the unique id to allow | 408 // If a pointerdown has been canceled, queue the unique id to allow |
418 // suppressing mouse events from gesture events. For mouse events | 409 // suppressing mouse events from gesture events. For mouse events |
419 // fired from GestureTap & GestureLongPress (which are triggered by | 410 // fired from GestureTap & GestureLongPress (which are triggered by |
420 // single touches only), it is enough to queue the ids only for | 411 // single touches only), it is enough to queue the ids only for |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 | 447 |
457 removePointer(pointerEvent); | 448 removePointer(pointerEvent); |
458 } | 449 } |
459 | 450 |
460 return result; | 451 return result; |
461 } | 452 } |
462 | 453 |
463 WebInputEventResult PointerEventManager::sendMousePointerEvent( | 454 WebInputEventResult PointerEventManager::sendMousePointerEvent( |
464 Node* target, | 455 Node* target, |
465 const AtomicString& mouseEventType, | 456 const AtomicString& mouseEventType, |
466 const PlatformMouseEvent& mouseEvent) { | 457 const PlatformMouseEvent& mouseEvent, |
467 PointerEvent* pointerEvent = m_pointerEventFactory.create( | 458 const Vector<PlatformMouseEvent>& coalescedEvents) { |
468 mouseEventType, mouseEvent, m_frame->document()->domWindow()); | 459 PointerEvent* pointerEvent = |
| 460 m_pointerEventFactory.create(mouseEventType, mouseEvent, coalescedEvents, |
| 461 m_frame->document()->domWindow()); |
469 | 462 |
470 // This is for when the mouse is released outside of the page. | 463 // This is for when the mouse is released outside of the page. |
471 if (pointerEvent->type() == EventTypeNames::pointermove && | 464 if (pointerEvent->type() == EventTypeNames::pointermove && |
472 !pointerEvent->buttons()) { | 465 !pointerEvent->buttons()) { |
473 releasePointerCapture(pointerEvent->pointerId()); | 466 releasePointerCapture(pointerEvent->pointerId()); |
474 // Send got/lostpointercapture rightaway if necessary. | 467 // Send got/lostpointercapture rightaway if necessary. |
475 processPendingPointerCapture(pointerEvent); | 468 processPendingPointerCapture(pointerEvent); |
476 | 469 |
477 if (pointerEvent->isPrimary()) { | 470 if (pointerEvent->isPrimary()) { |
478 m_preventMouseEventForPointerType[toPointerTypeIndex( | 471 m_preventMouseEventForPointerType[toPointerTypeIndex( |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
719 return true; | 712 return true; |
720 } | 713 } |
721 return false; | 714 return false; |
722 } | 715 } |
723 | 716 |
724 EventTarget* PointerEventManager::getMouseCapturingNode() { | 717 EventTarget* PointerEventManager::getMouseCapturingNode() { |
725 return getCapturingNode(PointerEventFactory::s_mouseId); | 718 return getCapturingNode(PointerEventFactory::s_mouseId); |
726 } | 719 } |
727 | 720 |
728 } // namespace blink | 721 } // namespace blink |
OLD | NEW |