⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 278661 in webkit


Ignore:
Timestamp:
Jun 9, 2021, 9:02:23 AM (5 years ago)
Author:
Simon Fraser
Message:

Clean up scrollbar creation code in RenderLayerScrollableArea
https://bugs.webkit.org/show_bug.cgi?id=226805

Reviewed by Alan Bujtas.

Share code between updateScrollbarsAfterStyleChange() and updateScrollbarsAfterLayout() which
had a lot of common logic. updateScrollbarPresenceAndState() takes two optionals, indicating
whether information about overflow is available (which is only the case after layout).

Also make lots of member function declarations private in RenderLayerScrollableArea.

  • rendering/RenderLayerCompositor.cpp:

(WebCore::RenderLayerCompositor::updateScrollingNodeLayers):

  • rendering/RenderLayerScrollableArea.cpp:

(WebCore::RenderLayerScrollableArea::updateScrollbarPresenceAndState):
(WebCore::RenderLayerScrollableArea::updateScrollbarsAfterStyleChange):
(WebCore::RenderLayerScrollableArea::updateScrollbarsAfterLayout):

  • rendering/RenderLayerScrollableArea.h:
Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r278659 r278661  
     12021-06-09  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Clean up scrollbar creation code in RenderLayerScrollableArea
     4        https://bugs.webkit.org/show_bug.cgi?id=226805
     5
     6        Reviewed by Alan Bujtas.
     7
     8        Share code between updateScrollbarsAfterStyleChange() and updateScrollbarsAfterLayout() which
     9        had a lot of common logic. updateScrollbarPresenceAndState() takes two optionals, indicating
     10        whether information about overflow is available (which is only the case after layout).
     11
     12        Also make lots of member function declarations private in RenderLayerScrollableArea.
     13
     14        * rendering/RenderLayerCompositor.cpp:
     15        (WebCore::RenderLayerCompositor::updateScrollingNodeLayers):
     16        * rendering/RenderLayerScrollableArea.cpp:
     17        (WebCore::RenderLayerScrollableArea::updateScrollbarPresenceAndState):
     18        (WebCore::RenderLayerScrollableArea::updateScrollbarsAfterStyleChange):
     19        (WebCore::RenderLayerScrollableArea::updateScrollbarsAfterLayout):
     20        * rendering/RenderLayerScrollableArea.h:
     21
    1222021-06-09  Alan Bujtas  <zalan@apple.com>
    223
  • trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp

    r278428 r278661  
    46904690void RenderLayerCompositor::updateScrollingNodeLayers(ScrollingNodeID nodeID, RenderLayer& layer, ScrollingCoordinator& scrollingCoordinator)
    46914691{
    4692     auto* scrollableArea = layer.scrollableArea();
    4693     ASSERT(scrollableArea);
    4694 
    46954692    if (layer.isRenderViewLayer()) {
    46964693        FrameView& frameView = m_renderView.frameView();
     
    47004697            frameView.layerForHorizontalScrollbar(), frameView.layerForVerticalScrollbar() });
    47014698    } else {
     4699        auto* scrollableArea = layer.scrollableArea();
     4700        ASSERT(scrollableArea);
     4701
    47024702        auto& backing = *layer.backing();
    47034703        scrollingCoordinator.setNodeLayers(nodeID, { backing.graphicsLayer(),
  • trunk/Source/WebCore/rendering/RenderLayerScrollableArea.cpp

    r278527 r278661  
    10641064}
    10651065
     1066void RenderLayerScrollableArea::updateScrollbarPresenceAndState(std::optional<bool> hasHorizontalOverflow, std::optional<bool> hasVerticalOverflow)
     1067{
     1068    auto* box = m_layer.renderBox();
     1069    ASSERT(box);
     1070
     1071    enum class ScrollbarState {
     1072        NoScrollbar,
     1073        Enabled,
     1074        Disabled
     1075    };
     1076
     1077    auto scrollbarForAxis = [&](ScrollbarOrientation orientation) -> RefPtr<Scrollbar>& {
     1078        return orientation == ScrollbarOrientation::HorizontalScrollbar ? m_hBar : m_vBar;
     1079    };
     1080
     1081    auto stateForScrollbar = [&](ScrollbarOrientation orientation, std::optional<bool> hasOverflow, ScrollbarState nonScrollableState) {
     1082        if (hasOverflow)
     1083            return *hasOverflow ? ScrollbarState::Enabled : nonScrollableState;
     1084       
     1085        // If we don't have information about overflow (because we haven't done layout yet), just return the current state of the scrollbar.
     1086        auto existingScrollbar = scrollbarForAxis(orientation);
     1087        return (existingScrollbar && existingScrollbar->enabled()) ? ScrollbarState::Enabled : nonScrollableState;
     1088    };
     1089
     1090    auto stateForScrollbarOnAxis = [&](ScrollbarOrientation orientation, std::optional<bool> hasOverflow) {
     1091        if (box->hasAlwaysPresentScrollbar(orientation))
     1092            return stateForScrollbar(orientation, hasOverflow, ScrollbarState::Disabled);
     1093
     1094        if (box->hasAutoScrollbar(orientation))
     1095            return stateForScrollbar(orientation, hasOverflow, ScrollbarState::NoScrollbar);
     1096
     1097        return ScrollbarState::NoScrollbar;
     1098    };
     1099
     1100    auto horizontalBarState = stateForScrollbarOnAxis(ScrollbarOrientation::HorizontalScrollbar, hasHorizontalOverflow);
     1101    setHasHorizontalScrollbar(horizontalBarState != ScrollbarState::NoScrollbar);
     1102    if (horizontalBarState != ScrollbarState::NoScrollbar)
     1103        m_hBar->setEnabled(horizontalBarState == ScrollbarState::Enabled);
     1104
     1105    auto verticalBarState = stateForScrollbarOnAxis(ScrollbarOrientation::VerticalScrollbar, hasVerticalOverflow);
     1106    setHasVerticalScrollbar(verticalBarState != ScrollbarState::NoScrollbar);
     1107    if (verticalBarState != ScrollbarState::NoScrollbar)
     1108        m_vBar->setEnabled(verticalBarState == ScrollbarState::Enabled);
     1109}
     1110
     1111void RenderLayerScrollableArea::updateScrollbarsAfterStyleChange(const RenderStyle* oldStyle)
     1112{
     1113    // Overflow is a box concept.
     1114    RenderBox* box = m_layer.renderBox();
     1115    if (!box)
     1116        return;
     1117
     1118    // List box parts handle the scrollbars by themselves so we have nothing to do.
     1119    if (box->style().appearance() == ListboxPart)
     1120        return;
     1121
     1122    bool hadVerticalScrollbar = hasVerticalScrollbar();
     1123    updateScrollbarPresenceAndState();
     1124    bool hasVerticalScrollbar = this->hasVerticalScrollbar();
     1125
     1126    if (hadVerticalScrollbar != hasVerticalScrollbar || (hasVerticalScrollbar && oldStyle && oldStyle->shouldPlaceVerticalScrollbarOnLeft() != box->style().shouldPlaceVerticalScrollbarOnLeft()))
     1127        computeScrollOrigin();
     1128
     1129    if (!m_scrollDimensionsDirty)
     1130        updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollableVerticalOverflow());
     1131}
     1132
    10661133void RenderLayerScrollableArea::updateScrollbarsAfterLayout()
    10671134{
     
    10731140        return;
    10741141
    1075     bool hasHorizontalOverflow = this->hasHorizontalOverflow();
    1076     bool hasVerticalOverflow = this->hasVerticalOverflow();
    1077 
    1078     // If overflow requires a scrollbar, then we just need to enable or disable.
    1079     auto& renderer = m_layer.renderer();
    1080     if (m_hBar && box->hasAlwaysPresentScrollbar(ScrollbarOrientation::HorizontalScrollbar))
    1081         m_hBar->setEnabled(hasHorizontalOverflow);
    1082     if (m_vBar && box->hasAlwaysPresentScrollbar(ScrollbarOrientation::VerticalScrollbar))
    1083         m_vBar->setEnabled(hasVerticalOverflow);
     1142    bool hadHorizontalScrollbar = hasHorizontalScrollbar();
     1143    bool hadVerticalScrollbar = hasVerticalScrollbar();
     1144
     1145    updateScrollbarPresenceAndState(hasHorizontalOverflow(), hasVerticalOverflow());
    10841146
    10851147    // Scrollbars with auto behavior may need to lay out again if scrollbars got added or removed.
    1086     bool autoHorizontalScrollBarChanged = box->hasAutoScrollbar(ScrollbarOrientation::HorizontalScrollbar) && (hasHorizontalScrollbar() != hasHorizontalOverflow);
    1087     bool autoVerticalScrollBarChanged = box->hasAutoScrollbar(ScrollbarOrientation::VerticalScrollbar) && (hasVerticalScrollbar() != hasVerticalOverflow);
     1148    bool autoHorizontalScrollBarChanged = box->hasAutoScrollbar(ScrollbarOrientation::HorizontalScrollbar) && (hadHorizontalScrollbar != hasHorizontalScrollbar());
     1149    bool autoVerticalScrollBarChanged = box->hasAutoScrollbar(ScrollbarOrientation::VerticalScrollbar) && (hadVerticalScrollbar != hasVerticalScrollbar());
    10881150
    10891151    if (autoHorizontalScrollBarChanged || autoVerticalScrollBarChanged) {
    1090         if (box->hasAutoScrollbar(ScrollbarOrientation::HorizontalScrollbar))
    1091             setHasHorizontalScrollbar(hasHorizontalOverflow);
    1092         if (box->hasAutoScrollbar(ScrollbarOrientation::VerticalScrollbar))
    1093             setHasVerticalScrollbar(hasVerticalOverflow);
    1094 
    10951152        if (autoVerticalScrollBarChanged && shouldPlaceVerticalScrollbarOnLeft())
    10961153            computeScrollOrigin();
     
    10981155        m_layer.updateSelfPaintingLayer();
    10991156
     1157        auto& renderer = m_layer.renderer();
    11001158        renderer.repaint();
    11011159
    11021160        if (renderer.style().overflowX() == Overflow::Auto || renderer.style().overflowY() == Overflow::Auto) {
    11031161            if (!m_inOverflowRelayout) {
    1104                 m_inOverflowRelayout = true;
     1162                SetForScope<bool> inOverflowRelayoutScope(m_inOverflowRelayout, true);
    11051163                renderer.setNeedsLayout(MarkOnlyThis);
    11061164                if (is<RenderBlock>(renderer)) {
    1107                     RenderBlock& block = downcast<RenderBlock>(renderer);
     1165                    auto& block = downcast<RenderBlock>(renderer);
    11081166                    block.scrollbarsChanged(autoHorizontalScrollBarChanged, autoVerticalScrollBarChanged);
    11091167                    block.layoutBlock(true);
    11101168                } else
    11111169                    renderer.layout();
    1112                 m_inOverflowRelayout = false;
    11131170            }
    11141171        }
    11151172
     1173        // FIXME: This does not belong here.
    11161174        RenderObject* parent = renderer.parent();
    11171175        if (parent && parent->isFlexibleBox() && renderer.isBox())
     
    15381596}
    15391597
    1540 void RenderLayerScrollableArea::updateScrollbarsAfterStyleChange(const RenderStyle* oldStyle)
    1541 {
    1542     // Overflow are a box concept.
    1543     RenderBox* box = m_layer.renderBox();
    1544     if (!box)
    1545         return;
    1546 
    1547     // List box parts handle the scrollbars by themselves so we have nothing to do.
    1548     if (box->style().appearance() == ListboxPart)
    1549         return;
    1550 
    1551     Overflow overflowX = box->style().overflowX();
    1552     Overflow overflowY = box->style().overflowY();
    1553 
    1554     // To avoid doing a relayout in updateScrollbarsAfterLayout, we try to keep any automatic scrollbar that was already present.
    1555     bool hadVerticalScrollbar = m_vBar;
    1556     bool needsHorizontalScrollbar = (m_hBar && box->hasAutoScrollbar(ScrollbarOrientation::HorizontalScrollbar)) || box->hasAlwaysPresentScrollbar(ScrollbarOrientation::HorizontalScrollbar);
    1557     bool needsVerticalScrollbar = (m_vBar && box->hasAutoScrollbar(ScrollbarOrientation::VerticalScrollbar)) || box->hasAlwaysPresentScrollbar(ScrollbarOrientation::VerticalScrollbar);
    1558     setHasHorizontalScrollbar(needsHorizontalScrollbar);
    1559     setHasVerticalScrollbar(needsVerticalScrollbar);
    1560 
    1561     if (hadVerticalScrollbar != needsVerticalScrollbar || (needsVerticalScrollbar && oldStyle && box->style().shouldPlaceVerticalScrollbarOnLeft() != oldStyle->shouldPlaceVerticalScrollbarOnLeft()))
    1562         computeScrollOrigin();
    1563 
    1564     // With non-overlay overflow:scroll, scrollbars are always visible but may be disabled.
    1565     // When switching to another value, we need to re-enable them (see bug 11985).
    1566     if (m_hBar && needsHorizontalScrollbar && oldStyle && oldStyle->overflowX() == Overflow::Scroll && overflowX != Overflow::Scroll)
    1567         m_hBar->setEnabled(true);
    1568 
    1569     if (m_vBar && needsVerticalScrollbar && oldStyle && oldStyle->overflowY() == Overflow::Scroll && overflowY != Overflow::Scroll)
    1570         m_vBar->setEnabled(true);
    1571 
    1572     if (!m_scrollDimensionsDirty)
    1573         updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollableVerticalOverflow());
    1574 }
    1575 
    15761598void RenderLayerScrollableArea::updateScrollableAreaSet(bool hasOverflow)
    15771599{
  • trunk/Source/WebCore/rendering/RenderLayerScrollableArea.h

    r278253 r278661  
    102102    void setHasVerticalScrollbar(bool);
    103103
    104     Ref<Scrollbar> createScrollbar(ScrollbarOrientation);
    105     void destroyScrollbar(ScrollbarOrientation);
    106 
    107104    bool requiresScrollPositionReconciliation() const { return m_requiresScrollPositionReconciliation; }
    108105    void setRequiresScrollPositionReconciliation(bool requiresReconciliation = true) { m_requiresScrollPositionReconciliation = requiresReconciliation; }
     
    213210
    214211    void positionOverflowControls(const IntSize&);
    215     void clearScrollCorner();
    216     void clearResizer();
    217212
    218213    void updateAllScrollbarRelatedStyle();
    219 
    220     void drawPlatformResizerImage(GraphicsContext&, const LayoutRect& resizerCornerRect);
    221214
    222215    LayoutUnit overflowTop() const;
     
    231224    bool scrollingMayRevealBackground() const;
    232225
    233     void computeScrollDimensions();
    234     void computeScrollOrigin();
    235226    void computeHasCompositedScrollableOverflow();
    236 
    237     bool hasHorizontalOverflow() const;
    238     bool hasVerticalOverflow() const;
    239 
    240     bool showsOverflowControls() const;
    241227
    242228    // NOTE: This should only be called by the overridden setScrollOffset from ScrollableArea.
     
    246232    IntSize scrollbarOffset(const Scrollbar&) const;
    247233
    248     void updateScrollableAreaSet(bool hasOverflow);
    249 
    250     ScrollOffset clampScrollOffset(const ScrollOffset&) const;
    251 
    252234    void updateLayerPositionsAfterOverflowScroll();
    253235    void updateLayerPositionsAfterDocumentScroll();
     
    261243
    262244private:
     245    bool hasHorizontalOverflow() const;
     246    bool hasVerticalOverflow() const;
     247
     248    bool showsOverflowControls() const;
     249
     250    ScrollOffset clampScrollOffset(const ScrollOffset&) const;
     251
     252    void computeScrollDimensions();
     253    void computeScrollOrigin();
     254
     255    void updateScrollableAreaSet(bool hasOverflow);
     256
    263257    void updateScrollCornerStyle();
    264258    void updateResizerStyle();
     259
     260    void drawPlatformResizerImage(GraphicsContext&, const LayoutRect& resizerCornerRect);
     261
     262    Ref<Scrollbar> createScrollbar(ScrollbarOrientation);
     263    void destroyScrollbar(ScrollbarOrientation);
     264
     265    void clearScrollCorner();
     266    void clearResizer();
     267
     268    void updateScrollbarPresenceAndState(std::optional<bool> hasHorizontalOverflow = std::nullopt, std::optional<bool> hasVerticalOverflow = std::nullopt);
    265269
    266270private:
Note: See TracChangeset for help on using the changeset viewer.