Bug 1852321 - Fix wpt tests in jsshell for sync changes, r=Sasha
[gecko.git] / widget / ScrollbarDrawingWin.cpp
blobc2d85ae671b0915793bf53d558f0262c364479e0
1 /* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "ScrollbarDrawingWin.h"
8 #include "mozilla/gfx/Helpers.h"
9 #include "mozilla/Maybe.h"
10 #include "mozilla/StaticPrefs_widget.h"
11 #include "nsLayoutUtils.h"
12 #include "Theme.h"
13 #include "nsNativeTheme.h"
15 namespace mozilla::widget {
17 LayoutDeviceIntSize ScrollbarDrawingWin::GetMinimumWidgetSize(
18 nsPresContext* aPresContext, StyleAppearance aAppearance,
19 nsIFrame* aFrame) {
20 MOZ_ASSERT(nsNativeTheme::IsWidgetScrollbarPart(aAppearance));
22 switch (aAppearance) {
23 case StyleAppearance::ScrollbarbuttonUp:
24 case StyleAppearance::ScrollbarbuttonDown:
25 case StyleAppearance::ScrollbarbuttonLeft:
26 case StyleAppearance::ScrollbarbuttonRight:
27 // For scrollbar-width:thin, we don't display the buttons.
28 if (IsScrollbarWidthThin(aFrame)) {
29 return LayoutDeviceIntSize{};
31 [[fallthrough]];
32 case StyleAppearance::ScrollbarVertical:
33 case StyleAppearance::ScrollbarHorizontal:
34 case StyleAppearance::ScrollbarthumbVertical:
35 case StyleAppearance::ScrollbarthumbHorizontal: {
36 // TODO: for short scrollbars it could be nice if the thumb could shrink
37 // under this size.
38 auto relevantSize = GetScrollbarSize(aPresContext, aFrame);
39 const bool isHorizontal =
40 aAppearance == StyleAppearance::ScrollbarHorizontal ||
41 aAppearance == StyleAppearance::ScrollbarthumbHorizontal ||
42 aAppearance == StyleAppearance::ScrollbarbuttonLeft ||
43 aAppearance == StyleAppearance::ScrollbarbuttonRight;
44 auto size = LayoutDeviceIntSize{relevantSize, relevantSize};
45 if (aAppearance == StyleAppearance::ScrollbarHorizontal ||
46 aAppearance == StyleAppearance::ScrollbarVertical) {
47 // Always reserve some space in the right direction. Historically we've
48 // reserved 2 times the size in the other axis (for the buttons).
49 // We do this even when painting thin scrollbars just for consistency,
50 // though there just one would probably do there.
51 if (isHorizontal) {
52 size.width *= 2;
53 } else {
54 size.height *= 2;
57 return size;
59 default:
60 return LayoutDeviceIntSize{};
64 // Returns the style for custom scrollbar if the scrollbar part frame should
65 // use the custom drawing path, nullptr otherwise.
66 const ComputedStyle* GetCustomScrollbarStyle(nsIFrame* aFrame) {
67 const ComputedStyle* style = nsLayoutUtils::StyleForScrollbar(aFrame);
68 if (style->StyleUI()->HasCustomScrollbars() ||
69 ScrollbarDrawing::IsScrollbarWidthThin(*style)) {
70 return style;
72 bool useDarkScrollbar = !StaticPrefs::widget_disable_dark_scrollbar() &&
73 nsNativeTheme::IsDarkBackgroundForScrollbar(aFrame);
74 if (useDarkScrollbar) {
75 return style;
77 return nullptr;
80 Maybe<nsITheme::Transparency> ScrollbarDrawingWin::GetScrollbarPartTransparency(
81 nsIFrame* aFrame, StyleAppearance aAppearance) {
82 if (nsNativeTheme::IsWidgetScrollbarPart(aAppearance)) {
83 if (const ComputedStyle* style = GetCustomScrollbarStyle(aFrame)) {
84 auto* ui = style->StyleUI();
85 if (ui->mScrollbarColor.IsAuto() ||
86 ui->mScrollbarColor.AsColors().track.MaybeTransparent()) {
87 return Some(nsITheme::eTransparent);
89 // These widgets may be thinner than the track, so we need to return
90 // transparent for them to make the track visible.
91 switch (aAppearance) {
92 case StyleAppearance::ScrollbarthumbHorizontal:
93 case StyleAppearance::ScrollbarthumbVertical:
94 case StyleAppearance::ScrollbarbuttonUp:
95 case StyleAppearance::ScrollbarbuttonDown:
96 case StyleAppearance::ScrollbarbuttonLeft:
97 case StyleAppearance::ScrollbarbuttonRight:
98 return Some(nsITheme::eTransparent);
99 default:
100 break;
103 if (aFrame->PresContext()->UseOverlayScrollbars()) {
104 return Some(nsITheme::eTransparent);
108 switch (aAppearance) {
109 case StyleAppearance::ScrollbarHorizontal:
110 case StyleAppearance::ScrollbarVertical:
111 case StyleAppearance::Scrollcorner:
112 // Knowing that scrollbars and statusbars are opaque improves
113 // performance, because we create layers for them. This better be
114 // true across all Windows themes! If it's not true, we should
115 // paint an opaque background for them to make it true!
116 // TODO(emilio): Unclear how much this optimization matters in practice
117 // now we're in a WR-only world.
118 return Some(nsITheme::eOpaque);
119 default:
120 break;
123 return Nothing();
126 template <typename PaintBackendData>
127 bool ScrollbarDrawingWin::DoPaintScrollbarThumb(
128 PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
129 ScrollbarKind aScrollbarKind, nsIFrame* aFrame, const ComputedStyle& aStyle,
130 const ElementState& aElementState, const DocumentState& aDocumentState,
131 const Colors& aColors, const DPIRatio& aDpiRatio) {
132 sRGBColor thumbColor = ComputeScrollbarThumbColor(
133 aFrame, aStyle, aElementState, aDocumentState, aColors);
134 ThemeDrawing::FillRect(aPaintData, aRect, thumbColor);
135 return true;
138 bool ScrollbarDrawingWin::PaintScrollbarThumb(
139 DrawTarget& aDrawTarget, const LayoutDeviceRect& aRect,
140 ScrollbarKind aScrollbarKind, nsIFrame* aFrame, const ComputedStyle& aStyle,
141 const ElementState& aElementState, const DocumentState& aDocumentState,
142 const Colors& aColors, const DPIRatio& aDpiRatio) {
143 return DoPaintScrollbarThumb(aDrawTarget, aRect, aScrollbarKind, aFrame,
144 aStyle, aElementState, aDocumentState, aColors,
145 aDpiRatio);
148 bool ScrollbarDrawingWin::PaintScrollbarThumb(
149 WebRenderBackendData& aWrData, const LayoutDeviceRect& aRect,
150 ScrollbarKind aScrollbarKind, nsIFrame* aFrame, const ComputedStyle& aStyle,
151 const ElementState& aElementState, const DocumentState& aDocumentState,
152 const Colors& aColors, const DPIRatio& aDpiRatio) {
153 return DoPaintScrollbarThumb(aWrData, aRect, aScrollbarKind, aFrame, aStyle,
154 aElementState, aDocumentState, aColors,
155 aDpiRatio);
158 void ScrollbarDrawingWin::RecomputeScrollbarParams() {
159 uint32_t defaultSize = kDefaultWinScrollbarSize;
160 uint32_t overrideSize =
161 StaticPrefs::widget_non_native_theme_scrollbar_size_override();
162 if (overrideSize > 0) {
163 defaultSize = overrideSize;
165 ConfigureScrollbarSize(defaultSize);
167 if (StaticPrefs::widget_non_native_theme_win_scrollbar_use_system_size()) {
168 ConfigureScrollbarSize(LookAndFeel::GetInt(
169 LookAndFeel::IntID::SystemScrollbarSize, defaultSize));
173 } // namespace mozilla::widget