OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2009 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 #include "core/layout/api/LayoutItem.h" | 43 #include "core/layout/api/LayoutItem.h" |
44 #include "core/page/ChromeClient.h" | 44 #include "core/page/ChromeClient.h" |
45 #include "core/page/Page.h" | 45 #include "core/page/Page.h" |
46 #include "platform/KeyboardCodes.h" | 46 #include "platform/KeyboardCodes.h" |
47 #include "platform/Widget.h" | 47 #include "platform/Widget.h" |
48 #include "public/platform/Platform.h" | 48 #include "public/platform/Platform.h" |
49 | 49 |
50 namespace blink { | 50 namespace blink { |
51 | 51 |
52 namespace { | 52 namespace { |
53 float scaleDeltaToWindow(const Widget* widget, float delta) { | 53 float frameScale(const Widget* widget) { |
54 float scale = 1; | 54 float scale = 1.0f; |
55 if (widget) { | 55 if (widget) { |
56 FrameView* rootView = toFrameView(widget->root()); | 56 FrameView* rootView = toFrameView(widget->root()); |
57 if (rootView) | 57 if (rootView) |
58 scale = rootView->inputEventsScaleFactor(); | 58 scale = rootView->inputEventsScaleFactor(); |
59 } | 59 } |
60 return delta / scale; | 60 return scale; |
| 61 } |
| 62 |
| 63 FloatPoint frameTranslation(const Widget* widget) { |
| 64 float scale = 1; |
| 65 FloatSize offset; |
| 66 IntPoint visualViewport; |
| 67 FloatSize overscrollOffset; |
| 68 if (widget) { |
| 69 FrameView* rootView = toFrameView(widget->root()); |
| 70 if (rootView) { |
| 71 scale = rootView->inputEventsScaleFactor(); |
| 72 offset = FloatSize(rootView->inputEventsOffsetForEmulation()); |
| 73 visualViewport = flooredIntPoint(rootView->page() |
| 74 ->frameHost() |
| 75 .visualViewport() |
| 76 .visibleRect() |
| 77 .location()); |
| 78 overscrollOffset = |
| 79 rootView->page()->frameHost().chromeClient().elasticOverscroll(); |
| 80 } |
| 81 } |
| 82 return FloatPoint( |
| 83 -offset.width() / scale + visualViewport.x() + overscrollOffset.width(), |
| 84 -offset.height() / scale + visualViewport.y() + |
| 85 overscrollOffset.height()); |
| 86 } |
| 87 |
| 88 float scaleDeltaToWindow(const Widget* widget, float delta) { |
| 89 return delta / frameScale(widget); |
61 } | 90 } |
62 | 91 |
63 FloatSize scaleSizeToWindow(const Widget* widget, FloatSize size) { | 92 FloatSize scaleSizeToWindow(const Widget* widget, FloatSize size) { |
64 return FloatSize(scaleDeltaToWindow(widget, size.width()), | 93 return FloatSize(scaleDeltaToWindow(widget, size.width()), |
65 scaleDeltaToWindow(widget, size.height())); | 94 scaleDeltaToWindow(widget, size.height())); |
66 } | 95 } |
67 | 96 |
68 // This method converts from the renderer's coordinate space into Blink's root | 97 // This method converts from the renderer's coordinate space into Blink's root |
69 // frame coordinate space. It's somewhat unique in that it takes into account | 98 // frame coordinate space. It's somewhat unique in that it takes into account |
70 // DevTools emulation, which applies a scale and offset in the root layer (see | 99 // DevTools emulation, which applies a scale and offset in the root layer (see |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 if (button == WebMouseEvent::Button::NoButton) | 156 if (button == WebMouseEvent::Button::NoButton) |
128 return 0; | 157 return 0; |
129 | 158 |
130 unsigned webMouseButtonToPlatformModifier[] = { | 159 unsigned webMouseButtonToPlatformModifier[] = { |
131 PlatformEvent::LeftButtonDown, PlatformEvent::MiddleButtonDown, | 160 PlatformEvent::LeftButtonDown, PlatformEvent::MiddleButtonDown, |
132 PlatformEvent::RightButtonDown}; | 161 PlatformEvent::RightButtonDown}; |
133 | 162 |
134 return webMouseButtonToPlatformModifier[static_cast<int>(button)]; | 163 return webMouseButtonToPlatformModifier[static_cast<int>(button)]; |
135 } | 164 } |
136 | 165 |
137 ScrollGranularity toPlatformScrollGranularity( | |
138 WebGestureEvent::ScrollUnits units) { | |
139 switch (units) { | |
140 case WebGestureEvent::ScrollUnits::PrecisePixels: | |
141 return ScrollGranularity::ScrollByPrecisePixel; | |
142 case WebGestureEvent::ScrollUnits::Pixels: | |
143 return ScrollGranularity::ScrollByPixel; | |
144 case WebGestureEvent::ScrollUnits::Page: | |
145 return ScrollGranularity::ScrollByPage; | |
146 default: | |
147 NOTREACHED(); | |
148 return ScrollGranularity::ScrollByPrecisePixel; | |
149 } | |
150 } | |
151 | |
152 ScrollInertialPhase toPlatformScrollInertialPhase( | |
153 WebGestureEvent::InertialPhaseState state) { | |
154 static_assert( | |
155 ScrollInertialPhaseUnknown == static_cast<ScrollInertialPhase>( | |
156 WebGestureEvent::UnknownMomentumPhase), | |
157 "Inertial phases not equal"); | |
158 static_assert( | |
159 ScrollInertialPhaseNonMomentum == | |
160 static_cast<ScrollInertialPhase>(WebGestureEvent::NonMomentumPhase), | |
161 "Inertial phases not equal"); | |
162 static_assert( | |
163 ScrollInertialPhaseMomentum == | |
164 static_cast<ScrollInertialPhase>(WebGestureEvent::MomentumPhase), | |
165 "Inertial phases not equal"); | |
166 | |
167 return static_cast<ScrollInertialPhase>(state); | |
168 } | |
169 | |
170 WebGestureEvent::InertialPhaseState toWebGestureInertialPhaseState( | |
171 ScrollInertialPhase state) { | |
172 return static_cast<WebGestureEvent::InertialPhaseState>(state); | |
173 } | |
174 | |
175 WebGestureEvent::ScrollUnits toWebGestureScrollUnits( | |
176 ScrollGranularity granularity) { | |
177 switch (granularity) { | |
178 case ScrollGranularity::ScrollByPrecisePixel: | |
179 return WebGestureEvent::ScrollUnits::PrecisePixels; | |
180 case ScrollGranularity::ScrollByPixel: | |
181 return WebGestureEvent::ScrollUnits::Pixels; | |
182 case ScrollGranularity::ScrollByPage: | |
183 return WebGestureEvent::ScrollUnits::Page; | |
184 default: | |
185 NOTREACHED(); | |
186 return WebGestureEvent::ScrollUnits::PrecisePixels; | |
187 } | |
188 } | |
189 | |
190 } // namespace | 166 } // namespace |
191 | 167 |
192 // MakePlatformMouseEvent ----------------------------------------------------- | 168 // MakePlatformMouseEvent ----------------------------------------------------- |
193 | 169 |
194 // TODO(mustaq): Add tests for this. | 170 // TODO(mustaq): Add tests for this. |
195 PlatformMouseEventBuilder::PlatformMouseEventBuilder(Widget* widget, | 171 PlatformMouseEventBuilder::PlatformMouseEventBuilder(Widget* widget, |
196 const WebMouseEvent& e) { | 172 const WebMouseEvent& e) { |
197 // FIXME: Widget is always toplevel, unless it's a popup. We may be able | 173 // FIXME: Widget is always toplevel, unless it's a popup. We may be able |
198 // to get rid of this once we abstract popups into a WebKit API. | 174 // to get rid of this once we abstract popups into a WebKit API. |
199 m_position = widget->convertFromRootFrame( | 175 m_position = widget->convertFromRootFrame( |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 m_resendingPluginId = e.resendingPluginId; | 235 m_resendingPluginId = e.resendingPluginId; |
260 m_railsMode = static_cast<PlatformEvent::RailsMode>(e.railsMode); | 236 m_railsMode = static_cast<PlatformEvent::RailsMode>(e.railsMode); |
261 #if OS(MACOSX) | 237 #if OS(MACOSX) |
262 m_phase = static_cast<PlatformWheelEventPhase>(e.phase); | 238 m_phase = static_cast<PlatformWheelEventPhase>(e.phase); |
263 m_momentumPhase = static_cast<PlatformWheelEventPhase>(e.momentumPhase); | 239 m_momentumPhase = static_cast<PlatformWheelEventPhase>(e.momentumPhase); |
264 #endif | 240 #endif |
265 } | 241 } |
266 | 242 |
267 // PlatformGestureEventBuilder ----------------------------------------------- | 243 // PlatformGestureEventBuilder ----------------------------------------------- |
268 | 244 |
269 PlatformGestureEventBuilder::PlatformGestureEventBuilder( | 245 WebGestureEvent ScaleWebGestureEvent(Widget* widget, |
270 Widget* widget, | 246 const WebGestureEvent& event) { |
271 const WebGestureEvent& e) { | 247 WebGestureEvent result = event; |
272 switch (e.type) { | 248 result.frameScale = frameScale(widget); |
273 case WebInputEvent::GestureScrollBegin: | 249 FloatPoint translate = frameTranslation(widget); |
274 m_type = PlatformEvent::GestureScrollBegin; | 250 result.frameTranslateX = translate.x(); |
275 m_data.m_scroll.m_resendingPluginId = e.resendingPluginId; | 251 result.frameTranslateY = translate.y(); |
276 m_data.m_scroll.m_deltaX = e.data.scrollBegin.deltaXHint; | 252 return result; |
277 m_data.m_scroll.m_deltaY = e.data.scrollBegin.deltaYHint; | |
278 m_data.m_scroll.m_deltaUnits = | |
279 toPlatformScrollGranularity(e.data.scrollBegin.deltaHintUnits); | |
280 m_data.m_scroll.m_inertialPhase = | |
281 toPlatformScrollInertialPhase(e.data.scrollBegin.inertialPhase); | |
282 m_data.m_scroll.m_synthetic = e.data.scrollBegin.synthetic; | |
283 break; | |
284 case WebInputEvent::GestureScrollEnd: | |
285 m_type = PlatformEvent::GestureScrollEnd; | |
286 m_data.m_scroll.m_resendingPluginId = e.resendingPluginId; | |
287 m_data.m_scroll.m_deltaUnits = | |
288 toPlatformScrollGranularity(e.data.scrollEnd.deltaUnits); | |
289 m_data.m_scroll.m_inertialPhase = | |
290 toPlatformScrollInertialPhase(e.data.scrollEnd.inertialPhase); | |
291 m_data.m_scroll.m_synthetic = e.data.scrollEnd.synthetic; | |
292 break; | |
293 case WebInputEvent::GestureFlingStart: | |
294 m_type = PlatformEvent::GestureFlingStart; | |
295 m_data.m_scroll.m_velocityX = e.data.flingStart.velocityX; | |
296 m_data.m_scroll.m_velocityY = e.data.flingStart.velocityY; | |
297 break; | |
298 case WebInputEvent::GestureScrollUpdate: | |
299 m_type = PlatformEvent::GestureScrollUpdate; | |
300 m_data.m_scroll.m_resendingPluginId = e.resendingPluginId; | |
301 m_data.m_scroll.m_deltaX = | |
302 scaleDeltaToWindow(widget, e.data.scrollUpdate.deltaX); | |
303 m_data.m_scroll.m_deltaY = | |
304 scaleDeltaToWindow(widget, e.data.scrollUpdate.deltaY); | |
305 m_data.m_scroll.m_velocityX = e.data.scrollUpdate.velocityX; | |
306 m_data.m_scroll.m_velocityY = e.data.scrollUpdate.velocityY; | |
307 m_data.m_scroll.m_preventPropagation = | |
308 e.data.scrollUpdate.preventPropagation; | |
309 m_data.m_scroll.m_inertialPhase = | |
310 toPlatformScrollInertialPhase(e.data.scrollUpdate.inertialPhase); | |
311 m_data.m_scroll.m_deltaUnits = | |
312 toPlatformScrollGranularity(e.data.scrollUpdate.deltaUnits); | |
313 break; | |
314 case WebInputEvent::GestureTap: | |
315 m_type = PlatformEvent::GestureTap; | |
316 m_area = expandedIntSize(scaleSizeToWindow( | |
317 widget, FloatSize(e.data.tap.width, e.data.tap.height))); | |
318 m_data.m_tap.m_tapCount = e.data.tap.tapCount; | |
319 break; | |
320 case WebInputEvent::GestureTapUnconfirmed: | |
321 m_type = PlatformEvent::GestureTapUnconfirmed; | |
322 m_area = expandedIntSize(scaleSizeToWindow( | |
323 widget, FloatSize(e.data.tap.width, e.data.tap.height))); | |
324 break; | |
325 case WebInputEvent::GestureTapDown: | |
326 m_type = PlatformEvent::GestureTapDown; | |
327 m_area = expandedIntSize(scaleSizeToWindow( | |
328 widget, FloatSize(e.data.tapDown.width, e.data.tapDown.height))); | |
329 break; | |
330 case WebInputEvent::GestureShowPress: | |
331 m_type = PlatformEvent::GestureShowPress; | |
332 m_area = expandedIntSize(scaleSizeToWindow( | |
333 widget, FloatSize(e.data.showPress.width, e.data.showPress.height))); | |
334 break; | |
335 case WebInputEvent::GestureTapCancel: | |
336 m_type = PlatformEvent::GestureTapDownCancel; | |
337 break; | |
338 case WebInputEvent::GestureDoubleTap: | |
339 // DoubleTap gesture is now handled as PlatformEvent::GestureTap with | |
340 // tap_count = 2. So no need to convert to a Platfrom DoubleTap gesture. | |
341 // But in WebViewImpl::handleGestureEvent all WebGestureEvent are | |
342 // converted to PlatformGestureEvent, for completeness and not reach the | |
343 // NOTREACHED() at the end, convert the DoubleTap to a NoType. | |
344 m_type = PlatformEvent::NoType; | |
345 break; | |
346 case WebInputEvent::GestureTwoFingerTap: | |
347 m_type = PlatformEvent::GestureTwoFingerTap; | |
348 m_area = expandedIntSize(scaleSizeToWindow( | |
349 widget, FloatSize(e.data.twoFingerTap.firstFingerWidth, | |
350 e.data.twoFingerTap.firstFingerHeight))); | |
351 break; | |
352 case WebInputEvent::GestureLongPress: | |
353 m_type = PlatformEvent::GestureLongPress; | |
354 m_area = expandedIntSize(scaleSizeToWindow( | |
355 widget, FloatSize(e.data.longPress.width, e.data.longPress.height))); | |
356 break; | |
357 case WebInputEvent::GestureLongTap: | |
358 m_type = PlatformEvent::GestureLongTap; | |
359 m_area = expandedIntSize(scaleSizeToWindow( | |
360 widget, FloatSize(e.data.longPress.width, e.data.longPress.height))); | |
361 break; | |
362 case WebInputEvent::GesturePinchBegin: | |
363 m_type = PlatformEvent::GesturePinchBegin; | |
364 break; | |
365 case WebInputEvent::GesturePinchEnd: | |
366 m_type = PlatformEvent::GesturePinchEnd; | |
367 break; | |
368 case WebInputEvent::GesturePinchUpdate: | |
369 m_type = PlatformEvent::GesturePinchUpdate; | |
370 m_data.m_pinchUpdate.m_scale = e.data.pinchUpdate.scale; | |
371 break; | |
372 default: | |
373 NOTREACHED(); | |
374 } | |
375 m_position = widget->convertFromRootFrame(flooredIntPoint( | |
376 convertHitPointToRootFrame(widget, FloatPoint(e.x, e.y)))); | |
377 m_globalPosition = IntPoint(e.globalX, e.globalY); | |
378 m_timestamp = e.timeStampSeconds; | |
379 m_modifiers = e.modifiers; | |
380 switch (e.sourceDevice) { | |
381 case WebGestureDeviceTouchpad: | |
382 m_source = PlatformGestureSourceTouchpad; | |
383 break; | |
384 case WebGestureDeviceTouchscreen: | |
385 m_source = PlatformGestureSourceTouchscreen; | |
386 break; | |
387 case WebGestureDeviceUninitialized: | |
388 NOTREACHED(); | |
389 } | |
390 | |
391 m_uniqueTouchEventId = e.uniqueTouchEventId; | |
392 } | 253 } |
393 | 254 |
394 inline PlatformEvent::EventType toPlatformTouchEventType( | 255 inline PlatformEvent::EventType toPlatformTouchEventType( |
395 const WebInputEvent::Type type) { | 256 const WebInputEvent::Type type) { |
396 switch (type) { | 257 switch (type) { |
397 case WebInputEvent::TouchStart: | 258 case WebInputEvent::TouchStart: |
398 return PlatformEvent::TouchStart; | 259 return PlatformEvent::TouchStart; |
399 case WebInputEvent::TouchMove: | 260 case WebInputEvent::TouchMove: |
400 return PlatformEvent::TouchMove; | 261 return PlatformEvent::TouchMove; |
401 case WebInputEvent::TouchEnd: | 262 case WebInputEvent::TouchEnd: |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
757 WebTouchPoint::StateStationary); | 618 WebTouchPoint::StateStationary); |
758 ++touchesLength; | 619 ++touchesLength; |
759 } | 620 } |
760 // If any existing points are also in the change list, we should update | 621 // If any existing points are also in the change list, we should update |
761 // their state, otherwise just add the new points. | 622 // their state, otherwise just add the new points. |
762 addTouchPointsUpdateStateIfNecessary(toWebTouchPointState(event.type()), | 623 addTouchPointsUpdateStateIfNecessary(toWebTouchPointState(event.type()), |
763 event.changedTouches(), touches, | 624 event.changedTouches(), touches, |
764 &touchesLength, layoutItem); | 625 &touchesLength, layoutItem); |
765 } | 626 } |
766 | 627 |
767 WebGestureEventBuilder::WebGestureEventBuilder(const LayoutItem layoutItem, | |
768 const GestureEvent& event) { | |
769 if (event.type() == EventTypeNames::gestureshowpress) { | |
770 type = GestureShowPress; | |
771 } else if (event.type() == EventTypeNames::gesturelongpress) { | |
772 type = GestureLongPress; | |
773 } else if (event.type() == EventTypeNames::gesturetapdown) { | |
774 type = GestureTapDown; | |
775 } else if (event.type() == EventTypeNames::gesturescrollstart) { | |
776 type = GestureScrollBegin; | |
777 resendingPluginId = event.resendingPluginId(); | |
778 data.scrollBegin.deltaXHint = event.deltaX(); | |
779 data.scrollBegin.deltaYHint = event.deltaY(); | |
780 data.scrollBegin.deltaHintUnits = | |
781 toWebGestureScrollUnits(event.deltaUnits()); | |
782 data.scrollBegin.inertialPhase = | |
783 toWebGestureInertialPhaseState(event.inertialPhase()); | |
784 data.scrollBegin.synthetic = event.synthetic(); | |
785 } else if (event.type() == EventTypeNames::gesturescrollend) { | |
786 type = GestureScrollEnd; | |
787 resendingPluginId = event.resendingPluginId(); | |
788 data.scrollEnd.deltaUnits = toWebGestureScrollUnits(event.deltaUnits()); | |
789 data.scrollEnd.inertialPhase = | |
790 toWebGestureInertialPhaseState(event.inertialPhase()); | |
791 data.scrollEnd.synthetic = event.synthetic(); | |
792 } else if (event.type() == EventTypeNames::gesturescrollupdate) { | |
793 type = GestureScrollUpdate; | |
794 data.scrollUpdate.deltaUnits = toWebGestureScrollUnits(event.deltaUnits()); | |
795 data.scrollUpdate.deltaX = event.deltaX(); | |
796 data.scrollUpdate.deltaY = event.deltaY(); | |
797 data.scrollUpdate.inertialPhase = | |
798 toWebGestureInertialPhaseState(event.inertialPhase()); | |
799 resendingPluginId = event.resendingPluginId(); | |
800 } else if (event.type() == EventTypeNames::gestureflingstart) { | |
801 type = GestureFlingStart; | |
802 data.flingStart.velocityX = event.velocityX(); | |
803 data.flingStart.velocityY = event.velocityY(); | |
804 } else if (event.type() == EventTypeNames::gesturetap) { | |
805 type = GestureTap; | |
806 data.tap.tapCount = 1; | |
807 } | |
808 | |
809 timeStampSeconds = event.platformTimeStamp(); | |
810 modifiers = event.modifiers(); | |
811 | |
812 globalX = event.screenX(); | |
813 globalY = event.screenY(); | |
814 IntPoint localPoint = convertAbsoluteLocationForLayoutObjectInt( | |
815 event.absoluteLocation(), layoutItem); | |
816 x = localPoint.x(); | |
817 y = localPoint.y(); | |
818 | |
819 switch (event.source()) { | |
820 case GestureSourceTouchpad: | |
821 sourceDevice = WebGestureDeviceTouchpad; | |
822 break; | |
823 case GestureSourceTouchscreen: | |
824 sourceDevice = WebGestureDeviceTouchscreen; | |
825 break; | |
826 case GestureSourceUninitialized: | |
827 NOTREACHED(); | |
828 } | |
829 } | |
830 | |
831 Vector<PlatformMouseEvent> createPlatformMouseEventVector( | 628 Vector<PlatformMouseEvent> createPlatformMouseEventVector( |
832 Widget* widget, | 629 Widget* widget, |
833 const std::vector<const WebInputEvent*>& coalescedEvents) { | 630 const std::vector<const WebInputEvent*>& coalescedEvents) { |
834 Vector<PlatformMouseEvent> result; | 631 Vector<PlatformMouseEvent> result; |
835 for (const auto& event : coalescedEvents) { | 632 for (const auto& event : coalescedEvents) { |
836 DCHECK(WebInputEvent::isMouseEventType(event->type)); | 633 DCHECK(WebInputEvent::isMouseEventType(event->type)); |
837 result.append(PlatformMouseEventBuilder( | 634 result.append(PlatformMouseEventBuilder( |
838 widget, static_cast<const WebMouseEvent&>(*event))); | 635 widget, static_cast<const WebMouseEvent&>(*event))); |
839 } | 636 } |
840 return result; | 637 return result; |
841 } | 638 } |
842 | 639 |
843 Vector<PlatformTouchEvent> createPlatformTouchEventVector( | 640 Vector<PlatformTouchEvent> createPlatformTouchEventVector( |
844 Widget* widget, | 641 Widget* widget, |
845 const std::vector<const WebInputEvent*>& coalescedEvents) { | 642 const std::vector<const WebInputEvent*>& coalescedEvents) { |
846 Vector<PlatformTouchEvent> result; | 643 Vector<PlatformTouchEvent> result; |
847 for (const auto& event : coalescedEvents) { | 644 for (const auto& event : coalescedEvents) { |
848 DCHECK(WebInputEvent::isTouchEventType(event->type)); | 645 DCHECK(WebInputEvent::isTouchEventType(event->type)); |
849 result.append(PlatformTouchEventBuilder( | 646 result.append(PlatformTouchEventBuilder( |
850 widget, static_cast<const WebTouchEvent&>(*event))); | 647 widget, static_cast<const WebTouchEvent&>(*event))); |
851 } | 648 } |
852 return result; | 649 return result; |
853 } | 650 } |
854 | 651 |
855 } // namespace blink | 652 } // namespace blink |
OLD | NEW |