Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
REGRESSION (r290875): [iOS] Safari renders many blank tiles after nav…
…igating back to webpage from PDF https://bugs.webkit.org/show_bug.cgi?id=241536 rdar://94637323 Reviewed by Tim Horton. When using a standard content view, the logic in `WKApplicationStateTrackingView` creates a `WebKit::ApplicationStateTracker` after the view becomes parented in the view hierarchy (in `-didMoveToWindow`), and holds onto it until it is about to be unparented from the view hierarchy (in `-willMoveToWindow:`). However, in the case where `WKApplicationStateTrackingView` is a `WKPDFView` (i.e. we're hosting a remote PDFKit view controller), the behavior is much more intricate; this is because the `WKPDFView` is replaced in the view hierarchy by the remote view controller's sizing view once the `PDFHostViewController` has finished loading its remote content. Once this happens, the `-_contentView` of the `WKApplicationStateTrackingView` points to this sizing view instead, and the `WKPDFView` (which subclasses `WKApplicationStateTrackingView`) is no longer in the view hierarchy. Prior to r290875: when we remove `WKPDFView` from the view hierarchy and replace it with a sizing view, `self._contentView` in both cases already points to the `_UISizeTrackingView`, even though it hasn't been added to the view hierarchy yet. Since we bail if this size tracking view is not in the view hierarchy, we previously ended up never clearing out the application state tracker when loading a PDF, which means that `-[WKPDFView isBackground]` would always return NO, despite the view not being in the view hierarchy. In r290875, I replaced the `!self._contentView.window` check with `!_applicationStateTracker`, which caused us to now clear out the application state tracker when unparenting `WKPDFView`. This, in turn, means that `-[WKPDFView isBackground]` now returns YES when the `WKPDFView` is removed and replaced with the size tracking view. When navigating back to the previous page, this causes us to end up in a state where the `WindowIsActive` flag in `WebPageProxy::m_activityState` is off until the next page load, since we only update this flag in `WebPageProxy::finishAttachingToWebProcess`, which is called when `WKPDFView` is still being used as the custom content view. This ultimately causes the symptoms observed in this bug, which include blank tiles when scrolling. To address this bug, we first revert the changes in r290875, which allows `WKPDFView` to behave as if it were in the foreground, even when it's not in the view hierarchy: ``` - (void)willMoveToWindow:(UIWindow *)newWindow { if (!self._contentView.window || newWindow) return; … ``` Of course, this (by itself) would bring back <https://webkit.org/b/237505>; to preserve that fix, we additionally limit the early return to cases where the window is *not* in the process of being destroyed (that is, `-willMoveToWindow:` is called with both the new `window == nil`, while the current window `self.window == nil`): ``` - (void)willMoveToWindow:(UIWindow *)newWindow { BOOL windowIsBeingDeallocated = !self.window && !newWindow; if (!windowIsBeingDeallocated) { if (!self._contentView.window || newWindow) return; } … ``` Note that this is logically equivalent to: ``` - (void)willMoveToWindow:(UIWindow *)newWindow { if ((self.window || newWindow) && (!self._contentView.window || newWindow)) return; … ``` ...which can also be rewritten a bit more succinctly as: ``` - (void)willMoveToWindow:(UIWindow *)newWindow { if ((self.window && !self._contentView.window) || newWindow) return; … ``` In other words: - In the case where a standard content view is used (i.e. `self == self._contentView`), we always clear out `_applicationStateTracker` if the window we're moving to is `nil`. This takes care of the normal scenario of unparenting a web view, as well as the corner case where the web view is unparented in the middle of `-[UIWindow dealloc]`. - In the case of `PDFHostViewController` where a custom content view is used, we'll return early in `-willMoveToWindow:` and keep the existing `_applicationStateTracker`, because the size tracking view has not been parented yet. Test: ApplicationStateTracking.NavigatingFromPDFDoesNotLeaveWebViewInactive * Source/WebKit/UIProcess/ios/WKApplicationStateTrackingView.mm: (-[WKApplicationStateTrackingView willMoveToWindow:]): * Tools/TestWebKitAPI/Configurations/Base.xcconfig: Add `Source/WebKit/Platform/spi/ios` as a relative header include path for iOS family, such that we can import the internal `PDFKitSPI.h` in API tests. * Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * Tools/TestWebKitAPI/Tests/ios/ApplicationStateTracking.mm: (TestWebKitAPI::TEST): Introduce a new API test that loads a simple webpage, navigates to a PDF document (and uses a remote PDFKit view controller to render it), and then navigate back to the original webpage. * Tools/TestWebKitAPI/cocoa/TestWKWebView.mm: (-[WKWebView _isBackground]): Deleted. Remove a workaround for API tests that's no longer necessary, so that the new API test fails without this fix. This workaround was added in r231663, but became unnecessary after r236989, which removed the dependency on `-_isBackground`. * Tools/TestWebKitAPI/ios/TestPDFHostViewController.h: * Tools/TestWebKitAPI/ios/TestPDFHostViewController.mm: Added. Add a helper class that allows us to swizzle out `+createHostView:forExtensionIdentifier:`, and return a `PDFHostViewController` subclass, with a subset of method stubs required to avoid crashes when running API tests. This allows us to simulate PDFKit remote view controller presentation in API tests. (-[TestPDFHostViewController setDelegate:]): (-[TestPDFHostViewController setDocumentData:withScrollView:]): (-[TestPDFHostViewController currentPageIndex]): (-[TestPDFHostViewController pageCount]): (-[TestPDFHostViewController minimumZoomScale]): (-[TestPDFHostViewController maximumZoomScale]): (-[TestPDFHostViewController findString:withOptions:]): (-[TestPDFHostViewController cancelFindString]): (-[TestPDFHostViewController cancelFindStringWithHighlightsCleared:]): (-[TestPDFHostViewController focusOnSearchResultAtIndex:]): (-[TestPDFHostViewController clearSearchHighlights]): (-[TestPDFHostViewController goToPageIndex:]): (-[TestPDFHostViewController updatePDFViewLayout]): (-[TestPDFHostViewController gestureRecognizerShouldBegin:]): (-[TestPDFHostViewController pageNumberIndicator]): (-[TestPDFHostViewController snapshotViewRect:snapshotWidth:afterScreenUpdates:withResult:]): (-[TestPDFHostViewController beginPDFViewRotation]): (-[TestPDFHostViewController endPDFViewRotation]): (TestWebKitAPI::swizzledCreateHostViewForExtensionIdentifier): (TestWebKitAPI::createPDFHostViewControllerSwizzler): Canonical link: https://commits.webkit.org/251484@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@295479 268f45cc-cd09-0410-ab3c-d52691b4dbfc
- Loading branch information