Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Side by Side Diff: third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp

Issue 1930183002: Refactor scroll updates during flexbox layout. (Closed) Base URL: https://chromium.googlesource.com/chromium/src@rtl-scroll-origin
Patch Set: rebase + nits Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
3 * 3 *
4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation.
5 * 5 *
6 * Other contributors: 6 * Other contributors:
7 * Robert O'Callahan <roc+@cs.cmu.edu> 7 * Robert O'Callahan <roc+@cs.cmu.edu>
8 * David Baron <dbaron@fas.harvard.edu> 8 * David Baron <dbaron@fas.harvard.edu>
9 * Christian Biesinger <cbiesinger@gmail.com> 9 * Christian Biesinger <cbiesinger@gmail.com>
10 * Randall Jesup <rjesup@wgate.com> 10 * Randall Jesup <rjesup@wgate.com>
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 int PaintLayerScrollableArea::pixelSnappedScrollWidth() const 580 int PaintLayerScrollableArea::pixelSnappedScrollWidth() const
581 { 581 {
582 return snapSizeToPixel(scrollWidth(), box().clientLeft() + box().location(). x()); 582 return snapSizeToPixel(scrollWidth(), box().clientLeft() + box().location(). x());
583 } 583 }
584 584
585 int PaintLayerScrollableArea::pixelSnappedScrollHeight() const 585 int PaintLayerScrollableArea::pixelSnappedScrollHeight() const
586 { 586 {
587 return snapSizeToPixel(scrollHeight(), box().clientTop() + box().location(). y()); 587 return snapSizeToPixel(scrollHeight(), box().clientTop() + box().location(). y());
588 } 588 }
589 589
590 void PaintLayerScrollableArea::computeScrollDimensions() 590 void PaintLayerScrollableArea::updateScrollOrigin()
591 {
592 // This should do nothing prior to first layout; the if-clause will catch th at.
593 if (!overflowRect().size().isZero()) {
cbiesinger 2016/05/13 19:52:48 Thanks for adding the comment. I'd still change th
szager1 2016/05/13 20:52:05 Done.
594 LayoutPoint scrollableOverflow = m_overflowRect.location() - LayoutSize( box().borderLeft(), box().borderTop());
595 setScrollOrigin(flooredIntPoint(-scrollableOverflow) + box().originAdjus tmentForScrollbars());
596 }
597 }
598
599 void PaintLayerScrollableArea::updateScrollDimensions()
591 { 600 {
592 m_overflowRect = box().layoutOverflowRect(); 601 m_overflowRect = box().layoutOverflowRect();
593 box().flipForWritingMode(m_overflowRect); 602 box().flipForWritingMode(m_overflowRect);
594 603 updateScrollOrigin();
595 LayoutPoint scrollableOverflow = m_overflowRect.location() - LayoutSize(box( ).borderLeft(), box().borderTop());
596 setScrollOrigin(flooredIntPoint(-scrollableOverflow) + box().originAdjustmen tForScrollbars());
597 } 604 }
598 605
599 void PaintLayerScrollableArea::scrollToPosition(const DoublePoint& scrollPositio n, ScrollOffsetClamping clamp, ScrollBehavior scrollBehavior, ScrollType scrollT ype) 606 void PaintLayerScrollableArea::scrollToPosition(const DoublePoint& scrollPositio n, ScrollOffsetClamping clamp, ScrollBehavior scrollBehavior, ScrollType scrollT ype)
600 { 607 {
601 cancelProgrammaticScrollAnimation();
602
603 DoublePoint newScrollPosition = clamp == ScrollOffsetClamped ? clampScrollPo sition(scrollPosition) : scrollPosition; 608 DoublePoint newScrollPosition = clamp == ScrollOffsetClamped ? clampScrollPo sition(scrollPosition) : scrollPosition;
604 if (newScrollPosition != scrollPositionDouble()) 609 if (newScrollPosition != scrollPositionDouble())
605 ScrollableArea::setScrollPosition(newScrollPosition, scrollType, scrollB ehavior); 610 ScrollableArea::setScrollPosition(newScrollPosition, scrollType, scrollB ehavior);
606 } 611 }
607 612
608 bool PaintLayerScrollableArea::updateAfterLayout(SubtreeLayoutScope* delayedLayo utScope) 613 void PaintLayerScrollableArea::updateAfterLayout()
609 { 614 {
610 ASSERT(box().hasOverflowClip()); 615 ASSERT(box().hasOverflowClip());
611 616
612 bool didMarkForDelayedLayout = false; 617 bool relayoutIsPrevented = PreventRelayoutScope::relayoutIsPrevented();
618 bool scrollbarsAreFrozen = FreezeScrollbarsScope::scrollbarsAreFrozen();
613 619
614 if (needsScrollbarReconstruction()) { 620 if (needsScrollbarReconstruction()) {
615 m_scrollbarManager.setCanDetachScrollbars(false);
616 setHasHorizontalScrollbar(false); 621 setHasHorizontalScrollbar(false);
617 setHasVerticalScrollbar(false); 622 setHasVerticalScrollbar(false);
618 } 623 }
619 624
620 m_scrollbarManager.setCanDetachScrollbars(true); 625 updateScrollDimensions();
621
622 IntPoint originalOrigin = scrollOrigin();
623 computeScrollDimensions();
624
625 // Layout may cause us to be at an invalid scroll position. In this case we need
626 // to pull our scroll offsets back to the max (or push them up to the min).
627 DoublePoint clampedScrollPosition = clampScrollPosition(scrollPositionDouble ());
628 if (clampedScrollPosition != scrollPositionDouble()) {
629 scrollToPosition(clampedScrollPosition);
630 } else if (originalOrigin != scrollOrigin()) {
631 // TODO: We should be able to use scrollOriginChanged() here, but we can 't because
632 // PaintLayerScrollableArea does not maintain that flag: it gets set, bu t it never
633 // gets unset. We should unset the flag after layout.
634 scrollPositionChanged(scrollPositionDouble(), ProgrammaticScroll);
635 }
636
637 m_scrollbarManager.setCanDetachScrollbars(false);
638 626
639 bool hasHorizontalOverflow = this->hasHorizontalOverflow(); 627 bool hasHorizontalOverflow = this->hasHorizontalOverflow();
640 bool hasVerticalOverflow = this->hasVerticalOverflow(); 628 bool hasVerticalOverflow = this->hasVerticalOverflow();
641 629
642 { 630 {
643 // Hits in compositing/overflow/automatically-opt-into-composited-scroll ing-after-style-change.html. 631 // Hits in compositing/overflow/automatically-opt-into-composited-scroll ing-after-style-change.html.
644 DisableCompositingQueryAsserts disabler; 632 DisableCompositingQueryAsserts disabler;
645 633
646 // overflow:scroll should just enable/disable. 634 // overflow:scroll should just enable/disable.
647 if (box().style()->overflowX() == OverflowScroll && horizontalScrollbar( )) 635 if (box().style()->overflowX() == OverflowScroll && horizontalScrollbar( ))
648 horizontalScrollbar()->setEnabled(hasHorizontalOverflow); 636 horizontalScrollbar()->setEnabled(hasHorizontalOverflow);
649 if (box().style()->overflowY() == OverflowScroll && verticalScrollbar()) 637 if (box().style()->overflowY() == OverflowScroll && verticalScrollbar())
650 verticalScrollbar()->setEnabled(hasVerticalOverflow); 638 verticalScrollbar()->setEnabled(hasVerticalOverflow);
651 } 639 }
652 640
653 // We need to layout again if scrollbars are added or removed by overflow:au to, 641 // We need to layout again if scrollbars are added or removed by overflow:au to,
654 // or by changing between native and custom. 642 // or by changing between native and custom.
655 bool horizontalScrollBarChanged = (box().hasAutoHorizontalScrollbar() && (ha sHorizontalScrollbar() != hasHorizontalOverflow)) 643 bool horizontalScrollbarChanged = (box().hasAutoHorizontalScrollbar() && (ha sHorizontalScrollbar() != hasHorizontalOverflow))
656 || (box().style()->overflowX() == OverflowScroll && !horizontalScrollbar ()); 644 || (box().style()->overflowX() == OverflowScroll && !horizontalScrollbar ());
657 bool verticalScrollBarChanged = (box().hasAutoVerticalScrollbar() && (hasVer ticalScrollbar() != hasVerticalOverflow)) 645 bool verticalScrollbarChanged = (box().hasAutoVerticalScrollbar() && (hasVer ticalScrollbar() != hasVerticalOverflow))
658 || (box().style()->overflowY() == OverflowScroll && !verticalScrollbar() ); 646 || (box().style()->overflowY() == OverflowScroll && !verticalScrollbar() );
659 if (!visualViewportSuppliesScrollbars() && (horizontalScrollBarChanged || ve rticalScrollBarChanged)) { 647 if (!scrollbarsAreFrozen && !visualViewportSuppliesScrollbars() && (horizont alScrollbarChanged || verticalScrollbarChanged)) {
660 if (box().hasAutoHorizontalScrollbar()) 648 if (box().hasAutoHorizontalScrollbar())
661 setHasHorizontalScrollbar(hasHorizontalOverflow); 649 setHasHorizontalScrollbar(hasHorizontalOverflow);
662 else if (box().style()->overflowX() == OverflowScroll) 650 else if (box().style()->overflowX() == OverflowScroll)
663 setHasHorizontalScrollbar(true); 651 setHasHorizontalScrollbar(true);
664 if (box().hasAutoVerticalScrollbar()) 652 if (box().hasAutoVerticalScrollbar())
665 setHasVerticalScrollbar(hasVerticalOverflow); 653 setHasVerticalScrollbar(hasVerticalOverflow);
666 else if (box().style()->overflowY() == OverflowScroll) 654 else if (box().style()->overflowY() == OverflowScroll)
667 setHasVerticalScrollbar(true); 655 setHasVerticalScrollbar(true);
668 656
669 if (hasVerticalOverflow || hasHorizontalOverflow) 657 if (hasVerticalOverflow || hasHorizontalOverflow)
670 updateScrollCornerStyle(); 658 updateScrollCornerStyle();
671 659
672 layer()->updateSelfPaintingLayer(); 660 layer()->updateSelfPaintingLayer();
673 661
674 // Force an update since we know the scrollbars have changed things. 662 // Force an update since we know the scrollbars have changed things.
675 if (box().document().hasAnnotatedRegions()) 663 if (box().document().hasAnnotatedRegions())
676 box().document().setAnnotatedRegionsDirty(true); 664 box().document().setAnnotatedRegionsDirty(true);
677 665
678 // Our proprietary overflow: overlay value doesn't trigger a layout. 666 // Our proprietary overflow: overlay value doesn't trigger a layout.
679 if ((horizontalScrollBarChanged && box().style()->overflowX() != Overflo wOverlay) || (verticalScrollBarChanged && box().style()->overflowY() != Overflow Overlay)) { 667 if ((horizontalScrollbarChanged && box().style()->overflowX() != Overflo wOverlay) || (verticalScrollbarChanged && box().style()->overflowY() != Overflow Overlay)) {
680 if (!m_inOverflowRelayout) { 668 if (!m_inOverflowRelayout) {
681 m_inOverflowRelayout = true; 669 if ((verticalScrollbarChanged && box().isHorizontalWritingMode() )
682 if (delayedLayoutScope) { 670 || (horizontalScrollbarChanged && !box().isHorizontalWriting Mode())) {
671 box().setPreferredLogicalWidthsDirty();
672 box().updateLogicalWidth();
673 }
674 if (relayoutIsPrevented) {
683 if (box().isLayoutBlock()) 675 if (box().isLayoutBlock())
684 toLayoutBlock(box()).scrollbarsChanged(horizontalScrollB arChanged, verticalScrollBarChanged); 676 toLayoutBlock(box()).scrollbarsChanged(horizontalScrollb arChanged, verticalScrollbarChanged);
685 delayedLayoutScope->setNeedsLayout(&box(), LayoutInvalidatio nReason::ScrollbarChanged); 677 PreventRelayoutScope::setNeedsLayout(box());
686 didMarkForDelayedLayout = true;
687 } else { 678 } else {
679 m_inOverflowRelayout = true;
688 SubtreeLayoutScope layoutScope(box()); 680 SubtreeLayoutScope layoutScope(box());
689 layoutScope.setNeedsLayout(&box(), LayoutInvalidationReason: :ScrollbarChanged); 681 layoutScope.setNeedsLayout(&box(), LayoutInvalidationReason: :ScrollbarChanged);
690 if (box().isLayoutBlock()) { 682 if (box().isLayoutBlock()) {
691 LayoutBlock& block = toLayoutBlock(box()); 683 LayoutBlock& block = toLayoutBlock(box());
692 block.scrollbarsChanged(horizontalScrollBarChanged, vert icalScrollBarChanged); 684 block.scrollbarsChanged(horizontalScrollbarChanged, vert icalScrollbarChanged);
693 block.layoutBlock(true); 685 block.layoutBlock(true);
694 } else { 686 } else {
695 box().layout(); 687 box().layout();
696 } 688 }
689 m_inOverflowRelayout = false;
690 m_scrollbarManager.destroyDetachedScrollbars();
697 } 691 }
698 LayoutObject* parent = box().parent(); 692 LayoutObject* parent = box().parent();
699 if (parent && parent->isFlexibleBox()) 693 if (parent && parent->isFlexibleBox())
700 toLayoutFlexibleBox(parent)->clearCachedMainSizeForChild(box ()); 694 toLayoutFlexibleBox(parent)->clearCachedMainSizeForChild(box ());
701 m_inOverflowRelayout = false;
702 } 695 }
703 } 696 }
704 } 697 }
705 698
706 { 699 {
707 // Hits in compositing/overflow/automatically-opt-into-composited-scroll ing-after-style-change.html. 700 // Hits in compositing/overflow/automatically-opt-into-composited-scroll ing-after-style-change.html.
708 DisableCompositingQueryAsserts disabler; 701 DisableCompositingQueryAsserts disabler;
709 702
710 // Set up the range (and page step/line step). 703 // Set up the range (and page step/line step).
711 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) { 704 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) {
712 int clientWidth = box().pixelSnappedClientWidth(); 705 int clientWidth = box().pixelSnappedClientWidth();
713 horizontalScrollbar->setProportion(clientWidth, overflowRect().width ()); 706 horizontalScrollbar->setProportion(clientWidth, overflowRect().width ());
714 } 707 }
715 if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) { 708 if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) {
716 int clientHeight = box().pixelSnappedClientHeight(); 709 int clientHeight = box().pixelSnappedClientHeight();
717 verticalScrollbar->setProportion(clientHeight, overflowRect().height ()); 710 verticalScrollbar->setProportion(clientHeight, overflowRect().height ());
718 } 711 }
719 } 712 }
720 713
721 if (hasOverlayScrollbars()) { 714 if (!scrollbarsAreFrozen && hasOverlayScrollbars()) {
722 if (!scrollSize(HorizontalScrollbar)) 715 if (!scrollSize(HorizontalScrollbar))
723 setHasHorizontalScrollbar(false); 716 setHasHorizontalScrollbar(false);
724 if (!scrollSize(VerticalScrollbar)) 717 if (!scrollSize(VerticalScrollbar))
725 setHasVerticalScrollbar(false); 718 setHasVerticalScrollbar(false);
726 } 719 }
727 720
728 bool hasOverflow = hasScrollableHorizontalOverflow() || hasScrollableVertica lOverflow(); 721 clampScrollPositionsAfterLayout();
729 updateScrollableAreaSet(hasOverflow); 722
723 if (!scrollbarsAreFrozen) {
724 bool hasOverflow = hasScrollableHorizontalOverflow() || hasScrollableVer ticalOverflow();
725 updateScrollableAreaSet(hasOverflow);
726 }
730 727
731 DisableCompositingQueryAsserts disabler; 728 DisableCompositingQueryAsserts disabler;
732 positionOverflowControls(); 729 positionOverflowControls();
730 }
733 731
734 return didMarkForDelayedLayout; 732
733 void PaintLayerScrollableArea::clampScrollPositionsAfterLayout()
734 {
735 // If a vertical scrollbar was removed, the min/max scroll positions may hav e changed,
736 // so the scroll positions needs to be clamped. If the scroll position did not change,
737 // but the scroll origin *did* change, we still need to notify the scrollbar s to
738 // update their dimensions.
739
740 if (DelayScrollPositionClampScope::clampingIsDelayed()) {
741 DelayScrollPositionClampScope::setNeedsClamp(this);
742 return;
743 }
744
745 DoublePoint newScrollPosition = clampScrollPosition(scrollPositionDouble());
746 if (newScrollPosition != scrollPositionDouble())
747 ScrollableArea::setScrollPosition(newScrollPosition, ProgrammaticScroll) ;
748 else if (scrollOriginChanged())
749 scrollPositionChanged(newScrollPosition, ProgrammaticScroll);
750
751 setNeedsScrollPositionClamp(false);
752 resetScrollOriginChanged();
735 } 753 }
736 754
737 ScrollBehavior PaintLayerScrollableArea::scrollBehaviorStyle() const 755 ScrollBehavior PaintLayerScrollableArea::scrollBehaviorStyle() const
738 { 756 {
739 return box().style()->getScrollBehavior(); 757 return box().style()->getScrollBehavior();
740 } 758 }
741 759
742 bool PaintLayerScrollableArea::hasHorizontalOverflow() const 760 bool PaintLayerScrollableArea::hasHorizontalOverflow() const
743 { 761 {
744 return pixelSnappedScrollWidth() > box().pixelSnappedClientWidth(); 762 return pixelSnappedScrollWidth() > box().pixelSnappedClientWidth();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 // Avoid drawing two sets of scrollbars when one is provided by the visual v iewport. 810 // Avoid drawing two sets of scrollbars when one is provided by the visual v iewport.
793 if (visualViewportSuppliesScrollbars()) { 811 if (visualViewportSuppliesScrollbars()) {
794 setHasHorizontalScrollbar(false); 812 setHasHorizontalScrollbar(false);
795 setHasVerticalScrollbar(false); 813 setHasVerticalScrollbar(false);
796 return; 814 return;
797 } 815 }
798 816
799 EOverflow overflowX = box().style()->overflowX(); 817 EOverflow overflowX = box().style()->overflowX();
800 EOverflow overflowY = box().style()->overflowY(); 818 EOverflow overflowY = box().style()->overflowY();
801 819
802 // To avoid doing a relayout in updateScrollbarsAfterLayout, we try to keep any automatic scrollbar that was already present.
803 bool needsHorizontalScrollbar = (hasHorizontalScrollbar() && overflowDefines AutomaticScrollbar(overflowX)) || overflowRequiresScrollbar(overflowX); 820 bool needsHorizontalScrollbar = (hasHorizontalScrollbar() && overflowDefines AutomaticScrollbar(overflowX)) || overflowRequiresScrollbar(overflowX);
804 bool needsVerticalScrollbar = (hasVerticalScrollbar() && overflowDefinesAuto maticScrollbar(overflowY)) || overflowRequiresScrollbar(overflowY); 821 bool needsVerticalScrollbar = (hasVerticalScrollbar() && overflowDefinesAuto maticScrollbar(overflowY)) || overflowRequiresScrollbar(overflowY);
805 822
806 // Look for the scrollbarModes and reset the needs Horizontal & vertical Scr ollbar values based on scrollbarModes, as during force style change 823 // Look for the scrollbarModes and reset the needs Horizontal & vertical Scr ollbar values based on scrollbarModes, as during force style change
807 // StyleResolver::styleForDocument returns documentStyle with no overflow v alues, due to which we are destorying the scrollbars that was 824 // StyleResolver::styleForDocument returns documentStyle with no overflow v alues, due to which we are destorying the scrollbars that was
808 // already present. 825 // already present.
809 if (box().isLayoutView()) { 826 if (box().isLayoutView()) {
810 if (LocalFrame* frame = box().frame()) { 827 if (LocalFrame* frame = box().frame()) {
811 if (FrameView* frameView = frame->view()) { 828 if (FrameView* frameView = frame->view()) {
812 ScrollbarMode hMode; 829 ScrollbarMode hMode;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 { 880 {
864 layer()->updateScrollingStateAfterCompositingChange(); 881 layer()->updateScrollingStateAfterCompositingChange();
865 const bool layersChanged = m_topmostScrollChild != m_nextTopmostScrollChild; 882 const bool layersChanged = m_topmostScrollChild != m_nextTopmostScrollChild;
866 m_topmostScrollChild = m_nextTopmostScrollChild; 883 m_topmostScrollChild = m_nextTopmostScrollChild;
867 m_nextTopmostScrollChild = nullptr; 884 m_nextTopmostScrollChild = nullptr;
868 return layersChanged; 885 return layersChanged;
869 } 886 }
870 887
871 void PaintLayerScrollableArea::updateAfterOverflowRecalc() 888 void PaintLayerScrollableArea::updateAfterOverflowRecalc()
872 { 889 {
873 computeScrollDimensions(); 890 updateScrollDimensions();
874 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) { 891 if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) {
875 int clientWidth = box().pixelSnappedClientWidth(); 892 int clientWidth = box().pixelSnappedClientWidth();
876 horizontalScrollbar->setProportion(clientWidth, overflowRect().width()); 893 horizontalScrollbar->setProportion(clientWidth, overflowRect().width());
877 } 894 }
878 if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) { 895 if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) {
879 int clientHeight = box().pixelSnappedClientHeight(); 896 int clientHeight = box().pixelSnappedClientHeight();
880 verticalScrollbar->setProportion(clientHeight, overflowRect().height()); 897 verticalScrollbar->setProportion(clientHeight, overflowRect().height());
881 } 898 }
882 899
883 bool hasHorizontalOverflow = this->hasHorizontalOverflow(); 900 bool hasHorizontalOverflow = this->hasHorizontalOverflow();
884 bool hasVerticalOverflow = this->hasVerticalOverflow(); 901 bool hasVerticalOverflow = this->hasVerticalOverflow();
885 bool autoHorizontalScrollBarChanged = box().hasAutoHorizontalScrollbar() && (hasHorizontalScrollbar() != hasHorizontalOverflow); 902 bool autoHorizontalScrollbarChanged = box().hasAutoHorizontalScrollbar() && (hasHorizontalScrollbar() != hasHorizontalOverflow);
886 bool autoVerticalScrollBarChanged = box().hasAutoVerticalScrollbar() && (has VerticalScrollbar() != hasVerticalOverflow); 903 bool autoVerticalScrollbarChanged = box().hasAutoVerticalScrollbar() && (has VerticalScrollbar() != hasVerticalOverflow);
887 if (autoHorizontalScrollBarChanged || autoVerticalScrollBarChanged) 904 if (autoHorizontalScrollbarChanged || autoVerticalScrollbarChanged)
888 box().setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::U nknown); 905 box().setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::U nknown);
889 } 906 }
890 907
891 IntRect PaintLayerScrollableArea::rectForHorizontalScrollbar(const IntRect& bord erBoxRect) const 908 IntRect PaintLayerScrollableArea::rectForHorizontalScrollbar(const IntRect& bord erBoxRect) const
892 { 909 {
893 if (!hasHorizontalScrollbar()) 910 if (!hasHorizontalScrollbar())
894 return IntRect(); 911 return IntRect();
895 912
896 const IntRect& scrollCorner = scrollCornerRect(); 913 const IntRect& scrollCorner = scrollCornerRect();
897 914
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 if (hasVerticalScrollbar() && verticalScrollbar()->isCustomScrollbar()) { 1012 if (hasVerticalScrollbar() && verticalScrollbar()->isCustomScrollbar()) {
996 if (actualLayoutObject != toLayoutScrollbar(verticalScrollbar())->owning LayoutObject()) 1013 if (actualLayoutObject != toLayoutScrollbar(verticalScrollbar())->owning LayoutObject())
997 didCustomScrollbarOwnerChanged = true; 1014 didCustomScrollbarOwnerChanged = true;
998 } 1015 }
999 1016
1000 return hasAnyScrollbar && ((shouldUseCustom != hasCustom) || (shouldUseCusto m && didCustomScrollbarOwnerChanged)); 1017 return hasAnyScrollbar && ((shouldUseCustom != hasCustom) || (shouldUseCusto m && didCustomScrollbarOwnerChanged));
1001 } 1018 }
1002 1019
1003 void PaintLayerScrollableArea::setHasHorizontalScrollbar(bool hasScrollbar) 1020 void PaintLayerScrollableArea::setHasHorizontalScrollbar(bool hasScrollbar)
1004 { 1021 {
1022 if (FreezeScrollbarsScope::scrollbarsAreFrozen())
1023 return;
1024
1005 if (hasScrollbar == hasHorizontalScrollbar()) 1025 if (hasScrollbar == hasHorizontalScrollbar())
1006 return; 1026 return;
1007 1027
1008 setScrollbarNeedsPaintInvalidation(HorizontalScrollbar); 1028 setScrollbarNeedsPaintInvalidation(HorizontalScrollbar);
1009 1029
1010 m_scrollbarManager.setHasHorizontalScrollbar(hasScrollbar); 1030 m_scrollbarManager.setHasHorizontalScrollbar(hasScrollbar, !m_inOverflowRela yout);
1031
1032 updateScrollOrigin();
1011 1033
1012 // Destroying or creating one bar can cause our scrollbar corner to come and go. We need to update the opposite scrollbar's style. 1034 // Destroying or creating one bar can cause our scrollbar corner to come and go. We need to update the opposite scrollbar's style.
1013 if (hasHorizontalScrollbar()) 1035 if (hasHorizontalScrollbar())
1014 horizontalScrollbar()->styleChanged(); 1036 horizontalScrollbar()->styleChanged();
1015 if (hasVerticalScrollbar()) 1037 if (hasVerticalScrollbar())
1016 verticalScrollbar()->styleChanged(); 1038 verticalScrollbar()->styleChanged();
1017 1039
1018 setScrollCornerNeedsPaintInvalidation(); 1040 setScrollCornerNeedsPaintInvalidation();
1019 1041
1020 // Force an update since we know the scrollbars have changed things. 1042 // Force an update since we know the scrollbars have changed things.
1021 if (box().document().hasAnnotatedRegions()) 1043 if (box().document().hasAnnotatedRegions())
1022 box().document().setAnnotatedRegionsDirty(true); 1044 box().document().setAnnotatedRegionsDirty(true);
1023 } 1045 }
1024 1046
1025 void PaintLayerScrollableArea::setHasVerticalScrollbar(bool hasScrollbar) 1047 void PaintLayerScrollableArea::setHasVerticalScrollbar(bool hasScrollbar)
1026 { 1048 {
1049 if (FreezeScrollbarsScope::scrollbarsAreFrozen())
1050 return;
1051
1027 if (hasScrollbar == hasVerticalScrollbar()) 1052 if (hasScrollbar == hasVerticalScrollbar())
1028 return; 1053 return;
1029 1054
1030 setScrollbarNeedsPaintInvalidation(VerticalScrollbar); 1055 setScrollbarNeedsPaintInvalidation(VerticalScrollbar);
1031 1056
1032 m_scrollbarManager.setHasVerticalScrollbar(hasScrollbar); 1057 m_scrollbarManager.setHasVerticalScrollbar(hasScrollbar, !m_inOverflowRelayo ut);
1058
1059 updateScrollOrigin();
1033 1060
1034 // Destroying or creating one bar can cause our scrollbar corner to come and go. We need to update the opposite scrollbar's style. 1061 // Destroying or creating one bar can cause our scrollbar corner to come and go. We need to update the opposite scrollbar's style.
1035 if (hasHorizontalScrollbar()) 1062 if (hasHorizontalScrollbar())
1036 horizontalScrollbar()->styleChanged(); 1063 horizontalScrollbar()->styleChanged();
1037 if (hasVerticalScrollbar()) 1064 if (hasVerticalScrollbar())
1038 verticalScrollbar()->styleChanged(); 1065 verticalScrollbar()->styleChanged();
1039 1066
1040 setScrollCornerNeedsPaintInvalidation(); 1067 setScrollCornerNeedsPaintInvalidation();
1041 1068
1042 // Force an update since we know the scrollbars have changed things. 1069 // Force an update since we know the scrollbars have changed things.
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
1493 { 1520 {
1494 if (LocalFrame* frame = box().frame()) { 1521 if (LocalFrame* frame = box().frame()) {
1495 if (Page* page = frame->page()) 1522 if (Page* page = frame->page())
1496 return page->scrollingCoordinator() ? page->scrollingCoordinator()-> compositorAnimationTimeline() : nullptr; 1523 return page->scrollingCoordinator() ? page->scrollingCoordinator()-> compositorAnimationTimeline() : nullptr;
1497 } 1524 }
1498 return nullptr; 1525 return nullptr;
1499 } 1526 }
1500 1527
1501 PaintLayerScrollableArea::ScrollbarManager::ScrollbarManager(PaintLayerScrollabl eArea& scrollableArea) 1528 PaintLayerScrollableArea::ScrollbarManager::ScrollbarManager(PaintLayerScrollabl eArea& scrollableArea)
1502 : m_scrollableArea(&scrollableArea) 1529 : m_scrollableArea(&scrollableArea)
1503 , m_canDetachScrollbars(0)
1504 , m_hBarIsAttached(0) 1530 , m_hBarIsAttached(0)
1505 , m_vBarIsAttached(0) 1531 , m_vBarIsAttached(0)
1506 { 1532 {
1507 } 1533 }
1508 1534
1509 void PaintLayerScrollableArea::ScrollbarManager::dispose() 1535 void PaintLayerScrollableArea::ScrollbarManager::dispose()
1510 { 1536 {
1511 m_canDetachScrollbars = m_hBarIsAttached = m_vBarIsAttached = 0; 1537 m_hBarIsAttached = m_vBarIsAttached = 0;
1512 destroyScrollbar(HorizontalScrollbar); 1538 destroyScrollbar(HorizontalScrollbar);
1513 destroyScrollbar(VerticalScrollbar); 1539 destroyScrollbar(VerticalScrollbar);
1514 } 1540 }
1515 1541
1516 void PaintLayerScrollableArea::ScrollbarManager::setCanDetachScrollbars(bool det ach) 1542 void PaintLayerScrollableArea::ScrollbarManager::destroyDetachedScrollbars()
1517 { 1543 {
1518 ASSERT(!m_hBarIsAttached || m_hBar); 1544 ASSERT(!m_hBarIsAttached || m_hBar);
1519 ASSERT(!m_vBarIsAttached || m_vBar); 1545 ASSERT(!m_vBarIsAttached || m_vBar);
1520 m_canDetachScrollbars = detach ? 1 : 0; 1546 if (m_hBar && !m_hBarIsAttached)
1521 if (!detach) { 1547 destroyScrollbar(HorizontalScrollbar);
1522 if (m_hBar && !m_hBarIsAttached) 1548 if (m_vBar && !m_vBarIsAttached)
1523 destroyScrollbar(HorizontalScrollbar); 1549 destroyScrollbar(VerticalScrollbar);
1524 if (m_vBar && !m_vBarIsAttached)
1525 destroyScrollbar(VerticalScrollbar);
1526 }
1527 } 1550 }
1528 1551
1529 void PaintLayerScrollableArea::ScrollbarManager::setHasHorizontalScrollbar(bool hasScrollbar) 1552 void PaintLayerScrollableArea::ScrollbarManager::setHasHorizontalScrollbar(bool hasScrollbar, bool canDetach)
1530 { 1553 {
1531 if (hasScrollbar) { 1554 if (hasScrollbar) {
1532 // This doesn't hit in any tests, but since the equivalent code in setHa sVerticalScrollbar 1555 // This doesn't hit in any tests, but since the equivalent code in setHa sVerticalScrollbar
1533 // does, presumably this code does as well. 1556 // does, presumably this code does as well.
1534 DisableCompositingQueryAsserts disabler; 1557 DisableCompositingQueryAsserts disabler;
1535 if (!m_hBar) { 1558 if (!m_hBar) {
1536 m_hBar = createScrollbar(HorizontalScrollbar); 1559 m_hBar = createScrollbar(HorizontalScrollbar);
1537 m_hBarIsAttached = 1; 1560 m_hBarIsAttached = 1;
1538 if (!m_hBar->isCustomScrollbar()) 1561 if (!m_hBar->isCustomScrollbar())
1539 m_scrollableArea->didAddScrollbar(*m_hBar, HorizontalScrollbar); 1562 m_scrollableArea->didAddScrollbar(*m_hBar, HorizontalScrollbar);
1540 } else { 1563 } else {
1541 m_hBarIsAttached = 1; 1564 m_hBarIsAttached = 1;
1542 } 1565 }
1543
1544 } else { 1566 } else {
1545 m_hBarIsAttached = 0; 1567 m_hBarIsAttached = 0;
1546 if (!m_canDetachScrollbars) 1568 if (!canDetach)
1547 destroyScrollbar(HorizontalScrollbar); 1569 destroyScrollbar(HorizontalScrollbar);
1548 } 1570 }
1549 } 1571 }
1550 1572
1551 void PaintLayerScrollableArea::ScrollbarManager::setHasVerticalScrollbar(bool ha sScrollbar) 1573 void PaintLayerScrollableArea::ScrollbarManager::setHasVerticalScrollbar(bool ha sScrollbar, bool canDetach)
1552 { 1574 {
1553 if (hasScrollbar) { 1575 if (hasScrollbar) {
1554 DisableCompositingQueryAsserts disabler; 1576 DisableCompositingQueryAsserts disabler;
1555 if (!m_vBar) { 1577 if (!m_vBar) {
1556 m_vBar = createScrollbar(VerticalScrollbar); 1578 m_vBar = createScrollbar(VerticalScrollbar);
1557 m_vBarIsAttached = 1; 1579 m_vBarIsAttached = 1;
1558 if (!m_vBar->isCustomScrollbar()) 1580 if (!m_vBar->isCustomScrollbar())
1559 m_scrollableArea->didAddScrollbar(*m_vBar, VerticalScrollbar); 1581 m_scrollableArea->didAddScrollbar(*m_vBar, VerticalScrollbar);
1560 } else { 1582 } else {
1561 m_vBarIsAttached = 1; 1583 m_vBarIsAttached = 1;
1562 } 1584 }
1563
1564 } else { 1585 } else {
1565 m_vBarIsAttached = 0; 1586 m_vBarIsAttached = 0;
1566 if (!m_canDetachScrollbars) 1587 if (!canDetach)
1567 destroyScrollbar(VerticalScrollbar); 1588 destroyScrollbar(VerticalScrollbar);
1568 } 1589 }
1569 } 1590 }
1570 1591
1571 Scrollbar* PaintLayerScrollableArea::ScrollbarManager::createScrollbar(Scrollbar Orientation orientation) 1592 Scrollbar* PaintLayerScrollableArea::ScrollbarManager::createScrollbar(Scrollbar Orientation orientation)
1572 { 1593 {
1573 ASSERT(orientation == HorizontalScrollbar ? !m_hBarIsAttached : !m_vBarIsAtt ached); 1594 ASSERT(orientation == HorizontalScrollbar ? !m_hBarIsAttached : !m_vBarIsAtt ached);
1574 Scrollbar* scrollbar = nullptr; 1595 Scrollbar* scrollbar = nullptr;
1575 const LayoutObject& actualLayoutObject = layoutObjectForScrollbar(m_scrollab leArea->box()); 1596 const LayoutObject& actualLayoutObject = layoutObjectForScrollbar(m_scrollab leArea->box());
1576 bool hasCustomScrollbarStyle = actualLayoutObject.isBox() && actualLayoutObj ect.styleRef().hasPseudoStyle(PseudoIdScrollbar); 1597 bool hasCustomScrollbarStyle = actualLayoutObject.isBox() && actualLayoutObj ect.styleRef().hasPseudoStyle(PseudoIdScrollbar);
(...skipping 30 matching lines...) Expand all
1607 scrollbar = nullptr; 1628 scrollbar = nullptr;
1608 } 1629 }
1609 1630
1610 DEFINE_TRACE(PaintLayerScrollableArea::ScrollbarManager) 1631 DEFINE_TRACE(PaintLayerScrollableArea::ScrollbarManager)
1611 { 1632 {
1612 visitor->trace(m_scrollableArea); 1633 visitor->trace(m_scrollableArea);
1613 visitor->trace(m_hBar); 1634 visitor->trace(m_hBar);
1614 visitor->trace(m_vBar); 1635 visitor->trace(m_vBar);
1615 } 1636 }
1616 1637
1638 int PaintLayerScrollableArea::PreventRelayoutScope::s_count = 0;
1639 SubtreeLayoutScope* PaintLayerScrollableArea::PreventRelayoutScope::s_layoutScop e = nullptr;
1640 bool PaintLayerScrollableArea::PreventRelayoutScope::s_relayoutNeeded = false;
1641 WTF::Vector<LayoutObject*>* PaintLayerScrollableArea::PreventRelayoutScope::s_ne edsRelayout = nullptr;
1642
1643 PaintLayerScrollableArea::PreventRelayoutScope::PreventRelayoutScope(SubtreeLayo utScope& layoutScope)
1644 {
1645 if (!s_count) {
1646 ASSERT(!s_layoutScope);
1647 ASSERT(!s_needsRelayout || s_needsRelayout->isEmpty());
1648 s_layoutScope = &layoutScope;
1649 }
1650 s_count++;
1651 }
1652
1653 PaintLayerScrollableArea::PreventRelayoutScope::~PreventRelayoutScope()
1654 {
1655 if (--s_count == 0) {
1656 if (s_relayoutNeeded) {
1657 for (auto layoutObject : *s_needsRelayout)
1658 s_layoutScope->setNeedsLayout(layoutObject, LayoutInvalidationRe ason::ScrollbarChanged);
1659 s_needsRelayout->clear();
1660 }
1661 s_layoutScope = nullptr;
1662 }
1663 }
1664
1665 void PaintLayerScrollableArea::PreventRelayoutScope::setNeedsLayout(LayoutObject & layoutObject)
1666 {
1667 ASSERT(s_count);
1668 ASSERT(s_layoutScope);
1669 s_relayoutNeeded = true;
1670 if (!s_needsRelayout)
1671 s_needsRelayout = new WTF::Vector<LayoutObject*>();
1672 s_needsRelayout->append(&layoutObject);
1673 }
1674
1675 void PaintLayerScrollableArea::PreventRelayoutScope::resetRelayoutNeeded()
1676 {
1677 ASSERT(s_count == 0);
1678 ASSERT(!s_needsRelayout || s_needsRelayout->isEmpty());
1679 s_relayoutNeeded = false;
1680 }
1681
1682 int PaintLayerScrollableArea::FreezeScrollbarsScope::s_count = 0;
1683
1684 int PaintLayerScrollableArea::DelayScrollPositionClampScope::s_count = 0;
1685 PersistentHeapVector<Member<PaintLayerScrollableArea>>* PaintLayerScrollableArea ::DelayScrollPositionClampScope::s_needsClamp = nullptr;
1686
1687 PaintLayerScrollableArea::DelayScrollPositionClampScope::DelayScrollPositionClam pScope()
1688 {
1689 if (!s_needsClamp)
1690 s_needsClamp = new PersistentHeapVector<Member<PaintLayerScrollableArea> >();
1691 ASSERT(s_count > 0 || s_needsClamp->isEmpty());
1692 s_count++;
1693 }
1694
1695 PaintLayerScrollableArea::DelayScrollPositionClampScope::~DelayScrollPositionCla mpScope()
1696 {
1697 if (--s_count == 0)
1698 DelayScrollPositionClampScope::clampScrollableAreas();
1699 }
1700
1701 void PaintLayerScrollableArea::DelayScrollPositionClampScope::setNeedsClamp(Pain tLayerScrollableArea* scrollableArea)
1702 {
1703 if (!scrollableArea->needsScrollPositionClamp()) {
1704 scrollableArea->setNeedsScrollPositionClamp(true);
1705 s_needsClamp->append(scrollableArea);
1706 }
1707 }
1708
1709 void PaintLayerScrollableArea::DelayScrollPositionClampScope::clampScrollableAre as()
1710 {
1711 for (auto& scrollableArea : *s_needsClamp)
1712 scrollableArea->clampScrollPositionsAfterLayout();
1713 delete s_needsClamp;
1714 s_needsClamp = nullptr;
1715 }
1716
1617 } // namespace blink 1717 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698