Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS 17: History back sometimes scrolls to top of the page (with app banner) #19324

Conversation

smfr
Copy link
Contributor

@smfr smfr commented Oct 20, 2023

2bafc1b

iOS 17: History back sometimes scrolls to top of the page (with app banner)
https://bugs.webkit.org/show_bug.cgi?id=231563
rdar://117107620

Reviewed by Tim Horton.

Sometimes, navigating back to a page on iOS would fail to restore the scroll position to the correct
location. This happened when `WebPage::restorePageState()` hit the second mismatched
`minimumLayoutSizeInScrollViewCoordinates` clause, which made use of
`historyItem.unobscuredContentRect()`. This could happen when MobileSafari app banners were hidden
or shown. `historyItem.unobscuredContentRect()` had the wrong value in this case, containing a rect
that had a 0,0 location which triggered a scroll back to the top.

`historyItem.unobscuredContentRect()` was wrong because it was set in
`HistoryController::saveScrollPositionAndViewStateToItem()` which runs after we've reset the content
size in preparation for the navigation; note that this function uses
`frameView->cachedScrollPosition()`. So the fix is to cache `unobscuredContentRect()` and
`exposedContentRect()` in the same way.

This is messy; ScrollView shouldn't be in the business of storing caches related to page navigation,
but fixing that is out of scope for this change.

The API test navigates and goes back with a view size change, which triggers the bug.

Also add some release logging to help diagnose scroll restoration bugs.

* Source/WebCore/dom/Document.cpp:
(WebCore::Document::setBackForwardCacheState):
* Source/WebCore/loader/HistoryController.cpp:
(WebCore::FrameLoader::HistoryController::saveScrollPositionAndViewStateToItem):
* Source/WebCore/platform/ScrollView.cpp:
(WebCore::ScrollView::cacheCurrentScrollState):
* Source/WebCore/platform/ScrollView.h:
(WebCore::ScrollView::cachedUnobscuredContentRect const):
(WebCore::ScrollView::cachedExposedContentRect const):
(WebCore::ScrollView::cacheCurrentScrollPosition): Deleted.
* Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* Tools/TestWebKitAPI/Tests/ios/ScrollViewInsetTests.mm:
(TestWebKitAPI::TEST):
* Tools/TestWebKitAPI/ios/scrollable-page.html: Added.

Canonical link: https://commits.webkit.org/269611@main

b6b3e75

Misc iOS, tvOS & watchOS macOS Linux Windows
βœ… πŸ§ͺ style βœ… πŸ›  ios βœ… πŸ›  mac βœ… πŸ›  wpe   πŸ›  wincairo
βœ… πŸ§ͺ bindings βœ… πŸ›  ios-sim βœ… πŸ›  mac-AS-debug   πŸ§ͺ wpe-wk2
βœ… πŸ§ͺ webkitperl βœ… πŸ§ͺ ios-wk2 βœ… πŸ§ͺ api-mac βœ… πŸ›  gtk
  πŸ§ͺ ios-wk2-wpt βœ… πŸ§ͺ mac-wk1   πŸ§ͺ gtk-wk2
βœ… πŸ§ͺ api-ios βœ… πŸ§ͺ mac-wk2   πŸ§ͺ api-gtk
  πŸ›  tv   πŸ§ͺ mac-AS-debug-wk2
βœ… πŸ›  tv-sim
βœ… πŸ›  πŸ§ͺ merge   πŸ›  watch
βœ… πŸ›  watch-sim

@smfr smfr self-assigned this Oct 20, 2023
@smfr smfr added the Scrolling Bugs related to main thread and off-main thread scrolling label Oct 20, 2023
@smfr smfr force-pushed the eng/iOS-17-History-back-sometimes-scrolls-to-top-of-the-page-with-app-banner branch from 451a25d to 66d8e6c Compare October 20, 2023 01:45
@smfr smfr force-pushed the eng/iOS-17-History-back-sometimes-scrolls-to-top-of-the-page-with-app-banner branch from 66d8e6c to b6b3e75 Compare October 21, 2023 00:11
@smfr smfr added the merge-queue Applied to send a pull request to merge-queue label Oct 21, 2023
…anner)

https://bugs.webkit.org/show_bug.cgi?id=231563
rdar://117107620

Reviewed by Tim Horton.

Sometimes, navigating back to a page on iOS would fail to restore the scroll position to the correct
location. This happened when `WebPage::restorePageState()` hit the second mismatched
`minimumLayoutSizeInScrollViewCoordinates` clause, which made use of
`historyItem.unobscuredContentRect()`. This could happen when MobileSafari app banners were hidden
or shown. `historyItem.unobscuredContentRect()` had the wrong value in this case, containing a rect
that had a 0,0 location which triggered a scroll back to the top.

`historyItem.unobscuredContentRect()` was wrong because it was set in
`HistoryController::saveScrollPositionAndViewStateToItem()` which runs after we've reset the content
size in preparation for the navigation; note that this function uses
`frameView->cachedScrollPosition()`. So the fix is to cache `unobscuredContentRect()` and
`exposedContentRect()` in the same way.

This is messy; ScrollView shouldn't be in the business of storing caches related to page navigation,
but fixing that is out of scope for this change.

The API test navigates and goes back with a view size change, which triggers the bug.

Also add some release logging to help diagnose scroll restoration bugs.

* Source/WebCore/dom/Document.cpp:
(WebCore::Document::setBackForwardCacheState):
* Source/WebCore/loader/HistoryController.cpp:
(WebCore::FrameLoader::HistoryController::saveScrollPositionAndViewStateToItem):
* Source/WebCore/platform/ScrollView.cpp:
(WebCore::ScrollView::cacheCurrentScrollState):
* Source/WebCore/platform/ScrollView.h:
(WebCore::ScrollView::cachedUnobscuredContentRect const):
(WebCore::ScrollView::cachedExposedContentRect const):
(WebCore::ScrollView::cacheCurrentScrollPosition): Deleted.
* Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* Tools/TestWebKitAPI/Tests/ios/ScrollViewInsetTests.mm:
(TestWebKitAPI::TEST):
* Tools/TestWebKitAPI/ios/scrollable-page.html: Added.

Canonical link: https://commits.webkit.org/269611@main
@webkit-commit-queue webkit-commit-queue force-pushed the eng/iOS-17-History-back-sometimes-scrolls-to-top-of-the-page-with-app-banner branch from b6b3e75 to 2bafc1b Compare October 21, 2023 02:46
@webkit-commit-queue
Copy link
Collaborator

Committed 269611@main (2bafc1b): https://commits.webkit.org/269611@main

Reviewed commits have been landed. Closing PR #19324 and removing active labels.

@webkit-commit-queue webkit-commit-queue merged commit 2bafc1b into WebKit:main Oct 21, 2023
@webkit-commit-queue webkit-commit-queue removed the merge-queue Applied to send a pull request to merge-queue label Oct 21, 2023
@smfr smfr deleted the eng/iOS-17-History-back-sometimes-scrolls-to-top-of-the-page-with-app-banner branch December 22, 2023 16:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Scrolling Bugs related to main thread and off-main thread scrolling
Projects
None yet
4 participants