| 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" |
| 11 #include "core/frame/FrameView.h" | 11 #include "core/frame/FrameView.h" |
| 12 #include "core/frame/UseCounter.h" | 12 #include "core/frame/UseCounter.h" |
| 13 #include "core/html/HTMLCanvasElement.h" | 13 #include "core/html/HTMLCanvasElement.h" |
| 14 #include "core/input/EventHandler.h" | 14 #include "core/input/EventHandler.h" |
| 15 #include "core/input/EventHandlingUtil.h" | 15 #include "core/input/EventHandlingUtil.h" |
| 16 #include "core/input/MouseEventManager.h" | 16 #include "core/input/MouseEventManager.h" |
| 17 #include "core/input/TouchActionUtil.h" | 17 #include "core/input/TouchActionUtil.h" |
| 18 #include "core/layout/HitTestCanvasResult.h" | 18 #include "core/layout/HitTestCanvasResult.h" |
| 19 #include "core/page/ChromeClient.h" | 19 #include "core/page/ChromeClient.h" |
| 20 #include "core/page/Page.h" | 20 #include "core/page/Page.h" |
| 21 #include "platform/PlatformTouchEvent.h" | 21 #include "public/platform/WebTouchEvent.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 bool isInDocument(EventTarget* n) { | 31 bool isInDocument(EventTarget* n) { |
| 32 return n && n->toNode() && n->toNode()->isConnected(); | 32 return n && n->toNode() && n->toNode()->isConnected(); |
| 33 } | 33 } |
| 34 | 34 |
| 35 Vector<PlatformTouchPoint> getCoalescedPoints( | 35 Vector<WebTouchPoint> getCoalescedPoints( |
| 36 const Vector<PlatformTouchEvent>& coalescedEvents, | 36 const Vector<WebTouchEvent>& coalescedEvents, |
| 37 int id) { | 37 int id) { |
| 38 Vector<PlatformTouchPoint> relatedPoints; | 38 Vector<WebTouchPoint> relatedPoints; |
| 39 for (const auto& touchEvent : coalescedEvents) { | 39 for (const auto& touchEvent : coalescedEvents) { |
| 40 for (auto& point : touchEvent.touchPoints()) { | 40 for (unsigned i = 0; i < touchEvent.touchesLength; ++i) { |
| 41 // TODO(nzolghadr): Need to filter out stationary points | 41 // TODO(nzolghadr): Need to filter out stationary points |
| 42 if (point.id() == id) | 42 if (touchEvent.touches[i].id == id) |
| 43 relatedPoints.push_back(point); | 43 relatedPoints.push_back(touchEvent.touchPointInRootFrame(i)); |
| 44 } | 44 } |
| 45 } | 45 } |
| 46 return relatedPoints; | 46 return relatedPoints; |
| 47 } | 47 } |
| 48 | 48 |
| 49 } // namespace | 49 } // namespace |
| 50 | 50 |
| 51 PointerEventManager::PointerEventManager(LocalFrame& frame, | 51 PointerEventManager::PointerEventManager(LocalFrame& frame, |
| 52 MouseEventManager& mouseEventManager) | 52 MouseEventManager& mouseEventManager) |
| 53 : m_frame(frame), | 53 : m_frame(frame), |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 | 263 |
| 264 removePointer(pointerEvent); | 264 removePointer(pointerEvent); |
| 265 } | 265 } |
| 266 } | 266 } |
| 267 | 267 |
| 268 void PointerEventManager::unblockTouchPointers() { | 268 void PointerEventManager::unblockTouchPointers() { |
| 269 m_inCanceledStateForPointerTypeTouch = false; | 269 m_inCanceledStateForPointerTypeTouch = false; |
| 270 } | 270 } |
| 271 | 271 |
| 272 WebInputEventResult PointerEventManager::handleTouchEvents( | 272 WebInputEventResult PointerEventManager::handleTouchEvents( |
| 273 const PlatformTouchEvent& event, | 273 const WebTouchEvent& event, |
| 274 const Vector<PlatformTouchEvent>& coalescedEvents) { | 274 const Vector<WebTouchEvent>& coalescedEvents) { |
| 275 if (event.type() == PlatformEvent::TouchScrollStarted) { | 275 if (event.type() == WebInputEvent::TouchScrollStarted) { |
| 276 blockTouchPointers(); | 276 blockTouchPointers(); |
| 277 return WebInputEventResult::HandledSystem; | 277 return WebInputEventResult::HandledSystem; |
| 278 } | 278 } |
| 279 | 279 |
| 280 bool newTouchSequence = true; | 280 bool newTouchSequence = true; |
| 281 for (const auto& touchPoint : event.touchPoints()) { | 281 for (unsigned i = 0; i < event.touchesLength; ++i) { |
| 282 if (touchPoint.state() != PlatformTouchPoint::TouchPressed) { | 282 if (event.touches[i].state != WebTouchPoint::StatePressed) { |
| 283 newTouchSequence = false; | 283 newTouchSequence = false; |
| 284 break; | 284 break; |
| 285 } | 285 } |
| 286 } | 286 } |
| 287 if (newTouchSequence) | 287 if (newTouchSequence) |
| 288 unblockTouchPointers(); | 288 unblockTouchPointers(); |
| 289 | 289 |
| 290 // Do any necessary hit-tests and compute the event targets for all pointers | 290 // Do any necessary hit-tests and compute the event targets for all pointers |
| 291 // in the event. | 291 // in the event. |
| 292 HeapVector<TouchEventManager::TouchInfo> touchInfos; | 292 HeapVector<TouchEventManager::TouchInfo> touchInfos; |
| 293 computeTouchTargets(event, touchInfos); | 293 computeTouchTargets(event, touchInfos); |
| 294 | 294 |
| 295 // Any finger lifting is a user gesture only when it wasn't associated with a | 295 // Any finger lifting is a user gesture only when it wasn't associated with a |
| 296 // scroll. | 296 // scroll. |
| 297 // https://docs.google.com/document/d/1oF1T3O7_E4t1PYHV6gyCwHxOi3ystm0eSL5xZu7
nvOg/edit# | 297 // https://docs.google.com/document/d/1oF1T3O7_E4t1PYHV6gyCwHxOi3ystm0eSL5xZu7
nvOg/edit# |
| 298 // Re-use the same UserGesture for touchend and pointerup (but not for the | 298 // Re-use the same UserGesture for touchend and pointerup (but not for the |
| 299 // mouse events generated by GestureTap). | 299 // mouse events generated by GestureTap). |
| 300 // For the rare case of multi-finger scenarios spanning documents, it | 300 // For the rare case of multi-finger scenarios spanning documents, it |
| 301 // seems extremely unlikely to matter which document the gesture is | 301 // seems extremely unlikely to matter which document the gesture is |
| 302 // associated with so just pick the first finger. | 302 // associated with so just pick the first finger. |
| 303 RefPtr<UserGestureToken> possibleGestureToken; | 303 RefPtr<UserGestureToken> possibleGestureToken; |
| 304 if (event.type() == PlatformEvent::TouchEnd && | 304 if (event.type() == WebInputEvent::TouchEnd && |
| 305 !m_inCanceledStateForPointerTypeTouch && !touchInfos.isEmpty() && | 305 !m_inCanceledStateForPointerTypeTouch && !touchInfos.isEmpty() && |
| 306 touchInfos[0].targetFrame) { | 306 touchInfos[0].targetFrame) { |
| 307 possibleGestureToken = | 307 possibleGestureToken = |
| 308 DocumentUserGestureToken::create(touchInfos[0].targetFrame->document()); | 308 DocumentUserGestureToken::create(touchInfos[0].targetFrame->document()); |
| 309 } | 309 } |
| 310 UserGestureIndicator holder(possibleGestureToken); | 310 UserGestureIndicator holder(possibleGestureToken); |
| 311 | 311 |
| 312 dispatchTouchPointerEvents(event, coalescedEvents, touchInfos); | 312 dispatchTouchPointerEvents(event, coalescedEvents, touchInfos); |
| 313 | 313 |
| 314 return m_touchEventManager->handleTouchEvent(event, touchInfos); | 314 return m_touchEventManager->handleTouchEvent(event, touchInfos); |
| 315 } | 315 } |
| 316 | 316 |
| 317 void PointerEventManager::computeTouchTargets( | 317 void PointerEventManager::computeTouchTargets( |
| 318 const PlatformTouchEvent& event, | 318 const WebTouchEvent& event, |
| 319 HeapVector<TouchEventManager::TouchInfo>& touchInfos) { | 319 HeapVector<TouchEventManager::TouchInfo>& touchInfos) { |
| 320 for (const auto& touchPoint : event.touchPoints()) { | 320 for (unsigned touchPoint = 0; touchPoint < event.touchesLength; |
| 321 ++touchPoint) { |
| 321 TouchEventManager::TouchInfo touchInfo; | 322 TouchEventManager::TouchInfo touchInfo; |
| 322 touchInfo.point = touchPoint; | 323 touchInfo.point = event.touchPointInRootFrame(touchPoint); |
| 323 | 324 |
| 324 int pointerId = | 325 int pointerId = m_pointerEventFactory.getPointerEventId(touchInfo.point); |
| 325 m_pointerEventFactory.getPointerEventId(touchPoint.pointerProperties()); | |
| 326 // Do the hit test either when the touch first starts or when the touch | 326 // Do the hit test either when the touch first starts or when the touch |
| 327 // is not captured. |m_pendingPointerCaptureTarget| indicates the target | 327 // is not captured. |m_pendingPointerCaptureTarget| indicates the target |
| 328 // that will be capturing this event. |m_pointerCaptureTarget| may not | 328 // that will be capturing this event. |m_pointerCaptureTarget| may not |
| 329 // have this target yet since the processing of that will be done right | 329 // have this target yet since the processing of that will be done right |
| 330 // before firing the event. | 330 // before firing the event. |
| 331 if (touchInfo.point.state() == PlatformTouchPoint::TouchPressed || | 331 if (touchInfo.point.state == WebTouchPoint::StatePressed || |
| 332 !m_pendingPointerCaptureTarget.contains(pointerId)) { | 332 !m_pendingPointerCaptureTarget.contains(pointerId)) { |
| 333 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent | | 333 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent | |
| 334 HitTestRequest::ReadOnly | | 334 HitTestRequest::ReadOnly | |
| 335 HitTestRequest::Active; | 335 HitTestRequest::Active; |
| 336 LayoutPoint pagePoint = LayoutPoint( | 336 LayoutPoint pagePoint = LayoutPoint( |
| 337 m_frame->view()->rootFrameToContents(touchInfo.point.pos())); | 337 m_frame->view()->rootFrameToContents(touchInfo.point.position)); |
| 338 HitTestResult hitTestTesult = | 338 HitTestResult hitTestTesult = |
| 339 m_frame->eventHandler().hitTestResultAtPoint(pagePoint, hitType); | 339 m_frame->eventHandler().hitTestResultAtPoint(pagePoint, hitType); |
| 340 Node* node = hitTestTesult.innerNode(); | 340 Node* node = hitTestTesult.innerNode(); |
| 341 if (node) { | 341 if (node) { |
| 342 touchInfo.targetFrame = node->document().frame(); | 342 touchInfo.targetFrame = node->document().frame(); |
| 343 if (isHTMLCanvasElement(node)) { | 343 if (isHTMLCanvasElement(node)) { |
| 344 HitTestCanvasResult* hitTestCanvasResult = | 344 HitTestCanvasResult* hitTestCanvasResult = |
| 345 toHTMLCanvasElement(node)->getControlAndIdIfHitRegionExists( | 345 toHTMLCanvasElement(node)->getControlAndIdIfHitRegionExists( |
| 346 hitTestTesult.pointInInnerNodeFrame()); | 346 hitTestTesult.pointInInnerNodeFrame()); |
| 347 if (hitTestCanvasResult->getControl()) | 347 if (hitTestCanvasResult->getControl()) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 364 touchInfo.touchNode = | 364 touchInfo.touchNode = |
| 365 m_pendingPointerCaptureTarget.get(pointerId)->toNode(); | 365 m_pendingPointerCaptureTarget.get(pointerId)->toNode(); |
| 366 touchInfo.targetFrame = touchInfo.touchNode->document().frame(); | 366 touchInfo.targetFrame = touchInfo.touchNode->document().frame(); |
| 367 } | 367 } |
| 368 | 368 |
| 369 touchInfos.push_back(touchInfo); | 369 touchInfos.push_back(touchInfo); |
| 370 } | 370 } |
| 371 } | 371 } |
| 372 | 372 |
| 373 void PointerEventManager::dispatchTouchPointerEvents( | 373 void PointerEventManager::dispatchTouchPointerEvents( |
| 374 const PlatformTouchEvent& event, | 374 const WebTouchEvent& event, |
| 375 const Vector<PlatformTouchEvent>& coalescedEvents, | 375 const Vector<WebTouchEvent>& coalescedEvents, |
| 376 HeapVector<TouchEventManager::TouchInfo>& touchInfos) { | 376 HeapVector<TouchEventManager::TouchInfo>& touchInfos) { |
| 377 // Iterate through the touch points, sending PointerEvents to the targets as | 377 // Iterate through the touch points, sending PointerEvents to the targets as |
| 378 // required. | 378 // required. |
| 379 for (auto touchInfo : touchInfos) { | 379 for (auto touchInfo : touchInfos) { |
| 380 const PlatformTouchPoint& touchPoint = touchInfo.point; | 380 const WebTouchPoint& touchPoint = touchInfo.point; |
| 381 // Do not send pointer events for stationary touches or null targetFrame | 381 // Do not send pointer events for stationary touches or null targetFrame |
| 382 if (touchInfo.touchNode && touchInfo.targetFrame && | 382 if (touchInfo.touchNode && touchInfo.targetFrame && |
| 383 touchPoint.state() != PlatformTouchPoint::TouchStationary && | 383 touchPoint.state != WebTouchPoint::StateStationary && |
| 384 !m_inCanceledStateForPointerTypeTouch) { | 384 !m_inCanceledStateForPointerTypeTouch) { |
| 385 PointerEvent* pointerEvent = m_pointerEventFactory.create( | 385 PointerEvent* pointerEvent = m_pointerEventFactory.create( |
| 386 touchPoint, getCoalescedPoints(coalescedEvents, touchPoint.id()), | 386 touchPoint, getCoalescedPoints(coalescedEvents, touchPoint.id), |
| 387 event.getModifiers(), touchInfo.targetFrame, | 387 static_cast<WebInputEvent::Modifiers>(event.modifiers()), |
| 388 touchInfo.targetFrame, |
| 388 touchInfo.touchNode ? touchInfo.touchNode->document().domWindow() | 389 touchInfo.touchNode ? touchInfo.touchNode->document().domWindow() |
| 389 : nullptr); | 390 : nullptr); |
| 390 | 391 |
| 391 WebInputEventResult result = | 392 WebInputEventResult result = |
| 392 sendTouchPointerEvent(touchInfo.touchNode, pointerEvent); | 393 sendTouchPointerEvent(touchInfo.touchNode, pointerEvent); |
| 393 | 394 |
| 394 // If a pointerdown has been canceled, queue the unique id to allow | 395 // If a pointerdown has been canceled, queue the unique id to allow |
| 395 // suppressing mouse events from gesture events. For mouse events | 396 // suppressing mouse events from gesture events. For mouse events |
| 396 // fired from GestureTap & GestureLongPress (which are triggered by | 397 // fired from GestureTap & GestureLongPress (which are triggered by |
| 397 // single touches only), it is enough to queue the ids only for | 398 // single touches only), it is enough to queue the ids only for |
| 398 // primary pointers. | 399 // primary pointers. |
| 399 // TODO(mustaq): What about other cases (e.g. GestureTwoFingerTap)? | 400 // TODO(mustaq): What about other cases (e.g. GestureTwoFingerTap)? |
| 400 if (result != WebInputEventResult::NotHandled && | 401 if (result != WebInputEventResult::NotHandled && |
| 401 pointerEvent->type() == EventTypeNames::pointerdown && | 402 pointerEvent->type() == EventTypeNames::pointerdown && |
| 402 pointerEvent->isPrimary()) { | 403 pointerEvent->isPrimary()) { |
| 403 m_touchIdsForCanceledPointerdowns.append(event.uniqueTouchEventId()); | 404 m_touchIdsForCanceledPointerdowns.append(event.uniqueTouchEventId); |
| 404 } | 405 } |
| 405 } | 406 } |
| 406 } | 407 } |
| 407 } | 408 } |
| 408 | 409 |
| 409 WebInputEventResult PointerEventManager::sendTouchPointerEvent( | 410 WebInputEventResult PointerEventManager::sendTouchPointerEvent( |
| 410 EventTarget* target, | 411 EventTarget* target, |
| 411 PointerEvent* pointerEvent) { | 412 PointerEvent* pointerEvent) { |
| 412 if (m_inCanceledStateForPointerTypeTouch) | 413 if (m_inCanceledStateForPointerTypeTouch) |
| 413 return WebInputEventResult::NotHandled; | 414 return WebInputEventResult::NotHandled; |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 if (firstId > uniqueTouchEventId) | 693 if (firstId > uniqueTouchEventId) |
| 693 return false; | 694 return false; |
| 694 m_touchIdsForCanceledPointerdowns.takeFirst(); | 695 m_touchIdsForCanceledPointerdowns.takeFirst(); |
| 695 if (firstId == uniqueTouchEventId) | 696 if (firstId == uniqueTouchEventId) |
| 696 return true; | 697 return true; |
| 697 } | 698 } |
| 698 return false; | 699 return false; |
| 699 } | 700 } |
| 700 | 701 |
| 701 } // namespace blink | 702 } // namespace blink |
| OLD | NEW |