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

Side by Side Diff: Source/core/input/EventHandler.cpp

Issue 1144313003: Added PointerEvent firing on touch events. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebased. TODO fixes. Created 5 years, 6 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
« no previous file with comments | « Source/core/input/EventHandler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed. 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed.
3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) 3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies)
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 25 matching lines...) Expand all
36 #include "core/dom/Document.h" 36 #include "core/dom/Document.h"
37 #include "core/dom/TouchList.h" 37 #include "core/dom/TouchList.h"
38 #include "core/dom/shadow/ComposedTreeTraversal.h" 38 #include "core/dom/shadow/ComposedTreeTraversal.h"
39 #include "core/dom/shadow/ShadowRoot.h" 39 #include "core/dom/shadow/ShadowRoot.h"
40 #include "core/editing/Editor.h" 40 #include "core/editing/Editor.h"
41 #include "core/editing/FrameSelection.h" 41 #include "core/editing/FrameSelection.h"
42 #include "core/editing/SelectionController.h" 42 #include "core/editing/SelectionController.h"
43 #include "core/events/EventPath.h" 43 #include "core/events/EventPath.h"
44 #include "core/events/KeyboardEvent.h" 44 #include "core/events/KeyboardEvent.h"
45 #include "core/events/MouseEvent.h" 45 #include "core/events/MouseEvent.h"
46 #include "core/events/PointerEvent.h"
46 #include "core/events/TextEvent.h" 47 #include "core/events/TextEvent.h"
47 #include "core/events/TouchEvent.h" 48 #include "core/events/TouchEvent.h"
48 #include "core/events/WheelEvent.h" 49 #include "core/events/WheelEvent.h"
49 #include "core/fetch/ImageResource.h" 50 #include "core/fetch/ImageResource.h"
50 #include "core/frame/EventHandlerRegistry.h" 51 #include "core/frame/EventHandlerRegistry.h"
51 #include "core/frame/FrameHost.h" 52 #include "core/frame/FrameHost.h"
52 #include "core/frame/FrameView.h" 53 #include "core/frame/FrameView.h"
53 #include "core/frame/LocalFrame.h" 54 #include "core/frame/LocalFrame.h"
54 #include "core/frame/PinchViewport.h" 55 #include "core/frame/PinchViewport.h"
55 #include "core/frame/Settings.h" 56 #include "core/frame/Settings.h"
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 m_previousWheelScrolledNode = nullptr; 308 m_previousWheelScrolledNode = nullptr;
308 m_targetForTouchID.clear(); 309 m_targetForTouchID.clear();
309 m_touchSequenceDocument.clear(); 310 m_touchSequenceDocument.clear();
310 m_touchSequenceUserGestureToken.clear(); 311 m_touchSequenceUserGestureToken.clear();
311 m_scrollGestureHandlingNode = nullptr; 312 m_scrollGestureHandlingNode = nullptr;
312 m_lastGestureScrollOverWidget = false; 313 m_lastGestureScrollOverWidget = false;
313 m_previousGestureScrolledNode = nullptr; 314 m_previousGestureScrolledNode = nullptr;
314 m_scrollbarHandlingScrollGesture = nullptr; 315 m_scrollbarHandlingScrollGesture = nullptr;
315 m_maxMouseMovedDuration = 0; 316 m_maxMouseMovedDuration = 0;
316 m_touchPressed = false; 317 m_touchPressed = false;
318 m_pointerIdManager.clear();
317 m_mouseDownMayStartDrag = false; 319 m_mouseDownMayStartDrag = false;
318 m_lastShowPressTimestamp = 0; 320 m_lastShowPressTimestamp = 0;
319 m_lastDeferredTapElement = nullptr; 321 m_lastDeferredTapElement = nullptr;
320 m_eventHandlerWillResetCapturingMouseEventsNode = false; 322 m_eventHandlerWillResetCapturingMouseEventsNode = false;
321 m_mouseDownMayStartAutoscroll = false; 323 m_mouseDownMayStartAutoscroll = false;
322 m_svgPan = false; 324 m_svgPan = false;
323 m_mouseDownPos = IntPoint(); 325 m_mouseDownPos = IntPoint();
324 m_mouseDownTimestamp = 0; 326 m_mouseDownTimestamp = 0;
325 m_longTapShouldInvokeContextMenu = false; 327 m_longTapShouldInvokeContextMenu = false;
326 m_dragStartPos = LayoutPoint(); 328 m_dragStartPos = LayoutPoint();
(...skipping 3045 matching lines...) Expand 10 before | Expand all | Expand 10 after
3372 m_lastScrollbarUnderMouse->mouseExited(); 3374 m_lastScrollbarUnderMouse->mouseExited();
3373 3375
3374 // Send mouse entered if we're setting a new scrollbar. 3376 // Send mouse entered if we're setting a new scrollbar.
3375 if (scrollbar && setLast) 3377 if (scrollbar && setLast)
3376 scrollbar->mouseEntered(); 3378 scrollbar->mouseEntered();
3377 3379
3378 m_lastScrollbarUnderMouse = setLast ? scrollbar : nullptr; 3380 m_lastScrollbarUnderMouse = setLast ? scrollbar : nullptr;
3379 } 3381 }
3380 } 3382 }
3381 3383
3382 static const AtomicString& eventNameForTouchPointState(PlatformTouchPoint::State state) 3384 static const AtomicString& touchEventNameForTouchPointState(PlatformTouchPoint:: State state)
3383 { 3385 {
3384 switch (state) { 3386 switch (state) {
3385 case PlatformTouchPoint::TouchReleased: 3387 case PlatformTouchPoint::TouchReleased:
3386 return EventTypeNames::touchend; 3388 return EventTypeNames::touchend;
3387 case PlatformTouchPoint::TouchCancelled: 3389 case PlatformTouchPoint::TouchCancelled:
3388 return EventTypeNames::touchcancel; 3390 return EventTypeNames::touchcancel;
3389 case PlatformTouchPoint::TouchPressed: 3391 case PlatformTouchPoint::TouchPressed:
3390 return EventTypeNames::touchstart; 3392 return EventTypeNames::touchstart;
3391 case PlatformTouchPoint::TouchMoved: 3393 case PlatformTouchPoint::TouchMoved:
3392 return EventTypeNames::touchmove; 3394 return EventTypeNames::touchmove;
3393 case PlatformTouchPoint::TouchStationary: 3395 case PlatformTouchPoint::TouchStationary:
3394 // TouchStationary state is not converted to touch events, so fall throu gh to assert. 3396 // Fall through to default
3395 default: 3397 default:
3396 ASSERT_NOT_REACHED(); 3398 ASSERT_NOT_REACHED();
3397 return emptyAtom; 3399 return emptyAtom;
3400 }
3401 }
3402
3403 static const AtomicString& pointerEventNameForTouchPointState(PlatformTouchPoint ::State state)
3404 {
3405 switch (state) {
3406 case PlatformTouchPoint::TouchReleased:
3407 return EventTypeNames::pointerup;
3408 case PlatformTouchPoint::TouchCancelled:
3409 return EventTypeNames::pointercancel;
3410 case PlatformTouchPoint::TouchPressed:
3411 return EventTypeNames::pointerdown;
3412 case PlatformTouchPoint::TouchMoved:
3413 return EventTypeNames::pointermove;
3414 case PlatformTouchPoint::TouchStationary:
3415 // Fall through to default
3416 default:
3417 ASSERT_NOT_REACHED();
3418 return emptyAtom;
3398 } 3419 }
3399 } 3420 }
3400 3421
3401 HitTestResult EventHandler::hitTestResultInFrame(LocalFrame* frame, const Layout Point& point, HitTestRequest::HitTestRequestType hitType) 3422 HitTestResult EventHandler::hitTestResultInFrame(LocalFrame* frame, const Layout Point& point, HitTestRequest::HitTestRequestType hitType)
3402 { 3423 {
3403 HitTestResult result(HitTestRequest(hitType), point); 3424 HitTestResult result(HitTestRequest(hitType), point);
3404 3425
3405 if (!frame || !frame->contentLayoutObject()) 3426 if (!frame || !frame->contentLayoutObject())
3406 return result; 3427 return result;
3407 if (frame->view()) { 3428 if (frame->view()) {
3408 IntRect rect = frame->view()->visibleContentRect(IncludeScrollbars); 3429 IntRect rect = frame->view()->visibleContentRect(IncludeScrollbars);
3409 if (!rect.contains(roundedIntPoint(point))) 3430 if (!rect.contains(roundedIntPoint(point)))
3410 return result; 3431 return result;
3411 } 3432 }
3412 frame->contentLayoutObject()->hitTest(result); 3433 frame->contentLayoutObject()->hitTest(result);
3413 return result; 3434 return result;
3414 } 3435 }
3415 3436
3437 void EventHandler::dispatchPointerEventsForTouchEvent(const PlatformTouchEvent& event, Vector<TouchInfo>& touchInfos)
3438 {
3439 const String& PointerTypeStrForTouch("touch");
3440
3441 // Iterate through the touch points, sending PointerEvents to the targets as required.
3442 for (unsigned i = 0; i < touchInfos.size(); ++i) {
3443 TouchInfo& touchInfo = touchInfos[i];
3444 const PlatformTouchPoint& point = touchInfo.point;
3445 const unsigned& pointerId = point.id();
3446 const PlatformTouchPoint::State pointState = point.state();
3447
3448 if (pointState == PlatformTouchPoint::TouchStationary)
3449 continue;
3450 bool pointerReleasedOrCancelled =
3451 pointState == PlatformTouchPoint::TouchReleased || pointState == Pla tformTouchPoint::TouchCancelled;
3452 const AtomicString& eventName(pointerEventNameForTouchPointState(pointSt ate));
3453
3454 if (pointState == PlatformTouchPoint::TouchPressed)
3455 m_pointerIdManager.add(PointerIdManager::PointerTypeTouch, pointerId );
3456
3457 bool isEnterOrLeave = false;
3458
3459 PointerEventInit pointerEventInit;
3460 pointerEventInit.setPointerId(pointerId);
3461 pointerEventInit.setWidth(touchInfo.adjustedRadius.width());
3462 pointerEventInit.setHeight(touchInfo.adjustedRadius.height());
3463 pointerEventInit.setPressure(point.force());
3464 pointerEventInit.setPointerType(PointerTypeStrForTouch);
3465 pointerEventInit.setIsPrimary(m_pointerIdManager.isPrimary(PointerIdMana ger::PointerTypeTouch, pointerId));
3466 pointerEventInit.setScreenX(point.screenPos().x());
3467 pointerEventInit.setScreenY(point.screenPos().y());
3468 pointerEventInit.setClientX(touchInfo.adjustedPagePoint.x());
3469 pointerEventInit.setClientY(touchInfo.adjustedPagePoint.y());
3470 pointerEventInit.setButton(0);
3471 pointerEventInit.setButtons(pointerReleasedOrCancelled ? 0 : 1);
3472
3473 pointerEventInit.setCtrlKey(event.ctrlKey());
3474 pointerEventInit.setShiftKey(event.shiftKey());
3475 pointerEventInit.setAltKey(event.altKey());
3476 pointerEventInit.setMetaKey(event.metaKey());
3477
3478 pointerEventInit.setBubbles(!isEnterOrLeave);
3479 pointerEventInit.setCancelable(!isEnterOrLeave && pointState != Platform TouchPoint::TouchCancelled);
3480
3481 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = PointerEvent::create(eve ntName, pointerEventInit);
3482 touchInfo.touchTarget->toNode()->dispatchPointerEvent(pointerEvent.get() );
3483 touchInfo.consumed = pointerEvent->defaultPrevented() || pointerEvent->d efaultHandled();
3484
3485 // Remove the released/cancelled id at the end to correctly determine pr imary id above.
3486 if (pointerReleasedOrCancelled)
3487 m_pointerIdManager.remove(PointerIdManager::PointerTypeTouch, pointe rId);
3488 }
3489 }
3490
3491 bool EventHandler::dispatchTouchEvents(const PlatformTouchEvent& event,
3492 Vector<TouchInfo>& touchInfos, bool freshTouchEvents, bool allTouchReleased)
3493 {
3494 bool swallowedEvent = false;
3495
3496 // Build up the lists to use for the 'touches', 'targetTouches' and
3497 // 'changedTouches' attributes in the JS event. See
3498 // http://www.w3.org/TR/touch-events/#touchevent-interface for how these
3499 // lists fit together.
3500
3501 // Holds the complete set of touches on the screen.
3502 RefPtrWillBeRawPtr<TouchList> touches = TouchList::create();
3503
3504 // A different view on the 'touches' list above, filtered and grouped by
3505 // event target. Used for the 'targetTouches' list in the JS event.
3506 using TargetTouchesHeapMap = WillBeHeapHashMap<EventTarget*, RefPtrWillBeMem ber<TouchList>>;
3507 TargetTouchesHeapMap touchesByTarget;
3508
3509 // Array of touches per state, used to assemble the 'changedTouches' list.
3510 using EventTargetSet = WillBeHeapHashSet<RefPtrWillBeMember<EventTarget>>;
3511 struct {
3512 // The touches corresponding to the particular change state this struct
3513 // instance represents.
3514 RefPtrWillBeMember<TouchList> m_touches;
3515 // Set of targets involved in m_touches.
3516 EventTargetSet m_targets;
3517 } changedTouches[PlatformTouchPoint::TouchStateEnd];
3518
3519 for (unsigned i = 0; i < touchInfos.size(); ++i) {
3520 const TouchInfo& touchInfo = touchInfos[i];
3521 const PlatformTouchPoint& point = touchInfo.point;
3522 PlatformTouchPoint::State pointState = point.state();
3523
3524 if (touchInfo.consumed)
3525 continue;
3526
3527 RefPtrWillBeRawPtr<Touch> touch = Touch::create(
3528 touchInfo.targetFrame,
3529 touchInfo.touchTarget,
3530 point.id(),
3531 point.screenPos(),
3532 touchInfo.adjustedPagePoint,
3533 touchInfo.adjustedRadius,
3534 point.rotationAngle(),
3535 point.force());
3536
3537 // Ensure this target's touch list exists, even if it ends up empty, so
3538 // it can always be passed to TouchEvent::Create below.
3539 TargetTouchesHeapMap::iterator targetTouchesIterator = touchesByTarget.f ind(touchInfo.touchTarget);
3540 if (targetTouchesIterator == touchesByTarget.end()) {
3541 touchesByTarget.set(touchInfo.touchTarget, TouchList::create());
3542 targetTouchesIterator = touchesByTarget.find(touchInfo.touchTarget);
3543 }
3544
3545 // touches and targetTouches should only contain information about
3546 // touches still on the screen, so if this point is released or
3547 // cancelled it will only appear in the changedTouches list.
3548 if (pointState != PlatformTouchPoint::TouchReleased && pointState != Pla tformTouchPoint::TouchCancelled) {
3549 touches->append(touch);
3550 targetTouchesIterator->value->append(touch);
3551 }
3552
3553 // Now build up the correct list for changedTouches.
3554 // Note that any touches that are in the TouchStationary state (e.g. if
3555 // the user had several points touched but did not move them all) should
3556 // never be in the changedTouches list so we do not handle them
3557 // explicitly here. See https://bugs.webkit.org/show_bug.cgi?id=37609
3558 // for further discussion about the TouchStationary state.
3559 if (pointState != PlatformTouchPoint::TouchStationary && touchInfo.known Target) {
3560 ASSERT(pointState < PlatformTouchPoint::TouchStateEnd);
3561 if (!changedTouches[pointState].m_touches)
3562 changedTouches[pointState].m_touches = TouchList::create();
3563 changedTouches[pointState].m_touches->append(touch);
3564 changedTouches[pointState].m_targets.add(touchInfo.touchTarget);
3565 }
3566 }
3567 if (allTouchReleased) {
3568 m_touchSequenceDocument.clear();
3569 m_touchSequenceUserGestureToken.clear();
3570 }
3571
3572 // Now iterate through the changedTouches list and m_targets within it, send ing
3573 // TouchEvents to the targets as required.
3574 for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state ) {
3575 if (!changedTouches[state].m_touches)
3576 continue;
3577
3578 const AtomicString& eventName(touchEventNameForTouchPointState(static_ca st<PlatformTouchPoint::State>(state)));
3579 const EventTargetSet& targetsForState = changedTouches[state].m_targets;
3580 for (const RefPtrWillBeMember<EventTarget>& eventTarget : targetsForStat e) {
3581 EventTarget* touchEventTarget = eventTarget.get();
3582 RefPtrWillBeRawPtr<TouchEvent> touchEvent = TouchEvent::create(
3583 touches.get(), touchesByTarget.get(touchEventTarget), changedTou ches[state].m_touches.get(),
3584 eventName, touchEventTarget->toNode()->document().domWindow(),
3585 event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey (), event.cancelable(), event.causesScrollingIfUncanceled(), event.timestamp());
3586 touchEventTarget->toNode()->dispatchTouchEvent(touchEvent.get());
3587 swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() || touchEvent->defaultHandled();
3588 }
3589 }
3590
3591 return swallowedEvent;
3592 }
3593
3416 bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) 3594 bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
3417 { 3595 {
3418 TRACE_EVENT0("blink", "EventHandler::handleTouchEvent"); 3596 TRACE_EVENT0("blink", "EventHandler::handleTouchEvent");
3419 3597
3420 const Vector<PlatformTouchPoint>& points = event.touchPoints(); 3598 const Vector<PlatformTouchPoint>& points = event.touchPoints();
3421 3599
3422 unsigned i;
3423 bool freshTouchEvents = true; 3600 bool freshTouchEvents = true;
3424 bool allTouchReleased = true; 3601 bool allTouchReleased = true;
3425 for (i = 0; i < points.size(); ++i) { 3602 for (unsigned i = 0; i < points.size(); ++i) {
3426 const PlatformTouchPoint& point = points[i]; 3603 const PlatformTouchPoint& point = points[i];
3604
3427 if (point.state() != PlatformTouchPoint::TouchPressed) 3605 if (point.state() != PlatformTouchPoint::TouchPressed)
3428 freshTouchEvents = false; 3606 freshTouchEvents = false;
3429 if (point.state() != PlatformTouchPoint::TouchReleased && point.state() != PlatformTouchPoint::TouchCancelled) 3607 if (point.state() != PlatformTouchPoint::TouchReleased && point.state() != PlatformTouchPoint::TouchCancelled)
3430 allTouchReleased = false; 3608 allTouchReleased = false;
3431 } 3609 }
3432 if (freshTouchEvents) { 3610 if (freshTouchEvents) {
3433 // Ideally we'd ASSERT !m_touchSequenceDocument here since we should 3611 // Ideally we'd ASSERT !m_touchSequenceDocument here since we should
3434 // have cleared the active document when we saw the last release. But we 3612 // have cleared the active document when we saw the last release. But we
3435 // have some tests that violate this, ClusterFuzz could trigger it, and 3613 // have some tests that violate this, ClusterFuzz could trigger it, and
3436 // there may be cases where the browser doesn't reliably release all 3614 // there may be cases where the browser doesn't reliably release all
(...skipping 12 matching lines...) Expand all
3449 m_touchSequenceUserGestureToken = gestureIndicator->currentToken(); 3627 m_touchSequenceUserGestureToken = gestureIndicator->currentToken();
3450 3628
3451 ASSERT(m_frame->view()); 3629 ASSERT(m_frame->view());
3452 if (m_touchSequenceDocument && (!m_touchSequenceDocument->frame() || !m_touc hSequenceDocument->frame()->view())) { 3630 if (m_touchSequenceDocument && (!m_touchSequenceDocument->frame() || !m_touc hSequenceDocument->frame()->view())) {
3453 // If the active touch document has no frame or view, it's probably bein g destroyed 3631 // If the active touch document has no frame or view, it's probably bein g destroyed
3454 // so we can't dispatch events. 3632 // so we can't dispatch events.
3455 return false; 3633 return false;
3456 } 3634 }
3457 3635
3458 // First do hit tests for any new touch points. 3636 // First do hit tests for any new touch points.
3459 for (i = 0; i < points.size(); ++i) { 3637 for (unsigned i = 0; i < points.size(); ++i) {
3460 const PlatformTouchPoint& point = points[i]; 3638 const PlatformTouchPoint& point = points[i];
3461 3639
3462 // Touch events implicitly capture to the touched node, and don't change 3640 // Touch events implicitly capture to the touched node, and don't change
3463 // active/hover states themselves (Gesture events do). So we only need 3641 // active/hover states themselves (Gesture events do). So we only need
3464 // to hit-test on touchstart, and it can be read-only. 3642 // to hit-test on touchstart, and it can be read-only.
3465 if (point.state() == PlatformTouchPoint::TouchPressed) { 3643 if (point.state() == PlatformTouchPoint::TouchPressed) {
3466 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEv ent | HitTestRequest::ReadOnly | HitTestRequest::Active; 3644 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEv ent | HitTestRequest::ReadOnly | HitTestRequest::Active;
3467 LayoutPoint pagePoint = roundedLayoutPoint(m_frame->view()->rootFram eToContents(point.pos())); 3645 LayoutPoint pagePoint = roundedLayoutPoint(m_frame->view()->rootFram eToContents(point.pos()));
3468 HitTestResult result; 3646 HitTestResult result;
3469 if (!m_touchSequenceDocument) { 3647 if (!m_touchSequenceDocument) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3511 // document set to receive the events, then we can skip all the rest of 3689 // document set to receive the events, then we can skip all the rest of
3512 // this work. 3690 // this work.
3513 if (!m_touchSequenceDocument || !m_touchSequenceDocument->frameHost() || !m_ touchSequenceDocument->frameHost()->eventHandlerRegistry().hasEventHandlers(Even tHandlerRegistry::TouchEvent) || !m_touchSequenceDocument->frame()) { 3691 if (!m_touchSequenceDocument || !m_touchSequenceDocument->frameHost() || !m_ touchSequenceDocument->frameHost()->eventHandlerRegistry().hasEventHandlers(Even tHandlerRegistry::TouchEvent) || !m_touchSequenceDocument->frame()) {
3514 if (allTouchReleased) { 3692 if (allTouchReleased) {
3515 m_touchSequenceDocument.clear(); 3693 m_touchSequenceDocument.clear();
3516 m_touchSequenceUserGestureToken.clear(); 3694 m_touchSequenceUserGestureToken.clear();
3517 } 3695 }
3518 return false; 3696 return false;
3519 } 3697 }
3520 3698
3521 // Build up the lists to use for the 'touches', 'targetTouches' and 3699 // Compute and store the common info used by both PointerEvent and TouchEven t.
3522 // 'changedTouches' attributes in the JS event. See 3700 Vector<TouchInfo> touchInfos(points.size());
3523 // http://www.w3.org/TR/touch-events/#touchevent-interface for how these
3524 // lists fit together.
3525 3701
3526 // Holds the complete set of touches on the screen. 3702 for (unsigned i = 0; i < points.size(); ++i) {
3527 RefPtrWillBeRawPtr<TouchList> touches = TouchList::create();
3528
3529 // A different view on the 'touches' list above, filtered and grouped by
3530 // event target. Used for the 'targetTouches' list in the JS event.
3531 using TargetTouchesHeapMap = WillBeHeapHashMap<EventTarget*, RefPtrWillBeMem ber<TouchList>>;
3532 TargetTouchesHeapMap touchesByTarget;
3533
3534 // Array of touches per state, used to assemble the 'changedTouches' list.
3535 using EventTargetSet = WillBeHeapHashSet<RefPtrWillBeMember<EventTarget>>;
3536 struct {
3537 // The touches corresponding to the particular change state this struct
3538 // instance represents.
3539 RefPtrWillBeMember<TouchList> m_touches;
3540 // Set of targets involved in m_touches.
3541 EventTargetSet m_targets;
3542 } changedTouches[PlatformTouchPoint::TouchStateEnd];
3543
3544 for (i = 0; i < points.size(); ++i) {
3545 const PlatformTouchPoint& point = points[i]; 3703 const PlatformTouchPoint& point = points[i];
3546 PlatformTouchPoint::State pointState = point.state(); 3704 PlatformTouchPoint::State pointState = point.state();
3547 RefPtrWillBeRawPtr<EventTarget> touchTarget = nullptr; 3705 RefPtrWillBeRawPtr<EventTarget> touchTarget = nullptr;
3548 3706
3549 if (pointState == PlatformTouchPoint::TouchReleased || pointState == Pla tformTouchPoint::TouchCancelled) { 3707 if (pointState == PlatformTouchPoint::TouchReleased || pointState == Pla tformTouchPoint::TouchCancelled) {
3550 // The target should be the original target for this touch, so get 3708 // The target should be the original target for this touch, so get
3551 // it from the hashmap. As it's a release or cancel we also remove 3709 // it from the hashmap. As it's a release or cancel we also remove
3552 // it from the map. 3710 // it from the map.
3553 touchTarget = m_targetForTouchID.take(point.id()); 3711 touchTarget = m_targetForTouchID.take(point.id());
3554 } else { 3712 } else {
(...skipping 28 matching lines...) Expand all
3583 // a Touch is a Node so using the window could be a breaking change. 3741 // a Touch is a Node so using the window could be a breaking change.
3584 // Since we know there was no handler invoked, the specific target 3742 // Since we know there was no handler invoked, the specific target
3585 // should be completely irrelevant to the application. 3743 // should be completely irrelevant to the application.
3586 touchTarget = m_touchSequenceDocument; 3744 touchTarget = m_touchSequenceDocument;
3587 targetFrame = m_touchSequenceDocument->frame(); 3745 targetFrame = m_touchSequenceDocument->frame();
3588 } 3746 }
3589 ASSERT(targetFrame); 3747 ASSERT(targetFrame);
3590 3748
3591 // pagePoint should always be in the target element's document coordinat es. 3749 // pagePoint should always be in the target element's document coordinat es.
3592 FloatPoint pagePoint = targetFrame->view()->rootFrameToContents(point.po s()); 3750 FloatPoint pagePoint = targetFrame->view()->rootFrameToContents(point.po s());
3593
3594 float scaleFactor = 1.0f / targetFrame->pageZoomFactor(); 3751 float scaleFactor = 1.0f / targetFrame->pageZoomFactor();
3595 3752
3596 FloatPoint adjustedPagePoint = pagePoint.scaledBy(scaleFactor); 3753 TouchInfo& touchInfo = touchInfos[i];
3597 FloatSize adjustedRadius = point.radius().scaledBy(scaleFactor); 3754 touchInfo.point = point;
3598 3755 touchInfo.touchTarget = touchTarget.get();
3599 RefPtrWillBeRawPtr<Touch> touch = Touch::create( 3756 touchInfo.targetFrame = targetFrame;
3600 targetFrame, touchTarget.get(), point.id(), point.screenPos(), adjus tedPagePoint, adjustedRadius, point.rotationAngle(), point.force()); 3757 touchInfo.adjustedPagePoint = pagePoint.scaledBy(scaleFactor);
3601 3758 touchInfo.adjustedRadius = point.radius().scaledBy(scaleFactor);
3602 // Ensure this target's touch list exists, even if it ends up empty, so 3759 touchInfo.knownTarget = knownTarget;
3603 // it can always be passed to TouchEvent::Create below. 3760 touchInfo.consumed = false;
3604 TargetTouchesHeapMap::iterator targetTouchesIterator = touchesByTarget.f ind(touchTarget.get());
3605 if (targetTouchesIterator == touchesByTarget.end()) {
3606 touchesByTarget.set(touchTarget.get(), TouchList::create());
3607 targetTouchesIterator = touchesByTarget.find(touchTarget.get());
3608 }
3609
3610 // touches and targetTouches should only contain information about
3611 // touches still on the screen, so if this point is released or
3612 // cancelled it will only appear in the changedTouches list.
3613 if (pointState != PlatformTouchPoint::TouchReleased && pointState != Pla tformTouchPoint::TouchCancelled) {
3614 touches->append(touch);
3615 targetTouchesIterator->value->append(touch);
3616 }
3617
3618 // Now build up the correct list for changedTouches.
3619 // Note that any touches that are in the TouchStationary state (e.g. if
3620 // the user had several points touched but did not move them all) should
3621 // never be in the changedTouches list so we do not handle them
3622 // explicitly here. See https://bugs.webkit.org/show_bug.cgi?id=37609
3623 // for further discussion about the TouchStationary state.
3624 if (pointState != PlatformTouchPoint::TouchStationary && knownTarget) {
3625 ASSERT(pointState < PlatformTouchPoint::TouchStateEnd);
3626 if (!changedTouches[pointState].m_touches)
3627 changedTouches[pointState].m_touches = TouchList::create();
3628 changedTouches[pointState].m_touches->append(touch);
3629 changedTouches[pointState].m_targets.add(touchTarget);
3630 }
3631 }
3632 if (allTouchReleased) {
3633 m_touchSequenceDocument.clear();
3634 m_touchSequenceUserGestureToken.clear();
3635 } 3761 }
3636 3762
3637 // Now iterate the changedTouches list and m_targets within it, sending 3763 if (RuntimeEnabledFeatures::pointerEventEnabled()) {
3638 // events to the targets as required. 3764 dispatchPointerEventsForTouchEvent(event, touchInfos);
3639 bool swallowedEvent = false; 3765 // TODO(mustaq): This needs attention.
3640 for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state ) { 3766 // From CL discussion: The disposition of any pointer events affects onl y the generation of
3641 if (!changedTouches[state].m_touches) 3767 // touch events. If pointer events were handled (and hence no touch even ts generated) that is
3642 continue; 3768 // still equivalent to the touch events going unhandled because pointer event handler don't
3643 3769 // block scroll gesture generation.
3644 const AtomicString& stateName(eventNameForTouchPointState(static_cast<Pl atformTouchPoint::State>(state)));
3645 const EventTargetSet& targetsForState = changedTouches[state].m_targets;
3646 for (const RefPtrWillBeMember<EventTarget>& eventTarget : targetsForStat e) {
3647 EventTarget* touchEventTarget = eventTarget.get();
3648 RefPtrWillBeRawPtr<TouchEvent> touchEvent = TouchEvent::create(
3649 touches.get(), touchesByTarget.get(touchEventTarget), changedTou ches[state].m_touches.get(),
3650 stateName, touchEventTarget->toNode()->document().domWindow(),
3651 event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey (), event.cancelable(), event.causesScrollingIfUncanceled(), event.timestamp());
3652 touchEventTarget->toNode()->dispatchTouchEvent(touchEvent.get());
3653 swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() || touchEvent->defaultHandled();
3654 }
3655 } 3770 }
3656 3771
3657 return swallowedEvent; 3772 return dispatchTouchEvents(event, touchInfos, freshTouchEvents, allTouchRele ased);
3658 } 3773 }
3659 3774
3660 TouchAction EventHandler::intersectTouchAction(TouchAction action1, TouchAction action2) 3775 TouchAction EventHandler::intersectTouchAction(TouchAction action1, TouchAction action2)
3661 { 3776 {
3662 if (action1 == TouchActionNone || action2 == TouchActionNone) 3777 if (action1 == TouchActionNone || action2 == TouchActionNone)
3663 return TouchActionNone; 3778 return TouchActionNone;
3664 if (action1 == TouchActionAuto) 3779 if (action1 == TouchActionAuto)
3665 return action2; 3780 return action2;
3666 if (action2 == TouchActionAuto) 3781 if (action2 == TouchActionAuto)
3667 return action1; 3782 return action1;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
3761 unsigned EventHandler::accessKeyModifiers() 3876 unsigned EventHandler::accessKeyModifiers()
3762 { 3877 {
3763 #if OS(MACOSX) 3878 #if OS(MACOSX)
3764 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; 3879 return PlatformEvent::CtrlKey | PlatformEvent::AltKey;
3765 #else 3880 #else
3766 return PlatformEvent::AltKey; 3881 return PlatformEvent::AltKey;
3767 #endif 3882 #endif
3768 } 3883 }
3769 3884
3770 } // namespace blink 3885 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/input/EventHandler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698