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

Side by Side Diff: third_party/WebKit/Source/core/input/TouchEventManager.cpp

Issue 1971473002: Move touch hit testing to PointerEventManager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove stale code Created 4 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
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/TouchEventManager.h" 5 #include "core/input/TouchEventManager.h"
6 6
7 #include "core/dom/Document.h" 7 #include "core/dom/Document.h"
8 #include "core/events/TouchEvent.h" 8 #include "core/events/TouchEvent.h"
9 #include "core/frame/EventHandlerRegistry.h" 9 #include "core/frame/EventHandlerRegistry.h"
10 #include "core/frame/FrameHost.h" 10 #include "core/frame/FrameHost.h"
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 TargetTouchesHeapMap touchesByTarget; 162 TargetTouchesHeapMap touchesByTarget;
163 163
164 // Array of touches per state, used to assemble the |changedTouches| list. 164 // Array of touches per state, used to assemble the |changedTouches| list.
165 ChangedTouches changedTouches[PlatformTouchPoint::TouchStateEnd]; 165 ChangedTouches changedTouches[PlatformTouchPoint::TouchStateEnd];
166 166
167 for (unsigned i = 0; i < touchInfos.size(); ++i) { 167 for (unsigned i = 0; i < touchInfos.size(); ++i) {
168 const TouchInfo& touchInfo = touchInfos[i]; 168 const TouchInfo& touchInfo = touchInfos[i];
169 const PlatformTouchPoint& point = touchInfo.point; 169 const PlatformTouchPoint& point = touchInfo.point;
170 PlatformTouchPoint::TouchState pointState = point.state(); 170 PlatformTouchPoint::TouchState pointState = point.state();
171 171
172 if (touchInfo.consumed)
173 continue;
174
175 Touch* touch = Touch::create( 172 Touch* touch = Touch::create(
176 touchInfo.targetFrame.get(), 173 touchInfo.targetFrame.get(),
177 touchInfo.touchNode.get(), 174 touchInfo.touchNode.get(),
178 point.id(), 175 point.id(),
179 point.screenPos(), 176 point.screenPos(),
180 touchInfo.contentPoint, 177 touchInfo.contentPoint,
181 touchInfo.adjustedRadius, 178 touchInfo.adjustedRadius,
182 point.rotationAngle(), 179 point.rotationAngle(),
183 point.force(), 180 point.force(),
184 touchInfo.region); 181 touchInfo.region);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 void TouchEventManager::updateTargetAndRegionMapsForTouchStarts( 259 void TouchEventManager::updateTargetAndRegionMapsForTouchStarts(
263 HeapVector<TouchInfo>& touchInfos) 260 HeapVector<TouchInfo>& touchInfos)
264 { 261 {
265 for (auto& touchInfo : touchInfos) { 262 for (auto& touchInfo : touchInfos) {
266 // Touch events implicitly capture to the touched node, and don't change 263 // Touch events implicitly capture to the touched node, and don't change
267 // active/hover states themselves (Gesture events do). So we only need 264 // active/hover states themselves (Gesture events do). So we only need
268 // to hit-test on touchstart and when the target could be different than 265 // to hit-test on touchstart and when the target could be different than
269 // the corresponding pointer event target. 266 // the corresponding pointer event target.
270 if (touchInfo.point.state() == PlatformTouchPoint::TouchPressed) { 267 if (touchInfo.point.state() == PlatformTouchPoint::TouchPressed) {
271 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEv ent | HitTestRequest::ReadOnly | HitTestRequest::Active; 268 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEv ent | HitTestRequest::ReadOnly | HitTestRequest::Active;
272 LayoutPoint pagePoint = roundedLayoutPoint(m_frame->view()->rootFram eToContents(touchInfo.point.pos()));
273 HitTestResult result; 269 HitTestResult result;
274 if (!m_touchSequenceDocument) { 270 // For the touchPressed points hit-testing is done in
275 result = m_frame->eventHandler().hitTestResultAtPoint(pagePoint, hitType); 271 // PointerEventManager. If it was the second touch there is a
276 } else if (m_touchSequenceDocument->frame()) { 272 // capturing documents for the touch and |m_touchSequenceDocument|
277 LayoutPoint framePoint = roundedLayoutPoint(m_touchSequenceDocum ent->frame()->view()->rootFrameToContents(touchInfo.point.pos())); 273 // is not null. So if PointerEventManager should hit-test again
278 result = EventHandler::hitTestResultInFrame(m_touchSequenceDocum ent->frame(), framePoint, hitType); 274 // against |m_touchSequenceDocument| if the target set by
279 } else { 275 // PointerEventManager was either null or not in
276 // |m_touchSequenceDocument|.
277 if (m_touchSequenceDocument && (!touchInfo.touchNode
278 || &touchInfo.touchNode->document() != m_touchSequenceDocument)) {
279 if (m_touchSequenceDocument->frame()) {
Rick Byers 2016/05/17 14:20:01 this code is mostly copy/paste with the code in Po
Navid Zolghadr 2016/05/17 16:40:44 I have looked at this a little bit more. They do l
Rick Byers 2016/05/18 21:44:52 Sure, thanks!
280 LayoutPoint framePoint = roundedLayoutPoint(m_touchSequenceD ocument->frame()->view()->rootFrameToContents(touchInfo.point.pos()));
281 result = EventHandler::hitTestResultInFrame(m_touchSequenceD ocument->frame(), framePoint, hitType);
282 Node* node = result.innerNode();
283 if (!node)
284 continue;
285 if (isHTMLCanvasElement(node)) {
286 std::pair<Element*, String> regionInfo = toHTMLCanvasEle ment(node)->getControlAndIdIfHitRegionExists(result.pointInInnerNodeFrame());
287 if (regionInfo.first)
288 node = regionInfo.first;
289 touchInfo.region = regionInfo.second;
290 }
291 // Touch events should not go to text nodes.
292 if (node->isTextNode())
293 node = FlatTreeTraversal::parent(*node);
294 touchInfo.touchNode = node;
295 } else {
296 continue;
297 }
298 }
299 if (!touchInfo.touchNode)
280 continue; 300 continue;
281 }
282
283 Node* node = result.innerNode();
284 if (!node)
285 continue;
286 if (isHTMLCanvasElement(node)) {
287 std::pair<Element*, String> regionInfo = toHTMLCanvasElement(nod e)->getControlAndIdIfHitRegionExists(result.pointInInnerNodeFrame());
288 if (regionInfo.first)
289 node = regionInfo.first;
290 touchInfo.region = regionInfo.second;
291 }
292 // Touch events should not go to text nodes.
293 if (node->isTextNode())
294 node = FlatTreeTraversal::parent(*node);
295 touchInfo.touchNode = node;
296
297 if (!m_touchSequenceDocument) { 301 if (!m_touchSequenceDocument) {
298 // Keep track of which document should receive all touch events 302 // Keep track of which document should receive all touch events
299 // in the active sequence. This must be a single document to 303 // in the active sequence. This must be a single document to
300 // ensure we don't leak Nodes between documents. 304 // ensure we don't leak Nodes between documents.
301 m_touchSequenceDocument = &(touchInfo.touchNode->document()); 305 m_touchSequenceDocument = &(touchInfo.touchNode->document());
302 ASSERT(m_touchSequenceDocument->frame()->view()); 306 ASSERT(m_touchSequenceDocument->frame()->view());
303 } 307 }
304 308
305 // Ideally we'd ASSERT(!m_targetForTouchID.contains(point.id()) 309 // Ideally we'd ASSERT(!m_targetForTouchID.contains(point.id())
306 // since we shouldn't get a touchstart for a touch that's already 310 // since we shouldn't get a touchstart for a touch that's already
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 // pagePoint should always be in the target element's document coordinat es. 381 // pagePoint should always be in the target element's document coordinat es.
378 FloatPoint pagePoint = targetFrame->view()->rootFrameToContents( 382 FloatPoint pagePoint = targetFrame->view()->rootFrameToContents(
379 touchInfo.point.pos()); 383 touchInfo.point.pos());
380 float scaleFactor = 1.0f / targetFrame->pageZoomFactor(); 384 float scaleFactor = 1.0f / targetFrame->pageZoomFactor();
381 385
382 touchInfo.touchNode = touchNode; 386 touchInfo.touchNode = touchNode;
383 touchInfo.targetFrame = targetFrame; 387 touchInfo.targetFrame = targetFrame;
384 touchInfo.contentPoint = pagePoint.scaledBy(scaleFactor); 388 touchInfo.contentPoint = pagePoint.scaledBy(scaleFactor);
385 touchInfo.adjustedRadius = touchInfo.point.radius().scaledBy(scaleFactor ); 389 touchInfo.adjustedRadius = touchInfo.point.radius().scaledBy(scaleFactor );
386 touchInfo.knownTarget = knownTarget; 390 touchInfo.knownTarget = knownTarget;
387 touchInfo.consumed = false;
388 touchInfo.region = regionID; 391 touchInfo.region = regionID;
389 } 392 }
390 } 393 }
391 394
392 bool TouchEventManager::generateTouchInfosAfterHittest( 395 bool TouchEventManager::reHitTestTouchPointsIfNeeded(
393 const PlatformTouchEvent& event, 396 const PlatformTouchEvent& event,
394 HeapVector<TouchInfo>& touchInfos) 397 HeapVector<TouchInfo>& touchInfos)
395 { 398 {
396 bool newTouchSequence = true; 399 bool newTouchSequence = true;
397 bool allTouchesReleased = true; 400 bool allTouchesReleased = true;
398 401
399 for (const auto& point : event.touchPoints()) { 402 for (const auto& point : event.touchPoints()) {
400 if (point.state() != PlatformTouchPoint::TouchPressed) 403 if (point.state() != PlatformTouchPoint::TouchPressed)
401 newTouchSequence = false; 404 newTouchSequence = false;
402 if (point.state() != PlatformTouchPoint::TouchReleased && point.state() != PlatformTouchPoint::TouchCancelled) 405 if (point.state() != PlatformTouchPoint::TouchReleased && point.state() != PlatformTouchPoint::TouchCancelled)
403 allTouchesReleased = false; 406 allTouchesReleased = false;
404 } 407 }
405 if (newTouchSequence) { 408 if (newTouchSequence) {
406 // Ideally we'd ASSERT(!m_touchSequenceDocument) here since we should 409 // Ideally we'd ASSERT(!m_touchSequenceDocument) here since we should
407 // have cleared the active document when we saw the last release. But we 410 // have cleared the active document when we saw the last release. But we
408 // have some tests that violate this, ClusterFuzz could trigger it, and 411 // have some tests that violate this, ClusterFuzz could trigger it, and
409 // there may be cases where the browser doesn't reliably release all 412 // there may be cases where the browser doesn't reliably release all
410 // touches. http://crbug.com/345372 tracks this. 413 // touches. http://crbug.com/345372 tracks this.
411 m_touchSequenceDocument.clear(); 414 m_touchSequenceDocument.clear();
412 m_touchSequenceUserGestureToken.clear(); 415 m_touchSequenceUserGestureToken.clear();
413 } 416 }
414 417
415 ASSERT(m_frame->view()); 418 ASSERT(m_frame->view());
416 if (m_touchSequenceDocument && (!m_touchSequenceDocument->frame() || !m_touc hSequenceDocument->frame()->view())) { 419 if (m_touchSequenceDocument && (!m_touchSequenceDocument->frame() || !m_touc hSequenceDocument->frame()->view())) {
417 // If the active touch document has no frame or view, it's probably bein g destroyed 420 // If the active touch document has no frame or view, it's probably bein g destroyed
418 // so we can't dispatch events. 421 // so we can't dispatch events.
419 return false; 422 return false;
420 } 423 }
421 424
422 for (const auto& point : event.touchPoints()) {
423 TouchEventManager::TouchInfo touchInfo;
424 touchInfo.point = point;
425 touchInfos.append(touchInfo);
426 }
427
428 updateTargetAndRegionMapsForTouchStarts(touchInfos); 425 updateTargetAndRegionMapsForTouchStarts(touchInfos);
429 426
430 m_touchPressed = !allTouchesReleased; 427 m_touchPressed = !allTouchesReleased;
431 428
432 // If there's no document receiving touch events, or no handlers on the 429 // If there's no document receiving touch events, or no handlers on the
433 // document set to receive the events, then we can skip all the rest of 430 // document set to receive the events, then we can skip all the rest of
434 // this work. 431 // this work.
435 if (!m_touchSequenceDocument || !m_touchSequenceDocument->frameHost() || !ha sTouchHandlers(m_touchSequenceDocument->frameHost()->eventHandlerRegistry()) || !m_touchSequenceDocument->frame()) { 432 if (!m_touchSequenceDocument || !m_touchSequenceDocument->frameHost() || !ha sTouchHandlers(m_touchSequenceDocument->frameHost()->eventHandlerRegistry()) || !m_touchSequenceDocument->frame()) {
436 if (allTouchesReleased) { 433 if (allTouchesReleased) {
437 m_touchSequenceDocument.clear(); 434 m_touchSequenceDocument.clear();
438 m_touchSequenceUserGestureToken.clear(); 435 m_touchSequenceUserGestureToken.clear();
439 } 436 }
440 return false; 437 return false;
441 } 438 }
442 439
443 setAllPropertiesOfTouchInfos(touchInfos); 440 setAllPropertiesOfTouchInfos(touchInfos);
444 441
445 return true; 442 return true;
446 } 443 }
447 444
448 WebInputEventResult TouchEventManager::handleTouchEvent( 445 WebInputEventResult TouchEventManager::handleTouchEvent(
449 const PlatformTouchEvent& event, 446 const PlatformTouchEvent& event,
450 const HeapVector<TouchInfo>& touchInfos) 447 HeapVector<TouchInfo>& touchInfos)
451 { 448 {
449 if (!reHitTestTouchPointsIfNeeded(event, touchInfos))
450 return WebInputEventResult::NotHandled;
451
452 // Note that the disposition of any pointer events affects only the generati on of touch 452 // Note that the disposition of any pointer events affects only the generati on of touch
453 // events. If all pointer events were handled (and hence no touch events wer e fired), that 453 // events. If all pointer events were handled (and hence no touch events wer e fired), that
454 // is still equivalent to the touch events going unhandled because pointer e vent handler 454 // is still equivalent to the touch events going unhandled because pointer e vent handler
455 // don't block scroll gesture generation. 455 // don't block scroll gesture generation.
456 456
457 // TODO(crbug.com/507408): If PE handlers always call preventDefault, we won 't see TEs until after 457 // TODO(crbug.com/507408): If PE handlers always call preventDefault, we won 't see TEs until after
458 // scrolling starts because the scrolling would suppress upcoming PEs. This sudden "break" in TE 458 // scrolling starts because the scrolling would suppress upcoming PEs. This sudden "break" in TE
459 // suppression can make the visible TEs inconsistent (e.g. touchmove without a touchstart). 459 // suppression can make the visible TEs inconsistent (e.g. touchmove without a touchstart).
460 460
461 bool allTouchesReleased = true; 461 bool allTouchesReleased = true;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 } 518 }
519 519
520 DEFINE_TRACE(TouchEventManager) 520 DEFINE_TRACE(TouchEventManager)
521 { 521 {
522 visitor->trace(m_frame); 522 visitor->trace(m_frame);
523 visitor->trace(m_touchSequenceDocument); 523 visitor->trace(m_touchSequenceDocument);
524 visitor->trace(m_targetForTouchID); 524 visitor->trace(m_targetForTouchID);
525 } 525 }
526 526
527 } // namespace blink 527 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698