Changeset 266333 in webkit
- Timestamp:
- Aug 30, 2020 10:25:15 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 2 deleted
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r266332 r266333 1 2020-08-29 Simon Fraser <simon.fraser@apple.com> 2 3 Rewrite main thread scroll latching logic 4 https://bugs.webkit.org/show_bug.cgi?id=215979 5 6 Reviewed by Tim Horton. 7 8 Add a test for iframe unparenting in the middle of a latched scroll. 9 10 * fast/scrolling/latching/latched-scroll-remove-iframe.html: Added. 11 * fast/scrolling/latching/scroll-nested-iframe.html: 1000ms -> 0ms 12 * fast/scrolling/mac/rubberband-overflow-in-wheel-region.html: Test needs to latch the overflow by scrolling down then up. 13 1 14 2020-08-30 Youenn Fablet <youenn@apple.com> 2 15 -
trunk/LayoutTests/fast/scrolling/latching/scroll-nested-iframe.html
r259121 r266333 63 63 description("Tests that iframe does scroll when inner iframe is NOT scrollable."); 64 64 if (window.eventSender) { 65 setTimeout(scrollTest, 1000);65 setTimeout(scrollTest, 0); 66 66 return; 67 67 } -
trunk/LayoutTests/fast/scrolling/mac/rubberband-overflow-in-wheel-region.html
r265820 r266333 47 47 { 48 48 eventSender.mouseMoveTo(100, 100); 49 eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 1, "began", "none"); 50 eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 20, "changed", "none"); 49 // Scroll down to latch, then up to rubberband. 50 eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, "began", "none"); 51 eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -10, "changed", "none"); 52 eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -10, "changed", "none"); 53 eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 12, "changed", "none"); 54 eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 12, "changed", "none"); 51 55 eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, "ended", "none"); 52 56 await UIHelper.renderingUpdate(); -
trunk/Source/WebCore/ChangeLog
r266332 r266333 1 2020-08-29 Simon Fraser <simon.fraser@apple.com> 2 3 Rewrite main thread scroll latching logic 4 https://bugs.webkit.org/show_bug.cgi?id=215979 5 6 Reviewed by Tim Horton. 7 8 The existing main thread wheel event handling and latching logic had a number of issues, 9 some of which were indicated via the FIXME comments added in r266016: 10 - It tracked scrollable containers as ContainerNodes rather than ScrollableAreas 11 - It fetched and used latched state from a different frame, causing an EventHandler 12 to end up scrolling some unrelated frame. 13 - Overflow scrolling ignored latched state. 14 - The latching stack's purpose was unclear. 15 16 This patch fixes those issues. The design is as follow: 17 - Latching logic is moved into ScrollLatchingController, which is owned by Page. 18 - ScrollLatchingController owns a stack of FrameState. 19 - When receiving a wheel event, determineWheelEventTarget() identifies the target 20 ScrollableArea, if any, for that frame only. 21 - As hit-testing descends into subframes, state is pushed onto ScrollLatchingController's 22 state stack. Frames with potential scrollers have a non-null ScrollableArea in their state. 23 - The latched ScrollableArea is the top non-null ScrollableArea in this stack. 24 - EventHandler consults ScrollLatchingController for select, overflow and frame scrolling. 25 26 This change fixes an issue where scrolling over an overflow:scroll in the non-fast scrollable 27 region would rubber-band the overflow, rather than the main page (tested by the adjusted 28 fast/scrolling/mac/rubberband-overflow-in-wheel-region.html). 29 30 Tests: fast/scrolling/latching/latched-scroll-remove-iframe.html 31 32 * Sources.txt: 33 * WebCore.xcodeproj/project.pbxproj: 34 * dom/Element.cpp: 35 (WebCore::Element::removedFromAncestor): 36 * page/EventHandler.cpp: 37 (WebCore::EventHandler::EventHandler): 38 (WebCore::EventHandler::determineWheelEventTarget): 39 (WebCore::EventHandler::processWheelEventForScrolling): 40 (WebCore::EventHandler::platformCompletePlatformWidgetWheelEvent): 41 (WebCore::EventHandler::processWheelEventForScrollSnap): 42 (WebCore::EventHandler::completeWidgetWheelEvent): 43 (WebCore::EventHandler::handleWheelEvent): 44 (WebCore::EventHandler::clearLatchedState): 45 (WebCore::EventHandler::defaultWheelEventHandler): 46 (WebCore::EventHandler::clearLatchedStateTimerFired): Deleted. 47 (WebCore::EventHandler::clearOrScheduleClearingLatchedStateIfNeeded): Deleted. 48 * page/EventHandler.h: 49 * page/Page.cpp: 50 (WebCore::Page::startMonitoringWheelEvents): 51 (WebCore::Page::scrollLatchingController): 52 (WebCore::Page::scrollLatchingControllerIfExists): 53 (WebCore::Page::latchingState): Deleted. 54 (WebCore::Page::pushNewLatchingState): Deleted. 55 (WebCore::Page::resetLatchingState): Deleted. 56 (WebCore::Page::popLatchingState): Deleted. 57 (WebCore::Page::removeLatchingStateForTarget): Deleted. 58 * page/Page.h: 59 (WebCore::Page::latchingStateStack const): Deleted. 60 * page/mac/EventHandlerMac.mm: 61 (WebCore::EventHandler::determineWheelEventTarget): 62 (WebCore::EventHandler::processWheelEventForScrolling): 63 (WebCore::EventHandler::platformCompletePlatformWidgetWheelEvent): 64 (WebCore::EventHandler::processWheelEventForScrollSnap): 65 (WebCore::deltaIsPredominantlyVertical): Deleted. 66 (WebCore::scrolledToEdgeInDominantDirection): Deleted. 67 (WebCore::latchingIsLockedToPlatformFrame): Deleted. 68 (WebCore::latchingIsLockedToAncestorOfThisFrame): Deleted. 69 (WebCore::latchedToFrameOrBody): Deleted. 70 (WebCore::EventHandler::clearOrScheduleClearingLatchedStateIfNeeded): Deleted. 71 (WebCore::frameViewForLatchingState): Deleted. 72 * page/scrolling/ScrollLatchingController.cpp: Added. 73 (WebCore::ScrollLatchingController::ScrollLatchingController): 74 (WebCore::ScrollLatchingController::clear): 75 (WebCore::ScrollLatchingController::clearOrScheduleClearIfNeeded): 76 (WebCore::ScrollLatchingController::clearTimerFired): 77 (WebCore::ScrollLatchingController::receivedWheelEvent): 78 (WebCore::ScrollLatchingController::latchingAllowsScrollingInFrame const): 79 (WebCore::ScrollLatchingController::updateLatchingStateForFrame): 80 (WebCore::ScrollLatchingController::getLatchingStateForFrame const): 81 (WebCore::ScrollLatchingController::removeLatchingStateForTarget): 82 (WebCore::ScrollLatchingController::removeLatchingStateForFrame): 83 (WebCore::deltaIsPredominantlyVertical): 84 (WebCore::ScrollLatchingController::shouldLatchToScrollableArea const): 85 (WebCore::ScrollLatchingController::hasStateForFrame const): 86 (WebCore::ScrollLatchingController::stateForFrame): 87 (WebCore::ScrollLatchingController::stateForFrame const): 88 (WebCore::ScrollLatchingController::dump const): 89 (WebCore::operator<<): 90 * page/scrolling/ScrollLatchingController.h: Added. 91 (WebCore::ScrollLatchingController::cumulativeEventDelta const): 92 * page/scrolling/ScrollLatchingState.cpp: Removed. 93 * page/scrolling/ScrollLatchingState.h: Removed. 94 * page/scrolling/ScrollingTreeLatchingController.cpp: 95 (WebCore::ScrollingTreeLatchingController::receivedWheelEvent): 96 (WebCore::ScrollingTreeLatchingController::nodeDidHandleEvent): 97 * page/scrolling/ThreadedScrollingTree.cpp: 98 (WebCore::ThreadedScrollingTree::handleWheelEventAfterMainThread): 99 * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm: 100 (WebCore::ScrollingTreeScrollingNodeDelegateMac::allowsHorizontalStretching const): 101 (WebCore::ScrollingTreeScrollingNodeDelegateMac::allowsVerticalStretching const): 102 (WebCore::newGestureIsStarting): Deleted. 103 * platform/PlatformWheelEvent.h: 104 (WebCore::PlatformWheelEvent::isGestureStart const): 105 (WebCore::PlatformWheelEvent::isGestureContinuation const): 106 (WebCore::PlatformWheelEvent::shouldResetLatching const): 107 (WebCore::PlatformWheelEvent::isNonGestureEvent const): 108 (WebCore::PlatformWheelEvent::shouldConsiderLatching const): Deleted. Renamed to isGestureStart(). This class 109 should not prescribe latching behaviors. 110 1 111 2020-08-30 Youenn Fablet <youenn@apple.com> 2 112 -
trunk/Source/WebCore/Sources.txt
r266332 r266333 1685 1685 page/scrolling/AsyncScrollingCoordinator.cpp 1686 1686 page/scrolling/AxisScrollSnapOffsets.cpp 1687 page/scrolling/ScrollLatching State.cpp1687 page/scrolling/ScrollLatchingController.cpp 1688 1688 page/scrolling/ScrollingConstraints.cpp 1689 1689 page/scrolling/ScrollingCoordinator.cpp -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r266332 r266333 2216 2216 7AA3A6A4194B5C22001CBD24 /* TileCoverageMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AA3A6A2194B5C22001CBD24 /* TileCoverageMap.h */; }; 2217 2217 7AABA25A14BC613300AA9A11 /* DOMEditor.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AABA25814BC613300AA9A11 /* DOMEditor.h */; }; 2218 7AAFE8D019CB8672000F56D8 /* ScrollLatchingState.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AAFE8CE19CB8672000F56D8 /* ScrollLatchingState.h */; };2219 2218 7ADE722610CBBB9B006B3B3A /* ContextMenuProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ADE722510CBBB9B006B3B3A /* ContextMenuProvider.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2220 2219 7AE335F21ACB09E200E401EF /* WheelEventTestMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AE335F01ACB09E200E401EF /* WheelEventTestMonitor.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 5977 5976 0F94B6542209156C00157014 /* ScrollingTreePositionedNode.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollingTreePositionedNode.mm; sourceTree = "<group>"; }; 5978 5977 0F94F37C23661131003AA5C7 /* StyleRuleType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StyleRuleType.h; sourceTree = "<group>"; }; 5978 0F9510F024F4769C001F52DC /* ScrollLatchingController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScrollLatchingController.h; sourceTree = "<group>"; }; 5979 0F9510F224F4769C001F52DC /* ScrollLatchingController.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollLatchingController.cpp; sourceTree = "<group>"; }; 5979 5980 0F97A657155DA81E00FADD4C /* DisplayRefreshMonitorIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DisplayRefreshMonitorIOS.mm; sourceTree = "<group>"; }; 5980 5981 0F9B547522B4A772007B5E8A /* ScrollingStateOverflowScrollProxyNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScrollingStateOverflowScrollProxyNode.h; sourceTree = "<group>"; }; … … 10008 10009 7AABA25714BC613300AA9A11 /* DOMEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMEditor.cpp; sourceTree = "<group>"; }; 10009 10010 7AABA25814BC613300AA9A11 /* DOMEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMEditor.h; sourceTree = "<group>"; }; 10010 7AAFE8CD19CB8672000F56D8 /* ScrollLatchingState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollLatchingState.cpp; sourceTree = "<group>"; };10011 7AAFE8CE19CB8672000F56D8 /* ScrollLatchingState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollLatchingState.h; sourceTree = "<group>"; };10012 10011 7ADE722510CBBB9B006B3B3A /* ContextMenuProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContextMenuProvider.h; sourceTree = "<group>"; }; 10013 10012 7AE335EF1ACB09E200E401EF /* WheelEventTestMonitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WheelEventTestMonitor.cpp; sourceTree = "<group>"; }; … … 18012 18011 A6D5A99A1629D6FF00297330 /* ScrollingTreeScrollingNodeDelegate.cpp */, 18013 18012 A6D5A99B1629D70000297330 /* ScrollingTreeScrollingNodeDelegate.h */, 18014 7AAFE8CD19CB8672000F56D8 /* ScrollLatchingState.cpp */,18015 7AAFE8CE19CB8672000F56D8 /* ScrollLatchingState.h */,18013 0F9510F224F4769C001F52DC /* ScrollLatchingController.cpp */, 18014 0F9510F024F4769C001F52DC /* ScrollLatchingController.h */, 18016 18015 F46729251E0DE5AB00ACC3D8 /* ScrollSnapOffsetsInfo.h */, 18017 18016 0F6383DB18615B29003E5DB5 /* ThreadedScrollingTree.cpp */, … … 33514 33513 0F94B6492208FE3B00157014 /* ScrollingTreeStickyNode.h in Headers */, 33515 33514 83C5795D1DA5C301006F9C97 /* ScrollIntoViewOptions.h in Headers */, 33516 7AAFE8D019CB8672000F56D8 /* ScrollLatchingState.h in Headers */,33517 33515 83C5795D1DA5C301006F9C86 /* ScrollLogicalPosition.h in Headers */, 33518 33516 83C5795D1DA5C301006FAC97 /* ScrollOptions.h in Headers */, -
trunk/Source/WebCore/dom/Element.cpp
r266269 r266333 106 106 #include "ScriptDisallowedScope.h" 107 107 #include "ScrollIntoViewOptions.h" 108 #include "ScrollLatching State.h"108 #include "ScrollLatchingController.h" 109 109 #include "SelectorQuery.h" 110 110 #include "Settings.h" … … 2260 2260 frame->legacyAnimation().cancelAnimations(*this); 2261 2261 2262 #if PLATFORM(MAC) 2263 if (frame && frame->page()) 2264 frame->page()->removeLatchingStateForTarget(*this); 2262 #if ENABLE(WHEEL_EVENT_LATCHING) 2263 if (frame && frame->page()) { 2264 if (auto* scrollLatchingController = frame->page()->scrollLatchingControllerIfExists()) 2265 scrollLatchingController->removeLatchingStateForTarget(*this); 2266 } 2265 2267 #endif 2266 2268 -
trunk/Source/WebCore/page/EventHandler.cpp
r266295 r266333 90 90 #include "SVGNames.h" 91 91 #include "ScrollAnimator.h" 92 #include "ScrollLatching State.h"92 #include "ScrollLatchingController.h" 93 93 #include "Scrollbar.h" 94 94 #include "Settings.h" … … 391 391 : m_frame(frame) 392 392 , m_hoverTimer(*this, &EventHandler::hoverTimerFired) 393 #if PLATFORM(MAC)394 , m_clearLatchingStateTimer(*this, &EventHandler::clearLatchedStateTimerFired)395 #endif396 393 , m_autoscrollController(makeUnique<AutoscrollController>()) 397 394 #if !ENABLE(IOS_TOUCH_EVENTS) … … 2773 2770 } 2774 2771 2775 void EventHandler::clearLatchedStateTimerFired()2776 {2777 LOG(ScrollLatching, "EventHandler %p clearLatchedStateTimerFired()", this);2778 clearLatchedState();2779 }2780 2781 2772 #if !PLATFORM(MAC) 2782 2773 2783 void EventHandler::determineWheelEventTarget(const PlatformWheelEvent&, const HitTestResult&, RefPtr<Element>&, RefPtr<ContainerNode>&, WeakPtr<ScrollableArea>&, bool&)2774 void EventHandler::determineWheelEventTarget(const PlatformWheelEvent&, RefPtr<Element>&, WeakPtr<ScrollableArea>&, bool&) 2784 2775 { 2785 2776 } … … 2791 2782 } 2792 2783 2793 bool EventHandler::processWheelEventForScrolling(const PlatformWheelEvent& event, ContainerNode*,const WeakPtr<ScrollableArea>&)2784 bool EventHandler::processWheelEventForScrolling(const PlatformWheelEvent& event, const WeakPtr<ScrollableArea>&) 2794 2785 { 2795 2786 Ref<Frame> protectedFrame(m_frame); … … 2803 2794 } 2804 2795 2805 bool EventHandler::platformCompletePlatformWidgetWheelEvent(const PlatformWheelEvent&, const Widget&, ContainerNode*)2796 bool EventHandler::platformCompletePlatformWidgetWheelEvent(const PlatformWheelEvent&, const Widget&, const WeakPtr<ScrollableArea>&) 2806 2797 { 2807 2798 return true; … … 2810 2801 void EventHandler::processWheelEventForScrollSnap(const PlatformWheelEvent&, const WeakPtr<ScrollableArea>&) 2811 2802 { 2812 }2813 2814 void EventHandler::clearOrScheduleClearingLatchedStateIfNeeded(const PlatformWheelEvent&)2815 {2816 clearLatchedState();2817 2803 } 2818 2804 … … 2858 2844 } 2859 2845 2860 bool EventHandler::completeWidgetWheelEvent(const PlatformWheelEvent& event, const WeakPtr<Widget>& widget, const WeakPtr<ScrollableArea>& scrollableArea , ContainerNode* scrollableContainer)2846 bool EventHandler::completeWidgetWheelEvent(const PlatformWheelEvent& event, const WeakPtr<Widget>& widget, const WeakPtr<ScrollableArea>& scrollableArea) 2861 2847 { 2862 2848 m_isHandlingWheelEvent = false; … … 2874 2860 return true; 2875 2861 2876 return platformCompletePlatformWidgetWheelEvent(event, *widget.get(), scrollable Container);2862 return platformCompletePlatformWidgetWheelEvent(event, *widget.get(), scrollableArea); 2877 2863 } 2878 2864 … … 2888 2874 FrameView* view = m_frame.view(); 2889 2875 if (!view) 2876 return false; 2877 2878 if (!m_frame.page()) 2890 2879 return false; 2891 2880 … … 2908 2897 setFrameWasScrolledByUser(); 2909 2898 2899 if (m_frame.isMainFrame()) { 2900 #if ENABLE(WHEEL_EVENT_LATCHING) 2901 m_frame.page()->scrollLatchingController().receivedWheelEvent(event); 2902 #endif 2903 recordWheelEventForDeltaFilter(event); 2904 } 2905 2910 2906 HitTestRequest request; 2911 2907 HitTestResult result(view->windowToContents(event.position())); 2912 2908 document->hitTest(request, result); 2913 2909 2914 // FIXME: Why do we have track all three of targetElement, scrollableContainer and ScrollableArea?2915 2910 RefPtr<Element> element = result.targetElement(); 2916 RefPtr<ContainerNode> scrollableContainer;2917 2911 WeakPtr<ScrollableArea> scrollableArea; 2918 2912 bool isOverWidget = result.isOverWidget(); 2919 2920 // FIXME: Using the value of isOverWidget from the latching state triggers double-recursion into subframes. 2913 2921 2914 // FIXME: Despite doing this up-front search for the correct scrollable area, we dispatch events via elements which 2922 2915 // itself finds and tries to scroll overflow scrollers. 2923 determineWheelEventTarget(event, result, element, scrollableContainer, scrollableArea, isOverWidget); 2924 2925 #if ENABLE(WHEEL_EVENT_LATCHING) 2926 if (event.phase() == PlatformWheelEventPhaseNone && event.momentumPhase() == PlatformWheelEventPhaseNone && m_frame.page()) 2927 m_frame.page()->resetLatchingState(); 2928 #endif 2929 2930 recordWheelEventForDeltaFilter(event); 2916 determineWheelEventTarget(event, element, scrollableArea, isOverWidget); 2931 2917 2932 2918 if (element) { … … 2934 2920 if (WeakPtr<Widget> widget = widgetForElement(*element)) { 2935 2921 if (passWheelEventToWidget(event, *widget.get())) 2936 return completeWidgetWheelEvent(event, widget, scrollableArea , scrollableContainer.get());2922 return completeWidgetWheelEvent(event, widget, scrollableArea); 2937 2923 } 2938 2924 } … … 2954 2940 scrollableArea->setScrollShouldClearLatchedState(false); 2955 2941 2956 // FIXME: processWheelEventForScrolling() is only called for FrameView scrolling, not overflow scrolling, which is confusing. 2957 bool handledEvent = processWheelEventForScrolling(event, scrollableContainer.get(), scrollableArea); 2958 processWheelEventForScrollSnap(event, scrollableArea); 2942 // Event handling may have disconnected m_frame. 2943 if (!m_frame.page()) 2944 return false; 2945 2946 bool handledEvent = false; 2947 #if ENABLE(WHEEL_EVENT_LATCHING) 2948 WeakPtr<ScrollableArea> latchedScrollableArea; 2949 if (m_frame.page()->scrollLatchingController().latchingAllowsScrollingInFrame(m_frame, latchedScrollableArea)) { 2950 // FIXME: processWheelEventForScrolling() is only called for FrameView scrolling, not overflow scrolling, which is confusing. 2951 handledEvent = processWheelEventForScrolling(event, latchedScrollableArea); 2952 processWheelEventForScrollSnap(event, latchedScrollableArea); 2953 } 2954 #endif 2959 2955 return handledEvent; 2960 2956 } … … 2968 2964 #if ENABLE(WHEEL_EVENT_LATCHING) 2969 2965 LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::clearLatchedState()"); 2970 page->resetLatchingState(); 2971 #endif 2972 if (auto filter = page->wheelEventDeltaFilter()) 2966 if (auto* scrollLatchingController = page->scrollLatchingControllerIfExists()) 2967 scrollLatchingController->removeLatchingStateForFrame(m_frame); 2968 #endif 2969 if (auto* filter = page->wheelEventDeltaFilter()) 2973 2970 filter->endFilteringDeltas(); 2974 2971 } … … 2979 2976 return; 2980 2977 2978 if (!m_frame.page()) 2979 return; 2980 2981 2981 auto protectedFrame = makeRef(m_frame); 2982 2982 … … 2989 2989 2990 2990 #if ENABLE(WHEEL_EVENT_LATCHING) 2991 if (m_frame.page() && m_frame.page()->wheelEventDeltaFilter()->isFilteringDeltas()) {2991 if (m_frame.page()->wheelEventDeltaFilter()->isFilteringDeltas()) { 2992 2992 filteredPlatformDelta = m_frame.page()->wheelEventDeltaFilter()->filteredDelta(); 2993 2993 filteredVelocity = m_frame.page()->wheelEventDeltaFilter()->filteredVelocity(); 2994 } 2995 2996 WeakPtr<ScrollableArea> latchedScroller; 2997 if (!m_frame.page()->scrollLatchingController().latchingAllowsScrollingInFrame(m_frame, latchedScroller)) 2998 return; 2999 3000 if (latchedScroller) { 3001 if (latchedScroller == m_frame.view()) { 3002 // FrameView scrolling is handled via processWheelEventForScrolling(). 3003 return; 3004 } 3005 3006 auto platformEvent = wheelEvent.underlyingPlatformEvent(); 3007 if (platformEvent) { 3008 auto copiedEvent = platformEvent->copyWithDeltasAndVelocity(filteredPlatformDelta.width(), filteredPlatformDelta.height(), filteredVelocity); 3009 if (latchedScroller->handleWheelEvent(copiedEvent)) 3010 wheelEvent.setDefaultHandled(); 3011 return; 3012 } 2994 3013 } 2995 3014 #endif -
trunk/Source/WebCore/page/EventHandler.h
r265092 r266333 452 452 453 453 bool passWheelEventToWidget(const PlatformWheelEvent&, Widget&); 454 void determineWheelEventTarget(const PlatformWheelEvent&, const HitTestResult&, RefPtr<Element>& eventTarget, RefPtr<ContainerNode>& scrollableContainer, WeakPtr<ScrollableArea>&, bool& isOverWidget);454 void determineWheelEventTarget(const PlatformWheelEvent&, RefPtr<Element>& eventTarget, WeakPtr<ScrollableArea>&, bool& isOverWidget); 455 455 void recordWheelEventForDeltaFilter(const PlatformWheelEvent&); 456 bool processWheelEventForScrolling(const PlatformWheelEvent&, ContainerNode* scrollableContainer,const WeakPtr<ScrollableArea>&);456 bool processWheelEventForScrolling(const PlatformWheelEvent&, const WeakPtr<ScrollableArea>&); 457 457 void processWheelEventForScrollSnap(const PlatformWheelEvent&, const WeakPtr<ScrollableArea>&); 458 bool completeWidgetWheelEvent(const PlatformWheelEvent&, const WeakPtr<Widget>&, const WeakPtr<ScrollableArea>& , ContainerNode*);459 460 bool platformCompletePlatformWidgetWheelEvent(const PlatformWheelEvent&, const Widget&, ContainerNode* scrollableContainer);458 bool completeWidgetWheelEvent(const PlatformWheelEvent&, const WeakPtr<Widget>&, const WeakPtr<ScrollableArea>&); 459 460 bool platformCompletePlatformWidgetWheelEvent(const PlatformWheelEvent&, const Widget&, const WeakPtr<ScrollableArea>&); 461 461 462 462 void defaultSpaceEventHandler(KeyboardEvent&); … … 504 504 #endif 505 505 506 void clearOrScheduleClearingLatchedStateIfNeeded(const PlatformWheelEvent&);507 void clearLatchedStateTimerFired();508 506 void clearLatchedState(); 509 507 … … 536 534 Timer m_hoverTimer; 537 535 bool m_hasScheduledCursorUpdate { false }; 538 539 #if PLATFORM(MAC)540 Timer m_clearLatchingStateTimer;541 #endif542 536 543 537 std::unique_ptr<AutoscrollController> m_autoscrollController; -
trunk/Source/WebCore/page/Page.cpp
r266295 r266333 113 113 #include "ScriptDisallowedScope.h" 114 114 #include "ScriptedAnimationController.h" 115 #include "ScrollLatching State.h"115 #include "ScrollLatchingController.h" 116 116 #include "ScrollingCoordinator.h" 117 117 #include "Settings.h" … … 2839 2839 #if ENABLE(WHEEL_EVENT_LATCHING) 2840 2840 if (clearLatchingState) 2841 resetLatchingState();2841 scrollLatchingController().clear(); 2842 2842 #endif 2843 2843 … … 3142 3142 3143 3143 #if ENABLE(WHEEL_EVENT_LATCHING) 3144 ScrollLatchingState* Page::latchingState() 3145 { 3146 if (m_latchingState.isEmpty()) 3147 return nullptr; 3148 3149 return &m_latchingState.last(); 3150 } 3151 3152 void Page::pushNewLatchingState(ScrollLatchingState&& state) 3153 { 3154 m_latchingState.append(WTFMove(state)); 3155 } 3156 3157 void Page::resetLatchingState() 3158 { 3159 m_latchingState.clear(); 3160 } 3161 3162 void Page::popLatchingState() 3163 { 3164 m_latchingState.removeLast(); 3165 LOG_WITH_STREAM(ScrollLatching, stream << "Page::popLatchingState() - new state " << m_latchingState); 3166 } 3167 3168 void Page::removeLatchingStateForTarget(Element& targetNode) 3169 { 3170 if (m_latchingState.isEmpty()) 3171 return; 3172 3173 m_latchingState.removeAllMatching([&targetNode] (ScrollLatchingState& state) { 3174 auto* wheelElement = state.wheelEventElement(); 3175 if (!wheelElement) 3176 return false; 3177 3178 return targetNode.isEqualNode(wheelElement); 3179 }); 3180 LOG_WITH_STREAM(ScrollLatching, stream << "Page::removeLatchingStateForTarget() - new state " << m_latchingState); 3144 ScrollLatchingController& Page::scrollLatchingController() 3145 { 3146 if (!m_scrollLatchingController) 3147 m_scrollLatchingController = makeUnique<ScrollLatchingController>(); 3148 3149 return *m_scrollLatchingController; 3150 } 3151 3152 ScrollLatchingController* Page::scrollLatchingControllerIfExists() 3153 { 3154 return m_scrollLatchingController.get(); 3181 3155 } 3182 3156 #endif // ENABLE(WHEEL_EVENT_LATCHING) -
trunk/Source/WebCore/page/Page.h
r265623 r266333 132 132 class RenderObject; 133 133 class ResourceUsageOverlay; 134 class ScrollLatching State;134 class ScrollLatchingController; 135 135 class ScrollingCoordinator; 136 136 class ServicesOverlayController; … … 449 449 450 450 #if ENABLE(WHEEL_EVENT_LATCHING) 451 ScrollLatchingState* latchingState(); 452 const Vector<ScrollLatchingState>& latchingStateStack() const { return m_latchingState; } 453 void pushNewLatchingState(ScrollLatchingState&&); 454 void popLatchingState(); 455 void resetLatchingState(); 456 void removeLatchingStateForTarget(Element&); 451 ScrollLatchingController& scrollLatchingController(); 452 ScrollLatchingController* scrollLatchingControllerIfExists(); 457 453 #endif // ENABLE(WHEEL_EVENT_LATCHING) 458 454 … … 1039 1035 std::unique_ptr<PerformanceLogging> m_performanceLogging; 1040 1036 #if ENABLE(WHEEL_EVENT_LATCHING) 1041 Vector<ScrollLatchingState> m_latchingState;1037 std::unique_ptr<ScrollLatchingController> m_scrollLatchingController; 1042 1038 #endif 1043 1039 #if PLATFORM(MAC) && (ENABLE(SERVICE_CONTROLS) || ENABLE(TELEPHONE_NUMBER_DETECTION)) -
trunk/Source/WebCore/page/mac/EventHandlerMac.mm
r266292 r266333 60 60 #import "ScreenProperties.h" 61 61 #import "ScrollAnimator.h" 62 #import "ScrollLatching State.h"62 #import "ScrollLatchingController.h" 63 63 #import "ScrollableArea.h" 64 64 #import "Scrollbar.h" … … 785 785 return box.layer(); 786 786 } 787 787 788 // FIXME: This could be written in terms of ScrollableArea::enclosingScrollableArea(). 788 789 static ContainerNode* findEnclosingScrollableContainer(ContainerNode* node, const PlatformWheelEvent& wheelEvent) 789 790 { … … 818 819 } 819 820 820 static bool deltaIsPredominantlyVertical(float deltaX, float deltaY)821 {822 return std::abs(deltaY) > std::abs(deltaX);823 }824 825 static bool scrolledToEdgeInDominantDirection(const ContainerNode& container, const ScrollableArea& area, float deltaX, float deltaY)826 {827 if (!container.renderer())828 return true;829 830 if (!area.canHaveScrollbars())831 return true;832 833 const RenderStyle& style = container.renderer()->style();834 835 if (!deltaIsPredominantlyVertical(deltaX, deltaY) && deltaX) {836 if (style.overflowX() == Overflow::Hidden)837 return true;838 839 if (deltaX < 0)840 return area.scrolledToRight();841 842 return area.scrolledToLeft();843 }844 845 if (style.overflowY() == Overflow::Hidden)846 return true;847 848 if (deltaY < 0)849 return area.scrolledToBottom();850 851 return area.scrolledToTop();852 }853 854 821 static WeakPtr<ScrollableArea> scrollableAreaForEventTarget(Element* eventTarget) 855 822 { … … 870 837 } 871 838 872 static bool latchingIsLockedToPlatformFrame(const Frame& frame)873 {874 auto* page = frame.page();875 if (!page)876 return false;877 878 ScrollLatchingState* latchedState = page->latchingState();879 if (!latchedState)880 return false;881 882 if (frameHasPlatformWidget(frame) && &frame != latchedState->frame())883 return true;884 885 return false;886 }887 888 static bool latchingIsLockedToAncestorOfThisFrame(const Frame& frame)889 {890 auto* page = frame.page();891 if (!page)892 return false;893 894 ScrollLatchingState* latchedState = page->latchingState();895 if (!latchedState || !latchedState->frame())896 return false;897 898 if (&frame == latchedState->frame())899 return false;900 901 for (Frame* ancestor = frame.tree().parent(); ancestor; ancestor = ancestor->tree().parent()) {902 if (ancestor == latchedState->frame())903 return true;904 }905 906 return false;907 }908 909 839 static WeakPtr<ScrollableArea> scrollableAreaForContainerNode(ContainerNode& container) 910 840 { … … 920 850 } 921 851 922 static bool latchedToFrameOrBody(ContainerNode& container) 923 { 924 // FIXME(106133): We might need to add or switch to is<HTMLDocumentElement> when this bug is fixed. 925 return is<HTMLFrameSetElement>(container) || is<HTMLBodyElement>(container); 926 } 927 928 void EventHandler::clearOrScheduleClearingLatchedStateIfNeeded(const PlatformWheelEvent& event) 929 { 930 if (!m_frame.isMainFrame()) 931 return; 932 933 // Platform does not provide an indication that it will switch from non-momentum to momentum scrolling 934 // when handling wheel events. 935 // Logic below installs a timer when non-momentum scrolling ends. If momentum scroll does not start within that interval, 936 // reset the latched state. If it does, stop the timer, leaving the latched state untouched. 937 if (!m_clearLatchingStateTimer.isActive()) { 938 if (event.isEndOfNonMomentumScroll()) { 939 LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::clearOrScheduleClearingLatchedStateIfNeeded() - event" << event << ", scheduling clear timer"); 940 m_clearLatchingStateTimer.startOneShot(resetLatchedStateTimeout); 941 } 942 } else { 943 // If another wheel event scrolling starts, stop the timer manually, and reset the latched state immediately. 944 if (event.shouldConsiderLatching()) { 945 LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::clearOrScheduleClearingLatchedStateIfNeeded() - event" << event << ", timer pending, another scroll starting"); 946 if (auto* page = m_frame.page()) 947 page->resetLatchingState(); 948 m_clearLatchingStateTimer.stop(); 949 } else if (event.isTransitioningToMomentumScroll()) { 950 // Wheel events machinary is transitioning to momentum scrolling, so no need to reset latched state. Stop the timer. 951 m_clearLatchingStateTimer.stop(); 952 } 953 } 954 } 955 956 void EventHandler::determineWheelEventTarget(const PlatformWheelEvent& wheelEvent, const HitTestResult& result, RefPtr<Element>& wheelEventTarget, RefPtr<ContainerNode>& scrollableContainer, WeakPtr<ScrollableArea>& scrollableArea, bool& isOverWidget) 957 { 958 clearOrScheduleClearingLatchedStateIfNeeded(wheelEvent); 959 852 void EventHandler::determineWheelEventTarget(const PlatformWheelEvent& wheelEvent, RefPtr<Element>& wheelEventTarget, WeakPtr<ScrollableArea>& scrollableArea, bool& isOverWidget) 853 { 960 854 auto* page = m_frame.page(); 961 855 if (!page) … … 963 857 964 858 auto* view = m_frame.view(); 965 966 859 if (!view) 967 scrollableContainer = wheelEventTarget; 860 return; 861 862 if (eventTargetIsPlatformWidget(wheelEventTarget.get())) 863 scrollableArea = scrollableAreaForEventTarget(wheelEventTarget.get()); 968 864 else { 969 if (eventTargetIsPlatformWidget(wheelEventTarget.get())) { 970 scrollableContainer = wheelEventTarget; 971 scrollableArea = scrollableAreaForEventTarget(wheelEventTarget.get()); 972 } else { 973 scrollableContainer = findEnclosingScrollableContainer(wheelEventTarget.get(), wheelEvent); 974 if (scrollableContainer && !is<HTMLIFrameElement>(wheelEventTarget)) 975 scrollableArea = scrollableAreaForContainerNode(*scrollableContainer); 976 else { 977 // FIXME: Why does this assume the body? What if we hit an iframe inside an overflow:scroll? 978 scrollableContainer = view->frame().document()->bodyOrFrameset(); 979 scrollableArea = makeWeakPtr(static_cast<ScrollableArea&>(*view)); 980 } 981 982 LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::determineWheelEventTarget() - event" << wheelEvent << " found scrollableContainer" << ValueOrNull(scrollableContainer.get()) << " scrollableArea " << (scrollableArea ? scrollableArea.get() : nullptr)); 983 } 984 } 865 auto* scrollableContainer = findEnclosingScrollableContainer(wheelEventTarget.get(), wheelEvent); 866 if (scrollableContainer) 867 scrollableArea = scrollableAreaForContainerNode(*scrollableContainer); 868 else 869 scrollableArea = makeWeakPtr(static_cast<ScrollableArea&>(*view)); 870 } 871 872 LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::determineWheelEventTarget() - event" << wheelEvent << " found scrollableArea " << ValueOrNull(scrollableArea.get()) << ", latching state is " << page->scrollLatchingController()); 985 873 986 874 if (scrollableArea && page->isMonitoringWheelEvents()) 987 875 scrollableArea->scrollAnimator().setWheelEventTestMonitor(page->wheelEventTestMonitor()); 988 876 989 auto* latchingState = page->latchingState(); 990 if (wheelEvent.shouldConsiderLatching()) { 991 if (scrollableContainer && scrollableArea) { 992 bool startingAtScrollLimit = scrolledToEdgeInDominantDirection(*scrollableContainer, *scrollableArea.get(), wheelEvent.deltaX(), wheelEvent.deltaY()); 993 if (!startingAtScrollLimit) { 994 ScrollLatchingState latchingState; 995 latchingState.setWheelEventElement(wheelEventTarget.get()); 996 latchingState.setFrame(&m_frame); 997 latchingState.setScrollableContainer(scrollableContainer.get()); 998 latchingState.setWidgetIsLatched(result.isOverWidget()); 999 page->pushNewLatchingState(WTFMove(latchingState)); 1000 1001 page->wheelEventDeltaFilter()->beginFilteringDeltas(); 1002 isOverWidget = result.isOverWidget(); 1003 } 1004 1005 LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::determineWheelEventTarget() - considering latching for " << wheelEvent << ", at scroll limit " << startingAtScrollLimit << ", latching state " << page->latchingStateStack()); 1006 } 1007 } else if (wheelEvent.shouldResetLatching()) { 1008 clearLatchedState(); 1009 LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::determineWheelEventTarget() - reset latching for event " << wheelEvent << " latching state " << page->latchingStateStack()); 1010 } 1011 1012 // FIXME: This can use a stale laching state, before we just pushed or cleared. 1013 if (!wheelEvent.shouldResetLatching() && latchingState && latchingState->wheelEventElement()) { 1014 if (latchingIsLockedToPlatformFrame(m_frame)) 1015 return; 1016 1017 if (latchingIsLockedToAncestorOfThisFrame(m_frame)) 1018 return; 1019 1020 wheelEventTarget = latchingState->wheelEventElement(); 1021 isOverWidget = latchingState->widgetIsLatched(); 1022 scrollableContainer = latchingState->scrollableContainer(); 1023 1024 if (scrollableContainer) { 1025 if (!latchedToFrameOrBody(*scrollableContainer) && !latchingState->widgetIsLatched()) 1026 scrollableArea = scrollableAreaForContainerNode(*scrollableContainer); 1027 } 1028 } 877 if (wheelEvent.shouldResetLatching() || wheelEvent.isNonGestureEvent()) 878 return; 879 880 if (m_frame.isMainFrame() && wheelEvent.isGestureStart()) 881 page->wheelEventDeltaFilter()->beginFilteringDeltas(); 882 883 page->scrollLatchingController().updateAndFetchLatchingStateForFrame(m_frame, wheelEvent, wheelEventTarget, scrollableArea, isOverWidget); 1029 884 } 1030 885 … … 1048 903 } 1049 904 1050 static FrameView* frameViewForLatchingState(Frame& frame, const ScrollLatchingState& latchingState)1051 { 1052 if (latchingIsLockedToPlatformFrame(frame))1053 return frame.view(); 1054 1055 return latchingState.frame() ? latchingState.frame()->view() : frame.view();1056 } 1057 1058 bool EventHandler::processWheelEventForScrolling(const PlatformWheelEvent& wheelEvent, ContainerNode* scrollableContainer, const WeakPtr<ScrollableArea>& scrollableArea) 1059 { 1060 LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::processWheelEventForScrolling " << wheelEvent << " - scrollableContainer " << scrollableContainer << " scrollableArea " << scrollableArea.get() << " use latched element " << wheelEvent.useLatchedEventElement()); 905 bool EventHandler::processWheelEventForScrolling(const PlatformWheelEvent& wheelEvent, const WeakPtr<ScrollableArea>& scrollableArea) 906 { 907 LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::processWheelEventForScrolling " << wheelEvent << " - scrollableArea " << ValueOrNull(scrollableArea.get()) << " use latched element " << wheelEvent.useLatchedEventElement()); 908 909 #if ASSERT_ENABLED 910 { 911 // FIXME: Clean up processWheelEventForScrollSnap() and then turn this into an early return. 912 WeakPtr<ScrollableArea> latchedScrollableArea; 913 ASSERT(m_frame.page()->scrollLatchingController().latchingAllowsScrollingInFrame(m_frame, latchedScrollableArea)); 914 } 915 #endif 1061 916 1062 917 Ref<Frame> protectedFrame(m_frame); 918 919 if (!m_frame.page()) 920 return false; 1063 921 1064 922 FrameView* view = m_frame.view(); … … 1067 925 return false; 1068 926 1069 const auto* latchingState = m_frame.page() ? m_frame.page()->latchingState() : nullptr; 1070 1071 if (wheelEvent.useLatchedEventElement() && !latchingIsLockedToAncestorOfThisFrame(m_frame) && latchingState && latchingState->scrollableContainer()) { 927 // We handle non-view scrollableAreas elsewhere. 928 if (wheelEvent.useLatchedEventElement() && scrollableArea) { 1072 929 m_isHandlingWheelEvent = false; 1073 930 1074 LOG_WITH_STREAM(ScrollLatching, stream << " latching state " << *latchingState); 1075 1076 // WebKit2 code path 1077 if (!frameHasPlatformWidget(m_frame) && scrollableContainer == latchingState->scrollableContainer() && scrollableArea && view != scrollableArea) { 1078 // If we did not start at the scroll limit, do not pass the event on to be handled by enclosing scrollable regions. 1079 LOG_WITH_STREAM(Scrolling, stream << "EventHandler " << this << " processWheelEventForScrolling - latched to " << scrollableArea.get() << " and not propagating"); 931 LOG_WITH_STREAM(ScrollLatching, stream << " latching state " << m_frame.page()->scrollLatchingController()); 932 933 if (!frameHasPlatformWidget(m_frame) && scrollableArea != view) { 934 LOG_WITH_STREAM(Scrolling, stream << " latched to non-view scroller " << scrollableArea << " and not propagating"); 1080 935 return true; 1081 936 } 1082 937 1083 // FIXME: This set 'view' to a FrameView that is not this EventHandler's FrameView, which then gets scrolled from here, which is wrong. 1084 view = frameViewForLatchingState(m_frame, *latchingState); 1085 ASSERT(view); 938 LOG_WITH_STREAM(ScrollLatching, stream << " sending to view " << *view); 1086 939 1087 940 bool didHandleWheelEvent = view->wheelEvent(wheelEvent); 1088 if (scrollableContainer == latchingState->scrollableContainer()) {1089 // If we are just starting a scroll event, and have nowhere left to scroll, allow1090 // the enclosing frame to handle the scroll.1091 didHandleWheelEvent = true;1092 }1093 1094 941 // If the platform widget is handling the event, we always want to return false. 1095 if ( scrollableArea == view &&view->platformWidget())942 if (view->platformWidget()) 1096 943 didHandleWheelEvent = false; 1097 944 945 LOG_WITH_STREAM(ScrollLatching, stream << " EventHandler::processWheelEventForScrolling returning " << didHandleWheelEvent); 1098 946 return didHandleWheelEvent; 1099 947 } … … 1104 952 } 1105 953 1106 bool EventHandler::platformCompletePlatformWidgetWheelEvent(const PlatformWheelEvent& wheelEvent, const Widget& widget, ContainerNode* scrollableContainer)954 bool EventHandler::platformCompletePlatformWidgetWheelEvent(const PlatformWheelEvent& wheelEvent, const Widget& widget, const WeakPtr<ScrollableArea>& scrollableArea) 1107 955 { 1108 956 // WebKit1: Prevent multiple copies of the scrollWheel event from being sent to the NSScrollView widget. … … 1110 958 return true; 1111 959 1112 const auto* latchingState = m_frame.page() ? m_frame.page()->latchingState() : nullptr;1113 if (!latchingState)1114 return false; 1115 1116 if ( wheelEvent.useLatchedEventElement() && latchingState->scrollableContainer() && scrollableContainer == latchingState->scrollableContainer())1117 return true;1118 1119 return false;960 if (!m_frame.page()) 961 return false; 962 963 WeakPtr<ScrollableArea> latchedScrollableArea; 964 if (!m_frame.page()->scrollLatchingController().latchingAllowsScrollingInFrame(m_frame, latchedScrollableArea)) 965 return false; 966 967 return wheelEvent.useLatchedEventElement() && latchedScrollableArea && scrollableArea == latchedScrollableArea; 1120 968 } 1121 969 … … 1130 978 1131 979 #if ENABLE(CSS_SCROLL_SNAP) 1132 if ( ScrollAnimator* scrollAnimator = scrollableArea->existingScrollAnimator())980 if (auto* scrollAnimator = scrollableArea->existingScrollAnimator()) 1133 981 scrollAnimator->processWheelEventForScrollSnap(wheelEvent); 1134 982 #endif -
trunk/Source/WebCore/page/scrolling/ScrollingTreeLatchingController.cpp
r266262 r266333 37 37 namespace WebCore { 38 38 39 // See also EventHandlerMac.cpp39 // See also ScrollLatchingController.cpp 40 40 static const Seconds resetLatchedStateTimeout { 100_ms }; 41 41 … … 48 48 49 49 LockHolder locker(m_latchedNodeMutex); 50 if (wheelEvent. shouldConsiderLatching() && m_latchedNodeID && !latchedNodeIsRelevant()) {50 if (wheelEvent.isGestureStart() && m_latchedNodeID && !latchedNodeIsRelevant()) { 51 51 LOG_WITH_STREAM(ScrollLatching, stream << "ScrollingTreeLatchingController " << this << " receivedWheelEvent - " << (MonotonicTime::now() - m_lastLatchedNodeInterationTime).milliseconds() << "ms since last event, clearing latched node"); 52 52 m_latchedNodeID.reset(); … … 88 88 } 89 89 90 if (wheelEvent.delta().isZero() || !wheelEvent. shouldConsiderLatching())90 if (wheelEvent.delta().isZero() || !wheelEvent.isGestureStart()) 91 91 return; 92 92 -
trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp
r266292 r266333 64 64 bool ThreadedScrollingTree::handleWheelEventAfterMainThread(const PlatformWheelEvent& wheelEvent, ScrollingNodeID targetNodeID) 65 65 { 66 LOG_WITH_STREAM(Scrolling, stream << "ThreadedScrollingTree::handleWheelEventAfterMainThread " << wheelEvent); 66 67 SetForScope<bool> disallowLatchingScope(m_allowLatching, false); 67 68 -
trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm
r264908 r266333 168 168 // FIXME: We should find a way to share some of the code from newGestureIsStarting(), isAlreadyPinnedInDirectionOfGesture(), 169 169 // allowsVerticalStretching(), and allowsHorizontalStretching() with the implementation in ScrollAnimatorMac. 170 // This is also the same as PlatformWheelEvent::shouldConsiderLatching().171 static bool newGestureIsStarting(const PlatformWheelEvent& wheelEvent)172 {173 return wheelEvent.phase() == PlatformWheelEventPhaseMayBegin || wheelEvent.phase() == PlatformWheelEventPhaseBegan;174 }175 176 170 bool ScrollingTreeScrollingNodeDelegateMac::isAlreadyPinnedInDirectionOfGesture(const PlatformWheelEvent& wheelEvent, ScrollEventAxis axis) const 177 171 { … … 201 195 case ScrollElasticityAutomatic: { 202 196 bool scrollbarsAllowStretching = hasEnabledHorizontalScrollbar() || !hasEnabledVerticalScrollbar(); 203 bool eventPreventsStretching = newGestureIsStarting(wheelEvent) && isAlreadyPinnedInDirectionOfGesture(wheelEvent, ScrollEventAxis::Horizontal);197 bool eventPreventsStretching = wheelEvent.isGestureStart() && isAlreadyPinnedInDirectionOfGesture(wheelEvent, ScrollEventAxis::Horizontal); 204 198 return scrollbarsAllowStretching && !eventPreventsStretching; 205 199 } … … 223 217 case ScrollElasticityAutomatic: { 224 218 bool scrollbarsAllowStretching = hasEnabledVerticalScrollbar() || !hasEnabledHorizontalScrollbar(); 225 bool eventPreventsStretching = newGestureIsStarting(wheelEvent) && isAlreadyPinnedInDirectionOfGesture(wheelEvent, ScrollEventAxis::Vertical);219 bool eventPreventsStretching = wheelEvent.isGestureStart() && isAlreadyPinnedInDirectionOfGesture(wheelEvent, ScrollEventAxis::Vertical); 226 220 return scrollbarsAllowStretching && !eventPreventsStretching; 227 221 } -
trunk/Source/WebCore/platform/PlatformWheelEvent.h
r262294 r266333 152 152 #if ENABLE(ASYNC_SCROLLING) 153 153 bool useLatchedEventElement() const; 154 bool shouldConsiderLatching() const; 154 bool isGestureStart() const; 155 bool isGestureContinuation() const; // The fingers-down part of the gesture excluding momentum. 155 156 bool shouldResetLatching() const; 157 bool isNonGestureEvent() const; 156 158 bool isEndOfMomentumScroll() const; 157 159 #else … … 211 213 } 212 214 213 inline bool PlatformWheelEvent::shouldConsiderLatching() const 214 { 215 // FIXME: This should disallow latching if the delta is zero. 215 inline bool PlatformWheelEvent::isGestureStart() const 216 { 216 217 return m_phase == PlatformWheelEventPhaseBegan || m_phase == PlatformWheelEventPhaseMayBegin; 217 218 } 218 219 220 inline bool PlatformWheelEvent::isGestureContinuation() const 221 { 222 return m_phase == PlatformWheelEventPhaseChanged; 223 } 224 219 225 inline bool PlatformWheelEvent::shouldResetLatching() const 220 226 { 221 return m_phase == PlatformWheelEventPhaseCancelled || m_phase == PlatformWheelEventPhaseMayBegin || isEndOfMomentumScroll(); 227 return m_phase == PlatformWheelEventPhaseCancelled || m_phase == PlatformWheelEventPhaseMayBegin || (m_phase == PlatformWheelEventPhaseNone && m_momentumPhase == PlatformWheelEventPhaseNone) || isEndOfMomentumScroll(); 228 } 229 230 inline bool PlatformWheelEvent::isNonGestureEvent() const 231 { 232 return m_phase == PlatformWheelEventPhaseNone && m_momentumPhase == PlatformWheelEventPhaseNone; 222 233 } 223 234
Note: See TracChangeset
for help on using the changeset viewer.