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

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

Issue 2510133002: Add getCoalescedEvents API to PointerEvent (Closed)
Patch Set: rebase Created 4 years 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/events/PointerEventFactory.h" 5 #include "core/events/PointerEventFactory.h"
6 6
7 #include "core/frame/FrameView.h" 7 #include "core/frame/FrameView.h"
8 #include "platform/geometry/FloatSize.h" 8 #include "platform/geometry/FloatSize.h"
9 9
10 namespace blink { 10 namespace blink {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 CASE_BUTTON_TO_BUTTONS(X2); 68 CASE_BUTTON_TO_BUTTONS(X2);
69 CASE_BUTTON_TO_BUTTONS(Eraser); 69 CASE_BUTTON_TO_BUTTONS(Eraser);
70 } 70 }
71 71
72 #undef CASE_BUTTON_TO_BUTTONS 72 #undef CASE_BUTTON_TO_BUTTONS
73 73
74 NOTREACHED(); 74 NOTREACHED();
75 return 0; 75 return 0;
76 } 76 }
77 77
78 } // namespace 78 const AtomicString& pointerEventNameForTouchPointState(
79 79 PlatformTouchPoint::TouchState state) {
80 const int PointerEventFactory::s_invalidId = 0; 80 switch (state) {
81 81 case PlatformTouchPoint::TouchReleased:
82 // Mouse id is 1 to behave the same as MS Edge for compatibility reasons. 82 return EventTypeNames::pointerup;
83 const int PointerEventFactory::s_mouseId = 1; 83 case PlatformTouchPoint::TouchCancelled:
84 return EventTypeNames::pointercancel;
85 case PlatformTouchPoint::TouchPressed:
86 return EventTypeNames::pointerdown;
87 case PlatformTouchPoint::TouchMoved:
88 return EventTypeNames::pointermove;
89 case PlatformTouchPoint::TouchStationary:
90 // Fall through to default
91 default:
92 NOTREACHED();
93 return emptyAtom;
94 }
95 }
84 96
85 float getPointerEventPressure(float force, int buttons) { 97 float getPointerEventPressure(float force, int buttons) {
86 if (std::isnan(force)) 98 if (std::isnan(force))
87 return buttons ? 0.5 : 0; 99 return buttons ? 0.5 : 0;
88 return force; 100 return force;
89 } 101 }
90 102
103 void updateTouchPointerEventInit(const PlatformTouchPoint& touchPoint,
104 LocalFrame* targetFrame,
105 PointerEventInit* pointerEventInit) {
106 // This function should not update attributes like pointerId, isPrimary,
107 // and pointerType which is the same among the coalesced events and the
108 // dispatched event.
109
110 if (targetFrame) {
111 FloatPoint pagePoint =
112 targetFrame->view()->rootFrameToContents(touchPoint.pos());
113 float scaleFactor = 1.0f / targetFrame->pageZoomFactor();
114 FloatPoint scrollPosition(targetFrame->view()->scrollOffset());
115 FloatPoint clientPoint = pagePoint.scaledBy(scaleFactor);
116 clientPoint.moveBy(scrollPosition.scaledBy(-scaleFactor));
117
118 pointerEventInit->setClientX(clientPoint.x());
119 pointerEventInit->setClientY(clientPoint.y());
120
121 FloatSize pointRadius = touchPoint.radius().scaledBy(scaleFactor);
122 pointerEventInit->setWidth(pointRadius.width());
123 pointerEventInit->setHeight(pointRadius.height());
124 }
125
126 pointerEventInit->setScreenX(touchPoint.screenPos().x());
127 pointerEventInit->setScreenY(touchPoint.screenPos().y());
128 pointerEventInit->setPressure(
129 getPointerEventPressure(touchPoint.force(), pointerEventInit->buttons()));
130 pointerEventInit->setTiltX(touchPoint.pointerProperties().tiltX);
131 pointerEventInit->setTiltY(touchPoint.pointerProperties().tiltY);
132 }
133
134 void updateMousePointerEventInit(const PlatformMouseEvent& mouseEvent,
135 LocalDOMWindow* view,
136 PointerEventInit* pointerEventInit) {
137 // This function should not update attributes like pointerId, isPrimary,
138 // and pointerType which is the same among the coalesced events and the
139 // dispatched event.
140
141 pointerEventInit->setScreenX(mouseEvent.globalPosition().x());
142 pointerEventInit->setScreenY(mouseEvent.globalPosition().y());
143
144 IntPoint locationInFrameZoomed;
145 if (view && view->frame() && view->frame()->view()) {
146 LocalFrame* frame = view->frame();
147 FrameView* frameView = frame->view();
148 IntPoint locationInContents =
149 frameView->rootFrameToContents(mouseEvent.position());
150 locationInFrameZoomed = frameView->contentsToFrame(locationInContents);
151 float scaleFactor = 1 / frame->pageZoomFactor();
152 locationInFrameZoomed.scale(scaleFactor, scaleFactor);
153 }
154
155 pointerEventInit->setClientX(locationInFrameZoomed.x());
156 pointerEventInit->setClientY(locationInFrameZoomed.y());
157
158 pointerEventInit->setPressure(getPointerEventPressure(
159 mouseEvent.pointerProperties().force, pointerEventInit->buttons()));
160 pointerEventInit->setTiltX(mouseEvent.pointerProperties().tiltX);
161 pointerEventInit->setTiltY(mouseEvent.pointerProperties().tiltY);
162 }
163
164 } // namespace
165
166 const int PointerEventFactory::s_invalidId = 0;
167
168 // Mouse id is 1 to behave the same as MS Edge for compatibility reasons.
169 const int PointerEventFactory::s_mouseId = 1;
170
91 void PointerEventFactory::setIdTypeButtons( 171 void PointerEventFactory::setIdTypeButtons(
92 PointerEventInit& pointerEventInit, 172 PointerEventInit& pointerEventInit,
93 const WebPointerProperties& pointerProperties, 173 const WebPointerProperties& pointerProperties,
94 unsigned buttons) { 174 unsigned buttons) {
95 const WebPointerProperties::PointerType pointerType = 175 const WebPointerProperties::PointerType pointerType =
96 pointerProperties.pointerType; 176 pointerProperties.pointerType;
97 const IncomingId incomingId(pointerType, pointerProperties.id); 177 const IncomingId incomingId(pointerType, pointerProperties.id);
98 int pointerId = addIdAndActiveButtons(incomingId, buttons != 0); 178 int pointerId = addIdAndActiveButtons(incomingId, buttons != 0);
99 179
100 // Tweak the |buttons| to reflect pen eraser mode only if the pen is in 180 // Tweak the |buttons| to reflect pen eraser mode only if the pen is in
(...skipping 20 matching lines...) Expand all
121 pointerEventInit.setCancelable(type != EventTypeNames::pointerenter && 201 pointerEventInit.setCancelable(type != EventTypeNames::pointerenter &&
122 type != EventTypeNames::pointerleave && 202 type != EventTypeNames::pointerleave &&
123 type != EventTypeNames::pointercancel && 203 type != EventTypeNames::pointercancel &&
124 type != EventTypeNames::gotpointercapture && 204 type != EventTypeNames::gotpointercapture &&
125 type != EventTypeNames::lostpointercapture); 205 type != EventTypeNames::lostpointercapture);
126 206
127 pointerEventInit.setComposed(true); 207 pointerEventInit.setComposed(true);
128 pointerEventInit.setDetail(0); 208 pointerEventInit.setDetail(0);
129 } 209 }
130 210
131 PointerEvent* PointerEventFactory::create(const AtomicString& mouseEventName, 211 PointerEvent* PointerEventFactory::create(
132 const PlatformMouseEvent& mouseEvent, 212 const AtomicString& mouseEventName,
133 LocalDOMWindow* view) { 213 const PlatformMouseEvent& mouseEvent,
214 const Vector<PlatformMouseEvent>& coalescedMouseEvents,
215 LocalDOMWindow* view) {
134 DCHECK(mouseEventName == EventTypeNames::mousemove || 216 DCHECK(mouseEventName == EventTypeNames::mousemove ||
135 mouseEventName == EventTypeNames::mousedown || 217 mouseEventName == EventTypeNames::mousedown ||
136 mouseEventName == EventTypeNames::mouseup); 218 mouseEventName == EventTypeNames::mouseup);
137 219
138 AtomicString pointerEventName = 220 AtomicString pointerEventName =
139 pointerEventNameForMouseEventName(mouseEventName); 221 pointerEventNameForMouseEventName(mouseEventName);
222 DCHECK(pointerEventName == EventTypeNames::pointermove ||
223 coalescedMouseEvents.isEmpty());
224
140 unsigned buttons = 225 unsigned buttons =
141 MouseEvent::platformModifiersToButtons(mouseEvent.getModifiers()); 226 MouseEvent::platformModifiersToButtons(mouseEvent.getModifiers());
142 PointerEventInit pointerEventInit; 227 PointerEventInit pointerEventInit;
143 228
144 setIdTypeButtons(pointerEventInit, mouseEvent.pointerProperties(), buttons); 229 setIdTypeButtons(pointerEventInit, mouseEvent.pointerProperties(), buttons);
145 setEventSpecificFields(pointerEventInit, pointerEventName); 230 setEventSpecificFields(pointerEventInit, pointerEventName);
146 231
147 pointerEventInit.setScreenX(mouseEvent.globalPosition().x());
148 pointerEventInit.setScreenY(mouseEvent.globalPosition().y());
149
150 IntPoint locationInFrameZoomed;
151 if (view && view->frame() && view->frame()->view()) {
152 LocalFrame* frame = view->frame();
153 FrameView* frameView = frame->view();
154 IntPoint locationInContents =
155 frameView->rootFrameToContents(mouseEvent.position());
156 locationInFrameZoomed = frameView->contentsToFrame(locationInContents);
157 float scaleFactor = 1 / frame->pageZoomFactor();
158 locationInFrameZoomed.scale(scaleFactor, scaleFactor);
159 }
160
161 // Set up initial values for coordinates.
162 pointerEventInit.setClientX(locationInFrameZoomed.x());
163 pointerEventInit.setClientY(locationInFrameZoomed.y());
164
165 if (pointerEventName == EventTypeNames::pointerdown || 232 if (pointerEventName == EventTypeNames::pointerdown ||
166 pointerEventName == EventTypeNames::pointerup) { 233 pointerEventName == EventTypeNames::pointerup) {
167 WebPointerProperties::Button button = mouseEvent.pointerProperties().button; 234 WebPointerProperties::Button button = mouseEvent.pointerProperties().button;
168 // TODO(mustaq): Fix when the spec starts supporting hovering erasers. 235 // TODO(mustaq): Fix when the spec starts supporting hovering erasers.
169 if (mouseEvent.pointerProperties().pointerType == 236 if (mouseEvent.pointerProperties().pointerType ==
170 WebPointerProperties::PointerType::Eraser && 237 WebPointerProperties::PointerType::Eraser &&
171 button == WebPointerProperties::Button::Left) 238 button == WebPointerProperties::Button::Left)
172 button = WebPointerProperties::Button::Eraser; 239 button = WebPointerProperties::Button::Eraser;
173 pointerEventInit.setButton(static_cast<int>(button)); 240 pointerEventInit.setButton(static_cast<int>(button));
174 } else { 241 } else {
175 DCHECK(pointerEventName == EventTypeNames::pointermove); 242 DCHECK(pointerEventName == EventTypeNames::pointermove);
176 pointerEventInit.setButton( 243 pointerEventInit.setButton(
177 static_cast<int>(WebPointerProperties::Button::NoButton)); 244 static_cast<int>(WebPointerProperties::Button::NoButton));
178 } 245 }
179 pointerEventInit.setPressure(getPointerEventPressure(
180 mouseEvent.pointerProperties().force, pointerEventInit.buttons()));
181 pointerEventInit.setTiltX(mouseEvent.pointerProperties().tiltX);
182 pointerEventInit.setTiltY(mouseEvent.pointerProperties().tiltY);
183 246
184 UIEventWithKeyState::setFromPlatformModifiers(pointerEventInit, 247 UIEventWithKeyState::setFromPlatformModifiers(pointerEventInit,
185 mouseEvent.getModifiers()); 248 mouseEvent.getModifiers());
186 249
187 // Make sure chorded buttons fire pointermove instead of pointerup/down. 250 // Make sure chorded buttons fire pointermove instead of pointerup/down.
188 if ((pointerEventName == EventTypeNames::pointerdown && 251 if ((pointerEventName == EventTypeNames::pointerdown &&
189 (buttons & 252 (buttons &
190 ~buttonToButtonsBitfield(mouseEvent.pointerProperties().button)) != 253 ~buttonToButtonsBitfield(mouseEvent.pointerProperties().button)) !=
191 0) || 254 0) ||
192 (pointerEventName == EventTypeNames::pointerup && buttons != 0)) 255 (pointerEventName == EventTypeNames::pointerup && buttons != 0))
193 pointerEventName = EventTypeNames::pointermove; 256 pointerEventName = EventTypeNames::pointermove;
194 257
195 pointerEventInit.setView(view); 258 pointerEventInit.setView(view);
196 259
260 updateMousePointerEventInit(mouseEvent, view, &pointerEventInit);
261
262 // Created coalesced events init structure
263 HeapVector<Member<PointerEvent>> coalescedPointerEvents;
264 for (const auto& coalescedMouseEvent : coalescedMouseEvents) {
265 DCHECK_EQ(mouseEvent.pointerProperties().id,
266 coalescedMouseEvent.pointerProperties().id);
267 DCHECK_EQ(mouseEvent.pointerProperties().pointerType,
268 coalescedMouseEvent.pointerProperties().pointerType);
269 PointerEventInit coalescedEventInit = pointerEventInit;
270 updateMousePointerEventInit(coalescedMouseEvent, view, &coalescedEventInit);
271 coalescedPointerEvents.append(
272 PointerEvent::create(pointerEventName, coalescedEventInit));
273 }
274 pointerEventInit.setCoalescedEvents(coalescedPointerEvents);
275
197 return PointerEvent::create(pointerEventName, pointerEventInit); 276 return PointerEvent::create(pointerEventName, pointerEventInit);
198 } 277 }
199 278
200 PointerEvent* PointerEventFactory::create(const AtomicString& type, 279 PointerEvent* PointerEventFactory::create(
201 const PlatformTouchPoint& touchPoint, 280 const PlatformTouchPoint& touchPoint,
202 PlatformEvent::Modifiers modifiers, 281 const Vector<PlatformTouchPoint>& coalescedPoints,
203 const FloatSize& pointRadius, 282 PlatformEvent::Modifiers modifiers,
204 const FloatPoint& clientPoint, 283 LocalFrame* targetFrame,
205 DOMWindow* view) { 284 DOMWindow* view) {
206 const PlatformTouchPoint::TouchState pointState = touchPoint.state(); 285 const PlatformTouchPoint::TouchState pointState = touchPoint.state();
286 const AtomicString& type =
287 pointerEventNameForTouchPointState(touchPoint.state());
288
289 DCHECK(type == EventTypeNames::pointermove || coalescedPoints.isEmpty());
207 290
208 bool pointerReleasedOrCancelled = 291 bool pointerReleasedOrCancelled =
209 pointState == PlatformTouchPoint::TouchReleased || 292 pointState == PlatformTouchPoint::TouchReleased ||
210 pointState == PlatformTouchPoint::TouchCancelled; 293 pointState == PlatformTouchPoint::TouchCancelled;
211 bool pointerPressedOrReleased = 294 bool pointerPressedOrReleased =
212 pointState == PlatformTouchPoint::TouchPressed || 295 pointState == PlatformTouchPoint::TouchPressed ||
213 pointState == PlatformTouchPoint::TouchReleased; 296 pointState == PlatformTouchPoint::TouchReleased;
214 297
215 PointerEventInit pointerEventInit; 298 PointerEventInit pointerEventInit;
216 299
217 setIdTypeButtons(pointerEventInit, touchPoint.pointerProperties(), 300 setIdTypeButtons(pointerEventInit, touchPoint.pointerProperties(),
218 pointerReleasedOrCancelled ? 0 : 1); 301 pointerReleasedOrCancelled ? 0 : 1);
219
220 pointerEventInit.setWidth(pointRadius.width());
221 pointerEventInit.setHeight(pointRadius.height());
222 pointerEventInit.setScreenX(touchPoint.screenPos().x());
223 pointerEventInit.setScreenY(touchPoint.screenPos().y());
224 pointerEventInit.setClientX(clientPoint.x());
225 pointerEventInit.setClientY(clientPoint.y());
226 pointerEventInit.setButton(static_cast<int>( 302 pointerEventInit.setButton(static_cast<int>(
227 pointerPressedOrReleased ? WebPointerProperties::Button::Left 303 pointerPressedOrReleased ? WebPointerProperties::Button::Left
228 : WebPointerProperties::Button::NoButton)); 304 : WebPointerProperties::Button::NoButton));
229 pointerEventInit.setPressure( 305
230 getPointerEventPressure(touchPoint.force(), pointerEventInit.buttons()));
231 pointerEventInit.setTiltX(touchPoint.pointerProperties().tiltX);
232 pointerEventInit.setTiltY(touchPoint.pointerProperties().tiltY);
233 pointerEventInit.setView(view); 306 pointerEventInit.setView(view);
307 updateTouchPointerEventInit(touchPoint, targetFrame, &pointerEventInit);
234 308
235 UIEventWithKeyState::setFromPlatformModifiers(pointerEventInit, modifiers); 309 UIEventWithKeyState::setFromPlatformModifiers(pointerEventInit, modifiers);
236 310
237 setEventSpecificFields(pointerEventInit, type); 311 setEventSpecificFields(pointerEventInit, type);
238 312
313 // Created coalesced events init structure
314 HeapVector<Member<PointerEvent>> coalescedPointerEvents;
315 for (const auto& coalescedTouchPoint : coalescedPoints) {
316 DCHECK_EQ(touchPoint.state(), coalescedTouchPoint.state());
317 DCHECK_EQ(touchPoint.pointerProperties().id,
318 coalescedTouchPoint.pointerProperties().id);
319 DCHECK_EQ(touchPoint.pointerProperties().pointerType,
320 coalescedTouchPoint.pointerProperties().pointerType);
321 PointerEventInit coalescedEventInit = pointerEventInit;
322 updateTouchPointerEventInit(coalescedTouchPoint, targetFrame,
323 &coalescedEventInit);
324 coalescedPointerEvents.append(
325 PointerEvent::create(type, coalescedEventInit));
326 }
327 pointerEventInit.setCoalescedEvents(coalescedPointerEvents);
328
239 return PointerEvent::create(type, pointerEventInit); 329 return PointerEvent::create(type, pointerEventInit);
240 } 330 }
241 331
242 PointerEvent* PointerEventFactory::createPointerCancelEvent( 332 PointerEvent* PointerEventFactory::createPointerCancelEvent(
243 const int pointerId, 333 const int pointerId,
244 const WebPointerProperties::PointerType pointerType) { 334 const WebPointerProperties::PointerType pointerType) {
245 DCHECK(m_pointerIdMapping.contains(pointerId)); 335 DCHECK(m_pointerIdMapping.contains(pointerId));
246 m_pointerIdMapping.set( 336 m_pointerIdMapping.set(
247 pointerId, 337 pointerId,
248 PointerAttributes(m_pointerIdMapping.get(pointerId).incomingId, false)); 338 PointerAttributes(m_pointerIdMapping.get(pointerId).incomingId, false));
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 const WebPointerProperties& properties) const { 513 const WebPointerProperties& properties) const {
424 if (properties.pointerType == WebPointerProperties::PointerType::Mouse) 514 if (properties.pointerType == WebPointerProperties::PointerType::Mouse)
425 return PointerEventFactory::s_mouseId; 515 return PointerEventFactory::s_mouseId;
426 IncomingId id(properties.pointerType, properties.id); 516 IncomingId id(properties.pointerType, properties.id);
427 if (m_pointerIncomingIdMapping.contains(id)) 517 if (m_pointerIncomingIdMapping.contains(id))
428 return m_pointerIncomingIdMapping.get(id); 518 return m_pointerIncomingIdMapping.get(id);
429 return PointerEventFactory::s_invalidId; 519 return PointerEventFactory::s_invalidId;
430 } 520 }
431 521
432 } // namespace blink 522 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698