[iOS WK2] REGRESSION (r242687): Programmatic scroll of overflow scroll results in...
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 5 Apr 2019 05:18:17 +0000 (05:18 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 5 Apr 2019 05:18:17 +0000 (05:18 +0000)
commit8abe581a54ad55f468f25eb8d21a3dc13e192897
tree1a02cee242cab2737ea4609ea31a8b4cc7b3d094
parent67f9286458f9bfc05c16c227c3ac08da0a830f7b
[iOS WK2] REGRESSION (r242687): Programmatic scroll of overflow scroll results in bad rendering
https://bugs.webkit.org/show_bug.cgi?id=195584

Reviewed by Zalan Bujtas.

Source/WebCore:

Push data to the scrolling tree about whether an overflow:scroll scroll was programmatic, by having
RenderLayer::scrollToOffset() call into AsyncScrollingCoordinator::requestScrollPositionUpdate(),
just as we do for frames.

AsyncScrollingCoordinator::requestScrollPositionUpdate() is generalized to take any ScrollableArea.

Fix an assumption in the ScrollingTree that we only care about programmatic scrolls on the root node.
ScrollingTree::commitTreeState() no longer sets isHandlingProgrammaticScroll; instead,
callers of ScrollingTreeScrollingNode::scrollTo() pass a ScrollType. Commit functions pass
ScrollType::Programmatic when handling RequestedScrollPosition changes as necessary.

Programmatic scrolls need to get to the scrolling tree in the UI process so that we update
the tree's notion of scroll position, and trigger actual UIScrollView scrolls (layers may have
already been put in the right locations, but the UI process needs to know that a scroll happened).
However, we need to prevent notifications from programmatic scrolls getting back to the
web process, because this causes jumpiness. This is done via an early return in
RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll().

Tests: scrollingcoordinator/ios/programmatic-overflow-scroll.html
       scrollingcoordinator/ios/programmatic-page-scroll.html

* page/scrolling/AsyncScrollingCoordinator.cpp:
(WebCore::AsyncScrollingCoordinator::requestScrollPositionUpdate):
* page/scrolling/AsyncScrollingCoordinator.h:
* page/scrolling/ScrollingCoordinator.h:
(WebCore::ScrollingCoordinator::requestScrollPositionUpdate):
* page/scrolling/ScrollingTree.cpp:
(WebCore::ScrollingTree::commitTreeState):
(WebCore::ScrollingTree::isHandlingProgrammaticScroll): Deleted.
* page/scrolling/ScrollingTree.h:
(WebCore::ScrollingTree::isHandlingProgrammaticScroll const):
(WebCore::ScrollingTree::setIsHandlingProgrammaticScroll):
* page/scrolling/ScrollingTreeScrollingNode.cpp:
(WebCore::ScrollingTreeScrollingNode::scrollBy):
(WebCore::ScrollingTreeScrollingNode::scrollTo):
* page/scrolling/ScrollingTreeScrollingNode.h:
* page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
(WebCore::ScrollingTreeFrameScrollingNodeMac::commitStateAfterChildren):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::scrollToOffset):
(WebCore::RenderLayer::scrollingNodeID const):
* rendering/RenderLayer.h:
* rendering/RenderMarquee.cpp:
(WebCore::RenderMarquee::timerFired):

Source/WebKit:

Push data to the scrolling tree about whether an overflow:scroll scroll was programmatic, by having
RenderLayer::scrollToOffset() call into AsyncScrollingCoordinator::requestScrollPositionUpdate(),
just as we do for frames.

AsyncScrollingCoordinator::requestScrollPositionUpdate() is generalized to take any ScrollableArea.

Fix an assumption in the ScrollingTree that we only care about programmatic scrolls on the root node.
ScrollingTree::commitTreeState() no longer sets isHandlingProgrammaticScroll; instead,
callers of ScrollingTreeScrollingNode::scrollTo() pass a ScrollType. Commit functions pass
ScrollType::Programmatic when handling RequestedScrollPosition changes as necessary.

Programmatic scrolls need to get to the scrolling tree in the UI process so that we update
the tree's notion of scroll position, and trigger actual UIScrollView scrolls (layers may have
already been put in the right locations, but the UI process needs to know that a scroll happened).
However, we need to prevent notifications from programmatic scrolls getting back to the
web process, because this causes jumpiness. This is done via an early return in
RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll().

* UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp:
(WebKit::RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll):
* UIProcess/RemoteLayerTree/ios/ScrollingTreeFrameScrollingNodeRemoteIOS.mm:
(WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::commitStateAfterChildren): Subframe nodes have
a delegate, and that will take care of the requestedScrollPosition update.
* UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.h:
* UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.mm:
(WebKit::ScrollingTreeOverflowScrollingNodeIOS::commitStateAfterChildren):
* UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm:
(WebKit::ScrollingTreeScrollingNodeDelegateIOS::commitStateAfterChildren):

LayoutTests:

Testing of programmatic scrolls in frames is prevented by webkit.org/b/196635.

* scrollingcoordinator/ios/programmatic-overflow-scroll-expected.html: Added.
* scrollingcoordinator/ios/programmatic-overflow-scroll.html: Added.
* scrollingcoordinator/ios/programmatic-page-scroll-expected.html: Added.
* scrollingcoordinator/ios/programmatic-page-scroll.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@243926 268f45cc-cd09-0410-ab3c-d52691b4dbfc
23 files changed:
LayoutTests/ChangeLog
LayoutTests/scrollingcoordinator/ios/programmatic-overflow-scroll-expected.html [new file with mode: 0644]
LayoutTests/scrollingcoordinator/ios/programmatic-overflow-scroll.html [new file with mode: 0644]
LayoutTests/scrollingcoordinator/ios/programmatic-page-scroll-expected.html [new file with mode: 0644]
LayoutTests/scrollingcoordinator/ios/programmatic-page-scroll.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp
Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h
Source/WebCore/page/scrolling/ScrollingCoordinator.h
Source/WebCore/page/scrolling/ScrollingTree.cpp
Source/WebCore/page/scrolling/ScrollingTree.h
Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp
Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h
Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayer.h
Source/WebCore/rendering/RenderMarquee.cpp
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp
Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeFrameScrollingNodeRemoteIOS.mm
Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.h
Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.mm
Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm