Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 46 #include "core/events/DOMWindowEventQueue.h" | 46 #include "core/events/DOMWindowEventQueue.h" |
| 47 #include "core/events/EventPath.h" | 47 #include "core/events/EventPath.h" |
| 48 #include "core/events/KeyboardEvent.h" | 48 #include "core/events/KeyboardEvent.h" |
| 49 #include "core/events/MouseEvent.h" | 49 #include "core/events/MouseEvent.h" |
| 50 #include "core/events/TextEvent.h" | 50 #include "core/events/TextEvent.h" |
| 51 #include "core/events/TouchEvent.h" | 51 #include "core/events/TouchEvent.h" |
| 52 #include "core/events/WheelEvent.h" | 52 #include "core/events/WheelEvent.h" |
| 53 #include "core/fetch/ImageResource.h" | 53 #include "core/fetch/ImageResource.h" |
| 54 #include "core/frame/FrameView.h" | 54 #include "core/frame/FrameView.h" |
| 55 #include "core/frame/LocalFrame.h" | 55 #include "core/frame/LocalFrame.h" |
| 56 #include "core/frame/Settings.h" | |
| 56 #include "core/html/HTMLDialogElement.h" | 57 #include "core/html/HTMLDialogElement.h" |
| 57 #include "core/html/HTMLFrameElementBase.h" | 58 #include "core/html/HTMLFrameElementBase.h" |
| 58 #include "core/html/HTMLFrameSetElement.h" | 59 #include "core/html/HTMLFrameSetElement.h" |
| 59 #include "core/html/HTMLInputElement.h" | 60 #include "core/html/HTMLInputElement.h" |
| 61 #include "core/inspector/InspectorController.h" | |
| 60 #include "core/loader/FrameLoader.h" | 62 #include "core/loader/FrameLoader.h" |
| 61 #include "core/loader/FrameLoaderClient.h" | 63 #include "core/loader/FrameLoaderClient.h" |
| 62 #include "core/page/AutoscrollController.h" | 64 #include "core/page/AutoscrollController.h" |
| 63 #include "core/page/BackForwardClient.h" | 65 #include "core/page/BackForwardClient.h" |
| 64 #include "core/page/Chrome.h" | 66 #include "core/page/Chrome.h" |
| 65 #include "core/page/ChromeClient.h" | 67 #include "core/page/ChromeClient.h" |
| 66 #include "core/page/DragController.h" | 68 #include "core/page/DragController.h" |
| 67 #include "core/page/DragState.h" | 69 #include "core/page/DragState.h" |
| 68 #include "core/page/EditorClient.h" | 70 #include "core/page/EditorClient.h" |
| 71 #include "core/page/EventWithHitTestResults.h" | |
| 69 #include "core/page/FocusController.h" | 72 #include "core/page/FocusController.h" |
| 70 #include "core/page/FrameTree.h" | 73 #include "core/page/FrameTree.h" |
| 71 #include "core/inspector/InspectorController.h" | |
| 72 #include "core/page/MouseEventWithHitTestResults.h" | |
| 73 #include "core/page/Page.h" | 74 #include "core/page/Page.h" |
| 74 #include "core/frame/Settings.h" | |
| 75 #include "core/page/SpatialNavigation.h" | 75 #include "core/page/SpatialNavigation.h" |
| 76 #include "core/page/TouchAdjustment.h" | 76 #include "core/page/TouchAdjustment.h" |
| 77 #include "core/rendering/HitTestRequest.h" | 77 #include "core/rendering/HitTestRequest.h" |
| 78 #include "core/rendering/HitTestResult.h" | 78 #include "core/rendering/HitTestResult.h" |
| 79 #include "core/rendering/RenderFlowThread.h" | 79 #include "core/rendering/RenderFlowThread.h" |
| 80 #include "core/rendering/RenderLayer.h" | 80 #include "core/rendering/RenderLayer.h" |
| 81 #include "core/rendering/RenderTextControlSingleLine.h" | 81 #include "core/rendering/RenderTextControlSingleLine.h" |
| 82 #include "core/rendering/RenderView.h" | 82 #include "core/rendering/RenderView.h" |
| 83 #include "core/rendering/RenderWidget.h" | 83 #include "core/rendering/RenderWidget.h" |
| 84 #include "core/rendering/style/RenderStyle.h" | 84 #include "core/rendering/style/RenderStyle.h" |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 214 , m_svgPan(false) | 214 , m_svgPan(false) |
| 215 , m_resizeScrollableArea(0) | 215 , m_resizeScrollableArea(0) |
| 216 , m_eventHandlerWillResetCapturingMouseEventsNode(0) | 216 , m_eventHandlerWillResetCapturingMouseEventsNode(0) |
| 217 , m_clickCount(0) | 217 , m_clickCount(0) |
| 218 , m_shouldOnlyFireDragOverEvent(false) | 218 , m_shouldOnlyFireDragOverEvent(false) |
| 219 , m_mousePositionIsUnknown(true) | 219 , m_mousePositionIsUnknown(true) |
| 220 , m_mouseDownTimestamp(0) | 220 , m_mouseDownTimestamp(0) |
| 221 , m_widgetIsLatched(false) | 221 , m_widgetIsLatched(false) |
| 222 , m_touchPressed(false) | 222 , m_touchPressed(false) |
| 223 , m_scrollGestureHandlingNode(nullptr) | 223 , m_scrollGestureHandlingNode(nullptr) |
| 224 , m_lastHitTestResultOverWidget(false) | 224 , m_lastGestureScrollOverWidget(false) |
| 225 , m_maxMouseMovedDuration(0) | 225 , m_maxMouseMovedDuration(0) |
| 226 , m_baseEventType(PlatformEvent::NoType) | |
| 227 , m_didStartDrag(false) | 226 , m_didStartDrag(false) |
| 228 , m_longTapShouldInvokeContextMenu(false) | 227 , m_longTapShouldInvokeContextMenu(false) |
| 229 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) | 228 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) |
| 230 , m_lastShowPressTimestamp(0) | 229 , m_lastShowPressTimestamp(0) |
| 231 { | 230 { |
| 232 } | 231 } |
| 233 | 232 |
| 234 EventHandler::~EventHandler() | 233 EventHandler::~EventHandler() |
| 235 { | 234 { |
| 236 ASSERT(!m_fakeMouseMoveEventTimer.isActive()); | 235 ASSERT(!m_fakeMouseMoveEventTimer.isActive()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 288 m_mousePressNode = nullptr; | 287 m_mousePressNode = nullptr; |
| 289 m_mousePressed = false; | 288 m_mousePressed = false; |
| 290 m_capturesDragging = false; | 289 m_capturesDragging = false; |
| 291 m_capturingMouseEventsNode = nullptr; | 290 m_capturingMouseEventsNode = nullptr; |
| 292 m_latchedWheelEventNode = nullptr; | 291 m_latchedWheelEventNode = nullptr; |
| 293 m_previousWheelScrolledNode = nullptr; | 292 m_previousWheelScrolledNode = nullptr; |
| 294 m_targetForTouchID.clear(); | 293 m_targetForTouchID.clear(); |
| 295 m_touchSequenceDocument.clear(); | 294 m_touchSequenceDocument.clear(); |
| 296 m_touchSequenceUserGestureToken.clear(); | 295 m_touchSequenceUserGestureToken.clear(); |
| 297 m_scrollGestureHandlingNode = nullptr; | 296 m_scrollGestureHandlingNode = nullptr; |
| 298 m_lastHitTestResultOverWidget = false; | 297 m_lastGestureScrollOverWidget = false; |
| 299 m_previousGestureScrolledNode = nullptr; | 298 m_previousGestureScrolledNode = nullptr; |
| 300 m_scrollbarHandlingScrollGesture = nullptr; | 299 m_scrollbarHandlingScrollGesture = nullptr; |
| 301 m_maxMouseMovedDuration = 0; | 300 m_maxMouseMovedDuration = 0; |
| 302 m_baseEventType = PlatformEvent::NoType; | |
| 303 m_didStartDrag = false; | 301 m_didStartDrag = false; |
| 304 m_touchPressed = false; | 302 m_touchPressed = false; |
| 305 m_mouseDownMayStartSelect = false; | 303 m_mouseDownMayStartSelect = false; |
| 306 m_mouseDownMayStartDrag = false; | 304 m_mouseDownMayStartDrag = false; |
| 307 m_lastShowPressTimestamp = 0; | 305 m_lastShowPressTimestamp = 0; |
| 308 m_lastDeferredTapElement = nullptr; | 306 m_lastDeferredTapElement = nullptr; |
| 309 } | 307 } |
| 310 | 308 |
| 311 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved) | 309 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved) |
| 312 { | 310 { |
| (...skipping 1741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2054 ScrollableArea* sa = *it; | 2052 ScrollableArea* sa = *it; |
| 2055 ScrollAnimator* animator = sa->scrollAnimator(); | 2053 ScrollAnimator* animator = sa->scrollAnimator(); |
| 2056 if (animator) | 2054 if (animator) |
| 2057 animator->cancelAnimations(); | 2055 animator->cancelAnimations(); |
| 2058 } | 2056 } |
| 2059 return false; | 2057 return false; |
| 2060 } | 2058 } |
| 2061 | 2059 |
| 2062 bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent) | 2060 bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent) |
| 2063 { | 2061 { |
| 2064 IntPoint adjustedPoint = gestureEvent.position(); | 2062 TRACE_EVENT0("input", "EventHandler::handleGestureEvent"); |
| 2065 RefPtr<LocalFrame> subframe = nullptr; | 2063 |
| 2064 // Propagation to inner frames is handled below this function. | |
| 2065 ASSERT(m_frame == m_frame->localFrameRoot()); | |
| 2066 | |
| 2067 // Scrolling-related gesture events invoke EventHandler recursively for each frame down | |
| 2068 // the chain, doing a single-frame hit-test per frame. This matches handleWh eelEvent. | |
| 2069 // Perhaps we could simplify things by rewriting scroll handling to work inn er frame | |
| 2070 // out, and then unify with other gesture events. | |
| 2071 if (gestureEvent.isScrollEvent()) { | |
| 2072 return handleGestureScrollEvent(gestureEvent); | |
| 2073 } | |
|
esprehn
2014/06/27 08:33:58
no braces
Rick Byers
2014/06/27 15:38:23
Done.
| |
| 2074 | |
| 2075 // Non-scrolling related gesture events instead do a single cross-frame hit- test and | |
| 2076 // jump directly to the inner most frame. This matches handleMousePressEvent etc. | |
| 2077 | |
| 2078 // Hit test across all frames and do touch adjustment as necessary for the e vent type. | |
| 2079 GestureEventWithHitTestResults targetedEvent = targetGestureEvent(gestureEve nt); | |
| 2080 ASSERT(!(targetedEvent.hitTestResult().isOverWidget())); | |
|
esprehn
2014/06/27 08:33:58
remove extra braces
Rick Byers
2014/06/27 15:38:24
Done.
| |
| 2081 | |
| 2082 // Route to the correct frame. | |
| 2083 if (LocalFrame* innerFrame = targetedEvent.hitTestResult().innerNodeFrame()) | |
| 2084 return innerFrame->eventHandler().handleGestureEventInFrame(targetedEven t); | |
| 2085 | |
| 2086 // No hit test result, handle in root instance. Perhaps we should just retur n false instead? | |
| 2087 return handleGestureEventInFrame(targetedEvent); | |
| 2088 } | |
| 2089 | |
| 2090 bool EventHandler::handleGestureEventInFrame(const GestureEventWithHitTestResult s& targetedEvent) | |
| 2091 { | |
| 2092 ASSERT(!targetedEvent.event().isScrollEvent()); | |
| 2093 | |
| 2094 RefPtrWillBeRawPtr<Node> eventTarget = targetedEvent.hitTestResult().targetN ode(); | |
| 2095 RefPtr<Scrollbar> scrollbar = targetedEvent.hitTestResult().scrollbar(); | |
| 2096 const PlatformGestureEvent& gestureEvent = targetedEvent.event(); | |
| 2097 | |
| 2098 if (!scrollbar) { | |
| 2099 FrameView* view = m_frame->view(); | |
| 2100 scrollbar = view ? view->scrollbarAtPoint(gestureEvent.position()) : 0; | |
| 2101 } | |
| 2102 | |
| 2103 if (scrollbar) { | |
| 2104 bool eventSwallowed = scrollbar->gestureEvent(gestureEvent); | |
| 2105 if (gestureEvent.type() == PlatformEvent::GestureTapDown && eventSwallow ed) { | |
|
esprehn
2014/06/27 08:33:58
no braces
Rick Byers
2014/06/27 15:38:23
Done.
| |
| 2106 m_scrollbarHandlingScrollGesture = scrollbar; | |
| 2107 } | |
| 2108 if (eventSwallowed) | |
| 2109 return true; | |
| 2110 } | |
| 2111 | |
| 2112 if (eventTarget && eventTarget->dispatchGestureEvent(gestureEvent)) | |
| 2113 return true; | |
| 2114 | |
| 2066 switch (gestureEvent.type()) { | 2115 switch (gestureEvent.type()) { |
| 2067 case PlatformEvent::GestureScrollBegin: | |
| 2068 case PlatformEvent::GestureScrollUpdate: | |
| 2069 case PlatformEvent::GestureScrollUpdateWithoutPropagation: | |
| 2070 case PlatformEvent::GestureScrollEnd: | |
| 2071 case PlatformEvent::GestureFlingStart: | |
| 2072 // Handle directly in main frame | |
| 2073 break; | |
| 2074 | |
| 2075 case PlatformEvent::GestureTap: | 2116 case PlatformEvent::GestureTap: |
| 2076 case PlatformEvent::GestureTapUnconfirmed: | 2117 return handleGestureTap(targetedEvent); |
| 2118 case PlatformEvent::GestureShowPress: | |
| 2119 return handleGestureShowPress(); | |
| 2120 case PlatformEvent::GestureLongPress: | |
| 2121 return handleGestureLongPress(targetedEvent); | |
| 2122 case PlatformEvent::GestureLongTap: | |
| 2123 return handleGestureLongTap(targetedEvent); | |
| 2124 case PlatformEvent::GestureTwoFingerTap: | |
| 2125 return sendContextMenuEventForGesture(targetedEvent); | |
| 2077 case PlatformEvent::GestureTapDown: | 2126 case PlatformEvent::GestureTapDown: |
| 2078 case PlatformEvent::GestureShowPress: | |
| 2079 case PlatformEvent::GestureTapDownCancel: | |
| 2080 case PlatformEvent::GestureTwoFingerTap: | |
| 2081 case PlatformEvent::GestureLongPress: | |
| 2082 case PlatformEvent::GestureLongTap: | |
| 2083 case PlatformEvent::GesturePinchBegin: | 2127 case PlatformEvent::GesturePinchBegin: |
| 2084 case PlatformEvent::GesturePinchEnd: | 2128 case PlatformEvent::GesturePinchEnd: |
| 2085 case PlatformEvent::GesturePinchUpdate: | 2129 case PlatformEvent::GesturePinchUpdate: |
| 2086 adjustGesturePosition(gestureEvent, adjustedPoint); | 2130 case PlatformEvent::GestureTapDownCancel: |
| 2087 subframe = getSubFrameForGestureEvent(adjustedPoint, gestureEvent); | 2131 case PlatformEvent::GestureTapUnconfirmed: |
| 2088 if (subframe) | |
| 2089 return subframe->eventHandler().handleGestureEvent(gestureEvent); | |
| 2090 break; | 2132 break; |
| 2091 | |
| 2092 default: | 2133 default: |
| 2093 ASSERT_NOT_REACHED(); | 2134 ASSERT_NOT_REACHED(); |
| 2094 } | 2135 } |
| 2095 | 2136 |
| 2137 return false; | |
| 2138 } | |
| 2139 | |
| 2140 bool EventHandler::handleGestureScrollEvent(const PlatformGestureEvent& gestureE vent) | |
| 2141 { | |
| 2096 RefPtrWillBeRawPtr<Node> eventTarget = nullptr; | 2142 RefPtrWillBeRawPtr<Node> eventTarget = nullptr; |
| 2097 RefPtr<Scrollbar> scrollbar; | 2143 RefPtr<Scrollbar> scrollbar; |
| 2098 if (gestureEvent.type() == PlatformEvent::GestureScrollEnd | 2144 if (gestureEvent.type() != PlatformEvent::GestureScrollBegin) { |
| 2099 || gestureEvent.type() == PlatformEvent::GestureScrollUpdate | |
| 2100 || gestureEvent.type() == PlatformEvent::GestureScrollUpdateWithoutPropa gation | |
| 2101 || gestureEvent.type() == PlatformEvent::GestureFlingStart) { | |
| 2102 scrollbar = m_scrollbarHandlingScrollGesture.get(); | 2145 scrollbar = m_scrollbarHandlingScrollGesture.get(); |
| 2103 eventTarget = m_scrollGestureHandlingNode.get(); | 2146 eventTarget = m_scrollGestureHandlingNode.get(); |
| 2104 } | 2147 } |
| 2105 | 2148 |
| 2106 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent; | 2149 if (!eventTarget) { |
| 2107 double activeInterval = 0; | 2150 Document* document = m_frame->document(); |
| 2108 bool shouldKeepActiveForMinInterval = false; | 2151 if (!document->renderView()) |
| 2109 if (gestureEvent.type() == PlatformEvent::GestureShowPress | 2152 return false; |
| 2110 || gestureEvent.type() == PlatformEvent::GestureTapUnconfirmed) { | |
| 2111 hitType |= HitTestRequest::Active; | |
| 2112 } else if (gestureEvent.type() == PlatformEvent::GestureTapDownCancel) { | |
| 2113 hitType |= HitTestRequest::Release; | |
| 2114 // A TapDownCancel received when no element is active shouldn't really b e changing hover state. | |
| 2115 if (!m_frame->document()->activeHoverElement()) | |
| 2116 hitType |= HitTestRequest::ReadOnly; | |
| 2117 } else if (gestureEvent.type() == PlatformEvent::GestureTap) { | |
| 2118 hitType |= HitTestRequest::Release; | |
| 2119 // If the Tap is received very shortly after ShowPress, we want to | |
| 2120 // delay clearing of the active state so that it's visible to the user | |
| 2121 // for at least a couple of frames. | |
| 2122 activeInterval = WTF::currentTime() - m_lastShowPressTimestamp; | |
| 2123 shouldKeepActiveForMinInterval = m_lastShowPressTimestamp && activeInter val < minimumActiveInterval; | |
| 2124 if (shouldKeepActiveForMinInterval) | |
| 2125 hitType |= HitTestRequest::ReadOnly; | |
| 2126 } | |
| 2127 else | |
| 2128 hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly; | |
| 2129 | 2153 |
| 2130 if ((!scrollbar && !eventTarget) || !(hitType & HitTestRequest::ReadOnly)) { | 2154 FrameView* view = m_frame->view(); |
| 2131 IntPoint hitTestPoint = m_frame->view()->windowToContents(adjustedPoint) ; | 2155 if (!view) |
|
esprehn
2014/06/27 08:33:58
You don't need this null check, if you have a Rend
Rick Byers
2014/06/27 15:38:23
Done.
| |
| 2132 HitTestResult result = hitTestResultAtPoint(hitTestPoint, hitType | HitT estRequest::AllowFrameScrollbars); | 2156 return false; |
| 2133 | 2157 |
| 2134 if (shouldKeepActiveForMinInterval) { | 2158 LayoutPoint viewPoint = view->windowToContents(gestureEvent.position()); |
| 2135 m_lastDeferredTapElement = result.innerElement(); | 2159 HitTestRequest request(HitTestRequest::ReadOnly); |
| 2136 m_activeIntervalTimer.startOneShot(minimumActiveInterval - activeInt erval, FROM_HERE); | 2160 HitTestResult result(viewPoint); |
| 2137 } | 2161 document->renderView()->hitTest(request, result); |
|
esprehn
2014/06/27 08:33:58
What updated the layout before this call?
Rick Byers
2014/06/27 15:38:24
Nothing, as far as I can see, but that was the cas
| |
| 2138 | 2162 |
| 2139 eventTarget = result.targetNode(); | 2163 eventTarget = result.innerNode(); |
| 2140 if (!scrollbar) { | 2164 |
| 2141 FrameView* view = m_frame->view(); | 2165 m_lastGestureScrollOverWidget = result.isOverWidget(); |
| 2142 scrollbar = view ? view->scrollbarAtPoint(gestureEvent.position()) : 0; | 2166 m_scrollGestureHandlingNode = eventTarget; |
| 2143 } | 2167 m_previousGestureScrolledNode = nullptr; |
| 2168 | |
| 2169 if (!scrollbar) | |
| 2170 scrollbar = view->scrollbarAtPoint(gestureEvent.position()); | |
| 2144 if (!scrollbar) | 2171 if (!scrollbar) |
| 2145 scrollbar = result.scrollbar(); | 2172 scrollbar = result.scrollbar(); |
| 2146 } | 2173 } |
| 2147 | 2174 |
| 2148 if (scrollbar) { | 2175 if (scrollbar) { |
| 2149 bool eventSwallowed = scrollbar->gestureEvent(gestureEvent); | 2176 bool eventSwallowed = scrollbar->gestureEvent(gestureEvent); |
| 2150 if (gestureEvent.type() == PlatformEvent::GestureTapDown && eventSwallow ed) { | 2177 if (gestureEvent.type() == PlatformEvent::GestureScrollEnd |
| 2151 m_scrollbarHandlingScrollGesture = scrollbar; | |
| 2152 } else if (gestureEvent.type() == PlatformEvent::GestureScrollEnd | |
| 2153 || gestureEvent.type() == PlatformEvent::GestureFlingStart | 2178 || gestureEvent.type() == PlatformEvent::GestureFlingStart |
| 2154 || !eventSwallowed) { | 2179 || !eventSwallowed) { |
| 2155 m_scrollbarHandlingScrollGesture = nullptr; | 2180 m_scrollbarHandlingScrollGesture = nullptr; |
| 2156 } | 2181 } |
| 2157 | |
| 2158 if (eventSwallowed) | 2182 if (eventSwallowed) |
| 2159 return true; | 2183 return true; |
| 2160 } | 2184 } |
| 2161 | 2185 |
| 2162 if (eventTarget) { | 2186 if (eventTarget) { |
| 2163 bool eventSwallowed = false; | 2187 bool eventSwallowed = handleScrollGestureOnResizer(eventTarget.get(), ge stureEvent); |
| 2164 if (handleScrollGestureOnResizer(eventTarget.get(), gestureEvent)) | 2188 if (!eventSwallowed) |
| 2165 eventSwallowed = true; | |
| 2166 else | |
| 2167 eventSwallowed = eventTarget->dispatchGestureEvent(gestureEvent); | 2189 eventSwallowed = eventTarget->dispatchGestureEvent(gestureEvent); |
| 2168 if (gestureEvent.type() == PlatformEvent::GestureScrollBegin || gestureE vent.type() == PlatformEvent::GestureScrollEnd) { | |
| 2169 if (eventSwallowed) | |
| 2170 m_scrollGestureHandlingNode = eventTarget; | |
| 2171 } | |
| 2172 | |
| 2173 if (eventSwallowed) | 2190 if (eventSwallowed) |
| 2174 return true; | 2191 return true; |
| 2175 } | 2192 } |
| 2176 | 2193 |
| 2177 // FIXME: A more general scroll system (https://bugs.webkit.org/show_bug.cgi ?id=80596) will | |
| 2178 // eliminate the need for this. | |
| 2179 TemporaryChange<PlatformEvent::Type> baseEventType(m_baseEventType, gestureE vent.type()); | |
| 2180 | |
| 2181 switch (gestureEvent.type()) { | 2194 switch (gestureEvent.type()) { |
| 2182 case PlatformEvent::GestureScrollBegin: | 2195 case PlatformEvent::GestureScrollBegin: |
| 2183 return handleGestureScrollBegin(gestureEvent); | 2196 return handleGestureScrollBegin(gestureEvent); |
| 2184 case PlatformEvent::GestureScrollUpdate: | 2197 case PlatformEvent::GestureScrollUpdate: |
| 2185 case PlatformEvent::GestureScrollUpdateWithoutPropagation: | 2198 case PlatformEvent::GestureScrollUpdateWithoutPropagation: |
| 2186 return handleGestureScrollUpdate(gestureEvent); | 2199 return handleGestureScrollUpdate(gestureEvent); |
| 2187 case PlatformEvent::GestureScrollEnd: | 2200 case PlatformEvent::GestureScrollEnd: |
| 2188 return handleGestureScrollEnd(gestureEvent); | 2201 return handleGestureScrollEnd(gestureEvent); |
| 2189 case PlatformEvent::GestureTap: | |
| 2190 return handleGestureTap(gestureEvent, adjustedPoint); | |
| 2191 case PlatformEvent::GestureShowPress: | |
| 2192 return handleGestureShowPress(); | |
| 2193 case PlatformEvent::GestureLongPress: | |
| 2194 return handleGestureLongPress(gestureEvent, adjustedPoint); | |
| 2195 case PlatformEvent::GestureLongTap: | |
| 2196 return handleGestureLongTap(gestureEvent, adjustedPoint); | |
| 2197 case PlatformEvent::GestureTwoFingerTap: | |
| 2198 return handleGestureTwoFingerTap(gestureEvent, adjustedPoint); | |
| 2199 case PlatformEvent::GestureTapDown: | |
| 2200 case PlatformEvent::GesturePinchBegin: | |
| 2201 case PlatformEvent::GesturePinchEnd: | |
| 2202 case PlatformEvent::GesturePinchUpdate: | |
| 2203 case PlatformEvent::GestureTapDownCancel: | |
| 2204 case PlatformEvent::GestureTapUnconfirmed: | |
| 2205 case PlatformEvent::GestureFlingStart: | 2202 case PlatformEvent::GestureFlingStart: |
| 2206 break; | 2203 break; |
| 2207 default: | 2204 default: |
| 2208 ASSERT_NOT_REACHED(); | 2205 ASSERT_NOT_REACHED(); |
| 2209 } | 2206 } |
| 2210 | |
| 2211 return false; | 2207 return false; |
| 2212 } | 2208 } |
| 2213 | 2209 |
| 2214 bool EventHandler::handleGestureTap(const PlatformGestureEvent& gestureEvent, co nst IntPoint& adjustedPoint) | 2210 bool EventHandler::handleGestureTap(const GestureEventWithHitTestResults& target edEvent) |
| 2215 { | 2211 { |
| 2212 const PlatformGestureEvent& gestureEvent = targetedEvent.event(); | |
| 2213 | |
| 2216 // FIXME: Refactor this code to not hit test multiple times. We use the adju sted position to ensure that the correct node is targeted by the later redundant hit tests. | 2214 // FIXME: Refactor this code to not hit test multiple times. We use the adju sted position to ensure that the correct node is targeted by the later redundant hit tests. |
| 2217 | 2215 |
| 2218 unsigned modifierFlags = 0; | 2216 unsigned modifierFlags = 0; |
| 2219 if (gestureEvent.altKey()) | 2217 if (gestureEvent.altKey()) |
| 2220 modifierFlags |= PlatformEvent::AltKey; | 2218 modifierFlags |= PlatformEvent::AltKey; |
| 2221 if (gestureEvent.ctrlKey()) | 2219 if (gestureEvent.ctrlKey()) |
| 2222 modifierFlags |= PlatformEvent::CtrlKey; | 2220 modifierFlags |= PlatformEvent::CtrlKey; |
| 2223 if (gestureEvent.metaKey()) | 2221 if (gestureEvent.metaKey()) |
| 2224 modifierFlags |= PlatformEvent::MetaKey; | 2222 modifierFlags |= PlatformEvent::MetaKey; |
| 2225 if (gestureEvent.shiftKey()) | 2223 if (gestureEvent.shiftKey()) |
| 2226 modifierFlags |= PlatformEvent::ShiftKey; | 2224 modifierFlags |= PlatformEvent::ShiftKey; |
| 2227 PlatformEvent::Modifiers modifiers = static_cast<PlatformEvent::Modifiers>(m odifierFlags); | 2225 PlatformEvent::Modifiers modifiers = static_cast<PlatformEvent::Modifiers>(m odifierFlags); |
| 2228 | 2226 |
| 2227 IntPoint adjustedPoint = gestureEvent.position(); | |
| 2228 | |
| 2229 PlatformMouseEvent fakeMouseMove(adjustedPoint, gestureEvent.globalPosition( ), | 2229 PlatformMouseEvent fakeMouseMove(adjustedPoint, gestureEvent.globalPosition( ), |
| 2230 NoButton, PlatformEvent::MouseMoved, /* clickCount */ 0, | 2230 NoButton, PlatformEvent::MouseMoved, /* clickCount */ 0, |
| 2231 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp()); | 2231 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp()); |
| 2232 handleMouseMoveEvent(fakeMouseMove); | 2232 handleMouseMoveEvent(fakeMouseMove); |
| 2233 | 2233 |
| 2234 bool defaultPrevented = false; | 2234 bool defaultPrevented = false; |
| 2235 PlatformMouseEvent fakeMouseDown(adjustedPoint, gestureEvent.globalPosition( ), | 2235 PlatformMouseEvent fakeMouseDown(adjustedPoint, gestureEvent.globalPosition( ), |
| 2236 LeftButton, PlatformEvent::MousePressed, gestureEvent.tapCount(), | 2236 LeftButton, PlatformEvent::MousePressed, gestureEvent.tapCount(), |
| 2237 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp()); | 2237 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp()); |
| 2238 defaultPrevented |= handleMousePressEvent(fakeMouseDown); | 2238 defaultPrevented |= handleMousePressEvent(fakeMouseDown); |
| 2239 | 2239 |
| 2240 PlatformMouseEvent fakeMouseUp(adjustedPoint, gestureEvent.globalPosition(), | 2240 PlatformMouseEvent fakeMouseUp(adjustedPoint, gestureEvent.globalPosition(), |
| 2241 LeftButton, PlatformEvent::MouseReleased, gestureEvent.tapCount(), | 2241 LeftButton, PlatformEvent::MouseReleased, gestureEvent.tapCount(), |
| 2242 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp()); | 2242 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp()); |
| 2243 defaultPrevented |= handleMouseReleaseEvent(fakeMouseUp); | 2243 defaultPrevented |= handleMouseReleaseEvent(fakeMouseUp); |
| 2244 | 2244 |
| 2245 return defaultPrevented; | 2245 return defaultPrevented; |
| 2246 } | 2246 } |
| 2247 | 2247 |
| 2248 bool EventHandler::handleGestureLongPress(const PlatformGestureEvent& gestureEve nt, const IntPoint& adjustedPoint) | 2248 bool EventHandler::handleGestureLongPress(const GestureEventWithHitTestResults& targetedEvent) |
| 2249 { | 2249 { |
| 2250 const PlatformGestureEvent& gestureEvent = targetedEvent.event(); | |
| 2251 IntPoint adjustedPoint = gestureEvent.position(); | |
| 2252 | |
| 2253 // FIXME: Ideally we should try to remove the extra mouse-specific hit-tests here (re-using the | |
| 2254 // supplied HitTestResult), but that will require some overhaul of the touch drag-and-drop code | |
| 2255 // and LongPress is such a special scenario that it's unlikely to matter muc h in practice. | |
| 2256 | |
| 2250 m_longTapShouldInvokeContextMenu = false; | 2257 m_longTapShouldInvokeContextMenu = false; |
| 2251 if (m_frame->settings() && m_frame->settings()->touchDragDropEnabled() && m_ frame->view()) { | 2258 if (m_frame->settings() && m_frame->settings()->touchDragDropEnabled() && m_ frame->view()) { |
| 2252 PlatformMouseEvent mouseDownEvent(adjustedPoint, gestureEvent.globalPosi tion(), LeftButton, PlatformEvent::MousePressed, 1, | 2259 PlatformMouseEvent mouseDownEvent(adjustedPoint, gestureEvent.globalPosi tion(), LeftButton, PlatformEvent::MousePressed, 1, |
| 2253 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey (), gestureEvent.metaKey(), WTF::currentTime()); | 2260 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey (), gestureEvent.metaKey(), WTF::currentTime()); |
| 2254 m_mouseDown = mouseDownEvent; | 2261 m_mouseDown = mouseDownEvent; |
| 2255 | 2262 |
| 2256 PlatformMouseEvent mouseDragEvent(adjustedPoint, gestureEvent.globalPosi tion(), LeftButton, PlatformEvent::MouseMoved, 1, | 2263 PlatformMouseEvent mouseDragEvent(adjustedPoint, gestureEvent.globalPosi tion(), LeftButton, PlatformEvent::MouseMoved, 1, |
| 2257 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey (), gestureEvent.metaKey(), WTF::currentTime()); | 2264 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey (), gestureEvent.metaKey(), WTF::currentTime()); |
| 2258 HitTestRequest request(HitTestRequest::ReadOnly); | 2265 HitTestRequest request(HitTestRequest::ReadOnly); |
| 2259 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragE vent); | 2266 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragE vent); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 2278 HitTestResult result = hitTestResultAtPoint(hitTestPoint); | 2285 HitTestResult result = hitTestResultAtPoint(hitTestPoint); |
| 2279 Node* innerNode = result.targetNode(); | 2286 Node* innerNode = result.targetNode(); |
| 2280 if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable() || innerNode->isTextNode())) { | 2287 if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable() || innerNode->isTextNode())) { |
| 2281 selectClosestWordFromHitTestResult(result, DontAppendTrailingWhitesp ace); | 2288 selectClosestWordFromHitTestResult(result, DontAppendTrailingWhitesp ace); |
| 2282 if (m_frame->selection().isRange()) { | 2289 if (m_frame->selection().isRange()) { |
| 2283 focusDocumentView(); | 2290 focusDocumentView(); |
| 2284 return true; | 2291 return true; |
| 2285 } | 2292 } |
| 2286 } | 2293 } |
| 2287 } | 2294 } |
| 2288 return sendContextMenuEventForGesture(gestureEvent); | 2295 return sendContextMenuEventForGesture(targetedEvent); |
| 2289 } | 2296 } |
| 2290 | 2297 |
| 2291 bool EventHandler::handleGestureLongTap(const PlatformGestureEvent& gestureEvent , const IntPoint& adjustedPoint) | 2298 bool EventHandler::handleGestureLongTap(const GestureEventWithHitTestResults& ta rgetedEvent) |
| 2292 { | 2299 { |
| 2293 #if !OS(ANDROID) | 2300 #if !OS(ANDROID) |
| 2294 if (m_longTapShouldInvokeContextMenu) { | 2301 if (m_longTapShouldInvokeContextMenu) { |
| 2295 m_longTapShouldInvokeContextMenu = false; | 2302 m_longTapShouldInvokeContextMenu = false; |
| 2296 return sendContextMenuEventForGesture(gestureEvent); | 2303 return sendContextMenuEventForGesture(targetedEvent); |
| 2297 } | 2304 } |
| 2298 #endif | 2305 #endif |
| 2299 return false; | 2306 return false; |
| 2300 } | 2307 } |
| 2301 | 2308 |
| 2302 bool EventHandler::handleScrollGestureOnResizer(Node* eventTarget, const Platfor mGestureEvent& gestureEvent) { | 2309 bool EventHandler::handleScrollGestureOnResizer(Node* eventTarget, const Platfor mGestureEvent& gestureEvent) { |
| 2303 if (gestureEvent.type() == PlatformEvent::GestureScrollBegin) { | 2310 if (gestureEvent.type() == PlatformEvent::GestureScrollBegin) { |
| 2304 RenderLayer* layer = eventTarget->renderer() ? eventTarget->renderer()-> enclosingLayer() : 0; | 2311 RenderLayer* layer = eventTarget->renderer() ? eventTarget->renderer()-> enclosingLayer() : 0; |
| 2305 IntPoint p = m_frame->view()->windowToContents(gestureEvent.position()); | 2312 IntPoint p = m_frame->view()->windowToContents(gestureEvent.position()); |
| 2306 if (layer && layer->scrollableArea() && layer->scrollableArea()->isPoint InResizeControl(p, ResizerForTouch)) { | 2313 if (layer && layer->scrollableArea() && layer->scrollableArea()->isPoint InResizeControl(p, ResizerForTouch)) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 2319 if (m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode()) { | 2326 if (m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode()) { |
| 2320 m_resizeScrollableArea->setInResizeMode(false); | 2327 m_resizeScrollableArea->setInResizeMode(false); |
| 2321 m_resizeScrollableArea = 0; | 2328 m_resizeScrollableArea = 0; |
| 2322 return false; | 2329 return false; |
| 2323 } | 2330 } |
| 2324 } | 2331 } |
| 2325 | 2332 |
| 2326 return false; | 2333 return false; |
| 2327 } | 2334 } |
| 2328 | 2335 |
| 2329 bool EventHandler::handleGestureTwoFingerTap(const PlatformGestureEvent& gesture Event, const IntPoint& adjustedPoint) | 2336 bool EventHandler::passScrollGestureEventToWidget(const PlatformGestureEvent& ge stureEvent, RenderObject* renderer) |
| 2330 { | 2337 { |
| 2331 return sendContextMenuEventForGesture(gestureEvent); | 2338 ASSERT(gestureEvent.isScrollEvent()); |
| 2332 } | |
| 2333 | 2339 |
| 2334 bool EventHandler::passGestureEventToWidget(const PlatformGestureEvent& gestureE vent, Widget* widget) | 2340 if (!m_lastGestureScrollOverWidget) |
| 2335 { | |
| 2336 if (!widget) | |
| 2337 return false; | 2341 return false; |
| 2338 | 2342 |
| 2343 if (!renderer || !renderer->isWidget()) | |
| 2344 return false; | |
| 2345 | |
| 2346 Widget* widget = toRenderWidget(renderer)->widget(); | |
| 2347 | |
| 2339 if (!widget->isFrameView()) | 2348 if (!widget->isFrameView()) |
| 2340 return false; | 2349 return false; |
| 2341 | 2350 |
| 2342 return toFrameView(widget)->frame().eventHandler().handleGestureEvent(gestur eEvent); | 2351 return toFrameView(widget)->frame().eventHandler().handleGestureScrollEvent( gestureEvent); |
| 2343 } | |
| 2344 | |
| 2345 bool EventHandler::passGestureEventToWidgetIfPossible(const PlatformGestureEvent & gestureEvent, RenderObject* renderer) | |
| 2346 { | |
| 2347 if (m_lastHitTestResultOverWidget && renderer && renderer->isWidget()) { | |
| 2348 Widget* widget = toRenderWidget(renderer)->widget(); | |
| 2349 return widget && passGestureEventToWidget(gestureEvent, widget); | |
| 2350 } | |
| 2351 return false; | |
| 2352 } | 2352 } |
| 2353 | 2353 |
| 2354 bool EventHandler::handleGestureScrollEnd(const PlatformGestureEvent& gestureEve nt) { | 2354 bool EventHandler::handleGestureScrollEnd(const PlatformGestureEvent& gestureEve nt) { |
| 2355 RefPtrWillBeRawPtr<Node> node = m_scrollGestureHandlingNode; | 2355 RefPtrWillBeRawPtr<Node> node = m_scrollGestureHandlingNode; |
| 2356 clearGestureScrollNodes(); | 2356 clearGestureScrollNodes(); |
| 2357 | 2357 |
| 2358 if (node) | 2358 if (node) |
| 2359 passGestureEventToWidgetIfPossible(gestureEvent, node->renderer()); | 2359 passScrollGestureEventToWidget(gestureEvent, node->renderer()); |
| 2360 | 2360 |
| 2361 return false; | 2361 return false; |
| 2362 } | 2362 } |
| 2363 | 2363 |
| 2364 bool EventHandler::handleGestureScrollBegin(const PlatformGestureEvent& gestureE vent) | 2364 bool EventHandler::handleGestureScrollBegin(const PlatformGestureEvent& gestureE vent) |
| 2365 { | 2365 { |
| 2366 Document* document = m_frame->document(); | 2366 Document* document = m_frame->document(); |
| 2367 if (!document->renderView()) | 2367 if (!document->renderView()) |
| 2368 return false; | 2368 return false; |
| 2369 | 2369 |
| 2370 FrameView* view = m_frame->view(); | 2370 FrameView* view = m_frame->view(); |
| 2371 if (!view) | 2371 if (!view) |
| 2372 return false; | 2372 return false; |
| 2373 | 2373 |
| 2374 LayoutPoint viewPoint = view->windowToContents(gestureEvent.position()); | |
| 2375 HitTestRequest request(HitTestRequest::ReadOnly); | |
| 2376 HitTestResult result(viewPoint); | |
| 2377 document->renderView()->hitTest(request, result); | |
| 2378 | |
| 2379 m_lastHitTestResultOverWidget = result.isOverWidget(); | |
| 2380 m_scrollGestureHandlingNode = result.innerNode(); | |
| 2381 m_previousGestureScrolledNode = nullptr; | |
| 2382 | |
| 2383 // If there's no renderer on the node, send the event to the nearest ancesto r with a renderer. | 2374 // If there's no renderer on the node, send the event to the nearest ancesto r with a renderer. |
| 2384 // Needed for <option> and <optgroup> elements so we can touch scroll <selec t>s | 2375 // Needed for <option> and <optgroup> elements so we can touch scroll <selec t>s |
| 2385 while (m_scrollGestureHandlingNode && !m_scrollGestureHandlingNode->renderer ()) | 2376 while (m_scrollGestureHandlingNode && !m_scrollGestureHandlingNode->renderer ()) |
| 2386 m_scrollGestureHandlingNode = m_scrollGestureHandlingNode->parentOrShado wHostNode(); | 2377 m_scrollGestureHandlingNode = m_scrollGestureHandlingNode->parentOrShado wHostNode(); |
| 2387 | 2378 |
| 2388 if (!m_scrollGestureHandlingNode) | 2379 if (!m_scrollGestureHandlingNode) |
| 2389 return false; | 2380 return false; |
| 2390 | 2381 |
| 2391 passGestureEventToWidgetIfPossible(gestureEvent, m_scrollGestureHandlingNode ->renderer()); | 2382 passScrollGestureEventToWidget(gestureEvent, m_scrollGestureHandlingNode->re nderer()); |
| 2392 | 2383 |
| 2393 return true; | 2384 return true; |
| 2394 } | 2385 } |
| 2395 | 2386 |
| 2396 bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gesture Event) | 2387 bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gesture Event) |
| 2397 { | 2388 { |
| 2398 FloatSize delta(gestureEvent.deltaX(), gestureEvent.deltaY()); | 2389 FloatSize delta(gestureEvent.deltaX(), gestureEvent.deltaY()); |
| 2399 if (delta.isZero()) | 2390 if (delta.isZero()) |
| 2400 return false; | 2391 return false; |
| 2401 | 2392 |
| 2402 const float scaleFactor = m_frame->pageZoomFactor(); | 2393 const float scaleFactor = m_frame->pageZoomFactor(); |
| 2403 delta.scale(1 / scaleFactor, 1 / scaleFactor); | 2394 delta.scale(1 / scaleFactor, 1 / scaleFactor); |
| 2404 | 2395 |
| 2405 Node* node = m_scrollGestureHandlingNode.get(); | 2396 Node* node = m_scrollGestureHandlingNode.get(); |
| 2406 if (!node) | 2397 if (!node) |
| 2407 return sendScrollEventToView(gestureEvent, delta); | 2398 return sendScrollEventToView(gestureEvent, delta); |
| 2408 | 2399 |
| 2409 // Ignore this event if the targeted node does not have a valid renderer. | 2400 // Ignore this event if the targeted node does not have a valid renderer. |
| 2410 RenderObject* renderer = node->renderer(); | 2401 RenderObject* renderer = node->renderer(); |
| 2411 if (!renderer) | 2402 if (!renderer) |
| 2412 return false; | 2403 return false; |
| 2413 | 2404 |
| 2414 RefPtr<FrameView> protector(m_frame->view()); | 2405 RefPtr<FrameView> protector(m_frame->view()); |
| 2415 | 2406 |
| 2416 Node* stopNode = 0; | 2407 Node* stopNode = 0; |
| 2417 bool scrollShouldNotPropagate = gestureEvent.type() == PlatformEvent::Gestur eScrollUpdateWithoutPropagation; | 2408 bool scrollShouldNotPropagate = gestureEvent.type() == PlatformEvent::Gestur eScrollUpdateWithoutPropagation; |
| 2418 | 2409 |
| 2419 // Try to send the event to the correct view. | 2410 // Try to send the event to the correct view. |
| 2420 if (passGestureEventToWidgetIfPossible(gestureEvent, renderer)) { | 2411 if (passScrollGestureEventToWidget(gestureEvent, renderer)) { |
| 2421 if(scrollShouldNotPropagate) | 2412 if(scrollShouldNotPropagate) |
| 2422 m_previousGestureScrolledNode = m_scrollGestureHandlingNode; | 2413 m_previousGestureScrolledNode = m_scrollGestureHandlingNode; |
| 2423 | 2414 |
| 2424 return true; | 2415 return true; |
| 2425 } | 2416 } |
| 2426 | 2417 |
| 2427 if (scrollShouldNotPropagate) | 2418 if (scrollShouldNotPropagate) |
| 2428 stopNode = m_previousGestureScrolledNode.get(); | 2419 stopNode = m_previousGestureScrolledNode.get(); |
| 2429 | 2420 |
| 2430 // First try to scroll the closest scrollable RenderBox ancestor of |node|. | 2421 // First try to scroll the closest scrollable RenderBox ancestor of |node|. |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 2460 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey()); | 2451 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey()); |
| 2461 syntheticWheelEvent.setHasPreciseScrollingDeltas(true); | 2452 syntheticWheelEvent.setHasPreciseScrollingDeltas(true); |
| 2462 | 2453 |
| 2463 bool scrolledFrame = view->wheelEvent(syntheticWheelEvent); | 2454 bool scrolledFrame = view->wheelEvent(syntheticWheelEvent); |
| 2464 if (scrolledFrame) | 2455 if (scrolledFrame) |
| 2465 setFrameWasScrolledByUser(); | 2456 setFrameWasScrolledByUser(); |
| 2466 | 2457 |
| 2467 return scrolledFrame; | 2458 return scrolledFrame; |
| 2468 } | 2459 } |
| 2469 | 2460 |
| 2470 LocalFrame* EventHandler::getSubFrameForGestureEvent(const IntPoint& touchAdjust edPoint, const PlatformGestureEvent& gestureEvent) | |
| 2471 { | |
| 2472 PlatformMouseEvent mouseDown(touchAdjustedPoint, gestureEvent.globalPosition (), LeftButton, PlatformEvent::MousePressed, 1, | |
| 2473 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp()); | |
| 2474 HitTestRequest request(HitTestRequest::ReadOnly); | |
| 2475 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDown); | |
| 2476 return subframeForHitTestResult(mev); | |
| 2477 } | |
| 2478 | |
| 2479 void EventHandler::clearGestureScrollNodes() | 2461 void EventHandler::clearGestureScrollNodes() |
| 2480 { | 2462 { |
| 2481 m_scrollGestureHandlingNode = nullptr; | 2463 m_scrollGestureHandlingNode = nullptr; |
| 2482 m_previousGestureScrolledNode = nullptr; | 2464 m_previousGestureScrolledNode = nullptr; |
| 2483 } | 2465 } |
| 2484 | 2466 |
| 2485 bool EventHandler::isScrollbarHandlingGestures() const | 2467 bool EventHandler::isScrollbarHandlingGestures() const |
| 2486 { | 2468 { |
| 2487 return m_scrollbarHandlingScrollGesture.get(); | 2469 return m_scrollbarHandlingScrollGesture.get(); |
| 2488 } | 2470 } |
| 2489 | 2471 |
| 2490 bool EventHandler::shouldApplyTouchAdjustment(const PlatformGestureEvent& event) const | 2472 bool EventHandler::shouldApplyTouchAdjustment(const PlatformGestureEvent& event) const |
| 2491 { | 2473 { |
| 2492 if (m_frame->settings() && !m_frame->settings()->touchAdjustmentEnabled()) | 2474 if (m_frame->settings() && !m_frame->settings()->touchAdjustmentEnabled()) |
| 2493 return false; | 2475 return false; |
| 2494 return !event.area().isEmpty(); | 2476 return !event.area().isEmpty(); |
| 2495 } | 2477 } |
| 2496 | 2478 |
| 2497 bool EventHandler::bestClickableNodeForTouchPoint(const IntPoint& touchCenter, c onst IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode) | 2479 bool EventHandler::bestClickableNodeForHitTestResult(const HitTestResult& result , IntPoint& targetPoint, Node*& targetNode) |
| 2498 { | 2480 { |
| 2499 IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter); | 2481 // FIXME: Unify this with the other best* functions which are very similar. |
| 2500 HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::Re adOnly | HitTestRequest::Active, touchRadius); | 2482 |
| 2483 TRACE_EVENT0("input", "EventHandler::bestClickableNodeForHitTestResult"); | |
| 2484 ASSERT(result.isRectBasedTest()); | |
| 2501 | 2485 |
| 2502 // If the touch is over a scrollbar, don't adjust the touch point since touc h adjustment only takes into account | 2486 // If the touch is over a scrollbar, don't adjust the touch point since touc h adjustment only takes into account |
| 2503 // DOM nodes so a touch over a scrollbar will be adjusted towards nearby nod es. This leads to things like textarea | 2487 // DOM nodes so a touch over a scrollbar will be adjusted towards nearby nod es. This leads to things like textarea |
| 2504 // scrollbars being untouchable. | 2488 // scrollbars being untouchable. |
| 2505 if (result.scrollbar()) | 2489 if (result.scrollbar()) |
| 2506 return false; | 2490 return false; |
| 2507 | 2491 |
| 2508 IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius); | 2492 IntPoint touchCenter = m_frame->view()->contentsToWindow(result.roundedPoint InMainFrame()); |
| 2493 IntRect touchRect = m_frame->view()->contentsToWindow(result.hitTestLocation ().boundingBox()); | |
| 2494 | |
| 2509 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; | 2495 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; |
| 2510 copyToVector(result.rectBasedTestResult(), nodes); | 2496 copyToVector(result.rectBasedTestResult(), nodes); |
| 2511 | 2497 |
| 2512 // FIXME: Should be able to handle targetNode being a shadow DOM node to avo id performing uncessary hit tests | 2498 // FIXME: Should be able to handle targetNode being a shadow DOM node to avo id performing uncessary hit tests |
| 2513 // in the case where further processing on the node is required. Returning t he shadow ancestor prevents a | 2499 // in the case where further processing on the node is required. Returning t he shadow ancestor prevents a |
| 2514 // regression in touchadjustment/html-label.html. Some refinement is require d to testing/internals to | 2500 // regression in touchadjustment/html-label.html. Some refinement is require d to testing/internals to |
| 2515 // handle targetNode being a shadow DOM node. | 2501 // handle targetNode being a shadow DOM node. |
| 2516 | 2502 |
| 2517 // FIXME: the explicit Vector conversion copies into a temporary and is wast eful. | 2503 // FIXME: the explicit Vector conversion copies into a temporary and is wast eful. |
| 2518 // FIXME: targetNode and success are only used by Internals functions. We sh ould | 2504 // FIXME: targetNode and success are only used by Internals functions. We sh ould |
| 2519 // instead have dedicated test methods so we only do this work in tests. | 2505 // instead have dedicated test methods so we only do this work in tests. |
| 2520 bool success = findBestClickableCandidate(targetNode, targetPoint, touchCent er, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> > (nodes)); | 2506 bool success = findBestClickableCandidate(targetNode, targetPoint, touchCent er, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> > (nodes)); |
| 2521 if (success && targetNode) | 2507 if (success && targetNode) |
| 2522 targetNode = targetNode->deprecatedShadowAncestorNode(); | 2508 targetNode = targetNode->deprecatedShadowAncestorNode(); |
| 2523 return success; | 2509 return success; |
| 2524 } | 2510 } |
| 2525 | 2511 |
| 2526 bool EventHandler::bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode) | 2512 bool EventHandler::bestContextMenuNodeForHitTestResult(const HitTestResult& resu lt, IntPoint& targetPoint, Node*& targetNode) |
| 2527 { | 2513 { |
| 2528 IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter); | 2514 ASSERT(result.isRectBasedTest()); |
| 2529 HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::Re adOnly | HitTestRequest::Active, touchRadius); | 2515 IntPoint touchCenter = m_frame->view()->contentsToWindow(result.roundedPoint InMainFrame()); |
| 2530 | 2516 IntRect touchRect = m_frame->view()->contentsToWindow(result.hitTestLocation ().boundingBox()); |
| 2531 IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius); | |
| 2532 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; | 2517 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; |
| 2533 copyToVector(result.rectBasedTestResult(), nodes); | 2518 copyToVector(result.rectBasedTestResult(), nodes); |
| 2534 | 2519 |
| 2535 // FIXME: the explicit Vector conversion copies into a temporary and is wast eful. | 2520 // FIXME: the explicit Vector conversion copies into a temporary and is wast eful. |
| 2536 return findBestContextMenuCandidate(targetNode, targetPoint, touchCenter, to uchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes)); | 2521 return findBestContextMenuCandidate(targetNode, targetPoint, touchCenter, to uchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes)); |
| 2537 } | 2522 } |
| 2538 | 2523 |
| 2539 bool EventHandler::bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, co nst IntSize& touchRadius, IntRect& targetArea, Node*& targetNode) | 2524 bool EventHandler::bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, co nst IntSize& touchRadius, IntRect& targetArea, Node*& targetNode) |
| 2540 { | 2525 { |
| 2541 IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter); | 2526 IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter); |
| 2542 HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::Re adOnly | HitTestRequest::Active, touchRadius); | 2527 HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::Re adOnly | HitTestRequest::Active, touchRadius); |
| 2543 | 2528 |
| 2544 IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius); | 2529 IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius); |
| 2545 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; | 2530 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; |
| 2546 copyToVector(result.rectBasedTestResult(), nodes); | 2531 copyToVector(result.rectBasedTestResult(), nodes); |
| 2547 | 2532 |
| 2548 // FIXME: the explicit Vector conversion copies into a temporary and is wast eful. | 2533 // FIXME: the explicit Vector conversion copies into a temporary and is wast eful. |
| 2549 return findBestZoomableArea(targetNode, targetArea, touchCenter, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes)); | 2534 return findBestZoomableArea(targetNode, targetArea, touchCenter, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes)); |
| 2550 } | 2535 } |
| 2551 | 2536 |
| 2552 void EventHandler::adjustGesturePosition(const PlatformGestureEvent& gestureEven t, IntPoint& adjustedPoint) | 2537 GestureEventWithHitTestResults EventHandler::targetGestureEvent(const PlatformGe stureEvent& gestureEvent, bool readOnly) |
| 2553 { | 2538 { |
| 2554 if (!shouldApplyTouchAdjustment(gestureEvent)) | 2539 ASSERT(m_frame == m_frame->localFrameRoot()); |
| 2555 return; | 2540 // Scrolling events get hit tested per frame (like wheel events do). |
| 2541 ASSERT(!gestureEvent.isScrollEvent()); | |
| 2556 | 2542 |
| 2557 Node* targetNode = 0; | 2543 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent | Hi tTestRequest::AllowFrameScrollbars; |
| 2558 switch (gestureEvent.type()) { | 2544 double activeInterval = 0; |
| 2559 case PlatformEvent::GestureTap: | 2545 bool shouldKeepActiveForMinInterval = false; |
| 2560 case PlatformEvent::GestureTapUnconfirmed: | 2546 if (readOnly) { |
| 2561 case PlatformEvent::GestureTapDown: | 2547 hitType |= HitTestRequest::ReadOnly; |
| 2562 case PlatformEvent::GestureShowPress: | 2548 } else if (gestureEvent.type() == PlatformEvent::GestureShowPress |
| 2563 bestClickableNodeForTouchPoint(gestureEvent.position(), IntSize(gestureE vent.area().width() / 2, gestureEvent.area().height() / 2), adjustedPoint, targe tNode); | 2549 || gestureEvent.type() == PlatformEvent::GestureTapUnconfirmed) { |
| 2564 break; | 2550 hitType |= HitTestRequest::Active; |
| 2565 case PlatformEvent::GestureLongPress: | 2551 } else if (gestureEvent.type() == PlatformEvent::GestureTapDownCancel) { |
| 2566 case PlatformEvent::GestureLongTap: | 2552 hitType |= HitTestRequest::Release; |
| 2567 case PlatformEvent::GestureTwoFingerTap: | 2553 // A TapDownCancel received when no element is active shouldn't really b e changing hover state. |
| 2568 bestContextMenuNodeForTouchPoint(gestureEvent.position(), IntSize(gestur eEvent.area().width() / 2, gestureEvent.area().height() / 2), adjustedPoint, tar getNode); | 2554 if (!m_frame->document()->activeHoverElement()) |
| 2569 break; | 2555 hitType |= HitTestRequest::ReadOnly; |
| 2570 default: | 2556 } else if (gestureEvent.type() == PlatformEvent::GestureTap) { |
| 2571 // FIXME: Implement handling for other types as needed. | 2557 hitType |= HitTestRequest::Release; |
| 2572 ASSERT_NOT_REACHED(); | 2558 // If the Tap is received very shortly after ShowPress, we want to |
| 2559 // delay clearing of the active state so that it's visible to the user | |
| 2560 // for at least a couple of frames. | |
| 2561 activeInterval = WTF::currentTime() - m_lastShowPressTimestamp; | |
| 2562 shouldKeepActiveForMinInterval = m_lastShowPressTimestamp && activeInter val < minimumActiveInterval; | |
| 2563 if (shouldKeepActiveForMinInterval) | |
| 2564 hitType |= HitTestRequest::ReadOnly; | |
| 2565 } else { | |
| 2566 hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly; | |
| 2573 } | 2567 } |
| 2568 | |
| 2569 // Perform the rect-based hit-test. Note that we don't yet apply hover/activ e state here | |
| 2570 // because we need to resolve touch adjustment first so that we apply hover/ active it to | |
| 2571 // the final adjusted node. | |
| 2572 IntPoint hitTestPoint = m_frame->view()->windowToContents(gestureEvent.posit ion()); | |
| 2573 IntSize touchRadius = gestureEvent.area(); | |
| 2574 touchRadius.scale(1.f / 2); | |
| 2575 HitTestResult hitTestResult = hitTestResultAtPoint(hitTestPoint, hitType | H itTestRequest::ReadOnly, touchRadius); | |
| 2576 | |
| 2577 // Adjust the location of the gesture to the most likely nearby node, as app ropriate for the | |
| 2578 // type of event. | |
| 2579 PlatformGestureEvent adjustedEvent = gestureEvent; | |
| 2580 if (shouldApplyTouchAdjustment(gestureEvent)) { | |
|
esprehn
2014/06/27 08:33:58
We should consider breaking this stuff up into sma
Rick Byers
2014/06/27 15:38:23
Done. Added getHitTypeForGestureType and applyTou
| |
| 2581 Node* adjustedNode = 0; | |
| 2582 IntPoint adjustedPoint = gestureEvent.position(); | |
| 2583 IntSize radius = gestureEvent.area(); | |
| 2584 radius.scale(1.f / 2); | |
| 2585 bool adjusted = false; | |
| 2586 switch (gestureEvent.type()) { | |
| 2587 case PlatformEvent::GestureTap: | |
| 2588 case PlatformEvent::GestureTapUnconfirmed: | |
| 2589 case PlatformEvent::GestureTapDown: | |
| 2590 case PlatformEvent::GestureShowPress: | |
| 2591 adjusted = bestClickableNodeForHitTestResult(hitTestResult, adjusted Point, adjustedNode); | |
|
esprehn
2014/06/27 08:33:58
If this was a helper you could just do
return bes
Rick Byers
2014/06/27 15:38:24
I've got a plan to unify the best*ForHitTestResult
| |
| 2592 break; | |
| 2593 case PlatformEvent::GestureLongPress: | |
| 2594 case PlatformEvent::GestureLongTap: | |
| 2595 case PlatformEvent::GestureTwoFingerTap: | |
| 2596 adjusted = bestContextMenuNodeForHitTestResult(hitTestResult, adjust edPoint, adjustedNode); | |
| 2597 break; | |
| 2598 default: | |
| 2599 // FIXME: Implement handling for other types as needed. | |
| 2600 ASSERT_NOT_REACHED(); | |
| 2601 } | |
| 2602 | |
| 2603 if (adjusted) { | |
|
esprehn
2014/06/27 08:33:58
If it was in a helper you could just write:
if (a
Rick Byers
2014/06/27 15:38:24
Again I think I can make this even simpler, but it
| |
| 2604 hitTestResult.resolveRectBasedTest(adjustedNode, m_frame->view()->wi ndowToContents(adjustedPoint)); | |
| 2605 adjustedEvent.applyTouchAdjustment(adjustedPoint); | |
| 2606 } | |
| 2607 } | |
| 2608 | |
| 2609 // Now apply hover/active state to the final target. | |
| 2610 // FIXME: This is supposed to send mouseenter/mouseleave events, but doesn't because we | |
| 2611 // aren't passing a PlatformMouseEvent. | |
| 2612 HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent); | |
| 2613 if (!request.readOnly()) | |
| 2614 m_frame->document()->updateHoverActiveState(request, hitTestResult.inner Element()); | |
| 2615 | |
| 2616 if (shouldKeepActiveForMinInterval) { | |
| 2617 m_lastDeferredTapElement = hitTestResult.innerElement(); | |
| 2618 m_activeIntervalTimer.startOneShot(minimumActiveInterval - activeInterva l, FROM_HERE); | |
| 2619 } | |
| 2620 | |
| 2621 return GestureEventWithHitTestResults(adjustedEvent, hitTestResult); | |
| 2574 } | 2622 } |
| 2575 | 2623 |
| 2576 bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event) | 2624 bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event) |
| 2577 { | 2625 { |
| 2578 Document* doc = m_frame->document(); | 2626 Document* doc = m_frame->document(); |
| 2579 FrameView* v = m_frame->view(); | 2627 FrameView* v = m_frame->view(); |
| 2580 if (!v) | 2628 if (!v) |
| 2581 return false; | 2629 return false; |
| 2582 | 2630 |
| 2583 // Clear mouse press state to avoid initiating a drag while context menu is up. | 2631 // Clear mouse press state to avoid initiating a drag while context menu is up. |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2670 #else | 2718 #else |
| 2671 PlatformEvent::Type eventType = PlatformEvent::MousePressed; | 2719 PlatformEvent::Type eventType = PlatformEvent::MousePressed; |
| 2672 #endif | 2720 #endif |
| 2673 | 2721 |
| 2674 PlatformMouseEvent mouseEvent(position, globalPosition, RightButton, eventTy pe, 1, false, false, false, false, WTF::currentTime()); | 2722 PlatformMouseEvent mouseEvent(position, globalPosition, RightButton, eventTy pe, 1, false, false, false, false, WTF::currentTime()); |
| 2675 | 2723 |
| 2676 handleMousePressEvent(mouseEvent); | 2724 handleMousePressEvent(mouseEvent); |
| 2677 return sendContextMenuEvent(mouseEvent); | 2725 return sendContextMenuEvent(mouseEvent); |
| 2678 } | 2726 } |
| 2679 | 2727 |
| 2680 bool EventHandler::sendContextMenuEventForGesture(const PlatformGestureEvent& ev ent) | 2728 bool EventHandler::sendContextMenuEventForGesture(const GestureEventWithHitTestR esults& targetedEvent) |
| 2681 { | 2729 { |
| 2682 #if OS(WIN) | 2730 #if OS(WIN) |
| 2683 PlatformEvent::Type eventType = PlatformEvent::MouseReleased; | 2731 PlatformEvent::Type eventType = PlatformEvent::MouseReleased; |
| 2684 #else | 2732 #else |
| 2685 PlatformEvent::Type eventType = PlatformEvent::MousePressed; | 2733 PlatformEvent::Type eventType = PlatformEvent::MousePressed; |
| 2686 #endif | 2734 #endif |
| 2687 | 2735 |
| 2688 IntPoint adjustedPoint = event.position(); | 2736 PlatformMouseEvent mouseEvent(targetedEvent.event().position(), targetedEven t.event().globalPosition(), RightButton, eventType, 1, false, false, false, fals e, WTF::currentTime()); |
| 2689 adjustGesturePosition(event, adjustedPoint); | |
| 2690 PlatformMouseEvent mouseEvent(adjustedPoint, event.globalPosition(), RightBu tton, eventType, 1, false, false, false, false, WTF::currentTime()); | |
| 2691 // To simulate right-click behavior, we send a right mouse down and then | 2737 // To simulate right-click behavior, we send a right mouse down and then |
| 2692 // context menu event. | 2738 // context menu event. |
| 2739 // FIXME: Send HitTestResults to avoid redundant hit tests. | |
| 2693 handleMousePressEvent(mouseEvent); | 2740 handleMousePressEvent(mouseEvent); |
| 2694 return sendContextMenuEvent(mouseEvent); | 2741 return sendContextMenuEvent(mouseEvent); |
| 2695 // We do not need to send a corresponding mouse release because in case of | 2742 // We do not need to send a corresponding mouse release because in case of |
| 2696 // right-click, the context menu takes capture and consumes all events. | 2743 // right-click, the context menu takes capture and consumes all events. |
| 2697 } | 2744 } |
| 2698 | 2745 |
| 2699 void EventHandler::scheduleHoverStateUpdate() | 2746 void EventHandler::scheduleHoverStateUpdate() |
| 2700 { | 2747 { |
| 2701 if (!m_hoverTimer.isActive()) | 2748 if (!m_hoverTimer.isActive()) |
| 2702 m_hoverTimer.startOneShot(0, FROM_HERE); | 2749 m_hoverTimer.startOneShot(0, FROM_HERE); |
| (...skipping 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3751 unsigned EventHandler::accessKeyModifiers() | 3798 unsigned EventHandler::accessKeyModifiers() |
| 3752 { | 3799 { |
| 3753 #if OS(MACOSX) | 3800 #if OS(MACOSX) |
| 3754 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; | 3801 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; |
| 3755 #else | 3802 #else |
| 3756 return PlatformEvent::AltKey; | 3803 return PlatformEvent::AltKey; |
| 3757 #endif | 3804 #endif |
| 3758 } | 3805 } |
| 3759 | 3806 |
| 3760 } // namespace WebCore | 3807 } // namespace WebCore |
| OLD | NEW |