Changeset 284738 in webkit
- Timestamp:
- Oct 22, 2021 8:25:23 PM (9 months ago)
- Location:
- trunk
- Files:
-
- 1 added
- 16 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp (modified) (1 diff)
-
Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h (modified) (1 diff)
-
Source/WebCore/page/scrolling/ScrollingCoordinator.h (modified) (1 diff)
-
Source/WebCore/page/scrolling/ScrollingStateScrollingNode.cpp (modified) (1 diff)
-
Source/WebCore/page/scrolling/ScrollingStateScrollingNode.h (modified) (1 diff)
-
Source/WebCore/page/scrolling/ScrollingStateTree.cpp (modified) (1 diff)
-
Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.cpp (modified) (2 diffs)
-
Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp (modified) (2 diffs)
-
Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm (modified) (1 diff)
-
Source/WebCore/rendering/RenderLayerCompositor.cpp (modified) (3 diffs)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (modified) (6 diffs)
-
Tools/TestWebKitAPI/Tests/mac/ScrollingCoordinatorTests.mm (added)
-
Tools/TestWebKitAPI/cocoa/TestWKWebView.h (modified) (1 diff)
-
Tools/TestWebKitAPI/cocoa/TestWKWebView.mm (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r284732 r284738 1 2021-10-22 Simon Fraser <simon.fraser@apple.com> 2 3 Content offset in this codepen when switching tabs 4 https://bugs.webkit.org/show_bug.cgi?id=231989 5 6 Reviewed by Tim Horton. 7 8 New baselines. 9 10 * tiled-drawing/scrolling/clamp-out-of-bounds-scrolls-expected.txt: 11 * tiled-drawing/scrolling/scrolling-tree-after-scroll-expected.txt: 12 1 13 2021-10-22 Eric Hutchison <ehutchison@apple.com> 2 14 -
trunk/Source/WebCore/ChangeLog
r284737 r284738 1 2021-10-22 Simon Fraser <simon.fraser@apple.com> 2 3 Content offset in this codepen when switching tabs 4 https://bugs.webkit.org/show_bug.cgi?id=231989 5 6 Reviewed by Tim Horton. 7 8 There were two problems that occurred with async-scrollable iframes when their associated 9 WKWebView was removed and re-added to the view hierarchy (e.g. when switching tabs). 10 These resulted in misplaced position:fixed content, and the first user scroll in the 11 iframe causing the scroll position to jump back to the top. 12 13 The positon:fixed issue was caused by an ordering problem in 14 ScrollingTreeFrameScrollingNode::commitStateBeforeChildren() which resulted in the layout 15 viewport being computed incorrectly; we called updateViewportForCurrentScrollPosition() 16 before setting the min and max scroll position, so we'd always clamp the layout viewport to 17 a location of 0,0. 18 19 The second scroll position reset issue was caused by the ScrollingTreeScrollingNode's 20 m_currentScrollPosition reverting to a stale after re-attaching the iframe's scrolling 21 subtree. ScrollingTreeScrollingNode::commitStateBeforeChildren() has code to set 22 m_currentScrollPosition from the state tree node's scroll position on first commit; 23 the issue was that ScrollingStateScrollingNode's scrollPosition() was not updated on every 24 scroll, only when something triggered a scrolling tree commit. 25 26 Fix by updating ScrollingStateScrollingNode's scrollPosition() for frame nodes on detach 27 (overflow scrolling nodes have their scroll positions updated eagerly). 28 29 Both fixes are tested by the ScrollingCoordinatorTests.ScrollingTreeAfterDetachReattach API test. 30 31 * page/scrolling/AsyncScrollingCoordinator.cpp: 32 (WebCore::AsyncScrollingCoordinator::frameViewWillBeDetached): 33 * page/scrolling/AsyncScrollingCoordinator.h: 34 * page/scrolling/ScrollingCoordinator.h: 35 (WebCore::ScrollingCoordinator::frameViewWillBeDetached): 36 * page/scrolling/ScrollingStateScrollingNode.cpp: 37 (WebCore::ScrollingStateScrollingNode::hasScrollPositionRequest const): 38 * page/scrolling/ScrollingStateScrollingNode.h: 39 * page/scrolling/ScrollingStateTree.cpp: 40 (WebCore::ScrollingStateTree::insertNode): 41 * page/scrolling/ScrollingTreeFrameScrollingNode.cpp: 42 (WebCore::ScrollingTreeFrameScrollingNode::commitStateBeforeChildren): 43 * page/scrolling/ScrollingTreeScrollingNode.cpp: 44 (WebCore::ScrollingTreeScrollingNode::commitStateBeforeChildren): 45 (WebCore::ScrollingTreeScrollingNode::dumpProperties const): 46 * page/scrolling/mac/ScrollingCoordinatorMac.mm: 47 (WebCore::ScrollingCoordinatorMac::commitTreeStateIfNeeded): 48 * rendering/RenderLayerCompositor.cpp: 49 (WebCore::RenderLayerCompositor::detachRootLayer): 50 1 51 2021-10-22 Eric Carlson <eric.carlson@apple.com> 2 52 -
trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp
r284685 r284738 185 185 } 186 186 187 void AsyncScrollingCoordinator::frameViewWillBeDetached(FrameView& frameView) 188 { 189 ASSERT(isMainThread()); 190 ASSERT(m_page); 191 192 if (!coordinatesScrollingForFrameView(frameView)) 193 return; 194 195 auto* scrollingNode = downcast<ScrollingStateScrollingNode>(m_scrollingStateTree->stateNodeForID(frameView.scrollingNodeID())); 196 if (!scrollingNode) 197 return; 198 199 scrollingNode->setScrollPosition(frameView.scrollPosition()); 200 } 201 187 202 void AsyncScrollingCoordinator::updateIsMonitoringWheelEventsForFrameView(const FrameView& frameView) 188 203 { -
trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h
r284534 r284738 102 102 WEBCORE_EXPORT void frameViewVisualViewportChanged(FrameView&) override; 103 103 WEBCORE_EXPORT void frameViewEventTrackingRegionsChanged(FrameView&) override; 104 WEBCORE_EXPORT void frameViewWillBeDetached(FrameView&) override; 104 105 105 106 WEBCORE_EXPORT bool requestScrollPositionUpdate(ScrollableArea&, const ScrollPosition&, ScrollType, ScrollClamping) final; -
trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h
r284534 r284738 97 97 virtual void frameViewRootLayerDidChange(FrameView&); 98 98 99 virtual void frameViewWillBeDetached(FrameView&) { } 100 99 101 // Traverses the scrolling tree, setting layer positions to represent the current scrolled state. 100 102 virtual void applyScrollingTreeLayerPositions() { } -
trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.cpp
r284685 r284738 207 207 } 208 208 209 bool ScrollingStateScrollingNode::hasScrollPositionRequest() const 210 { 211 return hasChangedProperty(Property::RequestedScrollPosition) && m_requestedScrollData.requestType == ScrollRequestType::PositionUpdate; 212 } 213 209 214 void ScrollingStateScrollingNode::setIsMonitoringWheelEvents(bool isMonitoringWheelEvents) 210 215 { -
trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.h
r284685 r284738 79 79 WEBCORE_EXPORT void setRequestedScrollData(const RequestedScrollData&); 80 80 81 WEBCORE_EXPORT bool hasScrollPositionRequest() const; 82 81 83 bool isMonitoringWheelEvents() const { return m_isMonitoringWheelEvents; } 82 84 WEBCORE_EXPORT void setIsMonitoringWheelEvents(bool); -
trunk/Source/WebCore/page/scrolling/ScrollingStateTree.cpp
r284685 r284738 177 177 if (parentID) { 178 178 if (auto unparentedNode = m_unparentedNodes.take(newNodeID)) { 179 LOG_WITH_STREAM(ScrollingTree, stream << "ScrollingStateTree " << this << " insertNode " << newNodeID << " getting node from unparented nodes");179 LOG_WITH_STREAM(ScrollingTree, stream << "ScrollingStateTree " << this << " insertNode reattaching node " << newNodeID); 180 180 newNode = unparentedNode.get(); 181 181 nodeWasReattachedRecursive(*unparentedNode); -
trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.cpp
r284685 r284738 73 73 m_fixedElementsLayoutRelativeToFrame = state.fixedElementsLayoutRelativeToFrame(); 74 74 75 if (state.hasChangedProperty(ScrollingStateNode::Property::LayoutViewport)) {75 if (state.hasChangedProperty(ScrollingStateNode::Property::LayoutViewport)) 76 76 m_layoutViewport = state.layoutViewport(); 77 updateViewportForCurrentScrollPosition({ });78 }79 77 80 78 if (state.hasChangedProperty(ScrollingStateNode::Property::MinLayoutViewportOrigin)) … … 86 84 if (state.hasChangedProperty(ScrollingStateNode::Property::OverrideVisualViewportSize)) 87 85 m_overrideVisualViewportSize = state.overrideVisualViewportSize(); 86 87 if (state.hasChangedProperty(ScrollingStateNode::Property::LayoutViewport)) { 88 // This requires that minLayoutViewportOrigin and maxLayoutViewportOrigin have been updated. 89 updateViewportForCurrentScrollPosition({ }); 90 } 88 91 } 89 92 -
trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp
r284685 r284738 68 68 if (state.hasChangedProperty(ScrollingStateNode::Property::ScrollPosition)) { 69 69 m_lastCommittedScrollPosition = state.scrollPosition(); 70 if (m_isFirstCommit && !state.has ChangedProperty(ScrollingStateNode::Property::RequestedScrollPosition))70 if (m_isFirstCommit && !state.hasScrollPositionRequest()) 71 71 m_currentScrollPosition = m_lastCommittedScrollPosition; 72 72 } … … 337 337 ts.dumpProperty("last committed scroll position", m_lastCommittedScrollPosition); 338 338 339 if (m_scrollOrigin != IntPoint()) 339 if (!m_currentScrollPosition.isZero()) 340 ts.dumpProperty("scroll position", m_currentScrollPosition); 341 342 if (!m_scrollOrigin.isZero()) 340 343 ts.dumpProperty("scroll origin", m_scrollOrigin); 341 344 -
trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm
r284685 r284738 115 115 return; 116 116 117 LOG_WITH_STREAM(ScrollingTree, stream << scrollingStateTreeAsText(debugScrollingStateTreeAsTextBehaviors));117 LOG_WITH_STREAM(ScrollingTree, stream << "ScrollingCoordinatorMac::commitTreeState: state tree " << scrollingStateTreeAsText(debugScrollingStateTreeAsTextBehaviors)); 118 118 119 119 auto stateTree = scrollingStateTree()->commit(LayerRepresentation::PlatformLayerRepresentation); -
trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp
r284093 r284738 4245 4245 return; 4246 4246 4247 if (auto* scrollingCoordinator = this->scrollingCoordinator()) 4248 scrollingCoordinator->frameViewWillBeDetached(m_renderView.frameView()); 4249 4247 4250 switch (m_rootLayerAttachment) { 4248 4251 case RootLayerAttachedViaEnclosingFrame: { … … 4258 4261 4259 4262 if (auto frameRootScrollingNodeID = m_renderView.frameView().scrollingNodeID()) { 4260 if (auto* scrollingCoordinator = this->scrollingCoordinator()) 4263 if (auto* scrollingCoordinator = this->scrollingCoordinator()) { 4264 scrollingCoordinator->frameViewWillBeDetached(m_renderView.frameView()); 4261 4265 scrollingCoordinator->unparentNode(frameRootScrollingNodeID); 4266 } 4262 4267 } 4263 4268 break; … … 4265 4270 case RootLayerAttachedViaChromeClient: { 4266 4271 auto& frame = m_renderView.frameView().frame(); 4272 4273 if (auto* scrollingCoordinator = this->scrollingCoordinator()) 4274 scrollingCoordinator->frameViewWillBeDetached(m_renderView.frameView()); 4275 4267 4276 page().chrome().client().attachRootGraphicsLayer(frame, nullptr); 4268 4277 } -
trunk/Tools/ChangeLog
r284721 r284738 1 2021-10-22 Simon Fraser <simon.fraser@apple.com> 2 3 Content offset in this codepen when switching tabs 4 https://bugs.webkit.org/show_bug.cgi?id=231989 5 6 Reviewed by Tim Horton. 7 8 API test that scrolls an iframe via wheel events, then detached and re-attaches the view. 9 10 The two wheel scrolls are necessary to exercise the "stale ScrollingStateScrollingNode 11 scroll position" issue. 12 13 The scrolling tree dumps validate the layout viewport part of the fix. 14 15 Also correct some functions where the sense of 'isWaitingForJavaScript' was flipped. 16 17 * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: 18 * TestWebKitAPI/Tests/mac/ScrollingCoordinatorTests.mm: Added. 19 (TestWebKitAPI::synthesizeWheelEvents): 20 (TestWebKitAPI::waitForScrollEventAndReturnScrollY): 21 (TestWebKitAPI::scrollingTreeElidingLastCommittedScrollPosition): 22 (TestWebKitAPI::TEST): 23 * TestWebKitAPI/cocoa/TestWKWebView.mm: 24 (-[WKWebView objectByEvaluatingJavaScript:]): 25 (-[WKWebView objectByEvaluatingJavaScriptWithUserGesture:]): 26 (-[WKWebView objectByCallingAsyncFunction:withArguments:error:]): 27 1 28 2021-10-22 Ryan Haddad <ryanhaddad@apple.com> 2 29 -
trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
r284685 r284738 87 87 0F5651F71FCE4DDC00310FBC /* NoHistoryItemScrollToFragment.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0F5651F61FCE4DDB00310FBC /* NoHistoryItemScrollToFragment.mm */; }; 88 88 0F5651F91FCE513500310FBC /* scroll-to-anchor.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 0F5651F81FCE50E800310FBC /* scroll-to-anchor.html */; }; 89 0FEFAF64271FC2CD005704D7 /* ScrollingCoordinatorTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0FEFAF63271FC2CD005704D7 /* ScrollingCoordinatorTests.mm */; }; 89 90 0FF1134E22D68679009A81DA /* ScrollViewScrollabilityTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0FF1134D22D68679009A81DA /* ScrollViewScrollabilityTests.mm */; }; 90 91 115EB3431EE0BA03003C2C0A /* ViewportSizeForViewportUnits.mm in Sources */ = {isa = PBXBuildFile; fileRef = 115EB3421EE0B720003C2C0A /* ViewportSizeForViewportUnits.mm */; }; … … 1862 1863 0FE447971B76F1E3009498EB /* ParkingLot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParkingLot.cpp; sourceTree = "<group>"; }; 1863 1864 0FEAE3671B7D19CB00CE17F2 /* Condition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Condition.cpp; sourceTree = "<group>"; }; 1865 0FEFAF63271FC2CD005704D7 /* ScrollingCoordinatorTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollingCoordinatorTests.mm; sourceTree = "<group>"; }; 1864 1866 0FF1134D22D68679009A81DA /* ScrollViewScrollabilityTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollViewScrollabilityTests.mm; sourceTree = "<group>"; }; 1865 1867 0FFC45A41B73EBE20085BD62 /* Lock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Lock.cpp; sourceTree = "<group>"; }; … … 3096 3098 F44A531021B8976900DBB99C /* InstanceMethodSwizzler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = InstanceMethodSwizzler.mm; path = ../TestRunnerShared/cocoa/InstanceMethodSwizzler.mm; sourceTree = "<group>"; }; 3097 3099 F44A7D1F268D5C6900B49BB8 /* ImageAnalysisTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ImageAnalysisTests.mm; sourceTree = "<group>"; }; 3098 F44A9AF52649BBDD00E7CB16 /* ImmediateActionTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImmediateActionTests.h; sourceTree = "<group>"; };3099 3100 F44A9AF62649BBDD00E7CB16 /* ImmediateActionTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ImmediateActionTests.mm; sourceTree = "<group>"; }; 3100 3101 F44C79FB20F9E50C0014478C /* ParserYieldTokenPlugIn.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ParserYieldTokenPlugIn.mm; sourceTree = "<group>"; }; … … 4833 4834 9B4F8FA3159D52B1002D9F94 /* HTMLCollectionNamedItem.mm */, 4834 4835 9B26FC6B159D061000CC3765 /* HTMLFormCollectionNamedItem.mm */, 4835 F44A9AF52649BBDD00E7CB16 /* ImmediateActionTests.h */,4836 4836 F44A9AF62649BBDD00E7CB16 /* ImmediateActionTests.mm */, 4837 4837 C507E8A614C6545B005D6B3B /* InspectorBar.mm */, … … 4853 4853 37C784DE197C8F2E0010A496 /* RenderedImageFromDOMNode.mm */, 4854 4854 3722C8681461E03E00C45D00 /* RenderedImageFromDOMRange.mm */, 4855 0FEFAF63271FC2CD005704D7 /* ScrollingCoordinatorTests.mm */, 4855 4856 261516D515B0E60500A2C201 /* SetAndUpdateCacheModel.mm */, 4856 4857 52B8CF9515868CF000281053 /* SetDocumentURI.mm */, … … 5851 5852 CDCFA7AA1E45183200C2433D /* SampleMap.cpp in Sources */, 5852 5853 CE0947372063223B003C9BA0 /* SchemeRegistry.mm in Sources */, 5854 0FEFAF64271FC2CD005704D7 /* ScrollingCoordinatorTests.mm in Sources */, 5853 5855 CDC0932B21C872C10030C4B0 /* ScrollingDoesNotPauseMedia.mm in Sources */, 5854 5856 7CCE7F121A411AE600447C4C /* ScrollPinningBehaviors.cpp in Sources */, -
trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h
r284685 r284738 140 140 - (void)sendClicksAtPoint:(NSPoint)pointInWindow numberOfClicks:(NSUInteger)numberOfClicks; 141 141 - (void)sendClickAtPoint:(NSPoint)pointInWindow; 142 - (void)wheelEventAtPoint:(CGPoint)pointInWindow wheelDelta:(CGSize)delta; 142 143 - (NSWindow *)hostWindow; 143 144 - (void)typeCharacter:(char)character modifiers:(NSEventModifierFlags)modifiers; -
trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm
r284685 r284738 205 205 - (id)objectByEvaluatingJavaScript:(NSString *)script 206 206 { 207 bool isWaitingForJavaScript= false;207 bool callbackComplete = false; 208 208 RetainPtr<id> evalResult; 209 209 [self _evaluateJavaScriptWithoutUserGesture:script completionHandler:[&] (id result, NSError *error) { 210 210 evalResult = result; 211 isWaitingForJavaScript= true;211 callbackComplete = true; 212 212 EXPECT_TRUE(!error); 213 213 if (error) 214 214 NSLog(@"Encountered error: %@ while evaluating script: %@", error, script); 215 215 }]; 216 TestWebKitAPI::Util::run(& isWaitingForJavaScript);216 TestWebKitAPI::Util::run(&callbackComplete); 217 217 return evalResult.autorelease(); 218 218 } … … 220 220 - (id)objectByEvaluatingJavaScriptWithUserGesture:(NSString *)script 221 221 { 222 bool isWaitingForJavaScript= false;222 bool callbackComplete = false; 223 223 RetainPtr<id> evalResult; 224 224 [self evaluateJavaScript:script completionHandler:[&] (id result, NSError *error) { 225 225 evalResult = result; 226 isWaitingForJavaScript= true;226 callbackComplete = true; 227 227 EXPECT_TRUE(!error); 228 228 if (error) 229 229 NSLog(@"Encountered error: %@ while evaluating script: %@", error, script); 230 230 }]; 231 TestWebKitAPI::Util::run(& isWaitingForJavaScript);231 TestWebKitAPI::Util::run(&callbackComplete); 232 232 return evalResult.autorelease(); 233 233 } … … 235 235 - (id)objectByCallingAsyncFunction:(NSString *)script withArguments:(NSDictionary *)arguments error:(NSError **)errorOut 236 236 { 237 bool isWaitingForJavaScript= false;237 bool callbackComplete = false; 238 238 if (errorOut) 239 239 *errorOut = nil; … … 244 244 evalResult = result; 245 245 strongError = error; 246 isWaitingForJavaScript= true;247 }]; 248 TestWebKitAPI::Util::run(& isWaitingForJavaScript);246 callbackComplete = true; 247 }]; 248 TestWebKitAPI::Util::run(&callbackComplete); 249 249 250 250 if (errorOut) … … 863 863 } 864 864 865 - (void)wheelEventAtPoint:(CGPoint)pointInWindow wheelDelta:(CGSize)delta 866 { 867 RetainPtr<CGEventRef> cgScrollEvent = adoptCF(CGEventCreateScrollWheelEvent(nullptr, kCGScrollEventUnitPixel, 2, delta.height, delta.width, 0)); 868 869 CGPoint locationInGlobalScreenCoordinates = [[self window] convertPointToScreen:pointInWindow]; 870 locationInGlobalScreenCoordinates.y = [[[NSScreen screens] objectAtIndex:0] frame].size.height - locationInGlobalScreenCoordinates.y; 871 CGEventSetLocation(cgScrollEvent.get(), locationInGlobalScreenCoordinates); 872 873 NSEvent* event = [NSEvent eventWithCGEvent:cgScrollEvent.get()]; 874 [self scrollWheel:event]; 875 } 876 865 877 - (NSWindow *)hostWindow 866 878 {
Note: See TracChangeset
for help on using the changeset viewer.