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

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

Issue 259413003: Correctly handle touch events that contain touches not previously reported to blink (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: rjkroege cr Created 6 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/page/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 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 , m_mouseDownWasInSubframe(false) 215 , m_mouseDownWasInSubframe(false)
216 , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFire d) 216 , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFire d)
217 , m_svgPan(false) 217 , m_svgPan(false)
218 , m_resizeScrollableArea(0) 218 , m_resizeScrollableArea(0)
219 , m_eventHandlerWillResetCapturingMouseEventsNode(0) 219 , m_eventHandlerWillResetCapturingMouseEventsNode(0)
220 , m_clickCount(0) 220 , m_clickCount(0)
221 , m_shouldOnlyFireDragOverEvent(false) 221 , m_shouldOnlyFireDragOverEvent(false)
222 , m_mousePositionIsUnknown(true) 222 , m_mousePositionIsUnknown(true)
223 , m_mouseDownTimestamp(0) 223 , m_mouseDownTimestamp(0)
224 , m_widgetIsLatched(false) 224 , m_widgetIsLatched(false)
225 , m_originatingTouchPointTargetKey(0)
226 , m_touchPressed(false) 225 , m_touchPressed(false)
227 , m_scrollGestureHandlingNode(nullptr) 226 , m_scrollGestureHandlingNode(nullptr)
228 , m_lastHitTestResultOverWidget(false) 227 , m_lastHitTestResultOverWidget(false)
229 , m_maxMouseMovedDuration(0) 228 , m_maxMouseMovedDuration(0)
230 , m_baseEventType(PlatformEvent::NoType) 229 , m_baseEventType(PlatformEvent::NoType)
231 , m_didStartDrag(false) 230 , m_didStartDrag(false)
232 , m_longTapShouldInvokeContextMenu(false) 231 , m_longTapShouldInvokeContextMenu(false)
233 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) 232 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired)
234 , m_lastShowPressTimestamp(0) 233 , m_lastShowPressTimestamp(0)
235 { 234 {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 m_mousePositionIsUnknown = true; 270 m_mousePositionIsUnknown = true;
272 m_lastKnownMousePosition = IntPoint(); 271 m_lastKnownMousePosition = IntPoint();
273 m_lastKnownMouseGlobalPosition = IntPoint(); 272 m_lastKnownMouseGlobalPosition = IntPoint();
274 m_lastMouseDownUserGestureToken.clear(); 273 m_lastMouseDownUserGestureToken.clear();
275 m_mousePressNode = nullptr; 274 m_mousePressNode = nullptr;
276 m_mousePressed = false; 275 m_mousePressed = false;
277 m_capturesDragging = false; 276 m_capturesDragging = false;
278 m_capturingMouseEventsNode = nullptr; 277 m_capturingMouseEventsNode = nullptr;
279 m_latchedWheelEventNode = nullptr; 278 m_latchedWheelEventNode = nullptr;
280 m_previousWheelScrolledNode = nullptr; 279 m_previousWheelScrolledNode = nullptr;
281 m_originatingTouchPointTargets.clear(); 280 m_targetForTouchID.clear();
282 m_originatingTouchPointDocument.clear(); 281 m_touchSequenceDocument.clear();
283 m_originatingTouchPointTargetKey = 0;
284 m_scrollGestureHandlingNode = nullptr; 282 m_scrollGestureHandlingNode = nullptr;
285 m_lastHitTestResultOverWidget = false; 283 m_lastHitTestResultOverWidget = false;
286 m_previousGestureScrolledNode = nullptr; 284 m_previousGestureScrolledNode = nullptr;
287 m_scrollbarHandlingScrollGesture = nullptr; 285 m_scrollbarHandlingScrollGesture = nullptr;
288 m_maxMouseMovedDuration = 0; 286 m_maxMouseMovedDuration = 0;
289 m_baseEventType = PlatformEvent::NoType; 287 m_baseEventType = PlatformEvent::NoType;
290 m_didStartDrag = false; 288 m_didStartDrag = false;
291 m_touchPressed = false; 289 m_touchPressed = false;
292 m_mouseDownMayStartSelect = false; 290 m_mouseDownMayStartSelect = false;
293 m_mouseDownMayStartDrag = false; 291 m_mouseDownMayStartDrag = false;
(...skipping 3136 matching lines...) Expand 10 before | Expand all | Expand 10 after
3430 return result; 3428 return result;
3431 } 3429 }
3432 frame->contentRenderer()->hitTest(HitTestRequest(hitType), result); 3430 frame->contentRenderer()->hitTest(HitTestRequest(hitType), result);
3433 return result; 3431 return result;
3434 } 3432 }
3435 3433
3436 bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) 3434 bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
3437 { 3435 {
3438 TRACE_EVENT0("webkit", "EventHandler::handleTouchEvent"); 3436 TRACE_EVENT0("webkit", "EventHandler::handleTouchEvent");
3439 3437
3440 // First build up the lists to use for the 'touches', 'targetTouches' and 'c hangedTouches' attributes
3441 // in the JS event. See http://www.sitepen.com/blog/2008/07/10/touching-and- gesturing-on-the-iphone/
3442 // for an overview of how these lists fit together.
3443
3444 // Holds the complete set of touches on the screen and will be used as the ' touches' list in the JS event.
3445 RefPtrWillBeRawPtr<TouchList> touches = TouchList::create();
3446
3447 // A different view on the 'touches' list above, filtered and grouped by eve nt target. Used for the
3448 // 'targetTouches' list in the JS event.
3449 typedef WillBeHeapHashMap<EventTarget*, RefPtrWillBeMember<TouchList> > Targ etTouchesHeapMap;
3450 TargetTouchesHeapMap touchesByTarget;
3451
3452 // Array of touches per state, used to assemble the 'changedTouches' list in the JS event.
3453 typedef HashSet<RefPtr<EventTarget> > EventTargetSet;
3454 struct {
3455 // The touches corresponding to the particular change state this struct instance represents.
3456 RefPtrWillBeMember<TouchList> m_touches;
3457 // Set of targets involved in m_touches.
3458 EventTargetSet m_targets;
3459 } changedTouches[PlatformTouchPoint::TouchStateEnd];
3460
3461 const Vector<PlatformTouchPoint>& points = event.touchPoints(); 3438 const Vector<PlatformTouchPoint>& points = event.touchPoints();
3462 3439
3463 UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture); 3440 UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
3464 3441
3465 unsigned i; 3442 unsigned i;
3466 bool freshTouchEvents = true; 3443 bool freshTouchEvents = true;
3467 bool allTouchReleased = true; 3444 bool allTouchReleased = true;
3468 for (i = 0; i < points.size(); ++i) { 3445 for (i = 0; i < points.size(); ++i) {
3469 const PlatformTouchPoint& point = points[i]; 3446 const PlatformTouchPoint& point = points[i];
3470 if (point.state() != PlatformTouchPoint::TouchPressed) 3447 if (point.state() != PlatformTouchPoint::TouchPressed)
3471 freshTouchEvents = false; 3448 freshTouchEvents = false;
3472 if (point.state() != PlatformTouchPoint::TouchReleased && point.state() != PlatformTouchPoint::TouchCancelled) 3449 if (point.state() != PlatformTouchPoint::TouchReleased && point.state() != PlatformTouchPoint::TouchCancelled)
3473 allTouchReleased = false; 3450 allTouchReleased = false;
3474 } 3451 }
3452 if (freshTouchEvents) {
3453 // Ideally we'd ASSERT !m_touchSequenceDocument here since we should
3454 // have cleared the active document when we saw the last release. But we
3455 // have some tests that violate this, ClusterFuzz could trigger it, and
3456 // there may be cases where the browser doesn't reliably release all
3457 // touches. http://crbug.com/345372 tracks this.
3458 m_touchSequenceDocument.clear();
3459 }
3475 3460
3461 // First do hit tests for any new touch points.
3476 for (i = 0; i < points.size(); ++i) { 3462 for (i = 0; i < points.size(); ++i) {
3477 const PlatformTouchPoint& point = points[i]; 3463 const PlatformTouchPoint& point = points[i];
3478 PlatformTouchPoint::State pointState = point.state();
3479 LayoutPoint pagePoint = documentPointForWindowPoint(m_frame, point.pos() ); 3464 LayoutPoint pagePoint = documentPointForWindowPoint(m_frame, point.pos() );
3480 3465
3481 // Gesture events trigger the active state, not touch events, 3466 // Touch events implicitly capture to the touched node, and don't change
3482 // so touch event hit tests can always be read only. 3467 // active/hover states themselves (Gesture events do). So we only need
3483 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent | HitTestRequest::ReadOnly; 3468 // to hit-test on touchstart, and it can be read-only.
3484 // The HitTestRequest types used for mouse events map quite adequately 3469 if (point.state() == PlatformTouchPoint::TouchPressed) {
3485 // to touch events. Note that in addition to meaning that the hit test 3470 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEv ent | HitTestRequest::ReadOnly | HitTestRequest::Active;
3486 // should affect the active state of the current node if necessary,
3487 // HitTestRequest::Active signifies that the hit test is taking place
3488 // with the mouse (or finger in this case) being pressed.
3489 switch (pointState) {
3490 case PlatformTouchPoint::TouchPressed:
3491 hitType |= HitTestRequest::Active;
3492 break;
3493 case PlatformTouchPoint::TouchMoved:
3494 hitType |= HitTestRequest::Active | HitTestRequest::Move;
3495 break;
3496 case PlatformTouchPoint::TouchReleased:
3497 case PlatformTouchPoint::TouchCancelled:
3498 hitType |= HitTestRequest::Release;
3499 break;
3500 case PlatformTouchPoint::TouchStationary:
3501 hitType |= HitTestRequest::Active;
3502 break;
3503 default:
3504 ASSERT_NOT_REACHED();
3505 break;
3506 }
3507
3508 // Increment the platform touch id by 1 to avoid storing a key of 0 in t he hashmap.
3509 unsigned touchPointTargetKey = point.id() + 1;
3510 RefPtr<EventTarget> touchTarget;
3511 if (pointState == PlatformTouchPoint::TouchPressed) {
3512 HitTestResult result; 3471 HitTestResult result;
3513 if (freshTouchEvents) { 3472 if (!m_touchSequenceDocument) {
3514 result = hitTestResultAtPoint(pagePoint, hitType); 3473 result = hitTestResultAtPoint(pagePoint, hitType);
3515 m_originatingTouchPointTargetKey = touchPointTargetKey; 3474 } else if (m_touchSequenceDocument->frame()) {
3516 } else if (m_originatingTouchPointDocument.get() && m_originatingTou chPointDocument->frame()) { 3475 LayoutPoint pagePointInOriginatingDocument = documentPointForWin dowPoint(m_touchSequenceDocument->frame(), point.pos());
3517 LayoutPoint pagePointInOriginatingDocument = documentPointForWin dowPoint(m_originatingTouchPointDocument->frame(), point.pos()); 3476 result = hitTestResultInFrame(m_touchSequenceDocument->frame(), pagePointInOriginatingDocument, hitType);
3518 result = hitTestResultInFrame(m_originatingTouchPointDocument->f rame(), pagePointInOriginatingDocument, hitType);
3519 } else 3477 } else
3520 continue; 3478 continue;
3521 3479
3522 Node* node = result.innerNode(); 3480 Node* node = result.innerNode();
3523 if (!node) 3481 if (!node)
3524 continue; 3482 continue;
3525 3483
3526 // Touch events should not go to text nodes 3484 // Touch events should not go to text nodes
3527 if (node->isTextNode()) 3485 if (node->isTextNode())
3528 node = NodeRenderingTraversal::parent(node); 3486 node = NodeRenderingTraversal::parent(node);
3529 3487
3530 Document& doc = node->document(); 3488 if (!m_touchSequenceDocument) {
3531 // Record the originating touch document even if it does not have a touch listener. 3489 // Keep track of which document should receive all touch events
3532 if (freshTouchEvents) { 3490 // in the active sequence. This must be a single document to
3533 m_originatingTouchPointDocument = &doc; 3491 // ensure we don't leak Nodes between documents.
3534 freshTouchEvents = false; 3492 m_touchSequenceDocument = &(result.innerNode()->document());
3535 } 3493 }
3536 if (!doc.hasTouchEventHandlers()) 3494
3537 continue; 3495 // Ideally we'd ASSERT(!m_targetForTouchID.contains(point.id())
3538 m_originatingTouchPointTargets.set(touchPointTargetKey, node); 3496 // since we shouldn't get a touchstart for a touch that's already
3539 touchTarget = node; 3497 // down. However EventSender allows this to be violated and there's
3498 // some tests that take advantage of it. There may also be edge
3499 // cases in the browser where this happens.
3500 // See http://crbug.com/345372.
3501 m_targetForTouchID.set(point.id(), node);
3540 3502
3541 TouchAction effectiveTouchAction = computeEffectiveTouchAction(pageP oint); 3503 TouchAction effectiveTouchAction = computeEffectiveTouchAction(pageP oint);
3542 if (effectiveTouchAction != TouchActionAuto) 3504 if (effectiveTouchAction != TouchActionAuto)
3543 m_frame->page()->chrome().client().setTouchAction(effectiveTouch Action); 3505 m_frame->page()->chrome().client().setTouchAction(effectiveTouch Action);
3506 }
3507 }
3544 3508
3545 } else if (pointState == PlatformTouchPoint::TouchReleased || pointState == PlatformTouchPoint::TouchCancelled) { 3509 m_touchPressed = !allTouchReleased;
3546 // The target should be the original target for this touch, so get i t from the hashmap. As it's a release or cancel
3547 // we also remove it from the map.
3548 touchTarget = m_originatingTouchPointTargets.take(touchPointTargetKe y);
3549 } else
3550 // No hittest is performed on move or stationary, since the target i s not allowed to change anyway.
3551 touchTarget = m_originatingTouchPointTargets.get(touchPointTargetKey );
3552 3510
3553 if (!touchTarget.get()) 3511 // If there's no document receiving touch events, or no handlers on the
3554 continue; 3512 // document set to receive the events, then we can skip all the rest of
3555 Document& doc = touchTarget->toNode()->document(); 3513 // this work.
3556 if (!doc.hasTouchEventHandlers()) 3514 if (!m_touchSequenceDocument || !m_touchSequenceDocument->hasTouchEventHandl ers() || !m_touchSequenceDocument->frame()) {
3557 continue; 3515 if (allTouchReleased)
3558 LocalFrame* targetFrame = doc.frame(); 3516 m_touchSequenceDocument.clear();
3559 if (!targetFrame) 3517 return false;
3560 continue; 3518 }
3519
3520 // Build up the lists to use for the 'touches', 'targetTouches' and
3521 // 'changedTouches' attributes in the JS event. See
3522 // http://www.w3.org/TR/touch-events/#touchevent-interface for how these
3523 // lists fit together.
3524
3525 // Holds the complete set of touches on the screen.
3526 RefPtrWillBeRawPtr<TouchList> touches = TouchList::create();
3527
3528 // A different view on the 'touches' list above, filtered and grouped by
3529 // event target. Used for the 'targetTouches' list in the JS event.
3530 typedef WillBeHeapHashMap<EventTarget*, RefPtrWillBeMember<TouchList> > Targ etTouchesHeapMap;
3531 TargetTouchesHeapMap touchesByTarget;
3532
3533 // Array of touches per state, used to assemble the 'changedTouches' list.
3534 typedef HashSet<RefPtr<EventTarget> > EventTargetSet;
3535 struct {
3536 // The touches corresponding to the particular change state this struct
3537 // instance represents.
3538 RefPtrWillBeMember<TouchList> m_touches;
3539 // Set of targets involved in m_touches.
3540 EventTargetSet m_targets;
3541 } changedTouches[PlatformTouchPoint::TouchStateEnd];
3542
3543 for (i = 0; i < points.size(); ++i) {
3544 const PlatformTouchPoint& point = points[i];
3545 LayoutPoint pagePoint = documentPointForWindowPoint(m_frame, point.pos() );
3546 PlatformTouchPoint::State pointState = point.state();
3547 RefPtr<EventTarget> touchTarget;
3548
3549 if (pointState == PlatformTouchPoint::TouchReleased || pointState == Pla tformTouchPoint::TouchCancelled) {
3550 // 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
3552 // it from the map.
3553 touchTarget = m_targetForTouchID.take(point.id());
3554 } else {
3555 // No hittest is performed on move or stationary, since the target
3556 // is not allowed to change anyway.
3557 touchTarget = m_targetForTouchID.get(point.id());
3558 }
3559
3560 LocalFrame* targetFrame;
3561 bool knownTarget;
3562 if (touchTarget) {
3563 Document& doc = touchTarget->toNode()->document();
3564 ASSERT(&doc == m_touchSequenceDocument.get());
3565 targetFrame = doc.frame();
3566 knownTarget = true;
3567 } else {
3568 // If we don't have a target registered for the point it means we've
3569 // missed our opportunity to do a hit test for it (due to some
3570 // optimization that prevented blink from ever seeing the
3571 // touchstart), or that the touch started outside the active touch
3572 // sequence document. We should still include the touch in the
3573 // Touches list reported to the application (eg. so it can
3574 // differentiate between a one and two finger gesture), but we won't
3575 // actually dispatch any events for it. Set the target to the
3576 // Document so that there's some valid node here. Perhaps this
3577 // should really be DOMWindow, but in all other cases the target of
3578 // a Touch is a Node so using the window could be a breaking change.
3579 // Since we know there was no handler invoked, the specific target
3580 // should be completely irrelevant to the application.
3581 touchTarget = m_touchSequenceDocument;
3582 targetFrame = m_touchSequenceDocument->frame();
3583 knownTarget = false;
3584 }
3585 ASSERT(targetFrame);
3561 3586
3562 if (m_frame != targetFrame) { 3587 if (m_frame != targetFrame) {
3563 // pagePoint should always be relative to the target elements contai ning frame. 3588 // pagePoint should always be relative to the target elements
3589 // containing frame.
3564 pagePoint = documentPointForWindowPoint(targetFrame, point.pos()); 3590 pagePoint = documentPointForWindowPoint(targetFrame, point.pos());
3565 } 3591 }
3566 3592
3567 float scaleFactor = targetFrame->pageZoomFactor(); 3593 float scaleFactor = targetFrame->pageZoomFactor();
3568 3594
3569 int adjustedPageX = lroundf(pagePoint.x() / scaleFactor); 3595 int adjustedPageX = lroundf(pagePoint.x() / scaleFactor);
3570 int adjustedPageY = lroundf(pagePoint.y() / scaleFactor); 3596 int adjustedPageY = lroundf(pagePoint.y() / scaleFactor);
3571 int adjustedRadiusX = lroundf(point.radiusX() / scaleFactor); 3597 int adjustedRadiusX = lroundf(point.radiusX() / scaleFactor);
3572 int adjustedRadiusY = lroundf(point.radiusY() / scaleFactor); 3598 int adjustedRadiusY = lroundf(point.radiusY() / scaleFactor);
3573 3599
3574 RefPtrWillBeRawPtr<Touch> touch = Touch::create(targetFrame, touchTarget .get(), point.id(), 3600 RefPtrWillBeRawPtr<Touch> touch = Touch::create(targetFrame, touchTarget .get(), point.id(),
3575 point.screenPos().x(), point.screenP os().y(), 3601 point.screenPos().x(), point.screenP os().y(),
3576 adjustedPageX, adjustedPageY, 3602 adjustedPageX, adjustedPageY,
3577 adjustedRadiusX, adjustedRadiusY, 3603 adjustedRadiusX, adjustedRadiusY,
3578 point.rotationAngle(), point.force() ); 3604 point.rotationAngle(), point.force() );
3579 3605
3580 // Ensure this target's touch list exists, even if it ends up empty, so it can always be passed to TouchEvent::Create below. 3606 // Ensure this target's touch list exists, even if it ends up empty, so
3607 // it can always be passed to TouchEvent::Create below.
3581 TargetTouchesHeapMap::iterator targetTouchesIterator = touchesByTarget.f ind(touchTarget.get()); 3608 TargetTouchesHeapMap::iterator targetTouchesIterator = touchesByTarget.f ind(touchTarget.get());
3582 if (targetTouchesIterator == touchesByTarget.end()) { 3609 if (targetTouchesIterator == touchesByTarget.end()) {
3583 touchesByTarget.set(touchTarget.get(), TouchList::create()); 3610 touchesByTarget.set(touchTarget.get(), TouchList::create());
3584 targetTouchesIterator = touchesByTarget.find(touchTarget.get()); 3611 targetTouchesIterator = touchesByTarget.find(touchTarget.get());
3585 } 3612 }
3586 3613
3587 // touches and targetTouches should only contain information about touch es still on the screen, so if this point is 3614 // touches and targetTouches should only contain information about
3588 // released or cancelled it will only appear in the changedTouches list. 3615 // touches still on the screen, so if this point is released or
3616 // cancelled it will only appear in the changedTouches list.
3589 if (pointState != PlatformTouchPoint::TouchReleased && pointState != Pla tformTouchPoint::TouchCancelled) { 3617 if (pointState != PlatformTouchPoint::TouchReleased && pointState != Pla tformTouchPoint::TouchCancelled) {
3590 touches->append(touch); 3618 touches->append(touch);
3591 targetTouchesIterator->value->append(touch); 3619 targetTouchesIterator->value->append(touch);
3592 } 3620 }
3593 3621
3594 // Now build up the correct list for changedTouches. 3622 // Now build up the correct list for changedTouches.
3595 // Note that any touches that are in the TouchStationary state (e.g. if 3623 // Note that any touches that are in the TouchStationary state (e.g. if
3596 // the user had several points touched but did not move them all) should 3624 // the user had several points touched but did not move them all) should
3597 // never be in the changedTouches list so we do not handle them explicit ly here. 3625 // never be in the changedTouches list so we do not handle them
3598 // See https://bugs.webkit.org/show_bug.cgi?id=37609 for further discuss ion 3626 // explicitly here. See https://bugs.webkit.org/show_bug.cgi?id=37609
3599 // about the TouchStationary state. 3627 // for further discussion about the TouchStationary state.
3600 if (pointState != PlatformTouchPoint::TouchStationary) { 3628 if (pointState != PlatformTouchPoint::TouchStationary && knownTarget) {
3601 ASSERT(pointState < PlatformTouchPoint::TouchStateEnd); 3629 ASSERT(pointState < PlatformTouchPoint::TouchStateEnd);
3602 if (!changedTouches[pointState].m_touches) 3630 if (!changedTouches[pointState].m_touches)
3603 changedTouches[pointState].m_touches = TouchList::create(); 3631 changedTouches[pointState].m_touches = TouchList::create();
3604 changedTouches[pointState].m_touches->append(touch); 3632 changedTouches[pointState].m_touches->append(touch);
3605 changedTouches[pointState].m_targets.add(touchTarget); 3633 changedTouches[pointState].m_targets.add(touchTarget);
3606 } 3634 }
3607 } 3635 }
3608 m_touchPressed = touches->length() > 0;
3609 if (allTouchReleased) 3636 if (allTouchReleased)
3610 m_originatingTouchPointDocument.clear(); 3637 m_touchSequenceDocument.clear();
3611 3638
3612 // Now iterate the changedTouches list and m_targets within it, sending even ts to the targets as required. 3639 // Now iterate the changedTouches list and m_targets within it, sending
3640 // events to the targets as required.
3613 bool swallowedEvent = false; 3641 bool swallowedEvent = false;
3614 RefPtrWillBeRawPtr<TouchList> emptyList = TouchList::create(); 3642 RefPtrWillBeRawPtr<TouchList> emptyList = TouchList::create();
3615 for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state ) { 3643 for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state ) {
3616 if (!changedTouches[state].m_touches) 3644 if (!changedTouches[state].m_touches)
3617 continue; 3645 continue;
3618 3646
3619 // When sending a touch cancel event, use empty touches and targetTouche s lists.
3620 bool isTouchCancelEvent = (state == PlatformTouchPoint::TouchCancelled);
3621 RefPtrWillBeRawPtr<TouchList>& effectiveTouches(isTouchCancelEvent ? emp tyList : touches);
3622 const AtomicString& stateName(eventNameForTouchPointState(static_cast<Pl atformTouchPoint::State>(state))); 3647 const AtomicString& stateName(eventNameForTouchPointState(static_cast<Pl atformTouchPoint::State>(state)));
3623 const EventTargetSet& targetsForState = changedTouches[state].m_targets; 3648 const EventTargetSet& targetsForState = changedTouches[state].m_targets;
3624
3625 for (EventTargetSet::const_iterator it = targetsForState.begin(); it != targetsForState.end(); ++it) { 3649 for (EventTargetSet::const_iterator it = targetsForState.begin(); it != targetsForState.end(); ++it) {
3626 EventTarget* touchEventTarget = it->get(); 3650 EventTarget* touchEventTarget = it->get();
3627 RefPtrWillBeRawPtr<TouchList> targetTouches(isTouchCancelEvent ? emp tyList.get() : touchesByTarget.get(touchEventTarget)); 3651 RefPtrWillBeRawPtr<TouchEvent> touchEvent = TouchEvent::create(
3628 ASSERT(targetTouches); 3652 touches.get(), touchesByTarget.get(touchEventTarget), changedTou ches[state].m_touches.get(),
3629 3653 stateName, touchEventTarget->toNode()->document().domWindow(),
3630 RefPtrWillBeRawPtr<TouchEvent> touchEvent = 3654 0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey(), e vent.metaKey(), event.cancelable());
3631 TouchEvent::create(effectiveTouches.get(), targetTouches.get(), changedTouches[state].m_touches.get(),
3632 stateName, touchEventTarget->toNode()->document().domWindow( ),
3633 0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey( ), event.metaKey(), event.cancelable());
3634 touchEventTarget->toNode()->dispatchTouchEvent(touchEvent.get()); 3655 touchEventTarget->toNode()->dispatchTouchEvent(touchEvent.get());
3635 swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() || touchEvent->defaultHandled(); 3656 swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() || touchEvent->defaultHandled();
3636 } 3657 }
3637 } 3658 }
3638 3659
3639 return swallowedEvent; 3660 return swallowedEvent;
3640 } 3661 }
3641 3662
3642 TouchAction EventHandler::intersectTouchAction(TouchAction action1, TouchAction action2) 3663 TouchAction EventHandler::intersectTouchAction(TouchAction action1, TouchAction action2)
3643 { 3664 {
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
3763 unsigned EventHandler::accessKeyModifiers() 3784 unsigned EventHandler::accessKeyModifiers()
3764 { 3785 {
3765 #if OS(MACOSX) 3786 #if OS(MACOSX)
3766 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; 3787 return PlatformEvent::CtrlKey | PlatformEvent::AltKey;
3767 #else 3788 #else
3768 return PlatformEvent::AltKey; 3789 return PlatformEvent::AltKey;
3769 #endif 3790 #endif
3770 } 3791 }
3771 3792
3772 } // namespace WebCore 3793 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/page/EventHandler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698