Expose SPI to disable synchronously blocking on painting after parenting a WKWebView
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 13 Oct 2016 17:44:27 +0000 (17:44 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 13 Oct 2016 17:44:27 +0000 (17:44 +0000)
https://bugs.webkit.org/show_bug.cgi?id=163364
<rdar://problem/28012494>

Reviewed by Geoff Garen.

Some clients may not want the default WKWebView behavior where we synchronously
block on the Web process after the first time a WKWebView is re-added to the window,
because they are e.g. parenting re-used WKWebViews while scrolling.

* UIProcess/API/APIPageConfiguration.h:
(API::PageConfiguration::shouldSynchronizeInitialPaintAfterMovingToWindow):
(API::PageConfiguration::setShouldSynchronizeInitialPaintAfterMovingToWindow):
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _initializeWithConfiguration:]):
* UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
(-[WKWebViewConfiguration init]):
(-[WKWebViewConfiguration copyWithZone:]):
(-[WKWebViewConfiguration _shouldSynchronizeInitialPaintAfterMovingToWindow]):
(-[WKWebViewConfiguration _setShouldSynchronizeInitialPaintAfterMovingToWindow:]):
* UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h:
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::WebPageProxy):
Add and plumb a new WKWebView configuration parameter.

(WebKit::WebPageProxy::dispatchViewStateChange):
If the new configuration parameter is set, don't block the main thread when
a view is reparented.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207292 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/APIPageConfiguration.h
Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit2/UIProcess/API/Cocoa/WKWebViewConfiguration.mm
Source/WebKit2/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebPageProxy.h

index 16425fe..86a5652 100644 (file)
@@ -1,3 +1,35 @@
+2016-10-13  Tim Horton  <timothy_horton@apple.com>
+
+        Expose SPI to disable synchronously blocking on painting after parenting a WKWebView
+        https://bugs.webkit.org/show_bug.cgi?id=163364
+        <rdar://problem/28012494>
+
+        Reviewed by Geoff Garen.
+
+        Some clients may not want the default WKWebView behavior where we synchronously
+        block on the Web process after the first time a WKWebView is re-added to the window,
+        because they are e.g. parenting re-used WKWebViews while scrolling.
+
+        * UIProcess/API/APIPageConfiguration.h:
+        (API::PageConfiguration::shouldSynchronizeInitialPaintAfterMovingToWindow):
+        (API::PageConfiguration::setShouldSynchronizeInitialPaintAfterMovingToWindow):
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _initializeWithConfiguration:]):
+        * UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
+        (-[WKWebViewConfiguration init]):
+        (-[WKWebViewConfiguration copyWithZone:]):
+        (-[WKWebViewConfiguration _shouldSynchronizeInitialPaintAfterMovingToWindow]):
+        (-[WKWebViewConfiguration _setShouldSynchronizeInitialPaintAfterMovingToWindow:]):
+        * UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h:
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::WebPageProxy):
+        Add and plumb a new WKWebView configuration parameter.
+
+        (WebKit::WebPageProxy::dispatchViewStateChange):
+        If the new configuration parameter is set, don't block the main thread when
+        a view is reparented.
+
 2016-10-12  Chris Dumez  <cdumez@apple.com>
 
         [Web IDL] Drop support for legacy [ConstructorConditional=*]
index 2beaefb..4706075 100644 (file)
@@ -92,6 +92,9 @@ public:
     bool initialCapitalizationEnabled() { return m_initialCapitalizationEnabled; }
     void setInitialCapitalizationEnabled(bool initialCapitalizationEnabled) { m_initialCapitalizationEnabled = initialCapitalizationEnabled; }
 
+    bool shouldWaitForPaintAfterViewDidMoveToWindow() const { return m_shouldWaitForPaintAfterViewDidMoveToWindow; }
+    void setShouldWaitForPaintAfterViewDidMoveToWindow(bool shouldSynchronize) { m_shouldWaitForPaintAfterViewDidMoveToWindow = shouldSynchronize; }
+
 private:
 
     RefPtr<WebKit::WebProcessPool> m_processPool;
@@ -112,6 +115,7 @@ private:
     bool m_alwaysRunsAtForegroundPriority = false;
 #endif
     bool m_initialCapitalizationEnabled = true;
+    bool m_shouldWaitForPaintAfterViewDidMoveToWindow = true;
 };
 
 } // namespace API
index df98f7e..bb5de2b 100644 (file)
@@ -438,6 +438,7 @@ static uint32_t convertSystemLayoutDirection(NSUserInterfaceLayoutDirection dire
     pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::httpEquivEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _allowsMetaRefresh]));
     pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::allowUniversalAccessFromFileURLsKey(), WebKit::WebPreferencesStore::Value(!![_configuration _allowUniversalAccessFromFileURLs]));
     pageConfiguration->setInitialCapitalizationEnabled([_configuration _initialCapitalizationEnabled]);
+    pageConfiguration->setShouldWaitForPaintAfterViewDidMoveToWindow([_configuration _shouldWaitForPaintAfterViewDidMoveToWindow]);
 
 #if PLATFORM(MAC)
     pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::showsURLsInToolTipsEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _showsURLsInToolTips]));
index ca99f6f..599559e 100644 (file)
@@ -123,6 +123,7 @@ private:
     BOOL _requiresUserActionForEditingControlsManager;
 #endif
     BOOL _initialCapitalizationEnabled;
+    BOOL _shouldWaitForPaintAfterViewDidMoveToWindow;
 
 #if ENABLE(APPLE_PAY)
     BOOL _applePayEnabled;
@@ -174,6 +175,7 @@ private:
     _requiresUserActionForEditingControlsManager = NO;
 #endif
     _initialCapitalizationEnabled = YES;
+    _shouldWaitForPaintAfterViewDidMoveToWindow = YES;
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     _allowsAirPlayForMediaPlayback = YES;
@@ -284,6 +286,7 @@ private:
     configuration->_mediaTypesRequiringUserActionForPlayback = self->_mediaTypesRequiringUserActionForPlayback;
     configuration->_mainContentUserGestureOverrideEnabled = self->_mainContentUserGestureOverrideEnabled;
     configuration->_initialCapitalizationEnabled = self->_initialCapitalizationEnabled;
+    configuration->_shouldWaitForPaintAfterViewDidMoveToWindow = self->_shouldWaitForPaintAfterViewDidMoveToWindow;
 
 #if PLATFORM(IOS)
     configuration->_allowsInlineMediaPlayback = self->_allowsInlineMediaPlayback;
@@ -655,6 +658,16 @@ static NSString *defaultApplicationNameForUserAgent()
     _initialCapitalizationEnabled = initialCapitalizationEnabled;
 }
 
+- (BOOL)_shouldWaitForPaintAfterViewDidMoveToWindow
+{
+    return _shouldWaitForPaintAfterViewDidMoveToWindow;
+}
+
+- (void)_setShouldWaitForPaintAfterViewDidMoveToWindow:(BOOL)shouldSynchronize
+{
+    _shouldWaitForPaintAfterViewDidMoveToWindow = shouldSynchronize;
+}
+
 #if PLATFORM(MAC)
 - (BOOL)_showsURLsInToolTips
 {
index 789d064..6ebfda8 100644 (file)
@@ -55,6 +55,7 @@
 @property (nonatomic, setter=_setAttachmentElementEnabled:) BOOL _attachmentElementEnabled WK_API_AVAILABLE(macosx(10.12), ios(10.0));
 @property (nonatomic, setter=_setInitialCapitalizationEnabled:) BOOL _initialCapitalizationEnabled WK_API_AVAILABLE(macosx(10.12), ios(10.0));
 @property (nonatomic, setter=_setApplePayEnabled:) BOOL _applePayEnabled WK_API_AVAILABLE(macosx(10.12), ios(10.0));
+@property (nonatomic, setter=_setShouldWaitForPaintAfterViewDidMoveToWindow:) BOOL _shouldWaitForPaintAfterViewDidMoveToWindow WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 #if TARGET_OS_IPHONE
 @property (nonatomic, setter=_setAlwaysRunsAtForegroundPriority:) BOOL _alwaysRunsAtForegroundPriority WK_API_AVAILABLE(ios(9_0));
index 764c6d3..3a4974a 100644 (file)
@@ -357,6 +357,7 @@ WebPageProxy::WebPageProxy(PageClient& pageClient, WebProcessProxy& process, uin
     , m_initialCapitalizationEnabled(m_configuration->initialCapitalizationEnabled())
     , m_backForwardList(WebBackForwardList::create(*this))
     , m_maintainsInactiveSelection(false)
+    , m_shouldWaitForPaintAfterViewDidMoveToWindow(m_configuration->shouldWaitForPaintAfterViewDidMoveToWindow())
     , m_isEditable(false)
     , m_textZoomFactor(1)
     , m_pageZoomFactor(1)
@@ -1524,7 +1525,7 @@ void WebPageProxy::dispatchViewStateChange()
 
     bool isNowInWindow = (changed & ViewState::IsInWindow) && isInWindow();
     // We always want to wait for the Web process to reply if we've been in-window before and are coming back in-window.
-    if (m_viewWasEverInWindow && isNowInWindow && m_drawingArea->hasVisibleContent())
+    if (m_viewWasEverInWindow && isNowInWindow && m_drawingArea->hasVisibleContent() && m_shouldWaitForPaintAfterViewDidMoveToWindow)
         m_viewStateChangeWantsSynchronousReply = true;
 
     // Don't wait synchronously if the view state is not visible. (This matters in particular on iOS, where a hidden page may be suspended.)
index 5203ed8..596fb6c 100644 (file)
@@ -1653,6 +1653,8 @@ private:
         
     bool m_maintainsInactiveSelection;
 
+    bool m_shouldWaitForPaintAfterViewDidMoveToWindow;
+
     String m_toolTip;
 
     EditorState m_editorState;