From 0534c6ad1a5573183250acbc3b1989e88714b35e Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Thu, 15 Oct 2020 04:54:41 +0000 Subject: [PATCH] Bug 1670853 - Support scrollbar-color and scrollbar-width on cross-platform and Linux non-native theme. r=spohl Differential Revision: https://phabricator.services.mozilla.com/D93307 --- gfx/2d/Types.h | 7 +- layout/base/nsCSSColorUtils.h | 5 +- widget/gtk/nsNativeBasicThemeGTK.cpp | 99 +++++++----- widget/gtk/nsNativeBasicThemeGTK.h | 4 + widget/nsNativeBasicTheme.cpp | 226 +++++++++++++++++++-------- widget/nsNativeBasicTheme.h | 17 +- 6 files changed, 246 insertions(+), 112 deletions(-) diff --git a/gfx/2d/Types.h b/gfx/2d/Types.h index c10b0cd4cadd..d48ff47d3803 100644 --- a/gfx/2d/Types.h +++ b/gfx/2d/Types.h @@ -450,10 +450,11 @@ enum class LuminanceType : int8_t { /* Color is stored in non-premultiplied form in sRGB color space */ struct sRGBColor { public: - sRGBColor() : r(0.0f), g(0.0f), b(0.0f), a(0.0f) {} - sRGBColor(Float aR, Float aG, Float aB, Float aA) + constexpr sRGBColor() : r(0.0f), g(0.0f), b(0.0f), a(0.0f) {} + constexpr sRGBColor(Float aR, Float aG, Float aB, Float aA) : r(aR), g(aG), b(aB), a(aA) {} - sRGBColor(Float aR, Float aG, Float aB) : r(aR), g(aG), b(aB), a(1.0f) {} + constexpr sRGBColor(Float aR, Float aG, Float aB) + : r(aR), g(aG), b(aB), a(1.0f) {} static sRGBColor White(float aA) { return sRGBColor(1.f, 1.f, 1.f, aA); } diff --git a/layout/base/nsCSSColorUtils.h b/layout/base/nsCSSColorUtils.h index df654b4f1092..23424beb94c9 100644 --- a/layout/base/nsCSSColorUtils.h +++ b/layout/base/nsCSSColorUtils.h @@ -19,6 +19,9 @@ int32_t(mozilla::Abs(NS_GetLuminosity(a | 0xff000000) - \ NS_GetLuminosity(b | 0xff000000))) +// Maximum value that NS_GetLuminosity can return. +#define NS_MAX_LUMINOSITY 255000 + // To determine 3D colors for groove / ridge borders based on the border color void NS_GetSpecial3DColors(nscolor aResult[2], nscolor aBorderColor); @@ -26,7 +29,7 @@ void NS_GetSpecial3DColors(nscolor aResult[2], nscolor aBorderColor); int NS_GetBrightness(uint8_t aRed, uint8_t aGreen, uint8_t aBlue); // Get Luminosity of a specific color. That is same as Y of YIQ color space. -// The range of return value is 0 to 255000. +// The range of return value is 0 to NS_MAX_LUMINOSITY. int32_t NS_GetLuminosity(nscolor aColor); // function to convert from RGBA color space to HSVA color space diff --git a/widget/gtk/nsNativeBasicThemeGTK.cpp b/widget/gtk/nsNativeBasicThemeGTK.cpp index 9025655da5a1..cf5adea6c14a 100644 --- a/widget/gtk/nsNativeBasicThemeGTK.cpp +++ b/widget/gtk/nsNativeBasicThemeGTK.cpp @@ -5,10 +5,13 @@ #include "nsNativeBasicThemeGTK.h" +#include "nsLayoutUtils.h" + using namespace mozilla; -static constexpr CSSIntCoord kMinimumScrollbarSize = 12; -static constexpr CSSIntCoord kMinimumScrollbarThumbSize = 40; +static constexpr CSSIntCoord kGtkMinimumScrollbarSize = 12; +static constexpr CSSIntCoord kGtkMinimumThinScrollbarSize = 6; +static constexpr CSSIntCoord kGtkMinimumScrollbarThumbSize = 40; already_AddRefed do_GetBasicNativeThemeDoNotUseDirectly() { static mozilla::StaticRefPtr gInstance; @@ -38,23 +41,47 @@ nsNativeBasicThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext, StyleAppearance aAppearance, LayoutDeviceIntSize* aResult, bool* aIsOverridable) { - if (!IsWidgetScrollbarPart(aAppearance)) { - return nsNativeBasicTheme::GetMinimumWidgetSize( - aPresContext, aFrame, aAppearance, aResult, aIsOverridable); - } - uint32_t dpiRatio = GetDPIRatio(aFrame); - auto size = static_cast(kMinimumScrollbarSize) * dpiRatio; - aResult->SizeTo(size, size); + + switch (aAppearance) { + case StyleAppearance::Scrollbar: + case StyleAppearance::ScrollbarSmall: + case StyleAppearance::ScrollbarVertical: + case StyleAppearance::ScrollbarHorizontal: + case StyleAppearance::ScrollbarbuttonUp: + case StyleAppearance::ScrollbarbuttonDown: + case StyleAppearance::ScrollbarbuttonLeft: + case StyleAppearance::ScrollbarbuttonRight: + case StyleAppearance::ScrollbarthumbVertical: + case StyleAppearance::ScrollbarthumbHorizontal: + case StyleAppearance::ScrollbartrackHorizontal: + case StyleAppearance::ScrollbartrackVertical: + case StyleAppearance::Scrollcorner: { + ComputedStyle* style = nsLayoutUtils::StyleForScrollbar(aFrame); + if (style->StyleUIReset()->mScrollbarWidth == StyleScrollbarWidth::Thin) { + aResult->SizeTo( + static_cast(kGtkMinimumThinScrollbarSize) * dpiRatio, + static_cast(kGtkMinimumThinScrollbarSize) * dpiRatio); + } else { + aResult->SizeTo( + static_cast(kGtkMinimumScrollbarSize) * dpiRatio, + static_cast(kGtkMinimumScrollbarSize) * dpiRatio); + } + break; + } + default: + return nsNativeBasicTheme::GetMinimumWidgetSize( + aPresContext, aFrame, aAppearance, aResult, aIsOverridable); + } switch (aAppearance) { case StyleAppearance::ScrollbarthumbHorizontal: aResult->width = - static_cast(kMinimumScrollbarThumbSize) * dpiRatio; + static_cast(kGtkMinimumScrollbarThumbSize) * dpiRatio; break; case StyleAppearance::ScrollbarthumbVertical: aResult->height = - static_cast(kMinimumScrollbarThumbSize) * dpiRatio; + static_cast(kGtkMinimumScrollbarThumbSize) * dpiRatio; break; default: break; @@ -64,50 +91,38 @@ nsNativeBasicThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext, return NS_OK; } -static sRGBColor GetScrollbarthumbColor(const EventStates& aState) { - if (aState.HasAllStates(NS_EVENT_STATE_ACTIVE)) { - return widget::sScrollbarThumbColorActive; - } - if (aState.HasAllStates(NS_EVENT_STATE_HOVER)) { - return widget::sScrollbarThumbColorHover; - } - return widget::sScrollbarThumbColor; -} - void nsNativeBasicThemeGTK::PaintScrollbarthumbHorizontal( - DrawTarget* aDrawTarget, const Rect& aRect, const EventStates& aState) { - sRGBColor thumbColor = GetScrollbarthumbColor(aState); + DrawTarget* aDrawTarget, const Rect& aRect, const ComputedStyle& aStyle, + const EventStates& aState) { + sRGBColor thumbColor = ComputeScrollbarthumbColor(aStyle, aState); Rect thumbRect(aRect); - thumbRect.Deflate(aRect.height / 4.0f); + thumbRect.Deflate(floorf(aRect.height / 4.0f)); PaintRoundedRectWithRadius(aDrawTarget, thumbRect, thumbColor, sRGBColor(), 0, thumbRect.height / 2.0f, 1); } void nsNativeBasicThemeGTK::PaintScrollbarthumbVertical( - DrawTarget* aDrawTarget, const Rect& aRect, const EventStates& aState) { - sRGBColor thumbColor = GetScrollbarthumbColor(aState); + DrawTarget* aDrawTarget, const Rect& aRect, const ComputedStyle& aStyle, + const EventStates& aState) { + sRGBColor thumbColor = ComputeScrollbarthumbColor(aStyle, aState); Rect thumbRect(aRect); - thumbRect.Deflate(aRect.width / 4.0f); + thumbRect.Deflate(floorf(aRect.width / 4.0f)); PaintRoundedRectWithRadius(aDrawTarget, thumbRect, thumbColor, sRGBColor(), 0, thumbRect.width / 2.0f, 1); } -void nsNativeBasicThemeGTK::PaintScrollbarHorizontal(DrawTarget* aDrawTarget, - const Rect& aRect, - bool aIsRoot) { - if (!aIsRoot) { - return; - } - aDrawTarget->FillRect(aRect, - ColorPattern(ToDeviceColor(widget::sScrollbarColor))); +void nsNativeBasicThemeGTK::PaintScrollbarHorizontal( + DrawTarget* aDrawTarget, const Rect& aRect, const ComputedStyle& aStyle, + bool aIsRoot) { + sRGBColor trackColor = + ComputeScrollbarColor(aStyle, aIsRoot, /* aDefaultTransparent = */ true); + aDrawTarget->FillRect(aRect, ColorPattern(ToDeviceColor(trackColor))); } void nsNativeBasicThemeGTK::PaintScrollbarVerticalAndCorner( - DrawTarget* aDrawTarget, const Rect& aRect, uint32_t aDpiRatio, - bool aIsRoot) { - if (!aIsRoot) { - return; - } - aDrawTarget->FillRect(aRect, - ColorPattern(ToDeviceColor(widget::sScrollbarColor))); + DrawTarget* aDrawTarget, const Rect& aRect, const ComputedStyle& aStyle, + uint32_t aDpiRatio, bool aIsRoot) { + sRGBColor trackColor = + ComputeScrollbarColor(aStyle, aIsRoot, /* aDefaultTransparent = */ true); + aDrawTarget->FillRect(aRect, ColorPattern(ToDeviceColor(trackColor))); } diff --git a/widget/gtk/nsNativeBasicThemeGTK.h b/widget/gtk/nsNativeBasicThemeGTK.h index 253e66b20f96..3df9a02eff78 100644 --- a/widget/gtk/nsNativeBasicThemeGTK.h +++ b/widget/gtk/nsNativeBasicThemeGTK.h @@ -21,13 +21,17 @@ class nsNativeBasicThemeGTK : public nsNativeBasicTheme { nsITheme::Transparency GetWidgetTransparency( nsIFrame* aFrame, StyleAppearance aAppearance) override; void PaintScrollbarthumbHorizontal(DrawTarget* aDrawTarget, const Rect& aRect, + const ComputedStyle& aStyle, const EventStates& aState) override; void PaintScrollbarthumbVertical(DrawTarget* aDrawTarget, const Rect& aRect, + const ComputedStyle& aStyle, const EventStates& aState) override; void PaintScrollbarHorizontal(DrawTarget* aDrawTarget, const Rect& aRect, + const ComputedStyle& aStyle, bool aIsRoot) override; void PaintScrollbarVerticalAndCorner(DrawTarget* aDrawTarget, const Rect& aRect, + const ComputedStyle& aStyle, uint32_t aDpiRatio, bool aIsRoot) override; diff --git a/widget/nsNativeBasicTheme.cpp b/widget/nsNativeBasicTheme.cpp index cfe99684696a..ce436b995143 100644 --- a/widget/nsNativeBasicTheme.cpp +++ b/widget/nsNativeBasicTheme.cpp @@ -5,6 +5,7 @@ #include "nsNativeBasicTheme.h" +#include "nsCSSColorUtils.h" #include "nsCSSRendering.h" #include "nsLayoutUtils.h" #include "PathHelpers.h" @@ -870,64 +871,115 @@ void nsNativeBasicTheme::PaintButton(nsIFrame* aFrame, DrawTarget* aDrawTarget, } } -void nsNativeBasicTheme::PaintScrollbarthumbHorizontal( - DrawTarget* aDrawTarget, const Rect& aRect, const EventStates& aState) { - sRGBColor thumbColor = sScrollbarThumbColor; - if (aState.HasState(NS_EVENT_STATE_ACTIVE)) { - thumbColor = sScrollbarThumbColorActive; - } else if (aState.HasState(NS_EVENT_STATE_HOVER)) { - thumbColor = sScrollbarThumbColorHover; +sRGBColor nsNativeBasicTheme::ComputeScrollbarthumbColor( + const ComputedStyle& aStyle, const EventStates& aState) { + const nsStyleUI* ui = aStyle.StyleUI(); + if (ui->mScrollbarColor.IsColors()) { + nscolor color = ui->mScrollbarColor.AsColors().thumb.CalcColor(aStyle); + return gfx::sRGBColor::FromABGR(color); } + if (aState.HasAllStates(NS_EVENT_STATE_ACTIVE)) { + return sScrollbarThumbColorActive; + } + if (aState.HasAllStates(NS_EVENT_STATE_HOVER)) { + return sScrollbarThumbColorHover; + } + return sScrollbarThumbColor; +} + +sRGBColor nsNativeBasicTheme::ComputeScrollbarColor(const ComputedStyle& aStyle, + bool aIsRoot, + bool aDefaultTransparent) { + const nsStyleUI* ui = aStyle.StyleUI(); + if (ui->mScrollbarColor.IsColors()) { + nscolor color = ui->mScrollbarColor.AsColors().track.CalcColor(aStyle); + if (aIsRoot) { + color = NS_ComposeColors(sScrollbarColor.ToABGR(), color); + } + return gfx::sRGBColor::FromABGR(color); + } + if (aIsRoot || !aDefaultTransparent) { + return sScrollbarColor; + } + return sScrollbarColorTransparent; +} + +void nsNativeBasicTheme::PaintScrollbarthumbHorizontal( + DrawTarget* aDrawTarget, const Rect& aRect, const ComputedStyle& aStyle, + const EventStates& aState) { + sRGBColor thumbColor = ComputeScrollbarthumbColor(aStyle, aState); aDrawTarget->FillRect(aRect, ColorPattern(ToDeviceColor(thumbColor))); } void nsNativeBasicTheme::PaintScrollbarthumbVertical( - DrawTarget* aDrawTarget, const Rect& aRect, const EventStates& aState) { - sRGBColor thumbColor = sScrollbarThumbColor; - if (aState.HasState(NS_EVENT_STATE_ACTIVE)) { - thumbColor = sScrollbarThumbColorActive; - } else if (aState.HasState(NS_EVENT_STATE_HOVER)) { - thumbColor = sScrollbarThumbColorHover; - } + DrawTarget* aDrawTarget, const Rect& aRect, const ComputedStyle& aStyle, + const EventStates& aState) { + sRGBColor thumbColor = ComputeScrollbarthumbColor(aStyle, aState); aDrawTarget->FillRect(aRect, ColorPattern(ToDeviceColor(thumbColor))); } void nsNativeBasicTheme::PaintScrollbarHorizontal(DrawTarget* aDrawTarget, const Rect& aRect, + const ComputedStyle& aStyle, bool aIsRoot) { - aDrawTarget->FillRect(aRect, ColorPattern(ToDeviceColor(sScrollbarColor))); - RefPtr builder = aDrawTarget->CreatePathBuilder(); - builder->MoveTo(Point(aRect.x, aRect.y)); - builder->LineTo(Point(aRect.x + aRect.width, aRect.y)); - RefPtr path = builder->Finish(); - aDrawTarget->Stroke(path, ColorPattern(ToDeviceColor(sScrollbarBorderColor))); + sRGBColor scrollbarColor = + ComputeScrollbarColor(aStyle, aIsRoot, /* aDefaultTransparent = */ false); + aDrawTarget->FillRect(aRect, ColorPattern(ToDeviceColor(scrollbarColor))); + // FIXME(heycam): We should probably derive the border color when custom + // scrollbar colors are in use too. But for now, just skip painting it, + // to avoid ugliness. + if (aStyle.StyleUI()->mScrollbarColor.IsAuto()) { + RefPtr builder = aDrawTarget->CreatePathBuilder(); + builder->MoveTo(Point(aRect.x, aRect.y)); + builder->LineTo(Point(aRect.x + aRect.width, aRect.y)); + RefPtr path = builder->Finish(); + aDrawTarget->Stroke(path, + ColorPattern(ToDeviceColor(sScrollbarBorderColor))); + } } void nsNativeBasicTheme::PaintScrollbarVerticalAndCorner( - DrawTarget* aDrawTarget, const Rect& aRect, uint32_t aDpiRatio, - bool aIsRoot) { - aDrawTarget->FillRect(aRect, ColorPattern(ToDeviceColor(sScrollbarColor))); - RefPtr builder = aDrawTarget->CreatePathBuilder(); - builder->MoveTo(Point(aRect.x, aRect.y)); - builder->LineTo(Point(aRect.x, aRect.y + aRect.height)); - RefPtr path = builder->Finish(); - aDrawTarget->Stroke(path, ColorPattern(ToDeviceColor(sScrollbarBorderColor)), - StrokeOptions(1.0f * aDpiRatio)); + DrawTarget* aDrawTarget, const Rect& aRect, const ComputedStyle& aStyle, + uint32_t aDpiRatio, bool aIsRoot) { + sRGBColor scrollbarColor = + ComputeScrollbarColor(aStyle, aIsRoot, /* aDefaultTransparent = */ false); + aDrawTarget->FillRect(aRect, ColorPattern(ToDeviceColor(scrollbarColor))); + // FIXME(heycam): We should probably derive the border color when custom + // scrollbar colors are in use too. But for now, just skip painting it, + // to avoid ugliness. + if (aStyle.StyleUI()->mScrollbarColor.IsAuto()) { + RefPtr builder = aDrawTarget->CreatePathBuilder(); + builder->MoveTo(Point(aRect.x, aRect.y)); + builder->LineTo(Point(aRect.x, aRect.y + aRect.height)); + RefPtr path = builder->Finish(); + aDrawTarget->Stroke(path, + ColorPattern(ToDeviceColor(sScrollbarBorderColor)), + StrokeOptions(1.0f * aDpiRatio)); + } } void nsNativeBasicTheme::PaintScrollbarbutton(DrawTarget* aDrawTarget, StyleAppearance aAppearance, const Rect& aRect, + const ComputedStyle& aStyle, const EventStates& aState, uint32_t aDpiRatio) { bool isActive = aState.HasState(NS_EVENT_STATE_ACTIVE); bool isHovered = aState.HasState(NS_EVENT_STATE_HOVER); - aDrawTarget->FillRect( - aRect, ColorPattern( - ToDeviceColor(isActive ? sScrollbarButtonActiveColor - : isHovered ? sScrollbarButtonHoverColor - : sScrollbarColor))); + bool hasCustomColor = aStyle.StyleUI()->mScrollbarColor.IsColors(); + sRGBColor buttonColor; + if (hasCustomColor) { + // When scrollbar-color is in use, use the thumb color for the button. + buttonColor = ComputeScrollbarthumbColor(aStyle, aState); + } else if (isActive) { + buttonColor = sScrollbarButtonActiveColor; + } else if (!hasCustomColor && isHovered) { + buttonColor = sScrollbarButtonHoverColor; + } else { + buttonColor = sScrollbarColor; + } + aDrawTarget->FillRect(aRect, ColorPattern(ToDeviceColor(buttonColor))); // Start with Up arrow. int32_t arrowPolygonX[] = {3, 0, -3}; @@ -961,25 +1013,47 @@ void nsNativeBasicTheme::PaintScrollbarbutton(DrawTarget* aDrawTarget, return; } + sRGBColor arrowColor; + if (hasCustomColor) { + // When scrollbar-color is in use, derive the arrow color from the button + // color. + nscolor bg = buttonColor.ToABGR(); + bool darken = NS_GetLuminosity(bg) >= NS_MAX_LUMINOSITY / 2; + if (isActive) { + float c = darken ? 0.0f : 1.0f; + arrowColor = sRGBColor(c, c, c); + } else { + uint8_t c = darken ? 0 : 255; + arrowColor = sRGBColor::FromABGR(NS_ComposeColors(bg, NS_RGBA(c, c, c, 160))); + } + } else if (isActive) { + arrowColor = sScrollbarArrowColorActive; + } else if (isHovered) { + arrowColor = sScrollbarArrowColorHover; + } else { + arrowColor = sScrollbarArrowColor; + } PaintArrow(aDrawTarget, aRect, arrowPolygonX, arrowPolygonY, arrowNumPoints, - arrowSize, - isActive - ? sScrollbarArrowColorActive - : isHovered ? sScrollbarArrowColorHover : sScrollbarArrowColor, + arrowSize, arrowColor, aDpiRatio); - RefPtr builder = aDrawTarget->CreatePathBuilder(); - builder->MoveTo(Point(aRect.x, aRect.y)); - if (aAppearance == StyleAppearance::ScrollbarbuttonUp || - aAppearance == StyleAppearance::ScrollbarbuttonDown) { - builder->LineTo(Point(aRect.x, aRect.y + aRect.height)); - } else { - builder->LineTo(Point(aRect.x + aRect.width, aRect.y)); - } + // FIXME(heycam): We should probably derive the border color when custom + // scrollbar colors are in use too. But for now, just skip painting it, + // to avoid ugliness. + if (!hasCustomColor) { + RefPtr builder = aDrawTarget->CreatePathBuilder(); + builder->MoveTo(Point(aRect.x, aRect.y)); + if (aAppearance == StyleAppearance::ScrollbarbuttonUp || + aAppearance == StyleAppearance::ScrollbarbuttonDown) { + builder->LineTo(Point(aRect.x, aRect.y + aRect.height)); + } else { + builder->LineTo(Point(aRect.x + aRect.width, aRect.y)); + } - RefPtr path = builder->Finish(); - aDrawTarget->Stroke(path, ColorPattern(ToDeviceColor(sScrollbarBorderColor)), - StrokeOptions(1.0f * aDpiRatio)); + RefPtr path = builder->Finish(); + aDrawTarget->Stroke(path, ColorPattern(ToDeviceColor(sScrollbarBorderColor)), + StrokeOptions(1.0f * aDpiRatio)); + } } // Checks whether the frame is for a root or , which @@ -1074,24 +1148,31 @@ nsNativeBasicTheme::DrawWidgetBackground(gfxContext* aContext, nsIFrame* aFrame, PaintMeterchunk(aFrame, dt, devPxRect, eventState, dpiRatio); break; case StyleAppearance::ScrollbarthumbHorizontal: - PaintScrollbarthumbHorizontal(dt, devPxRect, eventState); + PaintScrollbarthumbHorizontal( + dt, devPxRect, *nsLayoutUtils::StyleForScrollbar(aFrame), eventState); break; case StyleAppearance::ScrollbarthumbVertical: - PaintScrollbarthumbVertical(dt, devPxRect, eventState); + PaintScrollbarthumbVertical( + dt, devPxRect, *nsLayoutUtils::StyleForScrollbar(aFrame), eventState); break; case StyleAppearance::ScrollbarHorizontal: - PaintScrollbarHorizontal(dt, devPxRect, IsRootScrollbar(aFrame)); + PaintScrollbarHorizontal(dt, devPxRect, + *nsLayoutUtils::StyleForScrollbar(aFrame), + IsRootScrollbar(aFrame)); break; case StyleAppearance::ScrollbarVertical: case StyleAppearance::Scrollcorner: - PaintScrollbarVerticalAndCorner(dt, devPxRect, dpiRatio, - IsRootScrollbar(aFrame)); + PaintScrollbarVerticalAndCorner(dt, devPxRect, + *nsLayoutUtils::StyleForScrollbar(aFrame), + dpiRatio, IsRootScrollbar(aFrame)); break; case StyleAppearance::ScrollbarbuttonUp: case StyleAppearance::ScrollbarbuttonDown: case StyleAppearance::ScrollbarbuttonLeft: case StyleAppearance::ScrollbarbuttonRight: - PaintScrollbarbutton(dt, aAppearance, devPxRect, eventState, dpiRatio); + PaintScrollbarbutton(dt, aAppearance, devPxRect, + *nsLayoutUtils::StyleForScrollbar(aFrame), + eventState, dpiRatio); break; case StyleAppearance::Button: PaintButton(aFrame, dt, devPxRect, eventState, dpiRatio); @@ -1268,6 +1349,31 @@ nsNativeBasicTheme::GetMinimumWidgetSize(nsPresContext* aPresContext, aResult->width = static_cast(kMinimumSpinnerButtonWidth) * dpiRatio; break; + case StyleAppearance::Scrollbar: + case StyleAppearance::ScrollbarSmall: + case StyleAppearance::ScrollbarVertical: + case StyleAppearance::ScrollbarHorizontal: + case StyleAppearance::ScrollbarbuttonUp: + case StyleAppearance::ScrollbarbuttonDown: + case StyleAppearance::ScrollbarbuttonLeft: + case StyleAppearance::ScrollbarbuttonRight: + case StyleAppearance::ScrollbarthumbVertical: + case StyleAppearance::ScrollbarthumbHorizontal: + case StyleAppearance::ScrollbartrackHorizontal: + case StyleAppearance::ScrollbartrackVertical: + case StyleAppearance::Scrollcorner: { + ComputedStyle* style = nsLayoutUtils::StyleForScrollbar(aFrame); + if (style->StyleUIReset()->mScrollbarWidth == StyleScrollbarWidth::Thin) { + aResult->SizeTo( + static_cast(kMinimumThinScrollbarSize) * dpiRatio, + static_cast(kMinimumThinScrollbarSize) * dpiRatio); + } else { + aResult->SizeTo( + static_cast(kMinimumScrollbarSize) * dpiRatio, + static_cast(kMinimumScrollbarSize) * dpiRatio); + } + break; + } default: break; } @@ -1324,16 +1430,6 @@ nsITheme::ThemeGeometryType nsNativeBasicTheme::ThemeGeometryTypeForWidget( bool nsNativeBasicTheme::ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* aFrame, StyleAppearance aAppearance) { - if (IsWidgetScrollbarPart(aAppearance)) { - const auto* style = nsLayoutUtils::StyleForScrollbar(aFrame); - // We don't currently handle custom scrollbars on nsNativeBasicTheme. We - // could, potentially. - if (style->StyleUI()->HasCustomScrollbars() || - style->StyleUIReset()->mScrollbarWidth == StyleScrollbarWidth::Thin) { - return false; - } - } - switch (aAppearance) { case StyleAppearance::Radio: case StyleAppearance::Checkbox: diff --git a/widget/nsNativeBasicTheme.h b/widget/nsNativeBasicTheme.h index 1f318199b6e7..67fdb4994b4b 100644 --- a/widget/nsNativeBasicTheme.h +++ b/widget/nsNativeBasicTheme.h @@ -77,6 +77,8 @@ static const gfx::sRGBColor sColorMeterRed20( static const gfx::sRGBColor sScrollbarColor(gfx::sRGBColor(0.94f, 0.94f, 0.94f)); +static const gfx::sRGBColor sScrollbarColorTransparent( + gfx::sRGBColor(0.94f, 0.94f, 0.94f, 0.2f)); static const gfx::sRGBColor sScrollbarBorderColor(gfx::sRGBColor(1.0f, 1.0f, 1.0f)); static const gfx::sRGBColor sScrollbarThumbColor(gfx::sRGBColor(0.8f, 0.8f, @@ -103,6 +105,8 @@ static const gfx::sRGBColor sScrollbarButtonHoverColor(gfx::sRGBColor(0.86f, 0.86f)); static const CSSIntCoord kMinimumWidgetSize = 14; +static const CSSIntCoord kMinimumScrollbarSize = 14; +static const CSSIntCoord kMinimumThinScrollbarSize = 6; static const CSSIntCoord kMinimumColorPickerHeight = 32; static const CSSIntCoord kMinimumRangeThumbSize = 20; static const CSSIntCoord kMinimumDropdownArrowButtonWidth = 18; @@ -255,6 +259,11 @@ class nsNativeBasicTheme : protected nsNativeTheme, public nsITheme { const EventStates& aState); static std::pair ComputeRangeThumbColors( const EventStates& aState); + static sRGBColor ComputeScrollbarColor(const ComputedStyle& aStyle, + bool aIsRoot, + bool aDefaultTransparent); + static sRGBColor ComputeScrollbarthumbColor(const ComputedStyle& aStyle, + const EventStates& aState); static void PaintListbox(DrawTarget* aDrawTarget, const Rect& aRect, const EventStates& aState, uint32_t aDpiRatio); static void PaintMenulist(DrawTarget* aDrawTarget, const Rect& aRect, @@ -297,19 +306,25 @@ class nsNativeBasicTheme : protected nsNativeTheme, public nsITheme { virtual void PaintScrollbarthumbHorizontal(DrawTarget* aDrawTarget, const Rect& aRect, + const ComputedStyle& aStyle, const EventStates& aState); virtual void PaintScrollbarthumbVertical(DrawTarget* aDrawTarget, const Rect& aRect, + const ComputedStyle& aStyle, const EventStates& aState); virtual void PaintScrollbarHorizontal(DrawTarget* aDrawTarget, - const Rect& aRect, bool aIsRoot); + const Rect& aRect, + const ComputedStyle& aStyle, + bool aIsRoot); virtual void PaintScrollbarVerticalAndCorner(DrawTarget* aDrawTarget, const Rect& aRect, + const ComputedStyle& aStyle, uint32_t aDpiRatio, bool aIsRoot); virtual void PaintScrollbarbutton(DrawTarget* aDrawTarget, StyleAppearance aAppearance, const Rect& aRect, + const ComputedStyle& aStyle, const EventStates& aState, uint32_t aDpiRatio); };