Changeset 275811 in webkit


Ignore:
Timestamp:
Apr 11, 2021 3:53:50 PM (15 months ago)
Author:
Cameron McCormack
Message:

Fix initial horizontal scrollbar position when vertical scrollbar is on the left.
https://bugs.webkit.org/show_bug.cgi?id=224409

Reviewed by Darin Adler.

Source/WebCore:

Scrollable elements that place their vertical scrollbar on the left
(e.g. when they're direction: rtl or when the OS language is RTL and
the relevant setting to always follow OS scrollbar side is used) have
an incorrect scroll origin, which leads to creating a horizontal
scrollbar with an incorrect initial offset. This is because
RenderLayerScrollableArea::computeScrollDimensions runs prior to the
scrollbars being created. So whenever we start or stop having a
(non-overlay) vertical scrollbar on the left, we need to recompute
the scroll origin and fix up the horizontal scrollbar's offset.

Tests: fast/scrolling/rtl-scrollbars-initial-position-dynamic.html

fast/scrolling/rtl-scrollbars-initial-position.html

  • rendering/RenderLayerScrollableArea.cpp:

(WebCore::RenderLayerScrollableArea::computeScrollDimensions):
(WebCore::RenderLayerScrollableArea::computeScrollOrigin): Split this
out of computeScrollDimensions so we can call it from
updateScrollbarsAfterLayout and updateScrollbarsAfterStyleChange, and
have it ask the horizontal scrollbar to update its offset. We could
condition this on the scroll origin actually having changed, but
that's going to be a similar check that Scrollbar::offsetDidChange
does to ensure the offset value did indeed change. We don't want to
condition this on shouldPlaceBlockDirectionScrollbarOnLeft(), since
that's dependent on the current style, and we may be reacting to a
style change removed the vertical scrollbar on the left.
(WebCore::RenderLayerScrollableArea::updateScrollbarsAfterLayout):
(WebCore::RenderLayerScrollableArea::updateScrollbarsAfterStyleChange):

  • rendering/RenderLayerScrollableArea.h:

LayoutTests:

  • fast/scrolling/rtl-scrollbars-initial-position-dynamic-expected.html: Added.
  • fast/scrolling/rtl-scrollbars-initial-position-dynamic.html: Added.
  • fast/scrolling/rtl-scrollbars-initial-position-expected.html: Added.
  • fast/scrolling/rtl-scrollbars-initial-position.html: Added.
Location:
trunk
Files:
4 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r275808 r275811  
     12021-04-11  Cameron McCormack  <heycam@apple.com>
     2
     3        Fix initial horizontal scrollbar position when vertical scrollbar is on the left.
     4        https://bugs.webkit.org/show_bug.cgi?id=224409
     5
     6        Reviewed by Darin Adler.
     7
     8        * fast/scrolling/rtl-scrollbars-initial-position-dynamic-expected.html: Added.
     9        * fast/scrolling/rtl-scrollbars-initial-position-dynamic.html: Added.
     10        * fast/scrolling/rtl-scrollbars-initial-position-expected.html: Added.
     11        * fast/scrolling/rtl-scrollbars-initial-position.html: Added.
     12
    1132021-04-11  Sam Weinig  <weinig@apple.com>
    214
  • trunk/Source/WebCore/ChangeLog

    r275809 r275811  
     12021-04-11  Cameron McCormack  <heycam@apple.com>
     2
     3        Fix initial horizontal scrollbar position when vertical scrollbar is on the left.
     4        https://bugs.webkit.org/show_bug.cgi?id=224409
     5
     6        Reviewed by Darin Adler.
     7
     8        Scrollable elements that place their vertical scrollbar on the left
     9        (e.g. when they're `direction: rtl` or when the OS language is RTL and
     10        the relevant setting to always follow OS scrollbar side is used) have
     11        an incorrect scroll origin, which leads to creating a horizontal
     12        scrollbar with an incorrect initial offset.  This is because
     13        RenderLayerScrollableArea::computeScrollDimensions runs prior to the
     14        scrollbars being created.  So whenever we start or stop having a
     15        (non-overlay) vertical scrollbar on the left, we need to recompute
     16        the scroll origin and fix up the horizontal scrollbar's offset.
     17
     18        Tests: fast/scrolling/rtl-scrollbars-initial-position-dynamic.html
     19               fast/scrolling/rtl-scrollbars-initial-position.html
     20
     21        * rendering/RenderLayerScrollableArea.cpp:
     22        (WebCore::RenderLayerScrollableArea::computeScrollDimensions):
     23        (WebCore::RenderLayerScrollableArea::computeScrollOrigin): Split this
     24        out of computeScrollDimensions so we can call it from
     25        updateScrollbarsAfterLayout and updateScrollbarsAfterStyleChange, and
     26        have it ask the horizontal scrollbar to update its offset.  We could
     27        condition this on the scroll origin actually having changed, but
     28        that's going to be a similar check that Scrollbar::offsetDidChange
     29        does to ensure the offset value did indeed change.  We don't want to
     30        condition this on shouldPlaceBlockDirectionScrollbarOnLeft(), since
     31        that's dependent on the current style, and we may be reacting to a
     32        style change removed the vertical scrollbar on the left.
     33        (WebCore::RenderLayerScrollableArea::updateScrollbarsAfterLayout):
     34        (WebCore::RenderLayerScrollableArea::updateScrollbarsAfterStyleChange):
     35        * rendering/RenderLayerScrollableArea.h:
     36
    1372021-04-11  Darin Adler  <darin@apple.com>
    238
  • trunk/Source/WebCore/rendering/RenderLayerScrollableArea.cpp

    r275641 r275811  
    10071007void RenderLayerScrollableArea::computeScrollDimensions()
    10081008{
     1009    m_scrollDimensionsDirty = false;
     1010
     1011    m_scrollWidth = roundToInt(overflowRight() - overflowLeft());
     1012    m_scrollHeight = roundToInt(overflowBottom() - overflowTop());
     1013
     1014    computeScrollOrigin();
     1015    computeHasCompositedScrollableOverflow();
     1016}
     1017
     1018void RenderLayerScrollableArea::computeScrollOrigin()
     1019{
    10091020    RenderBox* box = m_layer.renderBox();
    10101021    ASSERT(box);
    1011 
    1012     m_scrollDimensionsDirty = false;
    1013 
    1014     m_scrollWidth = roundToInt(overflowRight() - overflowLeft());
    1015     m_scrollHeight = roundToInt(overflowBottom() - overflowTop());
    10161022
    10171023    int scrollableLeftOverflow = roundToInt(overflowLeft() - box->borderLeft());
     
    10211027    setScrollOrigin(IntPoint(-scrollableLeftOverflow, -scrollableTopOverflow));
    10221028
    1023     computeHasCompositedScrollableOverflow();
     1029    // Horizontal scrollbar offsets depend on the scroll origin when vertical
     1030    // scrollbars are on the left.
     1031    if (m_hBar)
     1032        m_hBar->offsetDidChange();
    10241033}
    10251034
     
    10951104        if (box->hasVerticalScrollbarWithAutoBehavior())
    10961105            setHasVerticalScrollbar(hasVerticalOverflow);
     1106
     1107        if (autoVerticalScrollBarChanged && shouldPlaceBlockDirectionScrollbarOnLeft())
     1108            computeScrollOrigin();
    10971109
    10981110        m_layer.updateSelfPaintingLayer();
     
    15531565
    15541566    // To avoid doing a relayout in updateScrollbarsAfterLayout, we try to keep any automatic scrollbar that was already present.
    1555     bool needsHorizontalScrollbar = box->hasOverflowClip() && ((horizontalScrollbar() && styleDefinesAutomaticScrollbar(box->style(), HorizontalScrollbar)) || styleRequiresScrollbar(box->style(), HorizontalScrollbar));
    1556     bool needsVerticalScrollbar = box->hasOverflowClip() && ((verticalScrollbar() && styleDefinesAutomaticScrollbar(box->style(), VerticalScrollbar)) || styleRequiresScrollbar(box->style(), VerticalScrollbar));
     1567    bool hadVerticalScrollbar = m_vBar;
     1568    bool needsHorizontalScrollbar = box->hasOverflowClip() && ((m_hBar && styleDefinesAutomaticScrollbar(box->style(), HorizontalScrollbar)) || styleRequiresScrollbar(box->style(), HorizontalScrollbar));
     1569    bool needsVerticalScrollbar = box->hasOverflowClip() && ((m_vBar && styleDefinesAutomaticScrollbar(box->style(), VerticalScrollbar)) || styleRequiresScrollbar(box->style(), VerticalScrollbar));
    15571570    setHasHorizontalScrollbar(needsHorizontalScrollbar);
    15581571    setHasVerticalScrollbar(needsVerticalScrollbar);
     1572
     1573    if (hadVerticalScrollbar != needsVerticalScrollbar || (needsVerticalScrollbar && oldStyle && box->style().shouldPlaceBlockDirectionScrollbarOnLeft() != oldStyle->shouldPlaceBlockDirectionScrollbarOnLeft()))
     1574        computeScrollOrigin();
    15591575
    15601576    // With non-overlay overflow:scroll, scrollbars are always visible but may be disabled.
  • trunk/Source/WebCore/rendering/RenderLayerScrollableArea.h

    r271788 r275811  
    232232
    233233    void computeScrollDimensions();
     234    void computeScrollOrigin();
    234235    void computeHasCompositedScrollableOverflow();
    235236
Note: See TracChangeset for help on using the changeset viewer.