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

Side by Side Diff: third_party/WebKit/Source/core/events/PointerEventManager.cpp

Issue 1670073004: Send node transition events for touch events (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/events/PointerEventManager.h" 5 #include "core/events/PointerEventManager.h"
6 #include "core/dom/shadow/ComposedTreeTraversal.h"
6 7
7 namespace blink { 8 namespace blink {
8 9
9 namespace { 10 namespace {
10 11
11 inline int toInt(WebPointerProperties::PointerType t) { return static_cast<int>( t); } 12 inline int toInt(WebPointerProperties::PointerType t) { return static_cast<int>( t); }
12 13
13 const char* pointerTypeNameForWebPointPointerType(WebPointerProperties::PointerT ype type) 14 const char* pointerTypeNameForWebPointPointerType(WebPointerProperties::PointerT ype type)
14 { 15 {
15 switch (type) { 16 switch (type) {
16 case WebPointerProperties::PointerType::Unknown: 17 case WebPointerProperties::PointerType::Unknown:
17 return ""; 18 return "";
18 case WebPointerProperties::PointerType::Touch: 19 case WebPointerProperties::PointerType::Touch:
19 return "touch"; 20 return "touch";
20 case WebPointerProperties::PointerType::Pen: 21 case WebPointerProperties::PointerType::Pen:
21 return "pen"; 22 return "pen";
22 case WebPointerProperties::PointerType::Mouse: 23 case WebPointerProperties::PointerType::Mouse:
23 return "mouse"; 24 return "mouse";
24 } 25 }
25 ASSERT_NOT_REACHED(); 26 ASSERT_NOT_REACHED();
26 return ""; 27 return "";
27 } 28 }
28 29
30 const AtomicString& pointerEventNameForTouchPointState(PlatformTouchPoint::State state)
31 {
32 switch (state) {
33 case PlatformTouchPoint::TouchReleased:
34 return EventTypeNames::pointerup;
35 case PlatformTouchPoint::TouchCancelled:
36 return EventTypeNames::pointercancel;
37 case PlatformTouchPoint::TouchPressed:
38 return EventTypeNames::pointerdown;
39 case PlatformTouchPoint::TouchMoved:
40 return EventTypeNames::pointermove;
41 case PlatformTouchPoint::TouchStationary:
42 // Fall through to default
43 default:
44 ASSERT_NOT_REACHED();
45 return emptyAtom;
46 }
47 }
48
49 bool isInDocument(EventTarget *n)
50 {
51 return n && n->toNode() && n->toNode()->inDocument();
52 }
53
54 void sendPointerEventToTarget(EventTarget *target,
55 PassRefPtrWillBeRawPtr<PointerEvent> pointerevent)
56 {
57 if (isInDocument(target))
58 target->dispatchEvent(pointerevent);
59 }
60
29 } // namespace 61 } // namespace
30 62
31 const PointerEventManager::MappedId PointerEventManager::s_invalidId = 0; 63 const PointerEventManager::MappedId PointerEventManager::s_invalidId = 0;
32 64
33 // Mouse id is 1 to behave the same as MS Edge for compatibility reasons. 65 // Mouse id is 1 to behave the same as MS Edge for compatibility reasons.
34 const PointerEventManager::MappedId PointerEventManager::s_mouseId = 1; 66 const PointerEventManager::MappedId PointerEventManager::s_mouseId = 1;
35 67
36 EventTarget* PointerEventManager::getCapturingNode(PassRefPtrWillBeRawPtr<Pointe rEvent> pointerEvent) 68 EventTarget* PointerEventManager::getCapturingNode(PassRefPtrWillBeRawPtr<Pointe rEvent> pointerEvent)
37 { 69 {
38 // TODO(nzolghadr): Add APIs to set the capturing nodes and return the corre ct node here 70 // TODO(nzolghadr): Add APIs to set the capturing nodes and return the corre ct node here
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 pointerEventInit.setCancelable(type != EventTypeNames::pointerenter 114 pointerEventInit.setCancelable(type != EventTypeNames::pointerenter
83 && type != EventTypeNames::pointerleave && type != EventTypeNames::point ercancel); 115 && type != EventTypeNames::pointerleave && type != EventTypeNames::point ercancel);
84 116
85 pointerEventInit.setView(view); 117 pointerEventInit.setView(view);
86 if (relatedTarget) 118 if (relatedTarget)
87 pointerEventInit.setRelatedTarget(relatedTarget); 119 pointerEventInit.setRelatedTarget(relatedTarget);
88 120
89 return PointerEvent::create(type, pointerEventInit); 121 return PointerEvent::create(type, pointerEventInit);
90 } 122 }
91 123
92 PassRefPtrWillBeRawPtr<PointerEvent> PointerEventManager::create(const AtomicStr ing& type, 124 PassRefPtrWillBeRawPtr<PointerEvent> PointerEventManager::create(
125 const AtomicString& type,
93 const PlatformTouchPoint& touchPoint, PlatformEvent::Modifiers modifiers, 126 const PlatformTouchPoint& touchPoint, PlatformEvent::Modifiers modifiers,
94 const double width, const double height, 127 const double width, const double height,
95 const double clientX, const double clientY) 128 const double clientX, const double clientY)
96 { 129 {
97 const PlatformTouchPoint::State pointState = touchPoint.state(); 130 const PlatformTouchPoint::State pointState = touchPoint.state();
98 131
99 bool pointerReleasedOrCancelled = pointState == PlatformTouchPoint::TouchRel eased 132 bool pointerReleasedOrCancelled = pointState == PlatformTouchPoint::TouchRel eased
100 || pointState == PlatformTouchPoint::TouchCancelled; 133 || pointState == PlatformTouchPoint::TouchCancelled;
101 134
102 bool isEnterOrLeave = false; 135 bool isEnterOrLeave = false;
(...skipping 16 matching lines...) Expand all
119 touchPoint.force(), pointerEventInit.buttons())); 152 touchPoint.force(), pointerEventInit.buttons()));
120 153
121 UIEventWithKeyState::setFromPlatformModifiers(pointerEventInit, modifiers); 154 UIEventWithKeyState::setFromPlatformModifiers(pointerEventInit, modifiers);
122 155
123 pointerEventInit.setBubbles(!isEnterOrLeave); 156 pointerEventInit.setBubbles(!isEnterOrLeave);
124 pointerEventInit.setCancelable(!isEnterOrLeave && pointState != PlatformTouc hPoint::TouchCancelled); 157 pointerEventInit.setCancelable(!isEnterOrLeave && pointState != PlatformTouc hPoint::TouchCancelled);
125 158
126 return PointerEvent::create(type, pointerEventInit); 159 return PointerEvent::create(type, pointerEventInit);
127 } 160 }
128 161
129 162 PassRefPtrWillBeRawPtr<PointerEvent> PointerEventManager::create(
130 PassRefPtrWillBeRawPtr<PointerEvent> PointerEventManager::createPointerCancel(co nst PlatformTouchPoint& touchPoint) 163 PassRefPtrWillBeRawPtr<PointerEvent> pointerevent,
164 const AtomicString& type,
165 PassRefPtrWillBeRawPtr<EventTarget> relatedTarget)
131 { 166 {
132 PointerEventInit pointerEventInit; 167 PointerEventInit pointerEventInit;
133 168
169 pointerEventInit.setPointerId(pointerevent->pointerId());
170 pointerEventInit.setPointerType(pointerevent->pointerType());
171 pointerEventInit.setIsPrimary(pointerevent->isPrimary());
172 pointerEventInit.setWidth(pointerevent->width());
173 pointerEventInit.setHeight(pointerevent->height());
174 pointerEventInit.setTiltX(pointerevent->tiltX());
175 pointerEventInit.setTiltY(pointerevent->tiltY());
176 pointerEventInit.setScreenX(pointerevent->screenX());
177 pointerEventInit.setScreenY(pointerevent->screenY());
178 pointerEventInit.setClientX(pointerevent->clientX());
179 pointerEventInit.setClientY(pointerevent->clientY());
180 pointerEventInit.setButton(pointerevent->button());
181 pointerEventInit.setButtons(pointerevent->buttons());
182 pointerEventInit.setPressure(pointerevent->pressure());
183
184 pointerEventInit.setBubbles(type != EventTypeNames::pointerenter
185 && type != EventTypeNames::pointerleave);
186 pointerEventInit.setCancelable(type != EventTypeNames::pointerenter
187 && type != EventTypeNames::pointerleave
188 && type != EventTypeNames::pointercancel);
189
190 return PointerEvent::create(type, pointerEventInit);
191 }
192
193 void PointerEventManager::sendNodeTransitionEvents(
mustaq 2016/02/08 17:01:34 This duplication looks bad. All you need here is a
Navid Zolghadr 2016/02/10 16:25:29 Done.
194 EventTarget* exitedTarget, EventTarget* enteredTarget,
195 PassRefPtrWillBeRawPtr<PointerEvent> pointerEvent)
196 {
197 if (exitedTarget == enteredTarget)
198 return;
199
200 if (!RuntimeEnabledFeatures::pointerEventEnabled())
201 return;
202
203 // Create lists of all exited/entered ancestors, locate the common ancestor
204 WillBeHeapVector<RefPtrWillBeMember<Node>, 32> exitedAncestors;
205 WillBeHeapVector<RefPtrWillBeMember<Node>, 32> enteredAncestors;
206 if (isInDocument(exitedTarget)) {
207 Node* exitedNode = exitedTarget->toNode();
208 exitedNode->updateDistribution();
209 for (Node* node = exitedNode; node; node = ComposedTreeTraversal::parent (*node))
210 exitedAncestors.append(node);
211 }
212 if (isInDocument(enteredTarget)) {
213 Node* enteredNode = enteredTarget->toNode();
214 enteredNode->updateDistribution();
215 for (Node* node = enteredNode; node; node = ComposedTreeTraversal::paren t(*node))
216 enteredAncestors.append(node);
217 }
218
219 size_t exitedAncestorIndex = exitedAncestors.size();
220 size_t enteredAncestorIndex = enteredAncestors.size();
221 if (!exitedAncestors.isEmpty() && !enteredAncestors.isEmpty()) {
222 for (size_t i = exitedAncestors.size(), j = enteredAncestors.size(); i>0 && j>0; j--, i--) {
223 if (exitedAncestors[i-1] == enteredAncestors[j-1]) {
224 exitedAncestorIndex = i-1;
225 enteredAncestorIndex = j-1;
226 } else {
227 break;
228 }
229 }
230 }
231
232 // Dispatch pointerout
233 sendPointerEventToTarget(exitedTarget,
234 create(pointerEvent, EventTypeNames::pointerout, enteredTarget));
235
236 // Dispatch pointerleave events, in child-to-parent order
237 for (size_t i = 0; i < exitedAncestorIndex; i++) {
238 sendPointerEventToTarget(exitedAncestors[i].get(),
239 create(pointerEvent, EventTypeNames::pointerleave, enteredTarget));
240 }
241
242 // Dispatch pointerover
243 sendPointerEventToTarget(enteredTarget,
244 create(pointerEvent, EventTypeNames::pointerover, exitedTarget));
245
246 // Dispatch pointerenter events, in parent-to-child order.
247 for (size_t j = enteredAncestorIndex; j > 0; j--) {
248 sendPointerEventToTarget(enteredAncestors[j-1].get(),
249 create(pointerEvent, EventTypeNames::pointerenter, exitedTarget));
250 }
251 }
252
253 void PointerEventManager::setNodeUnderPointer(
254 PassRefPtrWillBeRawPtr<PointerEvent> pointerevent, EventTarget* target)
255 {
256 if (m_nodeUnderPointer.contains(pointerevent->pointerId())) {
257 sendNodeTransitionEvents(m_nodeUnderPointer.get(
258 pointerevent->pointerId()), target, pointerevent);
259 if (!target)
260 m_nodeUnderPointer.remove(pointerevent->pointerId());
261 else
262 m_nodeUnderPointer.set(pointerevent->pointerId(), target);
263 } else if (target) {
264 sendNodeTransitionEvents(nullptr, target, pointerevent);
265 m_nodeUnderPointer.add(pointerevent->pointerId(), target);
266 }
267 }
268
269 void PointerEventManager::sendTouchCancelPointerEvent(PassRefPtrWillBeRawPtr<Eve ntTarget> target,
270 const PlatformTouchPoint& point)
271 {
272 RefPtrWillBeRawPtr<PointerEvent> pointerEvent =
273 createPointerCancel(point);
274
275 // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing v s pointer event capturing
276 target->dispatchEvent(pointerEvent.get());
277
278 remove(pointerEvent);
279 setNodeUnderPointer(pointerEvent, nullptr);
280 }
281
282 bool PointerEventManager::sendTouchPointerEvent(
283 PassRefPtrWillBeRawPtr<EventTarget> target,
284 const PlatformTouchPoint& touchPoint, PlatformEvent::Modifiers modifiers,
285 const double width, const double height,
286 const double clientX, const double clientY)
287 {
288 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = create(
289 pointerEventNameForTouchPointState(touchPoint.state()),
290 touchPoint, modifiers, width, height, clientX, clientY);
291
292 setNodeUnderPointer(pointerEvent, target);
293
294 // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing v s pointer event capturing
295 target->dispatchEvent(pointerEvent.get());
296
297 if (touchPoint.state() == PlatformTouchPoint::TouchReleased
298 || touchPoint.state() == PlatformTouchPoint::TouchCancelled) {
299 remove(pointerEvent);
300 setNodeUnderPointer(pointerEvent, nullptr);
301 }
302
303 return pointerEvent->defaultPrevented() || pointerEvent->defaultHandled();
304 }
305
306 PassRefPtrWillBeRawPtr<PointerEvent> PointerEventManager::createPointerCancel(
307 const PlatformTouchPoint& touchPoint)
308 {
309 PointerEventInit pointerEventInit;
310
134 setIdAndType(pointerEventInit, touchPoint.pointerProperties()); 311 setIdAndType(pointerEventInit, touchPoint.pointerProperties());
135 312
136 pointerEventInit.setBubbles(true); 313 pointerEventInit.setBubbles(true);
137 pointerEventInit.setCancelable(false); 314 pointerEventInit.setCancelable(false);
138 315
139 return PointerEvent::create(EventTypeNames::pointercancel, pointerEventInit) ; 316 return PointerEvent::create(EventTypeNames::pointercancel, pointerEventInit) ;
140 } 317 }
141 318
142 PointerEventManager::PointerEventManager() 319 PointerEventManager::PointerEventManager()
143 { 320 {
144 clear(); 321 clear();
145 } 322 }
146 323
147 PointerEventManager::~PointerEventManager() 324 PointerEventManager::~PointerEventManager()
148 { 325 {
149 clear(); 326 clear();
150 } 327 }
151 328
329 DEFINE_TRACE(PointerEventManager)
330 {
331 visitor->trace(m_nodeUnderPointer);
332 }
333
152 void PointerEventManager::clear() 334 void PointerEventManager::clear()
153 { 335 {
154 for (int type = 0; type <= toInt(WebPointerProperties::PointerType::LastEntr y); type++) { 336 for (int type = 0; type <= toInt(WebPointerProperties::PointerType::LastEntr y); type++) {
155 m_primaryId[type] = PointerEventManager::s_invalidId; 337 m_primaryId[type] = PointerEventManager::s_invalidId;
156 m_idCount[type] = 0; 338 m_idCount[type] = 0;
157 } 339 }
158 m_idMapping.clear(); 340 m_idMapping.clear();
159 m_idReverseMapping.clear(); 341 m_idReverseMapping.clear();
342 m_nodeUnderPointer.clear();
160 343
161 // Always add mouse pointer in initialization and never remove it. 344 // Always add mouse pointer in initialization and never remove it.
162 // No need to add it to m_idMapping as it is not going to be used with the e xisting APIs 345 // No need to add it to m_idMapping as it is not going to be used with the e xisting APIs
163 m_primaryId[toInt(WebPointerProperties::PointerType::Mouse)] = s_mouseId; 346 m_primaryId[toInt(WebPointerProperties::PointerType::Mouse)] = s_mouseId;
164 m_idReverseMapping.add(s_mouseId, IncomingId(toInt(WebPointerProperties::Poi nterType::Mouse), 0)); 347 m_idReverseMapping.add(s_mouseId, IncomingId(toInt(WebPointerProperties::Poi nterType::Mouse), 0));
165 348
166 m_currentId = PointerEventManager::s_mouseId+1; 349 m_currentId = PointerEventManager::s_mouseId+1;
167 } 350 }
168 351
169 PointerEventManager::MappedId PointerEventManager::add(const IncomingId p) 352 PointerEventManager::MappedId PointerEventManager::add(const IncomingId p)
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 if (!m_idReverseMapping.contains(mappedId)) 389 if (!m_idReverseMapping.contains(mappedId))
207 return false; 390 return false;
208 391
209 IncomingId p = m_idReverseMapping.get(mappedId); 392 IncomingId p = m_idReverseMapping.get(mappedId);
210 int type = p.first; 393 int type = p.first;
211 return m_primaryId[type] == mappedId; 394 return m_primaryId[type] == mappedId;
212 } 395 }
213 396
214 397
215 } // namespace blink 398 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698