Bug 1813046 - Simplify scrollbar sizing code. r=spohl

This removes the capability of having differently-sized vertical and
horizontal scrollbars (which is only potentially used in windows, and in
practice almost-never used). For that case, we choose the larger of
vertical/horizontal scrollbar sizes.

This is in order to be able to realistically expose the scrollbar size
to CSS, see blocked bug.

We make RecomputeScrollbarParams the central place where each scrollbar
style decides its sizes, and make GetDPIRatioForScrollbarPart handle the
cocoa special-case of scaling to 1 or 2, but nothing else.

Differential Revision: https://phabricator.services.mozilla.com/D168080
This commit is contained in:
Emilio Cobos Álvarez 2023-01-28 21:35:51 +00:00
Родитель 6c0bec1169
Коммит 604d8268b2
19 изменённых файлов: 139 добавлений и 210 удалений

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

@ -110,12 +110,9 @@ class nsITheme : public nsISupports {
* horizontal scrollbar.
*/
enum class Overlay { No, Yes };
struct ScrollbarSizes {
LayoutDeviceIntCoord mVertical;
LayoutDeviceIntCoord mHorizontal;
};
virtual ScrollbarSizes GetScrollbarSizes(nsPresContext*, StyleScrollbarWidth,
Overlay) = 0;
virtual LayoutDeviceIntCoord GetScrollbarSize(const nsPresContext*,
StyleScrollbarWidth,
Overlay) = 0;
/**
* Return the border for the widget, in device pixels.

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

@ -1660,10 +1660,9 @@ nscoord nsIScrollableFrame::GetNondisappearingScrollbarWidth(nsPresContext* aPc,
// We use this to size the combobox dropdown button. For that, we need to have
// the proper big, non-overlay scrollbar size, regardless of whether we're
// using e.g. scrollbar-width: thin, or overlay scrollbars.
auto sizes = aPc->Theme()->GetScrollbarSizes(aPc, StyleScrollbarWidth::Auto,
nsITheme::Overlay::No);
return aPc->DevPixelsToAppUnits(aWM.IsVertical() ? sizes.mHorizontal
: sizes.mVertical);
auto size = aPc->Theme()->GetScrollbarSize(aPc, StyleScrollbarWidth::Auto,
nsITheme::Overlay::No);
return aPc->DevPixelsToAppUnits(size);
}
void ScrollFrameHelper::HandleScrollbarStyleSwitching() {
@ -7219,18 +7218,18 @@ void ScrollFrameHelper::LayoutScrollbars(nsBoxLayoutState& aState,
auto scrollbarWidth = nsLayoutUtils::StyleForScrollbar(mOuter)
->StyleUIReset()
->ScrollbarWidth();
auto sizes = pc->Theme()->GetScrollbarSizes(pc, scrollbarWidth,
nsITheme::Overlay::No);
auto scrollbarSize = pc->Theme()->GetScrollbarSize(pc, scrollbarWidth,
nsITheme::Overlay::No);
nsSize resizerMinSize = mResizerBox->GetXULMinSize(aState);
nsRect r;
nscoord vScrollbarWidth = pc->DevPixelsToAppUnits(sizes.mVertical);
nscoord vScrollbarWidth = pc->DevPixelsToAppUnits(scrollbarSize);
r.width =
std::max(std::max(r.width, vScrollbarWidth), resizerMinSize.width);
r.x = scrollbarOnLeft ? aInsideBorderArea.x
: aInsideBorderArea.XMost() - r.width;
nscoord hScrollbarHeight = pc->DevPixelsToAppUnits(sizes.mHorizontal);
nscoord hScrollbarHeight = pc->DevPixelsToAppUnits(scrollbarSize);
r.height =
std::max(std::max(r.height, hScrollbarHeight), resizerMinSize.height);
r.y = aInsideBorderArea.YMost() - r.height;

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

@ -396,16 +396,11 @@ bool nsIFrame::AddXULMinSize(nsIFrame* aBox, nsSize& aSize, bool& aWidthSet,
case StyleAppearance::ScrollbarVertical:
case StyleAppearance::ScrollbarHorizontal: {
ComputedStyle* style = nsLayoutUtils::StyleForScrollbar(aBox);
auto sizes = theme->GetScrollbarSizes(
auto size = theme->GetScrollbarSize(
pc, style->StyleUIReset()->ScrollbarWidth(),
nsITheme::Overlay::No);
if (appearance == StyleAppearance::ScrollbarVertical) {
aSize.width = pc->DevPixelsToAppUnits(sizes.mVertical);
aWidthSet = true;
} else {
aSize.height = pc->DevPixelsToAppUnits(sizes.mHorizontal);
aHeightSet = true;
}
aSize.width = pc->DevPixelsToAppUnits(size);
aWidthSet = true;
break;
}
default:

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

@ -310,11 +310,9 @@ class LookAndFeel {
* 'Coarse | Fine | Hover'.
*/
AllPointerCapabilities,
/** The vertical scrollbar width, in CSS pixels. */
SystemVerticalScrollbarWidth,
/** The horizontal scrollbar height, in CSS pixels. */
SystemHorizontalScrollbarHeight,
/** The scrollbar size, in CSS pixels. */
SystemScrollbarSize,
/** A boolean value to determine whether a touch device is present */
TouchDeviceSupportPresent,

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

@ -22,16 +22,22 @@ namespace mozilla::widget {
using mozilla::RelativeLuminanceUtils;
/* static */
auto ScrollbarDrawing::GetDPIRatioForScrollbarPart(nsPresContext* aPc)
auto ScrollbarDrawing::GetDPIRatioForScrollbarPart(const nsPresContext* aPc)
-> DPIRatio {
if (auto* rootPc = aPc->GetRootPresContext()) {
if (nsCOMPtr<nsIWidget> widget = rootPc->GetRootWidget()) {
return widget->GetDefaultScale();
auto ratio = [&] {
if (auto* rootPc = aPc->GetRootPresContext()) {
if (nsCOMPtr<nsIWidget> widget = rootPc->GetRootWidget()) {
return widget->GetDefaultScale();
}
}
return DPIRatio(
float(AppUnitsPerCSSPixel()) /
float(aPc->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom()));
}();
if (mKind == Kind::Cocoa) {
return DPIRatio(ratio.scale >= 2.0f ? 2.0f : 1.0f);
}
return DPIRatio(
float(AppUnitsPerCSSPixel()) /
float(aPc->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom()));
return ratio;
}
/*static*/
@ -80,26 +86,41 @@ bool ScrollbarDrawing::IsScrollbarWidthThin(nsIFrame* aFrame) {
return IsScrollbarWidthThin(*style);
}
auto ScrollbarDrawing::GetScrollbarSizes(nsPresContext* aPresContext,
StyleScrollbarWidth aWidth, Overlay)
-> ScrollbarSizes {
uint32_t h = GetHorizontalScrollbarHeight();
uint32_t w = GetVerticalScrollbarWidth();
if (aWidth == StyleScrollbarWidth::Thin) {
h /= 2;
w /= 2;
}
auto dpi = GetDPIRatioForScrollbarPart(aPresContext);
return {(CSSCoord(w) * dpi).Rounded(), (CSSCoord(h) * dpi).Rounded()};
CSSIntCoord ScrollbarDrawing::GetCSSScrollbarSize(StyleScrollbarWidth aWidth,
Overlay aOverlay) const {
return mScrollbarSize[aWidth == StyleScrollbarWidth::Thin]
[aOverlay == Overlay::Yes];
}
auto ScrollbarDrawing::GetScrollbarSizes(nsPresContext* aPresContext,
nsIFrame* aFrame) -> ScrollbarSizes {
void ScrollbarDrawing::ConfigureScrollbarSize(StyleScrollbarWidth aWidth,
Overlay aOverlay,
CSSIntCoord aSize) {
mScrollbarSize[aWidth == StyleScrollbarWidth::Thin]
[aOverlay == Overlay::Yes] = aSize;
}
void ScrollbarDrawing::ConfigureScrollbarSize(CSSIntCoord aSize) {
ConfigureScrollbarSize(StyleScrollbarWidth::Auto, Overlay::No, aSize);
ConfigureScrollbarSize(StyleScrollbarWidth::Auto, Overlay::Yes, aSize);
ConfigureScrollbarSize(StyleScrollbarWidth::Thin, Overlay::No, aSize / 2);
ConfigureScrollbarSize(StyleScrollbarWidth::Thin, Overlay::Yes, aSize / 2);
}
LayoutDeviceIntCoord ScrollbarDrawing::GetScrollbarSize(
const nsPresContext* aPresContext, StyleScrollbarWidth aWidth,
Overlay aOverlay) {
return (CSSCoord(GetCSSScrollbarSize(aWidth, aOverlay)) *
GetDPIRatioForScrollbarPart(aPresContext))
.Rounded();
}
LayoutDeviceIntCoord ScrollbarDrawing::GetScrollbarSize(
const nsPresContext* aPresContext, nsIFrame* aFrame) {
auto* style = nsLayoutUtils::StyleForScrollbar(aFrame);
auto width = style->StyleUIReset()->ScrollbarWidth();
auto overlay =
aPresContext->UseOverlayScrollbars() ? Overlay::Yes : Overlay::No;
return GetScrollbarSizes(aPresContext, width, overlay);
return GetScrollbarSize(aPresContext, width, overlay);
}
bool ScrollbarDrawing::IsScrollbarTrackOpaque(nsIFrame* aFrame) {

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

@ -25,7 +25,6 @@ class ScrollbarDrawing {
using DrawTarget = mozilla::gfx::DrawTarget;
using sRGBColor = mozilla::gfx::sRGBColor;
using Colors = ThemeColors;
using ScrollbarSizes = nsITheme::ScrollbarSizes;
using Overlay = nsITheme::Overlay;
using WebRenderBackendData = mozilla::widget::WebRenderBackendData;
@ -48,7 +47,7 @@ class ScrollbarDrawing {
VerticalRight,
};
static DPIRatio GetDPIRatioForScrollbarPart(nsPresContext*);
DPIRatio GetDPIRatioForScrollbarPart(const nsPresContext*);
static nsIFrame* GetParentScrollbarFrame(nsIFrame* aFrame);
static bool IsParentScrollbarRolledOver(nsIFrame* aFrame);
@ -57,9 +56,11 @@ class ScrollbarDrawing {
static bool IsScrollbarWidthThin(const ComputedStyle& aStyle);
static bool IsScrollbarWidthThin(nsIFrame* aFrame);
virtual ScrollbarSizes GetScrollbarSizes(nsPresContext*, StyleScrollbarWidth,
Overlay);
ScrollbarSizes GetScrollbarSizes(nsPresContext*, nsIFrame*);
CSSIntCoord GetCSSScrollbarSize(StyleScrollbarWidth, Overlay) const;
LayoutDeviceIntCoord GetScrollbarSize(const nsPresContext*,
StyleScrollbarWidth, Overlay);
LayoutDeviceIntCoord GetScrollbarSize(const nsPresContext*, nsIFrame*);
virtual LayoutDeviceIntSize GetMinimumWidgetSize(nsPresContext*,
StyleAppearance aAppearance,
nsIFrame* aFrame) = 0;
@ -149,17 +150,21 @@ class ScrollbarDrawing {
virtual bool ShouldDrawScrollbarButtons() { return true; }
uint32_t GetHorizontalScrollbarHeight() const {
return mHorizontalScrollbarHeight;
}
uint32_t GetVerticalScrollbarWidth() const { return mVerticalScrollbarWidth; }
private:
// The scrollbar sizes for all our scrollbars. Indices are overlay or not,
// then thin or not. Should be configured via ConfigureScrollbarSize.
CSSIntCoord mScrollbarSize[2][2]{};
protected:
// For some kind of style differences a full virtual method is overkill, so we
// store the kind here so we can branch on it if necessary.
Kind mKind;
uint32_t mHorizontalScrollbarHeight = 0;
uint32_t mVerticalScrollbarWidth = 0;
// Configures the scrollbar sizes based on a single size.
void ConfigureScrollbarSize(CSSIntCoord);
// Configures a particular scrollbar size.
void ConfigureScrollbarSize(StyleScrollbarWidth, Overlay, CSSIntCoord);
};
} // namespace mozilla::widget

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

@ -16,22 +16,9 @@ LayoutDeviceIntSize ScrollbarDrawingAndroid::GetMinimumWidgetSize(
nsPresContext* aPresContext, StyleAppearance aAppearance,
nsIFrame* aFrame) {
MOZ_ASSERT(nsNativeTheme::IsWidgetScrollbarPart(aAppearance));
auto sizes =
GetScrollbarSizes(aPresContext, StyleScrollbarWidth::Auto, Overlay::Yes);
MOZ_ASSERT(sizes.mHorizontal == sizes.mVertical);
return LayoutDeviceIntSize{sizes.mHorizontal, sizes.mVertical};
}
auto ScrollbarDrawingAndroid::GetScrollbarSizes(nsPresContext* aPresContext,
StyleScrollbarWidth aWidth,
Overlay aOverlay)
-> ScrollbarSizes {
// We force auto-width scrollbars because scrollbars on android are already
// thin enough.
return ScrollbarDrawing::GetScrollbarSizes(
aPresContext, StyleScrollbarWidth::Auto, aOverlay);
auto size =
GetScrollbarSize(aPresContext, StyleScrollbarWidth::Auto, Overlay::Yes);
return LayoutDeviceIntSize{size, size};
}
template <typename PaintBackendData>
@ -89,5 +76,9 @@ void ScrollbarDrawingAndroid::RecomputeScrollbarParams() {
if (overrideSize > 0) {
defaultSize = overrideSize;
}
mHorizontalScrollbarHeight = mVerticalScrollbarWidth = defaultSize;
ConfigureScrollbarSize(defaultSize);
// We make thin scrollbars as wide as auto ones because auto scrollbars on
// android are already thin enough.
ConfigureScrollbarSize(StyleScrollbarWidth::Thin, Overlay::Yes, defaultSize);
ConfigureScrollbarSize(StyleScrollbarWidth::Thin, Overlay::No, defaultSize);
}

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

@ -20,9 +20,6 @@ class ScrollbarDrawingAndroid final : public ScrollbarDrawing {
StyleAppearance aAppearance,
nsIFrame* aFrame) override;
ScrollbarSizes GetScrollbarSizes(nsPresContext*, StyleScrollbarWidth,
Overlay) override;
template <typename PaintBackendData>
void DoPaintScrollbarThumb(PaintBackendData&, const LayoutDeviceRect& aRect,
ScrollbarKind, nsIFrame* aFrame,

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

@ -81,75 +81,39 @@ LayoutDeviceIntSize ScrollbarDrawingCocoa::GetMinimumWidgetSize(
nsIFrame* aFrame) {
MOZ_ASSERT(nsNativeTheme::IsWidgetScrollbarPart(aAppearance));
auto minSize = [&] {
auto minSize = [&]() -> CSSIntSize {
switch (aAppearance) {
case StyleAppearance::ScrollbarthumbHorizontal:
return IntSize{26, 0};
return {26, 0};
case StyleAppearance::ScrollbarthumbVertical:
return IntSize{0, 26};
return {0, 26};
case StyleAppearance::ScrollbarVertical:
case StyleAppearance::ScrollbarHorizontal:
case StyleAppearance::ScrollbartrackVertical:
case StyleAppearance::ScrollbartrackHorizontal: {
ComputedStyle* style = nsLayoutUtils::StyleForScrollbar(aFrame);
auto scrollbarWidth = style->StyleUIReset()->ScrollbarWidth();
auto size = GetScrollbarSize(
scrollbarWidth,
LookAndFeel::GetInt(LookAndFeel::IntID::UseOverlayScrollbars));
return IntSize{size, size};
auto size = GetCSSScrollbarSize(
scrollbarWidth, Overlay(aPresContext->UseOverlayScrollbars()));
return {size, size};
}
case StyleAppearance::ScrollbarbuttonUp:
case StyleAppearance::ScrollbarbuttonDown:
return IntSize{15, 16};
return {15, 16};
case StyleAppearance::ScrollbarbuttonLeft:
case StyleAppearance::ScrollbarbuttonRight:
return IntSize{16, 15};
return {16, 15};
default:
return IntSize{};
return {};
}
}();
auto dpi = GetDPIRatioForScrollbarPart(aPresContext).scale;
if (dpi >= 2.0f) {
return LayoutDeviceIntSize{minSize.width * 2, minSize.height * 2};
}
return LayoutDeviceIntSize{minSize.width, minSize.height};
}
/*static*/
CSSIntCoord ScrollbarDrawingCocoa::GetScrollbarSize(StyleScrollbarWidth aWidth,
bool aOverlay) {
bool isSmall = aWidth == StyleScrollbarWidth::Thin;
if (aOverlay) {
return isSmall ? 14 : 16;
}
return isSmall ? 11 : 15;
}
/*static*/
LayoutDeviceIntCoord ScrollbarDrawingCocoa::GetScrollbarSize(
StyleScrollbarWidth aWidth, bool aOverlay, DPIRatio aDpiRatio) {
CSSIntCoord size = GetScrollbarSize(aWidth, aOverlay);
if (aDpiRatio.scale >= 2.0f) {
return int32_t(size) * 2;
}
return int32_t(size);
}
auto ScrollbarDrawingCocoa::GetScrollbarSizes(nsPresContext* aPresContext,
StyleScrollbarWidth aWidth,
Overlay aOverlay)
-> ScrollbarSizes {
auto size = GetScrollbarSize(aWidth, aOverlay == Overlay::Yes,
GetDPIRatioForScrollbarPart(aPresContext));
return {size, size};
auto dpi = GetDPIRatioForScrollbarPart(aPresContext);
return LayoutDeviceIntSize::Round(CSSSize(minSize) * dpi);
}
static ThumbRect GetThumbRect(const LayoutDeviceRect& aRect,
const ScrollbarParams& aParams, float aScale) {
// This matches the sizing checks in GetMinimumWidgetSize etc.
aScale = aScale >= 2.0f ? 2.0f : 1.0f;
// Compute the thumb thickness. This varies based on aParams.small,
// aParams.overlay and aParams.rolledOver. non-overlay: 6 / 8, overlay
// non-hovered: 5 / 7, overlay hovered: 9 / 11
@ -255,9 +219,6 @@ static bool GetScrollbarTrackRects(const LayoutDeviceRect& aRect,
return false;
}
// This matches the sizing checks in GetMinimumWidgetSize etc.
aScale = aScale >= 2.0f ? 2.0f : 1.0f;
nscolor trackColor;
if (aParams.isCustom) {
trackColor = aParams.trackColor;
@ -323,9 +284,6 @@ static bool GetScrollCornerRects(const LayoutDeviceRect& aRect,
return false;
}
// This matches the sizing checks in GetMinimumWidgetSize etc.
aScale = aScale >= 2.0f ? 2.0f : 1.0f;
// Draw the following scroll corner.
//
// Output: Rectangles:
@ -506,13 +464,13 @@ bool ScrollbarDrawingCocoa::PaintScrollCorner(
}
void ScrollbarDrawingCocoa::RecomputeScrollbarParams() {
uint32_t defaultSize = 17;
uint32_t overrideSize =
StaticPrefs::widget_non_native_theme_scrollbar_size_override();
if (overrideSize > 0) {
defaultSize = overrideSize;
}
mHorizontalScrollbarHeight = mVerticalScrollbarWidth = defaultSize;
// FIXME(emilio): This doesn't respect the
// StaticPrefs::widget_non_native_theme_scrollbar_size_override() pref;
ConfigureScrollbarSize(15); // Just in case, for future-proofing
ConfigureScrollbarSize(StyleScrollbarWidth::Auto, Overlay::No, 15);
ConfigureScrollbarSize(StyleScrollbarWidth::Thin, Overlay::No, 11);
ConfigureScrollbarSize(StyleScrollbarWidth::Auto, Overlay::Yes, 16);
ConfigureScrollbarSize(StyleScrollbarWidth::Thin, Overlay::Yes, 14);
}
} // namespace mozilla::widget

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

@ -22,13 +22,7 @@ class ScrollbarDrawingCocoa final : public ScrollbarDrawing {
StyleAppearance aAppearance,
nsIFrame* aFrame) override;
static CSSIntCoord GetScrollbarSize(StyleScrollbarWidth aWidth,
bool aOverlay);
static LayoutDeviceIntCoord GetScrollbarSize(StyleScrollbarWidth aWidth,
bool aOverlay,
DPIRatio aDpiRatio);
ScrollbarSizes GetScrollbarSizes(nsPresContext*, StyleScrollbarWidth,
Overlay) override;
static CSSIntCoord GetScrollbarSize(StyleScrollbarWidth, bool aOverlay);
template <typename PaintBackendData>
void DoPaintScrollbarThumb(PaintBackendData&, const LayoutDeviceRect& aRect,

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

@ -18,9 +18,8 @@ LayoutDeviceIntSize ScrollbarDrawingGTK::GetMinimumWidgetSize(
nsPresContext* aPresContext, StyleAppearance aAppearance,
nsIFrame* aFrame) {
MOZ_ASSERT(nsNativeTheme::IsWidgetScrollbarPart(aAppearance));
auto sizes = GetScrollbarSizes(aPresContext, aFrame);
MOZ_ASSERT(sizes.mHorizontal == sizes.mVertical);
LayoutDeviceIntSize size{sizes.mHorizontal, sizes.mVertical};
auto scrollbarSize = GetScrollbarSize(aPresContext, aFrame);
LayoutDeviceIntSize size{scrollbarSize, scrollbarSize};
if (aAppearance == StyleAppearance::ScrollbarHorizontal ||
aAppearance == StyleAppearance::ScrollbarVertical ||
aAppearance == StyleAppearance::ScrollbarthumbHorizontal ||
@ -130,5 +129,5 @@ void ScrollbarDrawingGTK::RecomputeScrollbarParams() {
if (overrideSize > 0) {
defaultSize = overrideSize;
}
mHorizontalScrollbarHeight = mVerticalScrollbarWidth = defaultSize;
ConfigureScrollbarSize(defaultSize);
}

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

@ -35,14 +35,12 @@ LayoutDeviceIntSize ScrollbarDrawingWin::GetMinimumWidgetSize(
case StyleAppearance::ScrollbarthumbHorizontal: {
// TODO: for short scrollbars it could be nice if the thumb could shrink
// under this size.
auto sizes = GetScrollbarSizes(aPresContext, aFrame);
auto relevantSize = GetScrollbarSize(aPresContext, aFrame);
const bool isHorizontal =
aAppearance == StyleAppearance::ScrollbarHorizontal ||
aAppearance == StyleAppearance::ScrollbarthumbHorizontal ||
aAppearance == StyleAppearance::ScrollbarbuttonLeft ||
aAppearance == StyleAppearance::ScrollbarbuttonRight;
const auto relevantSize =
isHorizontal ? sizes.mHorizontal : sizes.mVertical;
auto size = LayoutDeviceIntSize{relevantSize, relevantSize};
if (aAppearance == StyleAppearance::ScrollbarHorizontal ||
aAppearance == StyleAppearance::ScrollbarVertical) {
@ -165,13 +163,11 @@ void ScrollbarDrawingWin::RecomputeScrollbarParams() {
if (overrideSize > 0) {
defaultSize = overrideSize;
}
mHorizontalScrollbarHeight = mVerticalScrollbarWidth = defaultSize;
ConfigureScrollbarSize(defaultSize);
if (StaticPrefs::widget_non_native_theme_win_scrollbar_use_system_size()) {
mHorizontalScrollbarHeight = LookAndFeel::GetInt(
LookAndFeel::IntID::SystemHorizontalScrollbarHeight, defaultSize);
mVerticalScrollbarWidth = LookAndFeel::GetInt(
LookAndFeel::IntID::SystemVerticalScrollbarWidth, defaultSize);
ConfigureScrollbarSize(LookAndFeel::GetInt(
LookAndFeel::IntID::SystemScrollbarSize, defaultSize));
}
}

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

@ -45,23 +45,6 @@ static constexpr CSSIntCoord kDefaultWinOverlayScrollbarSize = CSSIntCoord(12);
static constexpr CSSIntCoord kDefaultWinOverlayThinScrollbarSize =
CSSIntCoord(10);
auto ScrollbarDrawingWin11::GetScrollbarSizes(nsPresContext* aPresContext,
StyleScrollbarWidth aWidth,
Overlay aOverlay)
-> ScrollbarSizes {
if (aOverlay == Overlay::Yes) {
// TODO(emilio): Maybe make this configurable? Though this doesn't respect
// classic Windows registry settings, and cocoa overlay scrollbars also
// don't respect the override it seems, so this should be fine.
CSSCoord cssSize(aWidth == StyleScrollbarWidth::Thin
? kDefaultWinOverlayThinScrollbarSize
: kDefaultWinOverlayScrollbarSize);
auto size = (cssSize * GetDPIRatioForScrollbarPart(aPresContext)).Rounded();
return {size, size};
}
return ScrollbarDrawingWin::GetScrollbarSizes(aPresContext, aWidth, aOverlay);
}
LayoutDeviceIntSize ScrollbarDrawingWin11::GetMinimumWidgetSize(
nsPresContext* aPresContext, StyleAppearance aAppearance,
nsIFrame* aFrame) {
@ -73,24 +56,16 @@ LayoutDeviceIntSize ScrollbarDrawingWin11::GetMinimumWidgetSize(
constexpr float kArrowRatio = 14.0f / kDefaultWinScrollbarSize;
switch (aAppearance) {
case StyleAppearance::ScrollbarbuttonUp:
case StyleAppearance::ScrollbarbuttonDown: {
if (IsScrollbarWidthThin(aFrame)) {
return {};
}
const LayoutDeviceIntCoord size =
ScrollbarDrawing::GetScrollbarSizes(aPresContext, aFrame).mVertical;
return LayoutDeviceIntSize{
size, (kArrowRatio * LayoutDeviceCoord(size)).Rounded()};
}
case StyleAppearance::ScrollbarbuttonDown:
case StyleAppearance::ScrollbarbuttonLeft:
case StyleAppearance::ScrollbarbuttonRight: {
if (IsScrollbarWidthThin(aFrame)) {
return {};
}
const LayoutDeviceIntCoord size =
ScrollbarDrawing::GetScrollbarSizes(aPresContext, aFrame).mHorizontal;
ScrollbarDrawing::GetScrollbarSize(aPresContext, aFrame);
return LayoutDeviceIntSize{
(kArrowRatio * LayoutDeviceCoord(size)).Rounded(), size};
size, (kArrowRatio * LayoutDeviceCoord(size)).Rounded()};
}
default:
return ScrollbarDrawingWin::GetMinimumWidgetSize(aPresContext,
@ -375,4 +350,15 @@ bool ScrollbarDrawingWin11::PaintScrollbarThumb(
aDpiRatio);
}
void ScrollbarDrawingWin11::RecomputeScrollbarParams() {
ScrollbarDrawingWin::RecomputeScrollbarParams();
// TODO(emilio): Maybe make this configurable? Though this doesn't respect
// classic Windows registry settings, and cocoa overlay scrollbars also don't
// respect the override it seems, so this should be fine.
ConfigureScrollbarSize(StyleScrollbarWidth::Thin, Overlay::Yes,
kDefaultWinOverlayThinScrollbarSize);
ConfigureScrollbarSize(StyleScrollbarWidth::Auto, Overlay::Yes,
kDefaultWinOverlayScrollbarSize);
}
} // namespace mozilla::widget

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

@ -18,9 +18,6 @@ class ScrollbarDrawingWin11 final : public ScrollbarDrawingWin {
ScrollbarDrawingWin11() : ScrollbarDrawingWin(Kind::Win11) {}
virtual ~ScrollbarDrawingWin11() = default;
ScrollbarSizes GetScrollbarSizes(nsPresContext*, StyleScrollbarWidth,
Overlay) override;
LayoutDeviceIntSize GetMinimumWidgetSize(nsPresContext*,
StyleAppearance aAppearance,
nsIFrame* aFrame) override;
@ -62,6 +59,8 @@ class ScrollbarDrawingWin11 final : public ScrollbarDrawingWin {
const ElementState& aElementState,
const DocumentState& aDocumentState, const Colors&,
const DPIRatio&) override;
void RecomputeScrollbarParams() override;
};
} // namespace mozilla::widget

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

@ -188,17 +188,15 @@ void Theme::LookAndFeelChanged() {
}
}
/* static */
auto Theme::GetDPIRatio(nsPresContext* aPc, StyleAppearance aAppearance)
-> DPIRatio {
// Widgets react to zoom, except scrollbars.
if (IsWidgetScrollbarPart(aAppearance)) {
return ScrollbarDrawing::GetDPIRatioForScrollbarPart(aPc);
return GetScrollbarDrawing().GetDPIRatioForScrollbarPart(aPc);
}
return DPIRatio(float(AppUnitsPerCSSPixel()) / aPc->AppUnitsPerDevPixel());
}
/* static */
auto Theme::GetDPIRatio(nsIFrame* aFrame, StyleAppearance aAppearance)
-> DPIRatio {
return GetDPIRatio(aFrame->PresContext(), aAppearance);
@ -1500,11 +1498,10 @@ bool Theme::GetWidgetOverflow(nsDeviceContext* aContext, nsIFrame* aFrame,
return true;
}
auto Theme::GetScrollbarSizes(nsPresContext* aPresContext,
StyleScrollbarWidth aWidth, Overlay aOverlay)
-> ScrollbarSizes {
return GetScrollbarDrawing().GetScrollbarSizes(aPresContext, aWidth,
aOverlay);
LayoutDeviceIntCoord Theme::GetScrollbarSize(const nsPresContext* aPresContext,
StyleScrollbarWidth aWidth,
Overlay aOverlay) {
return GetScrollbarDrawing().GetScrollbarSize(aPresContext, aWidth, aOverlay);
}
nscoord Theme::GetCheckboxRadioPrefSize() {

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

@ -90,8 +90,9 @@ class Theme : protected nsNativeTheme, public nsITheme {
bool WidgetIsContainer(StyleAppearance) override;
bool ThemeDrawsFocusForWidget(nsIFrame*, StyleAppearance) override;
bool ThemeNeedsComboboxDropmarker() override;
ScrollbarSizes GetScrollbarSizes(nsPresContext*, StyleScrollbarWidth,
Overlay) override;
LayoutDeviceIntCoord GetScrollbarSize(const nsPresContext*,
StyleScrollbarWidth, Overlay) final;
nscoord GetCheckboxRadioPrefSize() override;
@ -100,8 +101,8 @@ class Theme : protected nsNativeTheme, public nsITheme {
protected:
virtual ~Theme() = default;
static DPIRatio GetDPIRatio(nsPresContext*, StyleAppearance);
static DPIRatio GetDPIRatio(nsIFrame*, StyleAppearance);
DPIRatio GetDPIRatio(nsPresContext*, StyleAppearance);
DPIRatio GetDPIRatio(nsIFrame*, StyleAppearance);
std::tuple<sRGBColor, sRGBColor, sRGBColor> ComputeCheckboxColors(
const ElementState&, StyleAppearance, const Colors&);

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

@ -18,9 +18,8 @@ LayoutDeviceIntSize ThemeCocoa::GetMinimumWidgetSize(
nsPresContext* aPresContext, nsIFrame* aFrame,
StyleAppearance aAppearance) {
if (aAppearance == StyleAppearance::MozMenulistArrowButton) {
LayoutDeviceIntCoord size = ScrollbarDrawingCocoa::GetScrollbarSize(
StyleScrollbarWidth::Auto, /* aOverlay = */ false,
GetDPIRatio(aFrame, aAppearance));
auto size =
GetScrollbarSize(aPresContext, StyleScrollbarWidth::Auto, Overlay::No);
return {size, size};
}
return Theme::GetMinimumWidgetSize(aPresContext, aFrame, aAppearance);

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

@ -182,8 +182,7 @@ static const char sIntPrefs[][45] = {
"ui.prefersReducedMotion",
"ui.primaryPointerCapabilities",
"ui.allPointerCapabilities",
"ui.systemVerticalScrollbarWidth",
"ui.systemHorizontalScrollbarHeight",
"ui.systemScrollbarSize",
"ui.touchDeviceSupportPresent",
"ui.titlebarRadius",
"ui.GtkMenuRadius",

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

@ -603,11 +603,9 @@ nsresult nsLookAndFeel::NativeGetInt(IntID aID, int32_t& aResult) {
case IntID::SystemUsesDarkTheme:
res = SystemWantsDarkTheme(aResult);
break;
case IntID::SystemVerticalScrollbarWidth:
aResult = WinUtils::GetSystemMetricsForDpi(SM_CXVSCROLL, 96);
break;
case IntID::SystemHorizontalScrollbarHeight:
aResult = WinUtils::GetSystemMetricsForDpi(SM_CXHSCROLL, 96);
case IntID::SystemScrollbarSize:
aResult = std::max(WinUtils::GetSystemMetricsForDpi(SM_CXVSCROLL, 96),
WinUtils::GetSystemMetricsForDpi(SM_CXHSCROLL, 96));
break;
case IntID::PrefersReducedMotion: {
BOOL enable = TRUE;