Bug 1758713 [wpt PR 33128] - Clarify the status of the CSS build system, a=testonly
[gecko.git] / widget / ScrollbarDrawingWin.cpp
blob31e081dc3d578088a138bb743082171815573122
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 if ((aAppearance == StyleAppearance::ScrollbarHorizontal ||
37 aAppearance == StyleAppearance::ScrollbarVertical) &&
38 !aPresContext->UseOverlayScrollbars()) {
39 return LayoutDeviceIntSize{};
41 // TODO: for short scrollbars it could be nice if the thumb could shrink
42 // under this size.
43 auto sizes = GetScrollbarSizes(aPresContext, aFrame);
44 const bool isHorizontal =
45 aAppearance == StyleAppearance::ScrollbarHorizontal ||
46 aAppearance == StyleAppearance::ScrollbarthumbHorizontal ||
47 aAppearance == StyleAppearance::ScrollbarbuttonLeft ||
48 aAppearance == StyleAppearance::ScrollbarbuttonRight;
49 const auto size = isHorizontal ? sizes.mHorizontal : sizes.mVertical;
50 return LayoutDeviceIntSize{size, size};
52 default:
53 return LayoutDeviceIntSize{};
57 Maybe<nsITheme::Transparency> ScrollbarDrawingWin::GetScrollbarPartTransparency(
58 nsIFrame* aFrame, StyleAppearance aAppearance) {
59 if (nsNativeTheme::IsWidgetScrollbarPart(aAppearance)) {
60 if (ComputedStyle* style = GetCustomScrollbarStyle(aFrame)) {
61 auto* ui = style->StyleUI();
62 if (ui->mScrollbarColor.IsAuto() ||
63 ui->mScrollbarColor.AsColors().track.MaybeTransparent()) {
64 return Some(nsITheme::eTransparent);
66 // These widgets may be thinner than the track, so we need to return
67 // transparent for them to make the track visible.
68 switch (aAppearance) {
69 case StyleAppearance::ScrollbarthumbHorizontal:
70 case StyleAppearance::ScrollbarthumbVertical:
71 case StyleAppearance::ScrollbarbuttonUp:
72 case StyleAppearance::ScrollbarbuttonDown:
73 case StyleAppearance::ScrollbarbuttonLeft:
74 case StyleAppearance::ScrollbarbuttonRight:
75 return Some(nsITheme::eTransparent);
76 default:
77 break;
80 if (aFrame->PresContext()->UseOverlayScrollbars()) {
81 return Some(nsITheme::eTransparent);
85 switch (aAppearance) {
86 case StyleAppearance::ScrollbarHorizontal:
87 case StyleAppearance::ScrollbarVertical:
88 case StyleAppearance::Scrollcorner:
89 case StyleAppearance::Statusbar:
90 // Knowing that scrollbars and statusbars are opaque improves
91 // performance, because we create layers for them. This better be
92 // true across all Windows themes! If it's not true, we should
93 // paint an opaque background for them to make it true!
94 // TODO(emilio): Unclear how much this optimization matters in practice
95 // now we're in a WR-only world.
96 return Some(nsITheme::eOpaque);
97 default:
98 break;
101 return Nothing();
104 // Returns the style for custom scrollbar if the scrollbar part frame should
105 // use the custom drawing path, nullptr otherwise.
107 // Optionally the caller can pass a pointer to aDarkScrollbar for whether
108 // custom scrollbar may be drawn due to dark background.
109 /*static*/
110 ComputedStyle* ScrollbarDrawingWin::GetCustomScrollbarStyle(
111 nsIFrame* aFrame, bool* aDarkScrollbar) {
112 ComputedStyle* style = nsLayoutUtils::StyleForScrollbar(aFrame);
113 if (style->StyleUI()->HasCustomScrollbars()) {
114 return style;
116 bool useDarkScrollbar = !StaticPrefs::widget_disable_dark_scrollbar() &&
117 nsNativeTheme::IsDarkBackground(aFrame);
118 if (useDarkScrollbar || IsScrollbarWidthThin(*style)) {
119 if (aDarkScrollbar) {
120 *aDarkScrollbar = useDarkScrollbar;
122 return style;
124 return nullptr;
127 template <typename PaintBackendData>
128 bool ScrollbarDrawingWin::DoPaintScrollbarThumb(
129 PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
130 bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
131 const EventStates& aElementState, const EventStates& aDocumentState,
132 const Colors& aColors, const DPIRatio& aDpiRatio) {
133 sRGBColor thumbColor = ComputeScrollbarThumbColor(
134 aFrame, aStyle, aElementState, aDocumentState, aColors);
135 ThemeDrawing::FillRect(aPaintData, aRect, thumbColor);
136 return true;
139 bool ScrollbarDrawingWin::PaintScrollbarThumb(
140 DrawTarget& aDrawTarget, const LayoutDeviceRect& aRect, bool aHorizontal,
141 nsIFrame* aFrame, const ComputedStyle& aStyle,
142 const EventStates& aElementState, const EventStates& aDocumentState,
143 const Colors& aColors, const DPIRatio& aDpiRatio) {
144 return DoPaintScrollbarThumb(aDrawTarget, aRect, aHorizontal, aFrame, aStyle,
145 aElementState, aDocumentState, aColors,
146 aDpiRatio);
149 bool ScrollbarDrawingWin::PaintScrollbarThumb(
150 WebRenderBackendData& aWrData, const LayoutDeviceRect& aRect,
151 bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
152 const EventStates& aElementState, const EventStates& aDocumentState,
153 const Colors& aColors, const DPIRatio& aDpiRatio) {
154 return DoPaintScrollbarThumb(aWrData, aRect, aHorizontal, aFrame, aStyle,
155 aElementState, aDocumentState, aColors,
156 aDpiRatio);
159 void ScrollbarDrawingWin::RecomputeScrollbarParams() {
160 uint32_t defaultSize = kDefaultWinScrollbarSize;
161 uint32_t overrideSize =
162 StaticPrefs::widget_non_native_theme_scrollbar_size_override();
163 if (overrideSize > 0) {
164 defaultSize = overrideSize;
166 mHorizontalScrollbarHeight = mVerticalScrollbarWidth = defaultSize;
168 if (StaticPrefs::widget_non_native_theme_win_scrollbar_use_system_size()) {
169 mHorizontalScrollbarHeight = LookAndFeel::GetInt(
170 LookAndFeel::IntID::SystemHorizontalScrollbarHeight, defaultSize);
171 mVerticalScrollbarWidth = LookAndFeel::GetInt(
172 LookAndFeel::IntID::SystemVerticalScrollbarWidth, defaultSize);
176 } // namespace mozilla::widget