<!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>[198656] trunk/Source/WebCore</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/198656">198656</a></dd>
<dt>Author</dt> <dd>mmaxfield@apple.com</dd>
<dt>Date</dt> <dd>2016-03-24 19:03:25 -0700 (Thu, 24 Mar 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[OS X] Overflow:scroll scrollbars do not obey overlay/always-on system preference changes
https://bugs.webkit.org/show_bug.cgi?id=155830

Reviewed by Simon Fraser.

When the scrollbar style changes, the available width of all ScrollableAreas change,
and therefore a relayout must occur.

Each ScrollableArea owns its own ScrollAnimator (if necessary). Upon creation, the
ScrollAnimator will start listening for changes to the system preference for
overlay / always-on scrollbars. When notified, the ScrollAnimator tells its owning
ScrollableArea that scrollbarStyleChanged().

For main-frame scrolling, FrameView overrides scrollbarStyleChanged and causes a
relayout. However, for overflow:scroll elements, no relayout is triggered. This
patch overrides availableContentSizeChanged() for RenderLayer (which is used for
overflow:scroll elements). This override triggers a relayout.

It also updates the mechanism in RenderBlock::recomputeLogicalWidth() to ensure that
a change in scrollbar size causes RenderBlockFlow::layoutBlock() to relayout its
children. This is appropriate because block child positioning is affected by
scrollbar size.

No new tests (for now). Presumably we could mock the message we receive when the
system preference is changed. However, I haven't implemented that yet.

* rendering/RenderBlock.cpp: Rename setHasBorderOrPaddingLogicalWidthChanged().
(WebCore::RenderBlock::styleDidChange):
(WebCore::RenderBlock::recomputeLogicalWidth):
* rendering/RenderBlock.h: Ditto.
(WebCore::RenderBlock::setShouldForceRelayoutChildren):
(WebCore::RenderBlock::shouldForceRelayoutChildren):
* rendering/RenderElement.cpp: Ditto.
(WebCore::RenderElement::RenderElement):
* rendering/RenderElement.h: Ditto.
(WebCore::RenderElement::setRenderBlockShouldForceRelayoutChildren):
(WebCore::RenderElement::renderBlockShouldForceRelayoutChildren):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::availableContentSizeChanged): Cause a relayout to occur.
* rendering/RenderLayer.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderBlockcpp">trunk/Source/WebCore/rendering/RenderBlock.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderBlockh">trunk/Source/WebCore/rendering/RenderBlock.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderElementcpp">trunk/Source/WebCore/rendering/RenderElement.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderElementh">trunk/Source/WebCore/rendering/RenderElement.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayercpp">trunk/Source/WebCore/rendering/RenderLayer.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerh">trunk/Source/WebCore/rendering/RenderLayer.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (198655 => 198656)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-03-25 01:13:10 UTC (rev 198655)
+++ trunk/Source/WebCore/ChangeLog        2016-03-25 02:03:25 UTC (rev 198656)
</span><span class="lines">@@ -1,3 +1,46 @@
</span><ins>+2016-03-24  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        [OS X] Overflow:scroll scrollbars do not obey overlay/always-on system preference changes
+        https://bugs.webkit.org/show_bug.cgi?id=155830
+
+        Reviewed by Simon Fraser.
+
+        When the scrollbar style changes, the available width of all ScrollableAreas change,
+        and therefore a relayout must occur.
+
+        Each ScrollableArea owns its own ScrollAnimator (if necessary). Upon creation, the
+        ScrollAnimator will start listening for changes to the system preference for
+        overlay / always-on scrollbars. When notified, the ScrollAnimator tells its owning
+        ScrollableArea that scrollbarStyleChanged().
+
+        For main-frame scrolling, FrameView overrides scrollbarStyleChanged and causes a
+        relayout. However, for overflow:scroll elements, no relayout is triggered. This
+        patch overrides availableContentSizeChanged() for RenderLayer (which is used for
+        overflow:scroll elements). This override triggers a relayout.
+
+        It also updates the mechanism in RenderBlock::recomputeLogicalWidth() to ensure that
+        a change in scrollbar size causes RenderBlockFlow::layoutBlock() to relayout its
+        children. This is appropriate because block child positioning is affected by
+        scrollbar size.
+
+        No new tests (for now). Presumably we could mock the message we receive when the
+        system preference is changed. However, I haven't implemented that yet.
+
+        * rendering/RenderBlock.cpp: Rename setHasBorderOrPaddingLogicalWidthChanged().
+        (WebCore::RenderBlock::styleDidChange):
+        (WebCore::RenderBlock::recomputeLogicalWidth):
+        * rendering/RenderBlock.h: Ditto.
+        (WebCore::RenderBlock::setShouldForceRelayoutChildren):
+        (WebCore::RenderBlock::shouldForceRelayoutChildren):
+        * rendering/RenderElement.cpp: Ditto.
+        (WebCore::RenderElement::RenderElement):
+        * rendering/RenderElement.h: Ditto.
+        (WebCore::RenderElement::setRenderBlockShouldForceRelayoutChildren):
+        (WebCore::RenderElement::renderBlockShouldForceRelayoutChildren):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::availableContentSizeChanged): Cause a relayout to occur.
+        * rendering/RenderLayer.h:
+
</ins><span class="cx"> 2016-03-24  Said Abou-Hallawa  &lt;sabouhallawa@apple,com&gt;
</span><span class="cx"> 
</span><span class="cx">         Change NativeImagePtr for CG to be RetainPtr&lt;CGImageRef&gt;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (198655 => 198656)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBlock.cpp        2016-03-25 01:13:10 UTC (rev 198655)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp        2016-03-25 02:03:25 UTC (rev 198656)
</span><span class="lines">@@ -315,7 +315,7 @@
</span><span class="cx"> 
</span><span class="cx">     // It's possible for our border/padding to change, but for the overall logical width of the block to
</span><span class="cx">     // end up being the same. We keep track of this change so in layoutBlock, we can know to set relayoutChildren=true.
</span><del>-    setHasBorderOrPaddingLogicalWidthChanged(oldStyle &amp;&amp; diff == StyleDifferenceLayout &amp;&amp; needsLayout() &amp;&amp; borderOrPaddingLogicalWidthChanged(oldStyle, &amp;newStyle));
</del><ins>+    setShouldForceRelayoutChildren(oldStyle &amp;&amp; diff == StyleDifferenceLayout &amp;&amp; needsLayout() &amp;&amp; borderOrPaddingLogicalWidthChanged(oldStyle, &amp;newStyle));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild)
</span><span class="lines">@@ -975,7 +975,7 @@
</span><span class="cx">     updateLogicalWidth();
</span><span class="cx">     
</span><span class="cx">     bool hasBorderOrPaddingLogicalWidthChanged = this-&gt;hasBorderOrPaddingLogicalWidthChanged();
</span><del>-    setHasBorderOrPaddingLogicalWidthChanged(false);
</del><ins>+    setShouldForceRelayoutChildren(false);
</ins><span class="cx"> 
</span><span class="cx">     return oldWidth != logicalWidth() || hasBorderOrPaddingLogicalWidthChanged;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBlock.h (198655 => 198656)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBlock.h        2016-03-25 01:13:10 UTC (rev 198655)
+++ trunk/Source/WebCore/rendering/RenderBlock.h        2016-03-25 02:03:25 UTC (rev 198656)
</span><span class="lines">@@ -103,11 +103,11 @@
</span><span class="cx"> 
</span><span class="cx">     void setHasMarginBeforeQuirk(bool b) { setRenderBlockHasMarginBeforeQuirk(b); }
</span><span class="cx">     void setHasMarginAfterQuirk(bool b) { setRenderBlockHasMarginAfterQuirk(b); }
</span><del>-    void setHasBorderOrPaddingLogicalWidthChanged(bool b) { setRenderBlockHasBorderOrPaddingLogicalWidthChanged(b); }
</del><ins>+    void setShouldForceRelayoutChildren(bool b) { setRenderBlockShouldForceRelayoutChildren(b); }
</ins><span class="cx"> 
</span><span class="cx">     bool hasMarginBeforeQuirk() const { return renderBlockHasMarginBeforeQuirk(); }
</span><span class="cx">     bool hasMarginAfterQuirk() const { return renderBlockHasMarginAfterQuirk(); }
</span><del>-    bool hasBorderOrPaddingLogicalWidthChanged() const { return renderBlockHasBorderOrPaddingLogicalWidthChanged(); }
</del><ins>+    bool hasBorderOrPaddingLogicalWidthChanged() const { return renderBlockShouldForceRelayoutChildren(); }
</ins><span class="cx"> 
</span><span class="cx">     bool hasMarginBeforeQuirk(const RenderBox&amp; child) const;
</span><span class="cx">     bool hasMarginAfterQuirk(const RenderBox&amp; child) const;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderElement.cpp (198655 => 198656)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderElement.cpp        2016-03-25 01:13:10 UTC (rev 198655)
+++ trunk/Source/WebCore/rendering/RenderElement.cpp        2016-03-25 02:03:25 UTC (rev 198656)
</span><span class="lines">@@ -95,7 +95,7 @@
</span><span class="cx">     , m_hasContinuation(false)
</span><span class="cx">     , m_renderBlockHasMarginBeforeQuirk(false)
</span><span class="cx">     , m_renderBlockHasMarginAfterQuirk(false)
</span><del>-    , m_renderBlockHasBorderOrPaddingLogicalWidthChanged(false)
</del><ins>+    , m_renderBlockShouldForceRelayoutChildren(false)
</ins><span class="cx">     , m_renderBlockFlowHasMarkupTruncation(false)
</span><span class="cx">     , m_renderBlockFlowLineLayoutPath(RenderBlockFlow::UndeterminedPath)
</span><span class="cx">     , m_firstChild(nullptr)
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderElement.h (198655 => 198656)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderElement.h        2016-03-25 01:13:10 UTC (rev 198655)
+++ trunk/Source/WebCore/rendering/RenderElement.h        2016-03-25 02:03:25 UTC (rev 198656)
</span><span class="lines">@@ -264,10 +264,10 @@
</span><span class="cx"> 
</span><span class="cx">     void setRenderBlockHasMarginBeforeQuirk(bool b) { m_renderBlockHasMarginBeforeQuirk = b; }
</span><span class="cx">     void setRenderBlockHasMarginAfterQuirk(bool b) { m_renderBlockHasMarginAfterQuirk = b; }
</span><del>-    void setRenderBlockHasBorderOrPaddingLogicalWidthChanged(bool b) { m_renderBlockHasBorderOrPaddingLogicalWidthChanged = b; }
</del><ins>+    void setRenderBlockShouldForceRelayoutChildren(bool b) { m_renderBlockShouldForceRelayoutChildren = b; }
</ins><span class="cx">     bool renderBlockHasMarginBeforeQuirk() const { return m_renderBlockHasMarginBeforeQuirk; }
</span><span class="cx">     bool renderBlockHasMarginAfterQuirk() const { return m_renderBlockHasMarginAfterQuirk; }
</span><del>-    bool renderBlockHasBorderOrPaddingLogicalWidthChanged() const { return m_renderBlockHasBorderOrPaddingLogicalWidthChanged; }
</del><ins>+    bool renderBlockShouldForceRelayoutChildren() const { return m_renderBlockShouldForceRelayoutChildren; }
</ins><span class="cx"> 
</span><span class="cx">     void setRenderBlockFlowLineLayoutPath(unsigned u) { m_renderBlockFlowLineLayoutPath = u; }
</span><span class="cx">     void setRenderBlockFlowHasMarkupTruncation(bool b) { m_renderBlockFlowHasMarkupTruncation = b; }
</span><span class="lines">@@ -330,7 +330,7 @@
</span><span class="cx"> 
</span><span class="cx">     unsigned m_renderBlockHasMarginBeforeQuirk : 1;
</span><span class="cx">     unsigned m_renderBlockHasMarginAfterQuirk : 1;
</span><del>-    unsigned m_renderBlockHasBorderOrPaddingLogicalWidthChanged : 1;
</del><ins>+    unsigned m_renderBlockShouldForceRelayoutChildren : 1;
</ins><span class="cx">     unsigned m_renderBlockFlowHasMarkupTruncation : 1;
</span><span class="cx">     unsigned m_renderBlockFlowLineLayoutPath : 2;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (198655 => 198656)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayer.cpp        2016-03-25 01:13:10 UTC (rev 198655)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp        2016-03-25 02:03:25 UTC (rev 198656)
</span><span class="lines">@@ -2916,6 +2916,17 @@
</span><span class="cx">     return contentsSize;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void RenderLayer::availableContentSizeChanged(AvailableSizeChangeReason reason)
+{
+    ScrollableArea::availableContentSizeChanged(reason);
+
+    if (reason == AvailableSizeChangeReason::ScrollbarsChanged) {
+        if (is&lt;RenderBlock&gt;(renderer()))
+            downcast&lt;RenderBlock&gt;(renderer()).setShouldForceRelayoutChildren(true);
+        renderer().setNeedsLayout();
+    }
+}
+
</ins><span class="cx"> bool RenderLayer::shouldSuspendScrollAnimations() const
</span><span class="cx"> {
</span><span class="cx">     return renderer().view().frameView().shouldSuspendScrollAnimations();
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayer.h (198655 => 198656)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayer.h        2016-03-25 01:13:10 UTC (rev 198655)
+++ trunk/Source/WebCore/rendering/RenderLayer.h        2016-03-25 02:03:25 UTC (rev 198656)
</span><span class="lines">@@ -203,6 +203,8 @@
</span><span class="cx">     ScrollOffset scrollOffset() const { return scrollOffsetFromPosition(m_scrollPosition); }
</span><span class="cx">     IntSize scrollableContentsSize() const;
</span><span class="cx"> 
</span><ins>+    void availableContentSizeChanged(AvailableSizeChangeReason) override;
+
</ins><span class="cx">     void scrollRectToVisible(const LayoutRect&amp;, const ScrollAlignment&amp; alignX, const ScrollAlignment&amp; alignY);
</span><span class="cx"> 
</span><span class="cx">     LayoutRect getRectToExpose(const LayoutRect&amp; visibleRect, const LayoutRect&amp; visibleRectRelativeToDocument, const LayoutRect&amp; exposeRect, const ScrollAlignment&amp; alignX, const ScrollAlignment&amp; alignY);
</span></span></pre>
</div>
</div>

</body>
</html>