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

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

Issue 2646163002: Remove PlatformTouchEvent/Point and use WebTouchEvent/Point instead (Closed)
Patch Set: Fix nit Created 3 years, 10 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/Deprecation.h" 9 #include "core/frame/Deprecation.h"
10 #include "core/frame/EventHandlerRegistry.h" 10 #include "core/frame/EventHandlerRegistry.h"
11 #include "core/frame/FrameHost.h" 11 #include "core/frame/FrameHost.h"
12 #include "core/frame/FrameView.h" 12 #include "core/frame/FrameView.h"
13 #include "core/html/HTMLCanvasElement.h" 13 #include "core/html/HTMLCanvasElement.h"
14 #include "core/input/EventHandlingUtil.h" 14 #include "core/input/EventHandlingUtil.h"
15 #include "core/input/TouchActionUtil.h" 15 #include "core/input/TouchActionUtil.h"
16 #include "core/layout/HitTestCanvasResult.h" 16 #include "core/layout/HitTestCanvasResult.h"
17 #include "core/page/ChromeClient.h" 17 #include "core/page/ChromeClient.h"
18 #include "core/page/Page.h" 18 #include "core/page/Page.h"
19 #include "platform/Histogram.h" 19 #include "platform/Histogram.h"
20 #include "platform/PlatformTouchEvent.h" 20 #include "public/platform/WebTouchEvent.h"
21 #include "wtf/CurrentTime.h" 21 #include "wtf/CurrentTime.h"
22 #include "wtf/PtrUtil.h" 22 #include "wtf/PtrUtil.h"
23 #include <memory> 23 #include <memory>
24 24
25 namespace blink { 25 namespace blink {
26 26
27 namespace { 27 namespace {
28 28
29 bool hasTouchHandlers(const EventHandlerRegistry& registry) { 29 bool hasTouchHandlers(const EventHandlerRegistry& registry) {
30 return registry.hasEventHandlers( 30 return registry.hasEventHandlers(
31 EventHandlerRegistry::TouchStartOrMoveEventBlocking) || 31 EventHandlerRegistry::TouchStartOrMoveEventBlocking) ||
32 registry.hasEventHandlers( 32 registry.hasEventHandlers(
33 EventHandlerRegistry::TouchStartOrMoveEventPassive) || 33 EventHandlerRegistry::TouchStartOrMoveEventPassive) ||
34 registry.hasEventHandlers( 34 registry.hasEventHandlers(
35 EventHandlerRegistry::TouchEndOrCancelEventBlocking) || 35 EventHandlerRegistry::TouchEndOrCancelEventBlocking) ||
36 registry.hasEventHandlers( 36 registry.hasEventHandlers(
37 EventHandlerRegistry::TouchEndOrCancelEventPassive); 37 EventHandlerRegistry::TouchEndOrCancelEventPassive);
38 } 38 }
39 39
40 const AtomicString& touchEventNameForTouchPointState( 40 const AtomicString& touchEventNameForTouchPointState(
41 PlatformTouchPoint::TouchState state) { 41 WebTouchPoint::State state) {
42 switch (state) { 42 switch (state) {
43 case PlatformTouchPoint::TouchReleased: 43 case WebTouchPoint::StateReleased:
44 return EventTypeNames::touchend; 44 return EventTypeNames::touchend;
45 case PlatformTouchPoint::TouchCancelled: 45 case WebTouchPoint::StateCancelled:
46 return EventTypeNames::touchcancel; 46 return EventTypeNames::touchcancel;
47 case PlatformTouchPoint::TouchPressed: 47 case WebTouchPoint::StatePressed:
48 return EventTypeNames::touchstart; 48 return EventTypeNames::touchstart;
49 case PlatformTouchPoint::TouchMoved: 49 case WebTouchPoint::StateMoved:
50 return EventTypeNames::touchmove; 50 return EventTypeNames::touchmove;
51 case PlatformTouchPoint::TouchStationary: 51 case WebTouchPoint::StateStationary:
52 // Fall through to default 52 // Fall through to default
53 default: 53 default:
54 ASSERT_NOT_REACHED(); 54 ASSERT_NOT_REACHED();
55 return emptyAtom; 55 return emptyAtom;
56 } 56 }
57 } 57 }
58 58
59 enum TouchEventDispatchResultType { 59 enum TouchEventDispatchResultType {
60 UnhandledTouches, // Unhandled touch events. 60 UnhandledTouches, // Unhandled touch events.
61 HandledTouches, // Handled touch events. 61 HandledTouches, // Handled touch events.
(...skipping 26 matching lines...) Expand all
88 88
89 TouchEventManager::TouchEventManager(LocalFrame& frame) : m_frame(frame) { 89 TouchEventManager::TouchEventManager(LocalFrame& frame) : m_frame(frame) {
90 clear(); 90 clear();
91 } 91 }
92 92
93 void TouchEventManager::clear() { 93 void TouchEventManager::clear() {
94 m_touchSequenceDocument.clear(); 94 m_touchSequenceDocument.clear();
95 m_targetForTouchID.clear(); 95 m_targetForTouchID.clear();
96 m_regionForTouchID.clear(); 96 m_regionForTouchID.clear();
97 m_touchPressed = false; 97 m_touchPressed = false;
98 m_currentEvent = PlatformEvent::NoType;
99 m_currentTouchAction = TouchActionAuto; 98 m_currentTouchAction = TouchActionAuto;
100 } 99 }
101 100
102 DEFINE_TRACE(TouchEventManager) { 101 DEFINE_TRACE(TouchEventManager) {
103 visitor->trace(m_frame); 102 visitor->trace(m_frame);
104 visitor->trace(m_touchSequenceDocument); 103 visitor->trace(m_touchSequenceDocument);
105 visitor->trace(m_targetForTouchID); 104 visitor->trace(m_targetForTouchID);
106 } 105 }
107 106
108 WebInputEventResult TouchEventManager::dispatchTouchEvents( 107 WebInputEventResult TouchEventManager::dispatchTouchEvents(
109 const PlatformTouchEvent& event, 108 const WebTouchEvent& event,
110 const HeapVector<TouchInfo>& touchInfos, 109 const HeapVector<TouchInfo>& touchInfos,
111 bool allTouchesReleased) { 110 bool allTouchesReleased) {
112 // Build up the lists to use for the |touches|, |targetTouches| and 111 // Build up the lists to use for the |touches|, |targetTouches| and
113 // |changedTouches| attributes in the JS event. See 112 // |changedTouches| attributes in the JS event. See
114 // http://www.w3.org/TR/touch-events/#touchevent-interface for how these 113 // http://www.w3.org/TR/touch-events/#touchevent-interface for how these
115 // lists fit together. 114 // lists fit together.
116 115
117 // Holds the complete set of touches on the screen. 116 // Holds the complete set of touches on the screen.
118 TouchList* touches = TouchList::create(); 117 TouchList* touches = TouchList::create();
119 118
120 // A different view on the 'touches' list above, filtered and grouped by 119 // A different view on the 'touches' list above, filtered and grouped by
121 // event target. Used for the |targetTouches| list in the JS event. 120 // event target. Used for the |targetTouches| list in the JS event.
122 using TargetTouchesHeapMap = HeapHashMap<EventTarget*, Member<TouchList>>; 121 using TargetTouchesHeapMap = HeapHashMap<EventTarget*, Member<TouchList>>;
123 TargetTouchesHeapMap touchesByTarget; 122 TargetTouchesHeapMap touchesByTarget;
124 123
125 // Array of touches per state, used to assemble the |changedTouches| list. 124 // Array of touches per state, used to assemble the |changedTouches| list.
126 ChangedTouches changedTouches[PlatformTouchPoint::TouchStateEnd]; 125 ChangedTouches changedTouches[WebTouchPoint::StateMax + 1];
127 126
128 for (auto touchInfo : touchInfos) { 127 for (auto touchInfo : touchInfos) {
129 const PlatformTouchPoint& point = touchInfo.point; 128 const WebTouchPoint& point = touchInfo.point;
130 PlatformTouchPoint::TouchState pointState = point.state(); 129 WebTouchPoint::State pointState = point.state;
131 130
132 Touch* touch = Touch::create( 131 Touch* touch = Touch::create(
133 touchInfo.targetFrame.get(), touchInfo.touchNode.get(), point.id(), 132 touchInfo.targetFrame.get(), touchInfo.touchNode.get(), point.id,
134 point.screenPos(), touchInfo.contentPoint, touchInfo.adjustedRadius, 133 point.screenPosition, touchInfo.contentPoint, touchInfo.adjustedRadius,
135 point.rotationAngle(), point.force(), touchInfo.region); 134 point.rotationAngle, point.force, touchInfo.region);
136 135
137 // Ensure this target's touch list exists, even if it ends up empty, so 136 // Ensure this target's touch list exists, even if it ends up empty, so
138 // it can always be passed to TouchEvent::Create below. 137 // it can always be passed to TouchEvent::Create below.
139 TargetTouchesHeapMap::iterator targetTouchesIterator = 138 TargetTouchesHeapMap::iterator targetTouchesIterator =
140 touchesByTarget.find(touchInfo.touchNode.get()); 139 touchesByTarget.find(touchInfo.touchNode.get());
141 if (targetTouchesIterator == touchesByTarget.end()) { 140 if (targetTouchesIterator == touchesByTarget.end()) {
142 touchesByTarget.set(touchInfo.touchNode.get(), TouchList::create()); 141 touchesByTarget.set(touchInfo.touchNode.get(), TouchList::create());
143 targetTouchesIterator = touchesByTarget.find(touchInfo.touchNode.get()); 142 targetTouchesIterator = touchesByTarget.find(touchInfo.touchNode.get());
144 } 143 }
145 144
146 // |touches| and |targetTouches| should only contain information about 145 // |touches| and |targetTouches| should only contain information about
147 // touches still on the screen, so if this point is released or 146 // touches still on the screen, so if this point is released or
148 // cancelled it will only appear in the |changedTouches| list. 147 // cancelled it will only appear in the |changedTouches| list.
149 if (pointState != PlatformTouchPoint::TouchReleased && 148 if (pointState != WebTouchPoint::StateReleased &&
150 pointState != PlatformTouchPoint::TouchCancelled) { 149 pointState != WebTouchPoint::StateCancelled) {
151 touches->append(touch); 150 touches->append(touch);
152 targetTouchesIterator->value->append(touch); 151 targetTouchesIterator->value->append(touch);
153 } 152 }
154 153
155 // Now build up the correct list for |changedTouches|. 154 // Now build up the correct list for |changedTouches|.
156 // Note that any touches that are in the TouchStationary state (e.g. if 155 // Note that any touches that are in the TouchStationary state (e.g. if
157 // the user had several points touched but did not move them all) should 156 // the user had several points touched but did not move them all) should
158 // never be in the |changedTouches| list so we do not handle them 157 // never be in the |changedTouches| list so we do not handle them
159 // explicitly here. See https://bugs.webkit.org/show_bug.cgi?id=37609 158 // explicitly here. See https://bugs.webkit.org/show_bug.cgi?id=37609
160 // for further discussion about the TouchStationary state. 159 // for further discussion about the TouchStationary state.
161 if (pointState != PlatformTouchPoint::TouchStationary && 160 if (pointState != WebTouchPoint::StateStationary && touchInfo.knownTarget) {
162 touchInfo.knownTarget) { 161 DCHECK_LE(pointState, WebTouchPoint::StateMax);
163 ASSERT(pointState < PlatformTouchPoint::TouchStateEnd);
164 if (!changedTouches[pointState].m_touches) 162 if (!changedTouches[pointState].m_touches)
165 changedTouches[pointState].m_touches = TouchList::create(); 163 changedTouches[pointState].m_touches = TouchList::create();
166 changedTouches[pointState].m_touches->append(touch); 164 changedTouches[pointState].m_touches->append(touch);
167 changedTouches[pointState].m_targets.insert(touchInfo.touchNode); 165 changedTouches[pointState].m_targets.insert(touchInfo.touchNode);
168 changedTouches[pointState].m_pointerType = 166 changedTouches[pointState].m_pointerType = point.pointerType;
169 point.pointerProperties().pointerType;
170 } 167 }
171 } 168 }
172 169
173 if (allTouchesReleased) { 170 if (allTouchesReleased) {
174 m_touchSequenceDocument.clear(); 171 m_touchSequenceDocument.clear();
175 m_currentTouchAction = TouchActionAuto; 172 m_currentTouchAction = TouchActionAuto;
176 } 173 }
177 174
178 WebInputEventResult eventResult = WebInputEventResult::NotHandled; 175 WebInputEventResult eventResult = WebInputEventResult::NotHandled;
179 176
180 // Now iterate through the |changedTouches| list and |m_targets| within it, 177 // Now iterate through the |changedTouches| list and |m_targets| within it,
181 // sending TouchEvents to the targets as required. 178 // sending TouchEvents to the targets as required.
182 for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; 179 for (unsigned state = 0; state <= WebTouchPoint::StateMax; ++state) {
183 ++state) {
184 if (!changedTouches[state].m_touches) 180 if (!changedTouches[state].m_touches)
185 continue; 181 continue;
186 182
187 const AtomicString& eventName(touchEventNameForTouchPointState( 183 const AtomicString& eventName(touchEventNameForTouchPointState(
188 static_cast<PlatformTouchPoint::TouchState>(state))); 184 static_cast<WebTouchPoint::State>(state)));
189 for (const auto& eventTarget : changedTouches[state].m_targets) { 185 for (const auto& eventTarget : changedTouches[state].m_targets) {
190 EventTarget* touchEventTarget = eventTarget; 186 EventTarget* touchEventTarget = eventTarget;
191 TouchEvent* touchEvent = TouchEvent::create( 187 TouchEvent* touchEvent = TouchEvent::create(
192 touches, touchesByTarget.get(touchEventTarget), 188 event, touches, touchesByTarget.get(touchEventTarget),
193 changedTouches[state].m_touches.get(), eventName, 189 changedTouches[state].m_touches.get(), eventName,
194 touchEventTarget->toNode()->document().domWindow(), 190 touchEventTarget->toNode()->document().domWindow(),
195 event.getModifiers(), event.cancelable(), 191 m_currentTouchAction);
196 event.causesScrollingIfUncanceled(),
197 event.touchStartOrFirstTouchMove(), event.timestamp(),
198 m_currentTouchAction, changedTouches[state].m_pointerType);
199 192
200 DispatchEventResult domDispatchResult = 193 DispatchEventResult domDispatchResult =
201 touchEventTarget->dispatchEvent(touchEvent); 194 touchEventTarget->dispatchEvent(touchEvent);
202 195
203 // Only report for top level documents with a single touch on 196 // Only report for top level documents with a single touch on
204 // touch-start or the first touch-move. 197 // touch-start or the first touch-move.
205 if (event.touchStartOrFirstTouchMove() && touchInfos.size() == 1 && 198 if (event.touchStartOrFirstTouchMove && touchInfos.size() == 1 &&
206 m_frame->isMainFrame()) { 199 m_frame->isMainFrame()) {
207 // Record the disposition and latency of touch starts and first touch 200 // Record the disposition and latency of touch starts and first touch
208 // moves before and after the page is fully loaded respectively. 201 // moves before and after the page is fully loaded respectively.
209 int64_t latencyInMicros = 202 int64_t latencyInMicros =
210 (TimeTicks::Now() - event.timestamp()).InMicroseconds(); 203 (TimeTicks::Now() -
211 if (event.cancelable()) { 204 TimeTicks::FromSeconds(event.timeStampSeconds()))
205 .InMicroseconds();
206 if (event.isCancelable()) {
212 if (m_frame->document()->isLoadCompleted()) { 207 if (m_frame->document()->isLoadCompleted()) {
213 DEFINE_STATIC_LOCAL(EnumerationHistogram, 208 DEFINE_STATIC_LOCAL(EnumerationHistogram,
214 touchDispositionsAfterPageLoadHistogram, 209 touchDispositionsAfterPageLoadHistogram,
215 ("Event.Touch.TouchDispositionsAfterPageLoad", 210 ("Event.Touch.TouchDispositionsAfterPageLoad",
216 TouchEventDispatchResultTypeMax)); 211 TouchEventDispatchResultTypeMax));
217 touchDispositionsAfterPageLoadHistogram.count( 212 touchDispositionsAfterPageLoadHistogram.count(
218 (domDispatchResult != DispatchEventResult::NotCanceled) 213 (domDispatchResult != DispatchEventResult::NotCanceled)
219 ? HandledTouches 214 ? HandledTouches
220 : UnhandledTouches); 215 : UnhandledTouches);
221 216
(...skipping 21 matching lines...) Expand all
243 touchDispositionsOutsideFlingHistogram, 238 touchDispositionsOutsideFlingHistogram,
244 ("Event.Touch.TouchDispositionsOutsideFling2", 239 ("Event.Touch.TouchDispositionsOutsideFling2",
245 TouchEventDispatchResultTypeMax)); 240 TouchEventDispatchResultTypeMax));
246 touchDispositionsOutsideFlingHistogram.count( 241 touchDispositionsOutsideFlingHistogram.count(
247 (domDispatchResult != DispatchEventResult::NotCanceled) 242 (domDispatchResult != DispatchEventResult::NotCanceled)
248 ? HandledTouches 243 ? HandledTouches
249 : UnhandledTouches); 244 : UnhandledTouches);
250 } 245 }
251 246
252 // Report the touch disposition when there is an active fling animation. 247 // Report the touch disposition when there is an active fling animation.
253 if (event.dispatchType() == 248 if (event.dispatchType ==
254 PlatformEvent::ListenersForcedNonBlockingDueToFling) { 249 WebInputEvent::ListenersForcedNonBlockingDueToFling) {
255 DEFINE_STATIC_LOCAL(EnumerationHistogram, 250 DEFINE_STATIC_LOCAL(EnumerationHistogram,
256 touchDispositionsDuringFlingHistogram, 251 touchDispositionsDuringFlingHistogram,
257 ("Event.Touch.TouchDispositionsDuringFling2", 252 ("Event.Touch.TouchDispositionsDuringFling2",
258 TouchEventDispatchResultTypeMax)); 253 TouchEventDispatchResultTypeMax));
259 touchDispositionsDuringFlingHistogram.count( 254 touchDispositionsDuringFlingHistogram.count(
260 touchEvent->preventDefaultCalledOnUncancelableEvent() 255 touchEvent->preventDefaultCalledOnUncancelableEvent()
261 ? HandledTouches 256 ? HandledTouches
262 : UnhandledTouches); 257 : UnhandledTouches);
263 } 258 }
264 } 259 }
265 eventResult = EventHandlingUtil::mergeEventResult( 260 eventResult = EventHandlingUtil::mergeEventResult(
266 eventResult, 261 eventResult,
267 EventHandlingUtil::toWebInputEventResult(domDispatchResult)); 262 EventHandlingUtil::toWebInputEventResult(domDispatchResult));
268 } 263 }
269 } 264 }
270 265
271 return eventResult; 266 return eventResult;
272 } 267 }
273 268
274 void TouchEventManager::updateTargetAndRegionMapsForTouchStarts( 269 void TouchEventManager::updateTargetAndRegionMapsForTouchStarts(
275 HeapVector<TouchInfo>& touchInfos) { 270 HeapVector<TouchInfo>& touchInfos) {
276 for (auto& touchInfo : touchInfos) { 271 for (auto& touchInfo : touchInfos) {
277 // Touch events implicitly capture to the touched node, and don't change 272 // Touch events implicitly capture to the touched node, and don't change
278 // active/hover states themselves (Gesture events do). So we only need 273 // active/hover states themselves (Gesture events do). So we only need
279 // to hit-test on touchstart and when the target could be different than 274 // to hit-test on touchstart and when the target could be different than
280 // the corresponding pointer event target. 275 // the corresponding pointer event target.
281 if (touchInfo.point.state() == PlatformTouchPoint::TouchPressed) { 276 if (touchInfo.point.state == WebTouchPoint::StatePressed) {
282 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent | 277 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent |
283 HitTestRequest::ReadOnly | 278 HitTestRequest::ReadOnly |
284 HitTestRequest::Active; 279 HitTestRequest::Active;
285 HitTestResult result; 280 HitTestResult result;
286 // For the touchPressed points hit-testing is done in 281 // For the touchPressed points hit-testing is done in
287 // PointerEventManager. If it was the second touch there is a 282 // PointerEventManager. If it was the second touch there is a
288 // capturing documents for the touch and |m_touchSequenceDocument| 283 // capturing documents for the touch and |m_touchSequenceDocument|
289 // is not null. So if PointerEventManager should hit-test again 284 // is not null. So if PointerEventManager should hit-test again
290 // against |m_touchSequenceDocument| if the target set by 285 // against |m_touchSequenceDocument| if the target set by
291 // PointerEventManager was either null or not in 286 // PointerEventManager was either null or not in
292 // |m_touchSequenceDocument|. 287 // |m_touchSequenceDocument|.
293 if (m_touchSequenceDocument && 288 if (m_touchSequenceDocument &&
294 (!touchInfo.touchNode || 289 (!touchInfo.touchNode ||
295 &touchInfo.touchNode->document() != m_touchSequenceDocument)) { 290 &touchInfo.touchNode->document() != m_touchSequenceDocument)) {
296 if (m_touchSequenceDocument->frame()) { 291 if (m_touchSequenceDocument->frame()) {
297 LayoutPoint framePoint = LayoutPoint( 292 LayoutPoint framePoint = LayoutPoint(
298 m_touchSequenceDocument->frame()->view()->rootFrameToContents( 293 m_touchSequenceDocument->frame()->view()->rootFrameToContents(
299 touchInfo.point.pos())); 294 touchInfo.point.position));
300 result = EventHandlingUtil::hitTestResultInFrame( 295 result = EventHandlingUtil::hitTestResultInFrame(
301 m_touchSequenceDocument->frame(), framePoint, hitType); 296 m_touchSequenceDocument->frame(), framePoint, hitType);
302 Node* node = result.innerNode(); 297 Node* node = result.innerNode();
303 if (!node) 298 if (!node)
304 continue; 299 continue;
305 if (isHTMLCanvasElement(node)) { 300 if (isHTMLCanvasElement(node)) {
306 HitTestCanvasResult* hitTestCanvasResult = 301 HitTestCanvasResult* hitTestCanvasResult =
307 toHTMLCanvasElement(node)->getControlAndIdIfHitRegionExists( 302 toHTMLCanvasElement(node)->getControlAndIdIfHitRegionExists(
308 result.pointInInnerNodeFrame()); 303 result.pointInInnerNodeFrame());
309 if (hitTestCanvasResult->getControl()) 304 if (hitTestCanvasResult->getControl())
(...skipping 17 matching lines...) Expand all
327 m_touchSequenceDocument = &(touchInfo.touchNode->document()); 322 m_touchSequenceDocument = &(touchInfo.touchNode->document());
328 ASSERT(m_touchSequenceDocument->frame()->view()); 323 ASSERT(m_touchSequenceDocument->frame()->view());
329 } 324 }
330 325
331 // Ideally we'd ASSERT(!m_targetForTouchID.contains(point.id()) 326 // Ideally we'd ASSERT(!m_targetForTouchID.contains(point.id())
332 // since we shouldn't get a touchstart for a touch that's already 327 // since we shouldn't get a touchstart for a touch that's already
333 // down. However EventSender allows this to be violated and there's 328 // down. However EventSender allows this to be violated and there's
334 // some tests that take advantage of it. There may also be edge 329 // some tests that take advantage of it. There may also be edge
335 // cases in the browser where this happens. 330 // cases in the browser where this happens.
336 // See http://crbug.com/345372. 331 // See http://crbug.com/345372.
337 m_targetForTouchID.set(touchInfo.point.id(), touchInfo.touchNode); 332 m_targetForTouchID.set(touchInfo.point.id, touchInfo.touchNode);
338 333
339 m_regionForTouchID.set(touchInfo.point.id(), touchInfo.region); 334 m_regionForTouchID.set(touchInfo.point.id, touchInfo.region);
340 335
341 TouchAction effectiveTouchAction = 336 TouchAction effectiveTouchAction =
342 TouchActionUtil::computeEffectiveTouchAction(*touchInfo.touchNode); 337 TouchActionUtil::computeEffectiveTouchAction(*touchInfo.touchNode);
343 if (effectiveTouchAction != TouchActionAuto) { 338 if (effectiveTouchAction != TouchActionAuto) {
344 m_frame->page()->chromeClient().setTouchAction(m_frame, 339 m_frame->page()->chromeClient().setTouchAction(m_frame,
345 effectiveTouchAction); 340 effectiveTouchAction);
346 341
347 // Combine the current touch action sequence with the touch action 342 // Combine the current touch action sequence with the touch action
348 // for the current finger press. 343 // for the current finger press.
349 m_currentTouchAction &= effectiveTouchAction; 344 m_currentTouchAction &= effectiveTouchAction;
350 } 345 }
351 } 346 }
352 } 347 }
353 } 348 }
354 349
355 void TouchEventManager::setAllPropertiesOfTouchInfos( 350 void TouchEventManager::setAllPropertiesOfTouchInfos(
356 HeapVector<TouchInfo>& touchInfos) { 351 HeapVector<TouchInfo>& touchInfos) {
357 for (auto& touchInfo : touchInfos) { 352 for (auto& touchInfo : touchInfos) {
358 PlatformTouchPoint::TouchState pointState = touchInfo.point.state(); 353 WebTouchPoint::State pointState = touchInfo.point.state;
359 Node* touchNode = nullptr; 354 Node* touchNode = nullptr;
360 String regionID; 355 String regionID;
361 356
362 if (pointState == PlatformTouchPoint::TouchReleased || 357 if (pointState == WebTouchPoint::StateReleased ||
363 pointState == PlatformTouchPoint::TouchCancelled) { 358 pointState == WebTouchPoint::StateCancelled) {
364 // The target should be the original target for this touch, so get 359 // The target should be the original target for this touch, so get
365 // it from the hashmap. As it's a release or cancel we also remove 360 // it from the hashmap. As it's a release or cancel we also remove
366 // it from the map. 361 // it from the map.
367 touchNode = m_targetForTouchID.take(touchInfo.point.id()); 362 touchNode = m_targetForTouchID.take(touchInfo.point.id);
368 regionID = m_regionForTouchID.take(touchInfo.point.id()); 363 regionID = m_regionForTouchID.take(touchInfo.point.id);
369 } else { 364 } else {
370 // No hittest is performed on move or stationary, since the target 365 // No hittest is performed on move or stationary, since the target
371 // is not allowed to change anyway. 366 // is not allowed to change anyway.
372 touchNode = m_targetForTouchID.get(touchInfo.point.id()); 367 touchNode = m_targetForTouchID.get(touchInfo.point.id);
373 regionID = m_regionForTouchID.get(touchInfo.point.id()); 368 regionID = m_regionForTouchID.get(touchInfo.point.id);
374 } 369 }
375 370
376 LocalFrame* targetFrame = nullptr; 371 LocalFrame* targetFrame = nullptr;
377 bool knownTarget = false; 372 bool knownTarget = false;
378 if (touchNode) { 373 if (touchNode) {
379 Document& doc = touchNode->document(); 374 Document& doc = touchNode->document();
380 // If the target node has moved to a new document while it was being 375 // If the target node has moved to a new document while it was being
381 // touched, we can't send events to the new document because that could 376 // touched, we can't send events to the new document because that could
382 // leak nodes from one document to another. See http://crbug.com/394339. 377 // leak nodes from one document to another. See http://crbug.com/394339.
383 if (&doc == m_touchSequenceDocument.get()) { 378 if (&doc == m_touchSequenceDocument.get()) {
(...skipping 15 matching lines...) Expand all
399 // a Touch is a Node so using the window could be a breaking change. 394 // a Touch is a Node so using the window could be a breaking change.
400 // Since we know there was no handler invoked, the specific target 395 // Since we know there was no handler invoked, the specific target
401 // should be completely irrelevant to the application. 396 // should be completely irrelevant to the application.
402 touchNode = m_touchSequenceDocument; 397 touchNode = m_touchSequenceDocument;
403 targetFrame = m_touchSequenceDocument->frame(); 398 targetFrame = m_touchSequenceDocument->frame();
404 } 399 }
405 ASSERT(targetFrame); 400 ASSERT(targetFrame);
406 401
407 // pagePoint should always be in the target element's document coordinates. 402 // pagePoint should always be in the target element's document coordinates.
408 FloatPoint pagePoint = 403 FloatPoint pagePoint =
409 targetFrame->view()->rootFrameToContents(touchInfo.point.pos()); 404 targetFrame->view()->rootFrameToContents(touchInfo.point.position);
410 float scaleFactor = 1.0f / targetFrame->pageZoomFactor(); 405 float scaleFactor = 1.0f / targetFrame->pageZoomFactor();
411 406
412 touchInfo.touchNode = touchNode; 407 touchInfo.touchNode = touchNode;
413 touchInfo.targetFrame = targetFrame; 408 touchInfo.targetFrame = targetFrame;
414 touchInfo.contentPoint = pagePoint.scaledBy(scaleFactor); 409 touchInfo.contentPoint = pagePoint.scaledBy(scaleFactor);
415 touchInfo.adjustedRadius = touchInfo.point.radius().scaledBy(scaleFactor); 410 touchInfo.adjustedRadius =
411 FloatSize(touchInfo.point.radiusX, touchInfo.point.radiusY)
412 .scaledBy(scaleFactor);
416 touchInfo.knownTarget = knownTarget; 413 touchInfo.knownTarget = knownTarget;
417 touchInfo.region = regionID; 414 touchInfo.region = regionID;
418 } 415 }
419 } 416 }
420 417
421 bool TouchEventManager::reHitTestTouchPointsIfNeeded( 418 bool TouchEventManager::reHitTestTouchPointsIfNeeded(
422 const PlatformTouchEvent& event, 419 const WebTouchEvent& event,
423 HeapVector<TouchInfo>& touchInfos) { 420 HeapVector<TouchInfo>& touchInfos) {
424 bool newTouchSequence = true; 421 bool newTouchSequence = true;
425 bool allTouchesReleased = true; 422 bool allTouchesReleased = true;
426 423
427 for (const auto& point : event.touchPoints()) { 424 for (unsigned i = 0; i < event.touchesLength; ++i) {
428 if (point.state() != PlatformTouchPoint::TouchPressed) 425 WebTouchPoint::State state = event.touches[i].state;
426 if (state != WebTouchPoint::StatePressed)
429 newTouchSequence = false; 427 newTouchSequence = false;
430 if (point.state() != PlatformTouchPoint::TouchReleased && 428 if (state != WebTouchPoint::StateReleased &&
431 point.state() != PlatformTouchPoint::TouchCancelled) 429 state != WebTouchPoint::StateCancelled)
432 allTouchesReleased = false; 430 allTouchesReleased = false;
433 } 431 }
434 if (newTouchSequence) { 432 if (newTouchSequence) {
435 // Ideally we'd ASSERT(!m_touchSequenceDocument) here since we should 433 // Ideally we'd ASSERT(!m_touchSequenceDocument) here since we should
436 // have cleared the active document when we saw the last release. But we 434 // have cleared the active document when we saw the last release. But we
437 // have some tests that violate this, ClusterFuzz could trigger it, and 435 // have some tests that violate this, ClusterFuzz could trigger it, and
438 // there may be cases where the browser doesn't reliably release all 436 // there may be cases where the browser doesn't reliably release all
439 // touches. http://crbug.com/345372 tracks this. 437 // touches. http://crbug.com/345372 tracks this.
440 m_touchSequenceDocument.clear(); 438 m_touchSequenceDocument.clear();
441 } 439 }
(...skipping 21 matching lines...) Expand all
463 m_touchSequenceDocument.clear(); 461 m_touchSequenceDocument.clear();
464 } 462 }
465 return false; 463 return false;
466 } 464 }
467 465
468 setAllPropertiesOfTouchInfos(touchInfos); 466 setAllPropertiesOfTouchInfos(touchInfos);
469 467
470 return true; 468 return true;
471 } 469 }
472 470
473 // TODO(rbyers): Replace with AutoReset as base/WTF unification permits.
474 class CurrentEventHolder {
475 // Always stack allocated to ensure lifetime doesn't exceed that of target
476 DISALLOW_NEW();
477
478 public:
479 CurrentEventHolder(PlatformEvent::EventType& target,
480 PlatformEvent::EventType value)
481 : m_target(target) {
482 m_target = value;
483 }
484 ~CurrentEventHolder() { m_target = PlatformEvent::NoType; }
485
486 private:
487 PlatformEvent::EventType& m_target;
488 };
489
490 WebInputEventResult TouchEventManager::handleTouchEvent( 471 WebInputEventResult TouchEventManager::handleTouchEvent(
491 const PlatformTouchEvent& event, 472 const WebTouchEvent& event,
492 HeapVector<TouchInfo>& touchInfos) { 473 HeapVector<TouchInfo>& touchInfos) {
493
494 // Track the current event for the scope of this function.
495 CurrentEventHolder holder(m_currentEvent, event.type());
496
497 if (!reHitTestTouchPointsIfNeeded(event, touchInfos)) 474 if (!reHitTestTouchPointsIfNeeded(event, touchInfos))
498 return WebInputEventResult::NotHandled; 475 return WebInputEventResult::NotHandled;
499 476
500 bool allTouchesReleased = true; 477 bool allTouchesReleased = true;
501 for (const auto& point : event.touchPoints()) { 478 for (unsigned i = 0; i < event.touchesLength; ++i) {
502 if (point.state() != PlatformTouchPoint::TouchReleased && 479 WebTouchPoint::State state = event.touches[i].state;
503 point.state() != PlatformTouchPoint::TouchCancelled) 480 if (state != WebTouchPoint::StateReleased &&
481 state != WebTouchPoint::StateCancelled)
504 allTouchesReleased = false; 482 allTouchesReleased = false;
505 } 483 }
506 484
507 return dispatchTouchEvents(event, touchInfos, allTouchesReleased); 485 return dispatchTouchEvents(event, touchInfos, allTouchesReleased);
508 } 486 }
509 487
510 bool TouchEventManager::isAnyTouchActive() const { 488 bool TouchEventManager::isAnyTouchActive() const {
511 return m_touchPressed; 489 return m_touchPressed;
512 } 490 }
513 491
514 } // namespace blink 492 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698