<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[282419] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/282419">282419</a></dd>
<dt>Author</dt> <dd>wenson_hsieh@apple.com</dd>
<dt>Date</dt> <dd>2021-09-14 15:42:58 -0700 (Tue, 14 Sep 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>[macOS] Avoid computing post-layout EditorState data unless necessary
https://bugs.webkit.org/show_bug.cgi?id=230204
<rdar://problem/83078713>

Reviewed by Devin Rousso.

Source/WebCore:

See WebKit/ChangeLog for more details.

* page/Page.h:
(WebCore::Page::isEditable const): Mark this getter `const`.
(WebCore::Page::isEditable): Deleted.

Source/WebKit:

Add a new codepath on macOS that allows us to entirely avoid post-layout EditorState computation in the case
where it's not needed for anything; in particular, unless the text touch bar may be presented or the UI delegate
implements the `-webView:didChangeFontAttributes:` method, the post-layout portion of EditorState is not needed
at all.

See below for more details.

* Shared/WebPageCreationParameters.cpp:
(WebKit::WebPageCreationParameters::encode const):
(WebKit::WebPageCreationParameters::decode):
* Shared/WebPageCreationParameters.h:

Plumb a bit indicating whether user interaction is required in order to show the text touch bar. See
`WebPage::shouldAvoidComputingPostLayoutDataForEditorState` below for more details.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::creationParameters):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::editorState const):
(WebKit::WebPage::updateEditorStateAfterLayoutIfEditabilityChanged):

When computing `EditorState.isContentEditable`, use VisibleSelection's `hasEditableStyle` method instead of
`isContentEditable`. Unlike the latter, the former does not trigger style resolution.

(WebKit::WebPage::didStartPageTransition):

Make a slight adjustment to only set the `m_hasEverFocusedElementDueToUserInteractionSincePageTransition` bit if
the user is actually interacting with text form control or editable element. This allows us to still avoid
computing post-layout editor state data in cases where the user has clicked on non-editable elements on the
page, such that text editing controls in the touch bar are still not being shown.

(WebKit::WebPage::didChangeSelectionOrOverflowScrollPosition):
(WebKit::WebPage::sendEditorStateUpdate):

Don't bother scheduling another post-layout EditorState in the case where post-layout data is missing, but we're
avoiding post-layout data computation altogether due to `shouldAvoidComputingPostLayoutDataForEditorState`
returning `true`.

* WebProcess/WebPage/WebPage.h:
(WebKit::WebPage::requiresPostLayoutDataForEditorState const):
(WebKit::WebPage::shouldAvoidComputingPostLayoutDataForEditorState const):
(WebKit::WebPage::platformNeedsLayoutForEditorState const): Deleted.

Rename this to `requiresPostLayoutDataForEditorState`, to avoid some confusion with the new method,
`shouldAvoidComputingPostLayoutDataForEditorState`. The former is a way for platforms to indicate that post-
layout data *must* be included, even if layout is not up to date yet upon computing the EditorState. The latter
is a way for platforms to indicate that we can completely avoid all post-layout editor state computation,
regardless of whether or not layout is up to date.

By default, if both of the above methods return `false`, we compute and include post-layout data only if layout
is up-to-date when computing the EditorState, and schedule a subsequent "full" EditorState update after the
next rendering update in the case where layout was *not* up-to-date already (indicated by the EditorState's
`isMissingPostLayoutData` flag).

* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::requiresPostLayoutDataForEditorState const):
(WebKit::WebPage::platformNeedsLayoutForEditorState const): Deleted.
* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::shouldAvoidComputingPostLayoutDataForEditorState const):

Only return `true` here if the user interaction requirements for showing text editing controls on the touch bar
have not been met, and the UI delegate method for observing font attributes is also not implemented by the
client.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorepagePageh">trunk/Source/WebCore/page/Page.h</a></li>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitSharedWebPageCreationParameterscpp">trunk/Source/WebKit/Shared/WebPageCreationParameters.cpp</a></li>
<li><a href="#trunkSourceWebKitSharedWebPageCreationParametersh">trunk/Source/WebKit/Shared/WebPageCreationParameters.h</a></li>
<li><a href="#trunkSourceWebKitUIProcessWebPageProxycpp">trunk/Source/WebKit/UIProcess/WebPageProxy.cpp</a></li>
<li><a href="#trunkSourceWebKitWebProcessWebPageWebPagecpp">trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp</a></li>
<li><a href="#trunkSourceWebKitWebProcessWebPageWebPageh">trunk/Source/WebKit/WebProcess/WebPage/WebPage.h</a></li>
<li><a href="#trunkSourceWebKitWebProcessWebPageiosWebPageIOSmm">trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm</a></li>
<li><a href="#trunkSourceWebKitWebProcessWebPagemacWebPageMacmm">trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (282418 => 282419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2021-09-14 22:41:23 UTC (rev 282418)
+++ trunk/Source/WebCore/ChangeLog      2021-09-14 22:42:58 UTC (rev 282419)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2021-09-14  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [macOS] Avoid computing post-layout EditorState data unless necessary
+        https://bugs.webkit.org/show_bug.cgi?id=230204
+        <rdar://problem/83078713>
+
+        Reviewed by Devin Rousso.
+
+        See WebKit/ChangeLog for more details.
+
+        * page/Page.h:
+        (WebCore::Page::isEditable const): Mark this getter `const`.
+        (WebCore::Page::isEditable): Deleted.
+
</ins><span class="cx"> 2021-09-14  Ryan Haddad  <ryanhaddad@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, reverting r282408.
</span></span></pre></div>
<a id="trunkSourceWebCorepagePageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/Page.h (282418 => 282419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/Page.h 2021-09-14 22:41:23 UTC (rev 282418)
+++ trunk/Source/WebCore/page/Page.h    2021-09-14 22:42:58 UTC (rev 282419)
</span><span class="lines">@@ -628,7 +628,7 @@
</span><span class="cx">     static const int maxNumberOfFrames = 1000;
</span><span class="cx"> 
</span><span class="cx">     void setEditable(bool isEditable) { m_isEditable = isEditable; }
</span><del>-    bool isEditable() { return m_isEditable; }
</del><ins>+    bool isEditable() const { return m_isEditable; }
</ins><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT VisibilityState visibilityState() const;
</span><span class="cx">     WEBCORE_EXPORT void resumeAnimatingImages();
</span></span></pre></div>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (282418 => 282419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/ChangeLog    2021-09-14 22:41:23 UTC (rev 282418)
+++ trunk/Source/WebKit/ChangeLog       2021-09-14 22:42:58 UTC (rev 282419)
</span><span class="lines">@@ -1,3 +1,75 @@
</span><ins>+2021-09-14  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [macOS] Avoid computing post-layout EditorState data unless necessary
+        https://bugs.webkit.org/show_bug.cgi?id=230204
+        <rdar://problem/83078713>
+
+        Reviewed by Devin Rousso.
+
+        Add a new codepath on macOS that allows us to entirely avoid post-layout EditorState computation in the case
+        where it's not needed for anything; in particular, unless the text touch bar may be presented or the UI delegate
+        implements the `-webView:didChangeFontAttributes:` method, the post-layout portion of EditorState is not needed
+        at all.
+
+        See below for more details.
+
+        * Shared/WebPageCreationParameters.cpp:
+        (WebKit::WebPageCreationParameters::encode const):
+        (WebKit::WebPageCreationParameters::decode):
+        * Shared/WebPageCreationParameters.h:
+
+        Plumb a bit indicating whether user interaction is required in order to show the text touch bar. See
+        `WebPage::shouldAvoidComputingPostLayoutDataForEditorState` below for more details.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::creationParameters):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::editorState const):
+        (WebKit::WebPage::updateEditorStateAfterLayoutIfEditabilityChanged):
+
+        When computing `EditorState.isContentEditable`, use VisibleSelection's `hasEditableStyle` method instead of
+        `isContentEditable`. Unlike the latter, the former does not trigger style resolution.
+
+        (WebKit::WebPage::didStartPageTransition):
+
+        Make a slight adjustment to only set the `m_hasEverFocusedElementDueToUserInteractionSincePageTransition` bit if
+        the user is actually interacting with text form control or editable element. This allows us to still avoid
+        computing post-layout editor state data in cases where the user has clicked on non-editable elements on the
+        page, such that text editing controls in the touch bar are still not being shown.
+
+        (WebKit::WebPage::didChangeSelectionOrOverflowScrollPosition):
+        (WebKit::WebPage::sendEditorStateUpdate):
+
+        Don't bother scheduling another post-layout EditorState in the case where post-layout data is missing, but we're
+        avoiding post-layout data computation altogether due to `shouldAvoidComputingPostLayoutDataForEditorState`
+        returning `true`.
+
+        * WebProcess/WebPage/WebPage.h:
+        (WebKit::WebPage::requiresPostLayoutDataForEditorState const):
+        (WebKit::WebPage::shouldAvoidComputingPostLayoutDataForEditorState const):
+        (WebKit::WebPage::platformNeedsLayoutForEditorState const): Deleted.
+
+        Rename this to `requiresPostLayoutDataForEditorState`, to avoid some confusion with the new method,
+        `shouldAvoidComputingPostLayoutDataForEditorState`. The former is a way for platforms to indicate that post-
+        layout data *must* be included, even if layout is not up to date yet upon computing the EditorState. The latter
+        is a way for platforms to indicate that we can completely avoid all post-layout editor state computation,
+        regardless of whether or not layout is up to date.
+
+        By default, if both of the above methods return `false`, we compute and include post-layout data only if layout
+        is up-to-date when computing the EditorState, and schedule a subsequent "full" EditorState update after the
+        next rendering update in the case where layout was *not* up-to-date already (indicated by the EditorState's
+        `isMissingPostLayoutData` flag).
+
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::requiresPostLayoutDataForEditorState const):
+        (WebKit::WebPage::platformNeedsLayoutForEditorState const): Deleted.
+        * WebProcess/WebPage/mac/WebPageMac.mm:
+        (WebKit::WebPage::shouldAvoidComputingPostLayoutDataForEditorState const):
+
+        Only return `true` here if the user interaction requirements for showing text editing controls on the touch bar
+        have not been met, and the UI delegate method for observing font attributes is also not implemented by the
+        client.
+
</ins><span class="cx"> 2021-09-14  Fujii Hironori  <Hironori.Fujii@sony.com>
</span><span class="cx"> 
</span><span class="cx">         Enable IPCMessages debug logging for non-Cocoa ports
</span></span></pre></div>
<a id="trunkSourceWebKitSharedWebPageCreationParameterscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/Shared/WebPageCreationParameters.cpp (282418 => 282419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/Shared/WebPageCreationParameters.cpp 2021-09-14 22:41:23 UTC (rev 282418)
+++ trunk/Source/WebKit/Shared/WebPageCreationParameters.cpp    2021-09-14 22:42:58 UTC (rev 282419)
</span><span class="lines">@@ -189,6 +189,10 @@
</span><span class="cx"> #if ENABLE(APP_HIGHLIGHTS)
</span><span class="cx">     encoder << appHighlightsVisible;
</span><span class="cx"> #endif
</span><ins>+
+#if HAVE(TOUCH_BAR)
+    encoder << requiresUserActionForEditingControlsManager;
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> std::optional<WebPageCreationParameters> WebPageCreationParameters::decode(IPC::Decoder& decoder)
</span><span class="lines">@@ -608,6 +612,11 @@
</span><span class="cx">         return std::nullopt;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if HAVE(TOUCH_BAR)
+    if (!decoder.decode(parameters.requiresUserActionForEditingControlsManager))
+        return std::nullopt;
+#endif
+
</ins><span class="cx">     return parameters;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitSharedWebPageCreationParametersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/Shared/WebPageCreationParameters.h (282418 => 282419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/Shared/WebPageCreationParameters.h   2021-09-14 22:41:23 UTC (rev 282418)
+++ trunk/Source/WebKit/Shared/WebPageCreationParameters.h      2021-09-14 22:42:58 UTC (rev 282419)
</span><span class="lines">@@ -264,7 +264,10 @@
</span><span class="cx"> #if ENABLE(APP_HIGHLIGHTS)
</span><span class="cx">     WebCore::HighlightVisibility appHighlightsVisible { WebCore::HighlightVisibility::Hidden };
</span><span class="cx"> #endif
</span><del>-    
</del><ins>+
+#if HAVE(TOUCH_BAR)
+    bool requiresUserActionForEditingControlsManager { false };
+#endif
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessWebPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (282418 => 282419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp   2021-09-14 22:41:23 UTC (rev 282418)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp      2021-09-14 22:42:58 UTC (rev 282419)
</span><span class="lines">@@ -8346,6 +8346,10 @@
</span><span class="cx">     parameters.appHighlightsVisible = appHighlightsVisibility() ? HighlightVisibility::Visible : HighlightVisibility::Hidden;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if HAVE(TOUCH_BAR)
+    parameters.requiresUserActionForEditingControlsManager = m_configuration->requiresUserActionForEditingControlsManager();
+#endif
+
</ins><span class="cx">     return parameters;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitWebProcessWebPageWebPagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (282418 => 282419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp       2021-09-14 22:41:23 UTC (rev 282418)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp  2021-09-14 22:42:58 UTC (rev 282419)
</span><span class="lines">@@ -515,6 +515,9 @@
</span><span class="cx">     , m_pageScrolledHysteresis([this](PAL::HysteresisState state) { if (state == PAL::HysteresisState::Stopped) pageStoppedScrolling(); }, pageScrollHysteresisDuration)
</span><span class="cx">     , m_canRunBeforeUnloadConfirmPanel(parameters.canRunBeforeUnloadConfirmPanel)
</span><span class="cx">     , m_canRunModal(parameters.canRunModal)
</span><ins>+#if HAVE(TOUCH_BAR)
+    , m_requiresUserActionForEditingControlsManager(parameters.requiresUserActionForEditingControlsManager)
+#endif
</ins><span class="cx"> #if ENABLE(META_VIEWPORT)
</span><span class="cx">     , m_forceAlwaysUserScalable(parameters.ignoresViewportScaleLimits)
</span><span class="cx"> #endif
</span><span class="lines">@@ -1228,7 +1231,7 @@
</span><span class="cx">     result.identifier = m_lastEditorStateIdentifier.increment();
</span><span class="cx">     result.selectionIsNone = selection.isNone();
</span><span class="cx">     result.selectionIsRange = selection.isRange();
</span><del>-    result.isContentEditable = selection.isContentEditable();
</del><ins>+    result.isContentEditable = selection.hasEditableStyle();
</ins><span class="cx">     result.isContentRichlyEditable = selection.isContentRichlyEditable();
</span><span class="cx">     result.isInPasswordField = selection.isInPasswordField();
</span><span class="cx">     result.hasComposition = editor.hasComposition();
</span><span class="lines">@@ -1243,7 +1246,14 @@
</span><span class="cx">         result.selectionIsRangeInsideImageOverlay = selectionRange && HTMLElement::isInsideImageOverlay(*selectionRange);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (shouldPerformLayout == ShouldPerformLayout::Yes || platformNeedsLayoutForEditorState(frame))
</del><ins>+    m_lastEditorStateWasContentEditable = result.isContentEditable ? EditorStateIsContentEditable::Yes : EditorStateIsContentEditable::No;
+
+    if (shouldAvoidComputingPostLayoutDataForEditorState()) {
+        getPlatformEditorState(frame, result);
+        return result;
+    }
+
+    if (shouldPerformLayout == ShouldPerformLayout::Yes || requiresPostLayoutDataForEditorState(frame))
</ins><span class="cx">         document->updateLayout(); // May cause document destruction
</span><span class="cx"> 
</span><span class="cx">     if (auto* frameView = document->view(); frameView && !frameView->needsLayout()) {
</span><span class="lines">@@ -1260,8 +1270,6 @@
</span><span class="cx"> 
</span><span class="cx">     getPlatformEditorState(frame, result);
</span><span class="cx"> 
</span><del>-    m_lastEditorStateWasContentEditable = result.isContentEditable ? EditorStateIsContentEditable::Yes : EditorStateIsContentEditable::No;
-
</del><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1312,9 +1320,12 @@
</span><span class="cx">     if (m_lastEditorStateWasContentEditable == EditorStateIsContentEditable::Unset)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    if (hasPendingEditorStateUpdate())
+        return;
+
</ins><span class="cx">     Ref frame = CheckedRef(m_page->focusController())->focusedOrMainFrame();
</span><del>-    EditorStateIsContentEditable editorStateIsContentEditable = frame->selection().selection().isContentEditable() ? EditorStateIsContentEditable::Yes : EditorStateIsContentEditable::No;
-    if (m_lastEditorStateWasContentEditable != editorStateIsContentEditable)
</del><ins>+    auto isEditable = frame->selection().selection().hasEditableStyle() ? EditorStateIsContentEditable::Yes : EditorStateIsContentEditable::No;
+    if (m_lastEditorStateWasContentEditable != isEditable)
</ins><span class="cx">         scheduleFullEditorStateUpdate();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -3545,10 +3556,10 @@
</span><span class="cx"> {
</span><span class="cx">     freezeLayerTree(LayerTreeFreezeReason::PageTransition);
</span><span class="cx"> 
</span><del>-#if PLATFORM(MAC)
</del><ins>+#if HAVE(TOUCH_BAR)
</ins><span class="cx">     bool hasPreviouslyFocusedDueToUserInteraction = m_hasEverFocusedElementDueToUserInteractionSincePageTransition;
</span><ins>+    m_hasEverFocusedElementDueToUserInteractionSincePageTransition = false;
</ins><span class="cx"> #endif
</span><del>-    m_hasEverFocusedElementDueToUserInteractionSincePageTransition = false;
</del><span class="cx">     m_lastEditorStateWasContentEditable = EditorStateIsContentEditable::Unset;
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="lines">@@ -5962,12 +5973,12 @@
</span><span class="cx">     if (m_isSelectingTextWhileInsertingAsynchronously)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-#if PLATFORM(MAC)
</del><ins>+#if HAVE(TOUCH_BAR)
</ins><span class="cx">     bool hasPreviouslyFocusedDueToUserInteraction = m_hasEverFocusedElementDueToUserInteractionSincePageTransition;
</span><del>-    m_hasEverFocusedElementDueToUserInteractionSincePageTransition |= m_userIsInteracting;
</del><ins>+    if (m_userIsInteracting && m_focusedElement)
+        m_hasEverFocusedElementDueToUserInteractionSincePageTransition = true;
</ins><span class="cx"> 
</span><span class="cx">     if (!hasPreviouslyFocusedDueToUserInteraction && m_hasEverFocusedElementDueToUserInteractionSincePageTransition) {
</span><del>-#if HAVE(TOUCH_BAR)
</del><span class="cx">         if (frame->document()->quirks().isTouchBarUpdateSupressedForHiddenContentEditable()) {
</span><span class="cx">             m_isTouchBarUpdateSupressedForHiddenContentEditable = true;
</span><span class="cx">             send(Messages::WebPageProxy::SetIsTouchBarUpdateSupressedForHiddenContentEditable(m_isTouchBarUpdateSupressedForHiddenContentEditable));
</span><span class="lines">@@ -5977,7 +5988,6 @@
</span><span class="cx">             m_isNeverRichlyEditableForTouchBar = true;
</span><span class="cx">             send(Messages::WebPageProxy::SetIsNeverRichlyEditableForTouchBar(m_isNeverRichlyEditableForTouchBar));
</span><span class="cx">         }
</span><del>-#endif
</del><span class="cx"> 
</span><span class="cx">         send(Messages::WebPageProxy::SetHasHadSelectionChangesFromUserInteraction(m_hasEverFocusedElementDueToUserInteractionSincePageTransition));
</span><span class="cx">     }
</span><span class="lines">@@ -5991,7 +6001,7 @@
</span><span class="cx">         discardedComposition();
</span><span class="cx">         return;
</span><span class="cx">     }
</span><del>-#endif
</del><ins>+#endif // HAVE(TOUCH_BAR)
</ins><span class="cx"> 
</span><span class="cx">     scheduleFullEditorStateUpdate();
</span><span class="cx"> }
</span><span class="lines">@@ -6511,8 +6521,7 @@
</span><span class="cx">     // next layer tree commit to compute and send the complete EditorState over.
</span><span class="cx">     auto state = editorState();
</span><span class="cx">     send(Messages::WebPageProxy::EditorStateChanged(state));
</span><del>-
-    if (state.isMissingPostLayoutData)
</del><ins>+    if (state.isMissingPostLayoutData && !shouldAvoidComputingPostLayoutDataForEditorState())
</ins><span class="cx">         scheduleFullEditorStateUpdate();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitWebProcessWebPageWebPageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (282418 => 282419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2021-09-14 22:41:23 UTC (rev 282418)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h    2021-09-14 22:42:58 UTC (rev 282419)
</span><span class="lines">@@ -1496,7 +1496,7 @@
</span><span class="cx">     void platformReinitialize();
</span><span class="cx">     void platformDetach();
</span><span class="cx">     void getPlatformEditorState(WebCore::Frame&, EditorState&) const;
</span><del>-    bool platformNeedsLayoutForEditorState(const WebCore::Frame&) const;
</del><ins>+    bool requiresPostLayoutDataForEditorState(const WebCore::Frame&) const;
</ins><span class="cx">     void platformWillPerformEditingCommand();
</span><span class="cx">     void sendEditorStateUpdate();
</span><span class="cx">     void getPlatformEditorStateCommon(const WebCore::Frame&, EditorState&) const;
</span><span class="lines">@@ -1920,6 +1920,7 @@
</span><span class="cx">     void consumeNetworkExtensionSandboxExtensions(const Vector<SandboxExtension::Handle>&);
</span><span class="cx"> 
</span><span class="cx">     bool hasPendingEditorStateUpdate() const;
</span><ins>+    bool shouldAvoidComputingPostLayoutDataForEditorState() const;
</ins><span class="cx"> 
</span><span class="cx">     WebCore::PageIdentifier m_identifier;
</span><span class="cx"> 
</span><span class="lines">@@ -2165,9 +2166,10 @@
</span><span class="cx">     std::optional<WebCore::IntSize> m_viewportSizeForCSSViewportUnits;
</span><span class="cx"> 
</span><span class="cx">     bool m_userIsInteracting { false };
</span><del>-    bool m_hasEverFocusedElementDueToUserInteractionSincePageTransition { false };
</del><span class="cx"> 
</span><span class="cx"> #if HAVE(TOUCH_BAR)
</span><ins>+    bool m_hasEverFocusedElementDueToUserInteractionSincePageTransition { false };
+    bool m_requiresUserActionForEditingControlsManager { false };
</ins><span class="cx">     bool m_isTouchBarUpdateSupressedForHiddenContentEditable { false };
</span><span class="cx">     bool m_isNeverRichlyEditableForTouchBar { false };
</span><span class="cx"> #endif
</span><span class="lines">@@ -2380,8 +2382,12 @@
</span><span class="cx"> 
</span><span class="cx"> #if !PLATFORM(IOS_FAMILY)
</span><span class="cx"> inline void WebPage::platformWillPerformEditingCommand() { }
</span><del>-inline bool WebPage::platformNeedsLayoutForEditorState(const WebCore::Frame&) const { return false; }
</del><ins>+inline bool WebPage::requiresPostLayoutDataForEditorState(const WebCore::Frame&) const { return false; }
</ins><span class="cx"> inline void WebPage::prepareToRunModalJavaScriptDialog() { }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if !PLATFORM(MAC)
+inline bool WebPage::shouldAvoidComputingPostLayoutDataForEditorState() const { return false; }
+#endif
+
</ins><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKitWebProcessWebPageiosWebPageIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (282418 => 282419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2021-09-14 22:41:23 UTC (rev 282418)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm    2021-09-14 22:42:58 UTC (rev 282419)
</span><span class="lines">@@ -250,7 +250,7 @@
</span><span class="cx">     return renderer->hasNonEmptyVisibleRectRespectingParentFrames();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool WebPage::platformNeedsLayoutForEditorState(const Frame& frame) const
</del><ins>+bool WebPage::requiresPostLayoutDataForEditorState(const Frame& frame) const
</ins><span class="cx"> {
</span><span class="cx">     // If we have a composition or are using a hardware keyboard then we need to send the full
</span><span class="cx">     // editor so that the UIProcess can update UI, including the position of the caret.
</span></span></pre></div>
<a id="trunkSourceWebKitWebProcessWebPagemacWebPageMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm (282418 => 282419)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm 2021-09-14 22:41:23 UTC (rev 282418)
+++ trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm    2021-09-14 22:42:58 UTC (rev 282419)
</span><span class="lines">@@ -1084,6 +1084,21 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool WebPage::shouldAvoidComputingPostLayoutDataForEditorState() const
+{
+    if (m_needsFontAttributes) {
+        // Font attribute information is propagated to the UI process through post-layout data on EditorState.
+        return false;
+    }
+
+    if (!m_requiresUserActionForEditingControlsManager || m_hasEverFocusedElementDueToUserInteractionSincePageTransition) {
+        // Text editing controls on the touch bar depend on having post-layout editor state data.
+        return false;
+    }
+
+    return true;
+}
+
</ins><span class="cx"> #if HAVE(APP_ACCENT_COLORS)
</span><span class="cx"> 
</span><span class="cx"> void WebPage::setAccentColor(WebCore::Color color)
</span></span></pre>
</div>
</div>

</body>
</html>