Bug 1656802. Make visual viewport only layout scrollbars affect the composition bounds/visual viewport. r=emilio,kats

AFAICT the spec says that these layout scrollbars that take up no layout space that scroll the visual viewport do affect the size of the visual viewport. (Double check this)

Most other users don't care about the size of these special scrollbars.

I left nsIDOMWindowUtils::getScrollbarSize unchanged (NB different from nsIDOMWindowUtils::getScrollbarSizes which is modified by this patch) because I'm less sure. I will file a followup about it.

Differential Revision: https://phabricator.services.mozilla.com/D85708
This commit is contained in:
Timothy Nikkel 2020-08-07 10:05:10 +00:00
Родитель 0f0f71e5bc
Коммит 2f60aa099a
6 изменённых файлов: 60 добавлений и 12 удалений

Просмотреть файл

@ -558,8 +558,10 @@ nsDOMWindowUtils::GetScrollbarSizes(Element* aElement,
return NS_ERROR_INVALID_ARG; return NS_ERROR_INVALID_ARG;
} }
CSSIntMargin scrollbarSizes = RoundedToInt( CSSIntMargin scrollbarSizes =
CSSMargin::FromAppUnits(scrollFrame->GetActualScrollbarSizes())); RoundedToInt(CSSMargin::FromAppUnits(scrollFrame->GetActualScrollbarSizes(
nsIScrollableFrame::ScrollbarSizesOptions::
INCLUDE_VISUAL_VIEWPORT_SCROLLBARS)));
*aOutVerticalScrollbarWidth = scrollbarSizes.LeftRight(); *aOutVerticalScrollbarWidth = scrollbarSizes.LeftRight();
*aOutHorizontalScrollbarHeight = scrollbarSizes.TopBottom(); *aOutHorizontalScrollbarHeight = scrollbarSizes.TopBottom();

Просмотреть файл

@ -205,6 +205,11 @@ interface nsIDOMWindowUtils : nsISupports {
* Note that on some platforms, scrollbars don't take up layout space * Note that on some platforms, scrollbars don't take up layout space
* ("overlay scrollbars"). On such platforms, the returned sizes are * ("overlay scrollbars"). On such platforms, the returned sizes are
* always zero. * always zero.
*
* Layout scrollbars that normally take up space but were only shown to
* scroll the visual viewport inside the layout viewport (the layout viewport
* cannot be scrolled) do not take up space but they still return their size
* from this function.
*/ */
void getScrollbarSizes(in Element aElement, void getScrollbarSizes(in Element aElement,
out uint32_t aVerticalScrollbarWidth, out uint32_t aVerticalScrollbarWidth,

Просмотреть файл

@ -8798,7 +8798,9 @@ nsMargin nsLayoutUtils::ScrollbarAreaToExcludeFromCompositionBoundsFor(
if (!scrollableFrame) { if (!scrollableFrame) {
return nsMargin(); return nsMargin();
} }
return scrollableFrame->GetActualScrollbarSizes(); return scrollableFrame->GetActualScrollbarSizes(
nsIScrollableFrame::ScrollbarSizesOptions::
INCLUDE_VISUAL_VIEWPORT_SCROLLBARS);
} }
/* static */ /* static */

Просмотреть файл

@ -6905,11 +6905,38 @@ nsRect ScrollFrameHelper::GetUnsnappedScrolledRectInternal(
aScrollPortSize, GetScrolledFrameDir()); aScrollPortSize, GetScrolledFrameDir());
} }
nsMargin ScrollFrameHelper::GetActualScrollbarSizes() const { nsMargin ScrollFrameHelper::GetActualScrollbarSizes(
nsIScrollableFrame::ScrollbarSizesOptions
aOptions /* = nsIScrollableFrame::ScrollbarSizesOptions::NONE */)
const {
nsRect r = mOuter->GetPaddingRectRelativeToSelf(); nsRect r = mOuter->GetPaddingRectRelativeToSelf();
return nsMargin(mScrollPort.y - r.y, r.XMost() - mScrollPort.XMost(), nsMargin m(mScrollPort.y - r.y, r.XMost() - mScrollPort.XMost(),
r.YMost() - mScrollPort.YMost(), mScrollPort.x - r.x); r.YMost() - mScrollPort.YMost(), mScrollPort.x - r.x);
if (aOptions == nsIScrollableFrame::ScrollbarSizesOptions::
INCLUDE_VISUAL_VIEWPORT_SCROLLBARS &&
!UsesOverlayScrollbars()) {
// If we are using layout scrollbars and they only exist to scroll the
// visual viewport then they do not take up any layout space (so the
// scrollport is the same as the padding rect) but they do cover everything
// below them so some callers may want to include this special type of
// scrollbars in the returned value.
if (mHScrollbarBox && mHasHorizontalScrollbar &&
mOnlyNeedHScrollbarToScrollVVInsideLV) {
m.bottom += mHScrollbarBox->GetRect().height;
}
if (mVScrollbarBox && mHasVerticalScrollbar &&
mOnlyNeedVScrollbarToScrollVVInsideLV) {
if (IsScrollbarOnRight()) {
m.right += mVScrollbarBox->GetRect().width;
} else {
m.left += mVScrollbarBox->GetRect().width;
}
}
}
return m;
} }
void ScrollFrameHelper::SetScrollbarVisibility(nsIFrame* aScrollbar, void ScrollFrameHelper::SetScrollbarVisibility(nsIFrame* aScrollbar,

Просмотреть файл

@ -344,7 +344,9 @@ class ScrollFrameHelper : public nsIReflowCallback {
return (mHasVerticalScrollbar ? nsIScrollableFrame::VERTICAL : 0) | return (mHasVerticalScrollbar ? nsIScrollableFrame::VERTICAL : 0) |
(mHasHorizontalScrollbar ? nsIScrollableFrame::HORIZONTAL : 0); (mHasHorizontalScrollbar ? nsIScrollableFrame::HORIZONTAL : 0);
} }
nsMargin GetActualScrollbarSizes() const; nsMargin GetActualScrollbarSizes(
nsIScrollableFrame::ScrollbarSizesOptions aOptions =
nsIScrollableFrame::ScrollbarSizesOptions::NONE) const;
nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState); nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState);
nscoord GetNondisappearingScrollbarWidth(nsBoxLayoutState* aState, nscoord GetNondisappearingScrollbarWidth(nsBoxLayoutState* aState,
mozilla::WritingMode aVerticalWM); mozilla::WritingMode aVerticalWM);
@ -905,8 +907,10 @@ class nsHTMLScrollFrame : public nsContainerFrame,
uint32_t GetScrollbarVisibility() const final { uint32_t GetScrollbarVisibility() const final {
return mHelper.GetScrollbarVisibility(); return mHelper.GetScrollbarVisibility();
} }
nsMargin GetActualScrollbarSizes() const final { nsMargin GetActualScrollbarSizes(
return mHelper.GetActualScrollbarSizes(); nsIScrollableFrame::ScrollbarSizesOptions aOptions =
nsIScrollableFrame::ScrollbarSizesOptions::NONE) const final {
return mHelper.GetActualScrollbarSizes(aOptions);
} }
nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) final { nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) final {
return mHelper.GetDesiredScrollbarSizes(aState); return mHelper.GetDesiredScrollbarSizes(aState);
@ -1385,8 +1389,10 @@ class nsXULScrollFrame final : public nsBoxFrame,
uint32_t GetScrollbarVisibility() const final { uint32_t GetScrollbarVisibility() const final {
return mHelper.GetScrollbarVisibility(); return mHelper.GetScrollbarVisibility();
} }
nsMargin GetActualScrollbarSizes() const final { nsMargin GetActualScrollbarSizes(
return mHelper.GetActualScrollbarSizes(); nsIScrollableFrame::ScrollbarSizesOptions aOptions =
nsIScrollableFrame::ScrollbarSizesOptions::NONE) const final {
return mHelper.GetActualScrollbarSizes(aOptions);
} }
nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) final { nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState) final {
return mHelper.GetDesiredScrollbarSizes(aState); return mHelper.GetDesiredScrollbarSizes(aState);

Просмотреть файл

@ -114,8 +114,14 @@ class nsIScrollableFrame : public nsIScrollbarMediator {
* positions that don't have a scrollbar or where the scrollbar is not * positions that don't have a scrollbar or where the scrollbar is not
* visible. Do not call this while this frame's descendants are being * visible. Do not call this while this frame's descendants are being
* reflowed, it won't be accurate. * reflowed, it won't be accurate.
* INCLUDE_VISUAL_VIEWPORT_SCROLLBARS means we include the size of layout
* scrollbars that are only visible to scroll the visual viewport inside the
* layout viewport (ie the layout viewport cannot be scrolled) even though
* there is no layout space set aside for these scrollbars.
*/ */
virtual nsMargin GetActualScrollbarSizes() const = 0; enum class ScrollbarSizesOptions { NONE, INCLUDE_VISUAL_VIEWPORT_SCROLLBARS };
virtual nsMargin GetActualScrollbarSizes(
ScrollbarSizesOptions aOptions = ScrollbarSizesOptions::NONE) const = 0;
/** /**
* Return the sizes of all scrollbars assuming that any scrollbars that could * Return the sizes of all scrollbars assuming that any scrollbars that could
* be visible due to overflowing content, are. This can be called during * be visible due to overflowing content, are. This can be called during