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

Side by Side Diff: Source/core/page/EventHandler.cpp

Issue 145003002: [DevTools] Switch from blink-based to content-based touch emulation. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: another rebase Created 6 years, 8 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
« no previous file with comments | « Source/core/page/EventHandler.h ('k') | Source/core/page/Page.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed. 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed.
3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) 3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies)
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 ~MaximumDurationTracker() 168 ~MaximumDurationTracker()
169 { 169 {
170 *m_maxDuration = max(*m_maxDuration, monotonicallyIncreasingTime() - m_s tart); 170 *m_maxDuration = max(*m_maxDuration, monotonicallyIncreasingTime() - m_s tart);
171 } 171 }
172 172
173 private: 173 private:
174 double* m_maxDuration; 174 double* m_maxDuration;
175 double m_start; 175 double m_start;
176 }; 176 };
177 177
178 class SyntheticTouchPoint : public PlatformTouchPoint {
179 public:
180
181 // The default values are based on http://dvcs.w3.org/hg/webevents/raw-file/ tip/touchevents.html
182 explicit SyntheticTouchPoint(const PlatformMouseEvent& event)
183 {
184 const static int idDefaultValue = 0;
185 const static int radiusYDefaultValue = 1;
186 const static int radiusXDefaultValue = 1;
187 const static float rotationAngleDefaultValue = 0.0f;
188 const static float forceDefaultValue = 1.0f;
189
190 m_id = idDefaultValue; // There is only one active TouchPoint.
191 m_screenPos = event.globalPosition();
192 m_pos = event.position();
193 m_radiusY = radiusYDefaultValue;
194 m_radiusX = radiusXDefaultValue;
195 m_rotationAngle = rotationAngleDefaultValue;
196 m_force = forceDefaultValue;
197
198 PlatformEvent::Type type = event.type();
199 ASSERT(type == PlatformEvent::MouseMoved || type == PlatformEvent::Mouse Pressed || type == PlatformEvent::MouseReleased);
200
201 switch (type) {
202 case PlatformEvent::MouseMoved:
203 m_state = TouchMoved;
204 break;
205 case PlatformEvent::MousePressed:
206 m_state = TouchPressed;
207 break;
208 case PlatformEvent::MouseReleased:
209 m_state = TouchReleased;
210 break;
211 default:
212 ASSERT_NOT_REACHED();
213 break;
214 }
215 }
216 };
217
218 class SyntheticSingleTouchEvent : public PlatformTouchEvent {
219 public:
220 explicit SyntheticSingleTouchEvent(const PlatformMouseEvent& event)
221 {
222 switch (event.type()) {
223 case PlatformEvent::MouseMoved:
224 m_type = TouchMove;
225 break;
226 case PlatformEvent::MousePressed:
227 m_type = TouchStart;
228 break;
229 case PlatformEvent::MouseReleased:
230 m_type = TouchEnd;
231 break;
232 default:
233 ASSERT_NOT_REACHED();
234 m_type = NoType;
235 break;
236 }
237 m_timestamp = event.timestamp();
238 m_modifiers = event.modifiers();
239 m_touchPoints.append(SyntheticTouchPoint(event));
240 }
241 };
242
243 static inline ScrollGranularity wheelGranularityToScrollGranularity(unsigned del taMode) 178 static inline ScrollGranularity wheelGranularityToScrollGranularity(unsigned del taMode)
244 { 179 {
245 switch (deltaMode) { 180 switch (deltaMode) {
246 case WheelEvent::DOM_DELTA_PAGE: 181 case WheelEvent::DOM_DELTA_PAGE:
247 return ScrollByPage; 182 return ScrollByPage;
248 case WheelEvent::DOM_DELTA_LINE: 183 case WheelEvent::DOM_DELTA_LINE:
249 return ScrollByLine; 184 return ScrollByLine;
250 case WheelEvent::DOM_DELTA_PIXEL: 185 case WheelEvent::DOM_DELTA_PIXEL:
251 return ScrollByPixel; 186 return ScrollByPixel;
252 default: 187 default:
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 , m_mouseDownTimestamp(0) 223 , m_mouseDownTimestamp(0)
289 , m_widgetIsLatched(false) 224 , m_widgetIsLatched(false)
290 , m_originatingTouchPointTargetKey(0) 225 , m_originatingTouchPointTargetKey(0)
291 , m_touchPressed(false) 226 , m_touchPressed(false)
292 , m_scrollGestureHandlingNode(nullptr) 227 , m_scrollGestureHandlingNode(nullptr)
293 , m_lastHitTestResultOverWidget(false) 228 , m_lastHitTestResultOverWidget(false)
294 , m_maxMouseMovedDuration(0) 229 , m_maxMouseMovedDuration(0)
295 , m_baseEventType(PlatformEvent::NoType) 230 , m_baseEventType(PlatformEvent::NoType)
296 , m_didStartDrag(false) 231 , m_didStartDrag(false)
297 , m_longTapShouldInvokeContextMenu(false) 232 , m_longTapShouldInvokeContextMenu(false)
298 , m_syntheticPageScaleFactor(0)
299 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) 233 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired)
300 , m_lastShowPressTimestamp(0) 234 , m_lastShowPressTimestamp(0)
301 { 235 {
302 } 236 }
303 237
304 EventHandler::~EventHandler() 238 EventHandler::~EventHandler()
305 { 239 {
306 ASSERT(!m_fakeMouseMoveEventTimer.isActive()); 240 ASSERT(!m_fakeMouseMoveEventTimer.isActive());
307 } 241 }
308 242
(...skipping 948 matching lines...) Expand 10 before | Expand all | Expand 10 after
1257 // Historically the code would just crash; this is clearly no worse than tha t. 1191 // Historically the code would just crash; this is clearly no worse than tha t.
1258 return view ? view->windowToContents(windowPoint) : windowPoint; 1192 return view ? view->windowToContents(windowPoint) : windowPoint;
1259 } 1193 }
1260 1194
1261 bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent) 1195 bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
1262 { 1196 {
1263 TRACE_EVENT0("webkit", "EventHandler::handleMousePressEvent"); 1197 TRACE_EVENT0("webkit", "EventHandler::handleMousePressEvent");
1264 1198
1265 RefPtr<FrameView> protector(m_frame->view()); 1199 RefPtr<FrameView> protector(m_frame->view());
1266 1200
1267 bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(mouseEvent);
1268 if (defaultPrevented)
1269 return true;
1270
1271 UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture); 1201 UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
1272 m_frame->tree().top()->eventHandler().m_lastMouseDownUserGestureToken = gest ureIndicator.currentToken(); 1202 m_frame->tree().top()->eventHandler().m_lastMouseDownUserGestureToken = gest ureIndicator.currentToken();
1273 1203
1274 cancelFakeMouseMoveEvent(); 1204 cancelFakeMouseMoveEvent();
1275 if (m_eventHandlerWillResetCapturingMouseEventsNode) 1205 if (m_eventHandlerWillResetCapturingMouseEventsNode)
1276 m_capturingMouseEventsNode = nullptr; 1206 m_capturingMouseEventsNode = nullptr;
1277 m_mousePressed = true; 1207 m_mousePressed = true;
1278 m_capturesDragging = true; 1208 m_capturesDragging = true;
1279 setLastKnownMousePosition(mouseEvent); 1209 setLastKnownMousePosition(mouseEvent);
1280 m_mouseDownTimestamp = mouseEvent.timestamp(); 1210 m_mouseDownTimestamp = mouseEvent.timestamp();
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1448 } 1378 }
1449 1379
1450 void EventHandler::handleMouseLeaveEvent(const PlatformMouseEvent& event) 1380 void EventHandler::handleMouseLeaveEvent(const PlatformMouseEvent& event)
1451 { 1381 {
1452 TRACE_EVENT0("webkit", "EventHandler::handleMouseLeaveEvent"); 1382 TRACE_EVENT0("webkit", "EventHandler::handleMouseLeaveEvent");
1453 1383
1454 RefPtr<FrameView> protector(m_frame->view()); 1384 RefPtr<FrameView> protector(m_frame->view());
1455 handleMouseMoveOrLeaveEvent(event); 1385 handleMouseMoveOrLeaveEvent(event);
1456 } 1386 }
1457 1387
1458 static Cursor& syntheticTouchCursor()
1459 {
1460 DEFINE_STATIC_LOCAL(Cursor, c, (Image::loadPlatformResource("syntheticTouchC ursor").get(), IntPoint(10, 10)));
1461 return c;
1462 }
1463
1464 bool EventHandler::handleMouseMoveOrLeaveEvent(const PlatformMouseEvent& mouseEv ent, HitTestResult* hoveredNode, bool onlyUpdateScrollbars) 1388 bool EventHandler::handleMouseMoveOrLeaveEvent(const PlatformMouseEvent& mouseEv ent, HitTestResult* hoveredNode, bool onlyUpdateScrollbars)
1465 { 1389 {
1466 ASSERT(m_frame); 1390 ASSERT(m_frame);
1467 ASSERT(m_frame->view()); 1391 ASSERT(m_frame->view());
1468 1392
1469 bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(mouseEvent);
1470 if (defaultPrevented) {
1471 m_frame->view()->setCursor(syntheticTouchCursor());
1472 return true;
1473 }
1474
1475 setLastKnownMousePosition(mouseEvent); 1393 setLastKnownMousePosition(mouseEvent);
1476 1394
1477 if (m_hoverTimer.isActive()) 1395 if (m_hoverTimer.isActive())
1478 m_hoverTimer.stop(); 1396 m_hoverTimer.stop();
1479 1397
1480 m_cursorUpdateTimer.stop(); 1398 m_cursorUpdateTimer.stop();
1481 1399
1482 cancelFakeMouseMoveEvent(); 1400 cancelFakeMouseMoveEvent();
1483 1401
1484 if (m_svgPan) { 1402 if (m_svgPan) {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1588 } 1506 }
1589 1507
1590 bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent) 1508 bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
1591 { 1509 {
1592 TRACE_EVENT0("webkit", "EventHandler::handleMouseReleaseEvent"); 1510 TRACE_EVENT0("webkit", "EventHandler::handleMouseReleaseEvent");
1593 1511
1594 RefPtr<FrameView> protector(m_frame->view()); 1512 RefPtr<FrameView> protector(m_frame->view());
1595 1513
1596 m_frame->selection().setCaretBlinkingSuspended(false); 1514 m_frame->selection().setCaretBlinkingSuspended(false);
1597 1515
1598 bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(mouseEvent);
1599 if (defaultPrevented)
1600 return true;
1601
1602 OwnPtr<UserGestureIndicator> gestureIndicator; 1516 OwnPtr<UserGestureIndicator> gestureIndicator;
1603 1517
1604 if (m_frame->tree().top()->eventHandler().m_lastMouseDownUserGestureToken) 1518 if (m_frame->tree().top()->eventHandler().m_lastMouseDownUserGestureToken)
1605 gestureIndicator = adoptPtr(new UserGestureIndicator(m_frame->tree().top ()->eventHandler().m_lastMouseDownUserGestureToken.release())); 1519 gestureIndicator = adoptPtr(new UserGestureIndicator(m_frame->tree().top ()->eventHandler().m_lastMouseDownUserGestureToken.release()));
1606 else 1520 else
1607 gestureIndicator = adoptPtr(new UserGestureIndicator(DefinitelyProcessin gUserGesture)); 1521 gestureIndicator = adoptPtr(new UserGestureIndicator(DefinitelyProcessin gUserGesture));
1608 1522
1609 #if OS(WIN) 1523 #if OS(WIN)
1610 if (Page* page = m_frame->page()) 1524 if (Page* page = m_frame->page())
1611 page->autoscrollController().handleMouseReleaseForPanScrolling(m_frame, mouseEvent); 1525 page->autoscrollController().handleMouseReleaseForPanScrolling(m_frame, mouseEvent);
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after
2104 2018
2105 if (!doc->renderer()) 2019 if (!doc->renderer())
2106 return false; 2020 return false;
2107 2021
2108 RefPtr<FrameView> protector(m_frame->view()); 2022 RefPtr<FrameView> protector(m_frame->view());
2109 2023
2110 FrameView* view = m_frame->view(); 2024 FrameView* view = m_frame->view();
2111 if (!view) 2025 if (!view)
2112 return false; 2026 return false;
2113 2027
2114 if (handleWheelEventAsEmulatedGesture(e))
2115 return true;
2116
2117 LayoutPoint vPoint = view->windowToContents(e.position()); 2028 LayoutPoint vPoint = view->windowToContents(e.position());
2118 2029
2119 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::ConfusingA ndOftenMisusedDisallowShadowContent); 2030 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::ConfusingA ndOftenMisusedDisallowShadowContent);
2120 HitTestResult result(vPoint); 2031 HitTestResult result(vPoint);
2121 doc->renderView()->hitTest(request, result); 2032 doc->renderView()->hitTest(request, result);
2122 2033
2123 Node* node = result.innerNode(); 2034 Node* node = result.innerNode();
2124 // Wheel events should not dispatch to text nodes. 2035 // Wheel events should not dispatch to text nodes.
2125 if (node && node->isTextNode()) 2036 if (node && node->isTextNode())
2126 node = NodeRenderingTraversal::parent(node); 2037 node = NodeRenderingTraversal::parent(node);
(...skipping 1618 matching lines...) Expand 10 before | Expand all | Expand 10 after
3745 stateName, touchEventTarget->toNode()->document().domWindow( ), 3656 stateName, touchEventTarget->toNode()->document().domWindow( ),
3746 0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey( ), event.metaKey()); 3657 0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey( ), event.metaKey());
3747 touchEventTarget->toNode()->dispatchTouchEvent(touchEvent.get()); 3658 touchEventTarget->toNode()->dispatchTouchEvent(touchEvent.get());
3748 swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() || touchEvent->defaultHandled(); 3659 swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() || touchEvent->defaultHandled();
3749 } 3660 }
3750 } 3661 }
3751 3662
3752 return swallowedEvent; 3663 return swallowedEvent;
3753 } 3664 }
3754 3665
3755 bool EventHandler::dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent & event)
3756 {
3757 if (!m_frame || !m_frame->settings() || !m_frame->settings()->touchEventEmul ationEnabled())
3758 return false;
3759
3760 PlatformEvent::Type eventType = event.type();
3761 if (eventType != PlatformEvent::MouseMoved && eventType != PlatformEvent::Mo usePressed && eventType != PlatformEvent::MouseReleased)
3762 return false;
3763
3764 HitTestRequest request(HitTestRequest::Active | HitTestRequest::ConfusingAnd OftenMisusedDisallowShadowContent);
3765 MouseEventWithHitTestResults mev = prepareMouseEvent(request, event);
3766 if (mev.scrollbar() || subframeForHitTestResult(mev))
3767 return false;
3768
3769 // The order is important. This check should follow the subframe test: http: //webkit.org/b/111292.
3770 if (eventType == PlatformEvent::MouseMoved && event.button() == NoButton)
3771 return true;
3772
3773 SyntheticSingleTouchEvent touchEvent(event);
3774 if (handleTouchEvent(touchEvent))
3775 return true;
3776
3777 return handleMouseEventAsEmulatedGesture(event);
3778 }
3779
3780 bool EventHandler::handleMouseEventAsEmulatedGesture(const PlatformMouseEvent& e vent)
3781 {
3782 PlatformEvent::Type eventType = event.type();
3783 if (event.button() != LeftButton || !m_frame->isMainFrame())
3784 return false;
3785
3786 // Simulate pinch / scroll gesture.
3787 const IntPoint& position = event.position();
3788 bool swallowEvent = false;
3789
3790 FrameView* view = m_frame->view();
3791 if (event.shiftKey()) {
3792 // Shift pressed - consider it gesture.
3793 swallowEvent = true;
3794 Page* page = m_frame->page();
3795 float pageScaleFactor = page->pageScaleFactor();
3796 switch (eventType) {
3797 case PlatformEvent::MousePressed:
3798 m_lastSyntheticPinchAnchorCss = adoptPtr(new IntPoint(view->scrollPo sition() + position));
3799 m_lastSyntheticPinchAnchorDip = adoptPtr(new IntPoint(position));
3800 m_lastSyntheticPinchAnchorDip->scale(pageScaleFactor, pageScaleFacto r);
3801 m_syntheticPageScaleFactor = pageScaleFactor;
3802 break;
3803 case PlatformEvent::MouseMoved:
3804 {
3805 if (!m_lastSyntheticPinchAnchorCss)
3806 break;
3807
3808 float dy = m_lastSyntheticPinchAnchorDip->y() - position.y() * p ageScaleFactor;
3809 float magnifyDelta = exp(dy * 0.002f);
3810 float newPageScaleFactor = m_syntheticPageScaleFactor * magnifyD elta;
3811
3812 IntPoint anchorCss(*m_lastSyntheticPinchAnchorDip.get());
3813 anchorCss.scale(1.f / newPageScaleFactor, 1.f / newPageScaleFact or);
3814 page->inspectorController().requestPageScaleFactor(newPageScaleF actor, *m_lastSyntheticPinchAnchorCss.get() - toIntSize(anchorCss));
3815 break;
3816 }
3817 case PlatformEvent::MouseReleased:
3818 m_lastSyntheticPinchAnchorCss.clear();
3819 m_lastSyntheticPinchAnchorDip.clear();
3820 default:
3821 break;
3822 }
3823 } else {
3824 switch (eventType) {
3825 case PlatformEvent::MouseMoved:
3826 {
3827 // Always consume move events.
3828 swallowEvent = true;
3829 int dx = m_lastSyntheticPanLocation ? position.x() - m_lastSynth eticPanLocation->x() : 0;
3830 int dy = m_lastSyntheticPanLocation ? position.y() - m_lastSynth eticPanLocation->y() : 0;
3831 if (dx || dy)
3832 view->scrollBy(IntSize(-dx, -dy));
3833 // Mouse dragged - consider it gesture.
3834 m_lastSyntheticPanLocation = adoptPtr(new IntPoint(position));
3835 break;
3836 }
3837 case PlatformEvent::MouseReleased:
3838 // There was a drag -> gesture.
3839 swallowEvent = !!m_lastSyntheticPanLocation;
3840 m_lastSyntheticPanLocation.clear();
3841 default:
3842 break;
3843 }
3844 }
3845
3846 return swallowEvent;
3847 }
3848
3849 bool EventHandler::handleWheelEventAsEmulatedGesture(const PlatformWheelEvent& e vent)
3850 {
3851 if (!m_frame || !m_frame->settings() || !m_frame->settings()->touchEventEmul ationEnabled())
3852 return false;
3853
3854 // Only convert vertical wheel w/ shift into pinch for touch-enabled device convenience.
3855 if (!event.shiftKey() || !event.deltaY())
3856 return false;
3857
3858 Page* page = m_frame->page();
3859 FrameView* view = m_frame->view();
3860 float pageScaleFactor = page->pageScaleFactor();
3861 IntPoint anchorBeforeCss(view->scrollPosition() + event.position());
3862 IntPoint anchorBeforeDip(event.position());
3863 anchorBeforeDip.scale(pageScaleFactor, pageScaleFactor);
3864
3865 float magnifyDelta = exp(event.deltaY() * 0.002f);
3866 float newPageScaleFactor = pageScaleFactor * magnifyDelta;
3867
3868 IntPoint anchorAfterCss(anchorBeforeDip);
3869 anchorAfterCss.scale(1.f / newPageScaleFactor, 1.f / newPageScaleFactor);
3870 page->inspectorController().requestPageScaleFactor(newPageScaleFactor, ancho rBeforeCss - toIntSize(anchorAfterCss));
3871 return true;
3872 }
3873
3874 TouchAction EventHandler::intersectTouchAction(TouchAction action1, TouchAction action2) 3666 TouchAction EventHandler::intersectTouchAction(TouchAction action1, TouchAction action2)
3875 { 3667 {
3876 if (action1 == TouchActionNone || action2 == TouchActionNone) 3668 if (action1 == TouchActionNone || action2 == TouchActionNone)
3877 return TouchActionNone; 3669 return TouchActionNone;
3878 if (action1 == TouchActionAuto) 3670 if (action1 == TouchActionAuto)
3879 return action2; 3671 return action2;
3880 if (action2 == TouchActionAuto) 3672 if (action2 == TouchActionAuto)
3881 return action1; 3673 return action1;
3882 if (!(action1 & action2)) 3674 if (!(action1 & action2))
3883 return TouchActionNone; 3675 return TouchActionNone;
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
3995 unsigned EventHandler::accessKeyModifiers() 3787 unsigned EventHandler::accessKeyModifiers()
3996 { 3788 {
3997 #if OS(MACOSX) 3789 #if OS(MACOSX)
3998 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; 3790 return PlatformEvent::CtrlKey | PlatformEvent::AltKey;
3999 #else 3791 #else
4000 return PlatformEvent::AltKey; 3792 return PlatformEvent::AltKey;
4001 #endif 3793 #endif
4002 } 3794 }
4003 3795
4004 } // namespace WebCore 3796 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/page/EventHandler.h ('k') | Source/core/page/Page.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698