Skip to content
Permalink
Browse files
[MacCatalyst] REGRESSION(r290091): sometimes can hang if WKWebView
…is unparented before the next visible content rect update

https://bugs.webkit.org/show_bug.cgi?id=240691
<rdar://problem/92006847>

Reviewed by Wenson Hsieh.

Test: WKWebViewResize.RemovesAssertionsAfterMovingToWindow

* Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm:
(-[WKWebView _processWillSwapOrDidExit]):
(-[WKWebView didMoveToWindow]):
(-[WKWebView _acquireResizeAssertionForReason:]):
Drive-by: WebProcess crashes should also clear the resize assertions.
Drive-by: Add a 1s timeout in case the next visible content rect update takes too long.

* Source/WebKit/UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h:
* Source/WebKit/UIProcess/API/ios/WKWebViewTestingIOS.mm:
(-[WKWebView _hasResizeAssertion]): Added.
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewResize.mm:
(TEST.WKWebViewResize.RemovesAssertionsAfterMovingToWindow): Added.

Canonical link: https://commits.webkit.org/250822@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294589 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
dcrousso committed May 20, 2022
1 parent 0733c28 commit f4ecf7181b71de0aa4574b51016579b68fc4587a
Showing 4 changed files with 66 additions and 1 deletion.
@@ -63,6 +63,7 @@
#import <pal/spi/cocoa/QuartzCoreSPI.h>
#import <pal/spi/ios/GraphicsServicesSPI.h>
#import <wtf/BlockPtr.h>
#import <wtf/Box.h>
#import <wtf/FixedVector.h>
#import <wtf/SystemTracing.h>
#import <wtf/cocoa/RuntimeApplicationChecksCocoa.h>
@@ -705,6 +706,10 @@ - (void)_processWillSwapOrDidExit
[self _hidePasswordView];
[self _cancelAnimatedResize];

#if HAVE(MAC_CATALYST_LIVE_RESIZE)
[self _invalidateResizeAssertions];
#endif

if (_gestureController)
_gestureController->disconnectFromProcess();

@@ -1561,6 +1566,9 @@ - (void)didMoveToWindow
if (_page->hasRunningProcess() && self.window)
_page->setIsInMultitaskingMode(self._isInMultitaskingMode);
#endif
#if HAVE(MAC_CATALYST_LIVE_RESIZE)
[self _invalidateResizeAssertions];
#endif
}

- (void)_setOpaqueInternal:(BOOL)opaque
@@ -2008,13 +2016,34 @@ - (void)_acquireResizeAssertionForReason:(NSString *)reason
return;

if (_resizeAssertions.isEmpty()) {
[self _doAfterNextVisibleContentRectUpdate:makeBlockPtr([weakSelf = WeakObjCPtr<WKWebView>(self)] {
auto didInvalidateResizeAssertions = Box<bool>::create(false);

[self _doAfterNextVisibleContentRectUpdate:makeBlockPtr([weakSelf = WeakObjCPtr<WKWebView>(self), didInvalidateResizeAssertions] {
auto strongSelf = weakSelf.get();
if (!strongSelf)
return;

if (*didInvalidateResizeAssertions)
return;

[strongSelf _invalidateResizeAssertions];

*didInvalidateResizeAssertions = true;
}).get()];

RunLoop::main().dispatchAfter(1_s, [weakSelf = WeakObjCPtr<WKWebView>(self), didInvalidateResizeAssertions] {
auto strongSelf = weakSelf.get();
WKWEBVIEW_RELEASE_LOG("WKWebview %p next visible content rect update took too long; clearing resize assertions", strongSelf.get());
if (!strongSelf)
return;

if (*didInvalidateResizeAssertions)
return;

[strongSelf _invalidateResizeAssertions];

*didInvalidateResizeAssertions = true;
});
}

_resizeAssertions.append(retainPtr([windowScene _holdLiveResizeSnapshotForReason:reason]));
@@ -90,6 +90,8 @@

- (NSString *)_serializedSelectionCaretBackgroundColorForTesting;

- (BOOL)_hasResizeAssertion;

@end

#endif // TARGET_OS_IPHONE
@@ -481,6 +481,15 @@ - (NSString *)_serializedSelectionCaretBackgroundColorForTesting
return serializationForCSS(WebCore::colorFromCocoaColor(backgroundColor));
}

- (BOOL)_hasResizeAssertion
{
#if HAVE(MAC_CATALYST_LIVE_RESIZE)
if (!_resizeAssertions.isEmpty())
return YES;
#endif
return NO;
}

@end

#endif // PLATFORM(IOS_FAMILY)
@@ -27,15 +27,18 @@

#import "TestCocoa.h"
#import "TestWKWebView.h"
#import <WebKit/WKWebViewPrivateForTesting.h>
#import <wtf/RetainPtr.h>

#if HAVE(MAC_CATALYST_LIVE_RESIZE)

TEST(WKWebViewResize, DoesNotAssertInDeallocAfterChangingFrame)
{
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
EXPECT_FALSE([webView _hasResizeAssertion]);

[webView setFrame:NSMakeRect(0, 0, 400, 300)];
EXPECT_TRUE([webView _hasResizeAssertion]);

bool didThrow = false;
@try {
@@ -49,8 +52,10 @@
TEST(WKWebViewResize, DoesNotAssertInDeallocAfterChangingBounds)
{
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
EXPECT_FALSE([webView _hasResizeAssertion]);

[webView setBounds:NSMakeRect(0, 0, 400, 300)];
EXPECT_TRUE([webView _hasResizeAssertion]);

bool didThrow = false;
@try {
@@ -61,4 +66,24 @@
EXPECT_FALSE(didThrow);
}

TEST(WKWebViewResize, RemovesAssertionsAfterMovingToWindow)
{
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
EXPECT_FALSE([webView _hasResizeAssertion]);

[webView setFrame:NSMakeRect(0, 0, 400, 300)];
EXPECT_TRUE([webView _hasResizeAssertion]);

auto window = adoptNS([[UIWindow alloc] initWithFrame:NSMakeRect(0, 0, 320, 568)]);

[window addSubview:webView.get()];
EXPECT_FALSE([webView _hasResizeAssertion]);

[webView setFrame:NSMakeRect(0, 0, 200, 150)];
EXPECT_TRUE([webView _hasResizeAssertion]);

[webView removeFromSuperview];
EXPECT_FALSE([webView _hasResizeAssertion]);
}

#endif // HAVE(MAC_CATALYST_LIVE_RESIZE)

0 comments on commit f4ecf71

Please sign in to comment.