Bug 1793579 [wpt PR 36253] - Set empty string for reflection of IDREF attributes...
[gecko.git] / widget / ScrollbarDrawingWin.cpp
blob97b5e9afe47400d261f3da38897ced7581ebdd95
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 // Returns the style for custom scrollbar if the scrollbar part frame should
58 // use the custom drawing path, nullptr otherwise.
59 const ComputedStyle* GetCustomScrollbarStyle(nsIFrame* aFrame) {
60 const ComputedStyle* style = nsLayoutUtils::StyleForScrollbar(aFrame);
61 if (style->StyleUI()->HasCustomScrollbars() ||
62 ScrollbarDrawing::IsScrollbarWidthThin(*style)) {
63 return style;
65 bool useDarkScrollbar = !StaticPrefs::widget_disable_dark_scrollbar() &&
66 nsNativeTheme::IsDarkBackgroundForScrollbar(aFrame);
67 if (useDarkScrollbar) {
68 return style;
70 return nullptr;
73 Maybe<nsITheme::Transparency> ScrollbarDrawingWin::GetScrollbarPartTransparency(
74 nsIFrame* aFrame, StyleAppearance aAppearance) {
75 if (nsNativeTheme::IsWidgetScrollbarPart(aAppearance)) {
76 if (const ComputedStyle* style = GetCustomScrollbarStyle(aFrame)) {
77 auto* ui = style->StyleUI();
78 if (ui->mScrollbarColor.IsAuto() ||
79 ui->mScrollbarColor.AsColors().track.MaybeTransparent()) {
80 return Some(nsITheme::eTransparent);
82 // These widgets may be thinner than the track, so we need to return
83 // transparent for them to make the track visible.
84 switch (aAppearance) {
85 case StyleAppearance::ScrollbarthumbHorizontal:
86 case StyleAppearance::ScrollbarthumbVertical:
87 case StyleAppearance::ScrollbarbuttonUp:
88 case StyleAppearance::ScrollbarbuttonDown:
89 case StyleAppearance::ScrollbarbuttonLeft:
90 case StyleAppearance::ScrollbarbuttonRight:
91 return Some(nsITheme::eTransparent);
92 default:
93 break;
96 if (aFrame->PresContext()->UseOverlayScrollbars()) {
97 return Some(nsITheme::eTransparent);
101 switch (aAppearance) {
102 case StyleAppearance::ScrollbarHorizontal:
103 case StyleAppearance::ScrollbarVertical:
104 case StyleAppearance::Scrollcorner:
105 case StyleAppearance::Statusbar:
106 // Knowing that scrollbars and statusbars are opaque improves
107 // performance, because we create layers for them. This better be
108 // true across all Windows themes! If it's not true, we should
109 // paint an opaque background for them to make it true!
110 // TODO(emilio): Unclear how much this optimization matters in practice
111 // now we're in a WR-only world.
112 return Some(nsITheme::eOpaque);
113 default:
114 break;
117 return Nothing();
120 template <typename PaintBackendData>
121 bool ScrollbarDrawingWin::DoPaintScrollbarThumb(
122 PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
123 ScrollbarKind aScrollbarKind, nsIFrame* aFrame, const ComputedStyle& aStyle,
124 const ElementState& aElementState, const DocumentState& aDocumentState,
125 const Colors& aColors, const DPIRatio& aDpiRatio) {
126 sRGBColor thumbColor = ComputeScrollbarThumbColor(
127 aFrame, aStyle, aElementState, aDocumentState, aColors);
128 ThemeDrawing::FillRect(aPaintData, aRect, thumbColor);
129 return true;
132 bool ScrollbarDrawingWin::PaintScrollbarThumb(
133 DrawTarget& aDrawTarget, const LayoutDeviceRect& aRect,
134 ScrollbarKind aScrollbarKind, nsIFrame* aFrame, const ComputedStyle& aStyle,
135 const ElementState& aElementState, const DocumentState& aDocumentState,
136 const Colors& aColors, const DPIRatio& aDpiRatio) {
137 return DoPaintScrollbarThumb(aDrawTarget, aRect, aScrollbarKind, aFrame,
138 aStyle, aElementState, aDocumentState, aColors,
139 aDpiRatio);
142 bool ScrollbarDrawingWin::PaintScrollbarThumb(
143 WebRenderBackendData& aWrData, const LayoutDeviceRect& aRect,
144 ScrollbarKind aScrollbarKind, nsIFrame* aFrame, const ComputedStyle& aStyle,
145 const ElementState& aElementState, const DocumentState& aDocumentState,
146 const Colors& aColors, const DPIRatio& aDpiRatio) {
147 return DoPaintScrollbarThumb(aWrData, aRect, aScrollbarKind, aFrame, aStyle,
148 aElementState, aDocumentState, aColors,
149 aDpiRatio);
152 void ScrollbarDrawingWin::RecomputeScrollbarParams() {
153 uint32_t defaultSize = kDefaultWinScrollbarSize;
154 uint32_t overrideSize =
155 StaticPrefs::widget_non_native_theme_scrollbar_size_override();
156 if (overrideSize > 0) {
157 defaultSize = overrideSize;
159 mHorizontalScrollbarHeight = mVerticalScrollbarWidth = defaultSize;
161 if (StaticPrefs::widget_non_native_theme_win_scrollbar_use_system_size()) {
162 mHorizontalScrollbarHeight = LookAndFeel::GetInt(
163 LookAndFeel::IntID::SystemHorizontalScrollbarHeight, defaultSize);
164 mVerticalScrollbarWidth = LookAndFeel::GetInt(
165 LookAndFeel::IntID::SystemVerticalScrollbarWidth, defaultSize);
169 } // namespace mozilla::widget