Bug 1719427: Refactor scrollbar drawing code across platforms. r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D129265
This commit is contained in:
@@ -255,7 +255,7 @@ class nsITheme : public nsISupports {
|
||||
*/
|
||||
virtual bool ThemeNeedsComboboxDropmarker() = 0;
|
||||
|
||||
virtual bool ThemeSupportsScrollbarButtons() { return true; }
|
||||
virtual bool ThemeSupportsScrollbarButtons() = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsITheme, NS_ITHEME_IID)
|
||||
|
||||
475
widget/ScrollbarDrawing.cpp
Normal file
475
widget/ScrollbarDrawing.cpp
Normal file
@@ -0,0 +1,475 @@
|
||||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 2; -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 : */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ScrollbarDrawing.h"
|
||||
|
||||
#include "mozilla/RelativeLuminanceUtils.h"
|
||||
#include "nsContainerFrame.h"
|
||||
#include "nsDeviceContext.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsLookAndFeel.h"
|
||||
#include "nsNativeTheme.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
using ScrollbarParams = ScrollbarDrawing::ScrollbarParams;
|
||||
using mozilla::RelativeLuminanceUtils;
|
||||
|
||||
uint32_t ScrollbarDrawing::sHorizontalScrollbarHeight = 0;
|
||||
uint32_t ScrollbarDrawing::sVerticalScrollbarWidth = 0;
|
||||
|
||||
/* static */
|
||||
auto ScrollbarDrawing::GetDPIRatioForScrollbarPart(nsPresContext* aPc)
|
||||
-> DPIRatio {
|
||||
if (auto* rootPc = aPc->GetRootPresContext()) {
|
||||
if (nsCOMPtr<nsIWidget> widget = rootPc->GetRootWidget()) {
|
||||
return widget->GetDefaultScale();
|
||||
}
|
||||
}
|
||||
return DPIRatio(
|
||||
float(AppUnitsPerCSSPixel()) /
|
||||
float(aPc->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom()));
|
||||
}
|
||||
|
||||
/*static*/
|
||||
nsIFrame* ScrollbarDrawing::GetParentScrollbarFrame(nsIFrame* aFrame) {
|
||||
// Walk our parents to find a scrollbar frame
|
||||
nsIFrame* scrollbarFrame = aFrame;
|
||||
do {
|
||||
if (scrollbarFrame->IsScrollbarFrame()) {
|
||||
break;
|
||||
}
|
||||
} while ((scrollbarFrame = scrollbarFrame->GetParent()));
|
||||
|
||||
// We return null if we can't find a parent scrollbar frame
|
||||
return scrollbarFrame;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
bool ScrollbarDrawing::IsParentScrollbarRolledOver(nsIFrame* aFrame) {
|
||||
nsIFrame* scrollbarFrame = GetParentScrollbarFrame(aFrame);
|
||||
return nsLookAndFeel::GetInt(LookAndFeel::IntID::UseOverlayScrollbars) != 0
|
||||
? nsNativeTheme::CheckBooleanAttr(scrollbarFrame, nsGkAtoms::hover)
|
||||
: nsNativeTheme::GetContentState(scrollbarFrame,
|
||||
StyleAppearance::None)
|
||||
.HasState(NS_EVENT_STATE_HOVER);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
bool ScrollbarDrawing::IsParentScrollbarHoveredOrActive(nsIFrame* aFrame) {
|
||||
nsIFrame* scrollbarFrame = GetParentScrollbarFrame(aFrame);
|
||||
return scrollbarFrame && scrollbarFrame->GetContent()
|
||||
->AsElement()
|
||||
->State()
|
||||
.HasAtLeastOneOfStates(NS_EVENT_STATE_HOVER |
|
||||
NS_EVENT_STATE_ACTIVE);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
bool ScrollbarDrawing::IsScrollbarWidthThin(const ComputedStyle& aStyle) {
|
||||
auto scrollbarWidth = aStyle.StyleUIReset()->mScrollbarWidth;
|
||||
return scrollbarWidth == StyleScrollbarWidth::Thin;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
bool ScrollbarDrawing::IsScrollbarWidthThin(nsIFrame* aFrame) {
|
||||
ComputedStyle* style = nsLayoutUtils::StyleForScrollbar(aFrame);
|
||||
return IsScrollbarWidthThin(*style);
|
||||
}
|
||||
|
||||
auto ScrollbarDrawing::GetScrollbarSizes(nsPresContext* aPresContext,
|
||||
StyleScrollbarWidth aWidth, Overlay)
|
||||
-> ScrollbarSizes {
|
||||
uint32_t h = sHorizontalScrollbarHeight;
|
||||
uint32_t w = sVerticalScrollbarWidth;
|
||||
if (aWidth == StyleScrollbarWidth::Thin) {
|
||||
h /= 2;
|
||||
w /= 2;
|
||||
}
|
||||
auto dpi = GetDPIRatioForScrollbarPart(aPresContext);
|
||||
return {(CSSCoord(w) * dpi).Rounded(), (CSSCoord(h) * dpi).Rounded()};
|
||||
}
|
||||
|
||||
/*static*/
|
||||
bool ScrollbarDrawing::IsScrollbarTrackOpaque(nsIFrame* aFrame) {
|
||||
auto trackColor = ComputeScrollbarTrackColor(
|
||||
aFrame, *nsLayoutUtils::StyleForScrollbar(aFrame),
|
||||
aFrame->PresContext()->Document()->GetDocumentState(), Colors(aFrame));
|
||||
return trackColor.a == 1.0f;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
sRGBColor ScrollbarDrawing::ComputeScrollbarTrackColor(
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const Colors& aColors) {
|
||||
const nsStyleUI* ui = aStyle.StyleUI();
|
||||
if (aColors.HighContrast()) {
|
||||
return aColors.System(StyleSystemColor::Window);
|
||||
}
|
||||
if (ShouldUseDarkScrollbar(aFrame, aStyle)) {
|
||||
return sRGBColor::FromU8(20, 20, 25, 77);
|
||||
}
|
||||
if (ui->mScrollbarColor.IsColors()) {
|
||||
return sRGBColor::FromABGR(
|
||||
ui->mScrollbarColor.AsColors().track.CalcColor(aStyle));
|
||||
}
|
||||
if (aDocumentState.HasAllStates(NS_DOCUMENT_STATE_WINDOW_INACTIVE)) {
|
||||
return aColors.SystemOrElse(StyleSystemColor::ThemedScrollbarInactive,
|
||||
[] { return sScrollbarColor; });
|
||||
}
|
||||
return aColors.SystemOrElse(StyleSystemColor::ThemedScrollbar,
|
||||
[] { return sScrollbarColor; });
|
||||
}
|
||||
|
||||
// Don't use the theme color for dark scrollbars if it's not a color (if it's
|
||||
// grey-ish), as that'd either lack enough contrast, or be close to what we'd do
|
||||
// by default anyways.
|
||||
static bool ShouldUseColorForActiveDarkScrollbarThumb(nscolor aColor) {
|
||||
auto IsDifferentEnough = [](int32_t aChannel, int32_t aOtherChannel) {
|
||||
return std::abs(aChannel - aOtherChannel) > 10;
|
||||
};
|
||||
return IsDifferentEnough(NS_GET_R(aColor), NS_GET_G(aColor)) ||
|
||||
IsDifferentEnough(NS_GET_R(aColor), NS_GET_B(aColor));
|
||||
}
|
||||
|
||||
/*static*/
|
||||
sRGBColor ScrollbarDrawing::ComputeScrollbarThumbColor(
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors& aColors) {
|
||||
if (!aColors.HighContrast() && ShouldUseDarkScrollbar(aFrame, aStyle)) {
|
||||
if (aElementState.HasState(NS_EVENT_STATE_ACTIVE) &&
|
||||
StaticPrefs::widget_non_native_theme_scrollbar_active_always_themed()) {
|
||||
auto color = LookAndFeel::GetColor(
|
||||
StyleSystemColor::ThemedScrollbarThumbActive,
|
||||
LookAndFeel::ColorScheme::Light, LookAndFeel::UseStandins::No);
|
||||
if (color && ShouldUseColorForActiveDarkScrollbarThumb(*color)) {
|
||||
return sRGBColor::FromABGR(*color);
|
||||
}
|
||||
}
|
||||
return sRGBColor::FromABGR(ThemeColors::AdjustUnthemedScrollbarThumbColor(
|
||||
NS_RGBA(249, 249, 250, 102), aElementState));
|
||||
}
|
||||
|
||||
const nsStyleUI* ui = aStyle.StyleUI();
|
||||
if (ui->mScrollbarColor.IsColors()) {
|
||||
return sRGBColor::FromABGR(ThemeColors::AdjustUnthemedScrollbarThumbColor(
|
||||
ui->mScrollbarColor.AsColors().thumb.CalcColor(aStyle), aElementState));
|
||||
}
|
||||
|
||||
auto systemColor = [&] {
|
||||
if (aDocumentState.HasState(NS_DOCUMENT_STATE_WINDOW_INACTIVE)) {
|
||||
return StyleSystemColor::ThemedScrollbarThumbInactive;
|
||||
}
|
||||
if (aElementState.HasState(NS_EVENT_STATE_ACTIVE)) {
|
||||
if (aColors.HighContrast()) {
|
||||
return StyleSystemColor::Selecteditem;
|
||||
}
|
||||
return StyleSystemColor::ThemedScrollbarThumbActive;
|
||||
}
|
||||
if (aElementState.HasState(NS_EVENT_STATE_HOVER)) {
|
||||
if (aColors.HighContrast()) {
|
||||
return StyleSystemColor::Selecteditem;
|
||||
}
|
||||
return StyleSystemColor::ThemedScrollbarThumbHover;
|
||||
}
|
||||
if (aColors.HighContrast()) {
|
||||
return StyleSystemColor::Windowtext;
|
||||
}
|
||||
return StyleSystemColor::ThemedScrollbarThumb;
|
||||
}();
|
||||
|
||||
return aColors.SystemOrElse(systemColor, [&] {
|
||||
return sRGBColor::FromABGR(ThemeColors::AdjustUnthemedScrollbarThumbColor(
|
||||
sScrollbarThumbColor.ToABGR(), aElementState));
|
||||
});
|
||||
}
|
||||
|
||||
/*static*/
|
||||
ScrollbarParams ScrollbarDrawing::ComputeScrollbarParams(
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle, bool aIsHorizontal) {
|
||||
ScrollbarParams params;
|
||||
params.overlay =
|
||||
nsLookAndFeel::GetInt(LookAndFeel::IntID::UseOverlayScrollbars) != 0;
|
||||
params.rolledOver = IsParentScrollbarRolledOver(aFrame);
|
||||
params.small =
|
||||
aStyle.StyleUIReset()->mScrollbarWidth == StyleScrollbarWidth::Thin;
|
||||
params.rtl = nsNativeTheme::IsFrameRTL(aFrame);
|
||||
params.horizontal = aIsHorizontal;
|
||||
params.onDarkBackground = !StaticPrefs::widget_disable_dark_scrollbar() &&
|
||||
nsNativeTheme::IsDarkBackground(aFrame);
|
||||
// Don't use custom scrollbars for overlay scrollbars since they are
|
||||
// generally good enough for use cases of custom scrollbars.
|
||||
if (!params.overlay) {
|
||||
const nsStyleUI* ui = aStyle.StyleUI();
|
||||
if (ui->HasCustomScrollbars()) {
|
||||
const auto& colors = ui->mScrollbarColor.AsColors();
|
||||
params.custom = true;
|
||||
params.trackColor = colors.track.CalcColor(aStyle);
|
||||
params.faceColor = colors.thumb.CalcColor(aStyle);
|
||||
}
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
template <typename PaintBackendData>
|
||||
bool ScrollbarDrawing::DoPaintDefaultScrollbar(
|
||||
PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors& aColors, const DPIRatio& aDpiRatio) {
|
||||
if (aFrame->PresContext()->UseOverlayScrollbars() &&
|
||||
!aElementState.HasAtLeastOneOfStates(NS_EVENT_STATE_HOVER |
|
||||
NS_EVENT_STATE_ACTIVE)) {
|
||||
return true;
|
||||
}
|
||||
auto scrollbarColor =
|
||||
ComputeScrollbarTrackColor(aFrame, aStyle, aDocumentState, aColors);
|
||||
ThemeDrawing::FillRect(aPaintData, aRect, scrollbarColor);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScrollbarDrawing::PaintScrollbar(
|
||||
DrawTarget& aDrawTarget, const LayoutDeviceRect& aRect, bool aHorizontal,
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors& aColors, const DPIRatio& aDpiRatio) {
|
||||
return DoPaintDefaultScrollbar(aDrawTarget, aRect, aHorizontal, aFrame,
|
||||
aStyle, aElementState, aDocumentState, aColors,
|
||||
aDpiRatio);
|
||||
}
|
||||
|
||||
bool ScrollbarDrawing::PaintScrollbar(
|
||||
WebRenderBackendData& aWrData, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors& aColors, const DPIRatio& aDpiRatio) {
|
||||
return DoPaintDefaultScrollbar(aWrData, aRect, aHorizontal, aFrame, aStyle,
|
||||
aElementState, aDocumentState, aColors,
|
||||
aDpiRatio);
|
||||
}
|
||||
|
||||
template <typename PaintBackendData>
|
||||
bool ScrollbarDrawing::DoPaintDefaultScrollCorner(
|
||||
PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const Colors& aColors,
|
||||
const DPIRatio& aDpiRatio) {
|
||||
auto scrollbarColor =
|
||||
ComputeScrollbarTrackColor(aFrame, aStyle, aDocumentState, aColors);
|
||||
ThemeDrawing::FillRect(aPaintData, aRect, scrollbarColor);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScrollbarDrawing::PaintScrollCorner(
|
||||
DrawTarget& aDrawTarget, const LayoutDeviceRect& aRect, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle, const EventStates& aDocumentState,
|
||||
const Colors& aColors, const DPIRatio& aDpiRatio) {
|
||||
return DoPaintDefaultScrollCorner(aDrawTarget, aRect, aFrame, aStyle,
|
||||
aDocumentState, aColors, aDpiRatio);
|
||||
}
|
||||
|
||||
bool ScrollbarDrawing::PaintScrollCorner(WebRenderBackendData& aWrData,
|
||||
const LayoutDeviceRect& aRect,
|
||||
nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors& aColors,
|
||||
const DPIRatio& aDpiRatio) {
|
||||
return DoPaintDefaultScrollCorner(aWrData, aRect, aFrame, aStyle,
|
||||
aDocumentState, aColors, aDpiRatio);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
bool ScrollbarDrawing::ShouldUseDarkScrollbar(nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle) {
|
||||
if (StaticPrefs::widget_disable_dark_scrollbar()) {
|
||||
return false;
|
||||
}
|
||||
if (aStyle.StyleUI()->mScrollbarColor.IsColors()) {
|
||||
return false;
|
||||
}
|
||||
return nsNativeTheme::IsDarkBackground(aFrame);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
nscolor ScrollbarDrawing::GetScrollbarButtonColor(nscolor aTrackColor,
|
||||
EventStates aStates) {
|
||||
// See numbers in GetScrollbarArrowColor.
|
||||
// This function is written based on ratios between values listed there.
|
||||
|
||||
bool isActive = aStates.HasState(NS_EVENT_STATE_ACTIVE);
|
||||
bool isHover = aStates.HasState(NS_EVENT_STATE_HOVER);
|
||||
if (!isActive && !isHover) {
|
||||
return aTrackColor;
|
||||
}
|
||||
float luminance = RelativeLuminanceUtils::Compute(aTrackColor);
|
||||
if (isActive) {
|
||||
if (luminance >= 0.18f) {
|
||||
luminance *= 0.134f;
|
||||
} else {
|
||||
luminance /= 0.134f;
|
||||
luminance = std::min(luminance, 1.0f);
|
||||
}
|
||||
} else {
|
||||
if (luminance >= 0.18f) {
|
||||
luminance *= 0.805f;
|
||||
} else {
|
||||
luminance /= 0.805f;
|
||||
}
|
||||
}
|
||||
return RelativeLuminanceUtils::Adjust(aTrackColor, luminance);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
Maybe<nscolor> ScrollbarDrawing::GetScrollbarArrowColor(nscolor aButtonColor) {
|
||||
// In Windows 10 scrollbar, there are several gray colors used:
|
||||
//
|
||||
// State | Background (lum) | Arrow | Contrast
|
||||
// -------+------------------+---------+---------
|
||||
// Normal | Gray 240 (87.1%) | Gray 96 | 5.5
|
||||
// Hover | Gray 218 (70.1%) | Black | 15.0
|
||||
// Active | Gray 96 (11.7%) | White | 6.3
|
||||
//
|
||||
// Contrast value is computed based on the definition in
|
||||
// https://www.w3.org/TR/WCAG20/#contrast-ratiodef
|
||||
//
|
||||
// This function is written based on these values.
|
||||
|
||||
if (NS_GET_A(aButtonColor) == 0) {
|
||||
// If the button color is transparent, because of e.g.
|
||||
// scrollbar-color: <something> transparent, then use
|
||||
// the thumb color, which is expected to have enough
|
||||
// contrast.
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
float luminance = RelativeLuminanceUtils::Compute(aButtonColor);
|
||||
// Color with luminance larger than 0.72 has contrast ratio over 4.6
|
||||
// to color with luminance of gray 96, so this value is chosen for
|
||||
// this range. It is the luminance of gray 221.
|
||||
if (luminance >= 0.72) {
|
||||
// ComputeRelativeLuminanceFromComponents(96). That function cannot
|
||||
// be constexpr because of std::pow.
|
||||
const float GRAY96_LUMINANCE = 0.117f;
|
||||
return Some(RelativeLuminanceUtils::Adjust(aButtonColor, GRAY96_LUMINANCE));
|
||||
}
|
||||
// The contrast ratio of a color to black equals that to white when its
|
||||
// luminance is around 0.18, with a contrast ratio ~4.6 to both sides,
|
||||
// thus the value below. It's the lumanince of gray 118.
|
||||
//
|
||||
// TODO(emilio): Maybe the button alpha is not the best thing to use here and
|
||||
// we should use the thumb alpha? It seems weird that the color of the arrow
|
||||
// depends on the opacity of the scrollbar thumb...
|
||||
if (luminance >= 0.18) {
|
||||
return Some(NS_RGBA(0, 0, 0, NS_GET_A(aButtonColor)));
|
||||
}
|
||||
return Some(NS_RGBA(255, 255, 255, NS_GET_A(aButtonColor)));
|
||||
}
|
||||
|
||||
std::pair<sRGBColor, sRGBColor> ScrollbarDrawing::ComputeScrollbarButtonColors(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors& aColors) {
|
||||
if (aColors.HighContrast()) {
|
||||
if (aElementState.HasAtLeastOneOfStates(NS_EVENT_STATE_ACTIVE |
|
||||
NS_EVENT_STATE_HOVER)) {
|
||||
return aColors.SystemPair(StyleSystemColor::Selecteditem,
|
||||
StyleSystemColor::Buttonface);
|
||||
}
|
||||
return aColors.SystemPair(StyleSystemColor::Window,
|
||||
StyleSystemColor::Windowtext);
|
||||
}
|
||||
|
||||
auto trackColor =
|
||||
ComputeScrollbarTrackColor(aFrame, aStyle, aDocumentState, aColors);
|
||||
nscolor buttonColor =
|
||||
GetScrollbarButtonColor(trackColor.ToABGR(), aElementState);
|
||||
auto arrowColor =
|
||||
GetScrollbarArrowColor(buttonColor)
|
||||
.map(sRGBColor::FromABGR)
|
||||
.valueOrFrom([&] {
|
||||
return ComputeScrollbarThumbColor(aFrame, aStyle, aElementState,
|
||||
aDocumentState, aColors);
|
||||
});
|
||||
return {sRGBColor::FromABGR(buttonColor), arrowColor};
|
||||
}
|
||||
|
||||
bool ScrollbarDrawing::PaintScrollbarButton(
|
||||
DrawTarget& aDrawTarget, StyleAppearance aAppearance,
|
||||
const LayoutDeviceRect& aRect, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle, const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors& aColors,
|
||||
const DPIRatio& aDpiRatio) {
|
||||
auto [buttonColor, arrowColor] = ComputeScrollbarButtonColors(
|
||||
aFrame, aAppearance, aStyle, aElementState, aDocumentState, aColors);
|
||||
aDrawTarget.FillRect(aRect.ToUnknownRect(),
|
||||
ColorPattern(ToDeviceColor(buttonColor)));
|
||||
|
||||
// Start with Up arrow.
|
||||
float arrowPolygonX[] = {-4.0f, 0.0f, 4.0f, 4.0f, 0.0f, -4.0f};
|
||||
float arrowPolygonY[] = {0.0f, -4.0f, 0.0f, 3.0f, -1.0f, 3.0f};
|
||||
|
||||
const float kPolygonSize = 17;
|
||||
|
||||
const int32_t arrowNumPoints = ArrayLength(arrowPolygonX);
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::ScrollbarbuttonUp:
|
||||
break;
|
||||
case StyleAppearance::ScrollbarbuttonDown:
|
||||
for (int32_t i = 0; i < arrowNumPoints; i++) {
|
||||
arrowPolygonY[i] *= -1;
|
||||
}
|
||||
break;
|
||||
case StyleAppearance::ScrollbarbuttonLeft:
|
||||
for (int32_t i = 0; i < arrowNumPoints; i++) {
|
||||
float temp = arrowPolygonX[i];
|
||||
arrowPolygonX[i] = arrowPolygonY[i];
|
||||
arrowPolygonY[i] = temp;
|
||||
}
|
||||
break;
|
||||
case StyleAppearance::ScrollbarbuttonRight:
|
||||
for (int32_t i = 0; i < arrowNumPoints; i++) {
|
||||
float temp = arrowPolygonX[i];
|
||||
arrowPolygonX[i] = arrowPolygonY[i] * -1;
|
||||
arrowPolygonY[i] = temp;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
ThemeDrawing::PaintArrow(aDrawTarget, aRect, arrowPolygonX, arrowPolygonY,
|
||||
kPolygonSize, arrowNumPoints, arrowColor);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void ScrollbarDrawing::RecomputeScrollbarParams() {
|
||||
uint32_t defaultSize = StaticPrefs::widget_non_native_theme_scrollbar_size();
|
||||
if (StaticPrefs::widget_non_native_theme_win_scrollbar_use_system_size()) {
|
||||
sHorizontalScrollbarHeight = LookAndFeel::GetInt(
|
||||
LookAndFeel::IntID::SystemHorizontalScrollbarHeight, defaultSize);
|
||||
sVerticalScrollbarWidth = LookAndFeel::GetInt(
|
||||
LookAndFeel::IntID::SystemVerticalScrollbarWidth, defaultSize);
|
||||
} else {
|
||||
sHorizontalScrollbarHeight = sVerticalScrollbarWidth = defaultSize;
|
||||
}
|
||||
// On GTK, widgets don't account for text scale factor, but that's included
|
||||
// in the usual DPI computations, so we undo that here, just like
|
||||
// GetMonitorScaleFactor does it in nsNativeThemeGTK.
|
||||
float scale =
|
||||
LookAndFeel::GetFloat(LookAndFeel::FloatID::TextScaleFactor, 1.0f);
|
||||
if (scale != 1.0f) {
|
||||
sVerticalScrollbarWidth =
|
||||
uint32_t(round(float(sVerticalScrollbarWidth) / scale));
|
||||
sHorizontalScrollbarHeight =
|
||||
uint32_t(round(float(sHorizontalScrollbarHeight) / scale));
|
||||
}
|
||||
}
|
||||
174
widget/ScrollbarDrawing.h
Normal file
174
widget/ScrollbarDrawing.h
Normal file
@@ -0,0 +1,174 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_widget_ScrollbarDrawing_h
|
||||
#define mozilla_widget_ScrollbarDrawing_h
|
||||
|
||||
#include "mozilla/EventStates.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "nsColor.h"
|
||||
#include "nsITheme.h"
|
||||
#include "ThemeColors.h"
|
||||
#include "ThemeDrawing.h"
|
||||
#include "Units.h"
|
||||
|
||||
namespace mozilla::widget {
|
||||
|
||||
static constexpr gfx::sRGBColor sScrollbarColor(
|
||||
gfx::sRGBColor::UnusualFromARGB(0xfff0f0f0));
|
||||
static constexpr gfx::sRGBColor sScrollbarThumbColor(
|
||||
gfx::sRGBColor::UnusualFromARGB(0xffcdcdcd));
|
||||
|
||||
class ScrollbarDrawing {
|
||||
protected:
|
||||
using DPIRatio = mozilla::CSSToLayoutDeviceScale;
|
||||
using EventStates = mozilla::EventStates;
|
||||
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;
|
||||
|
||||
public:
|
||||
ScrollbarDrawing() = default;
|
||||
virtual ~ScrollbarDrawing() = default;
|
||||
|
||||
struct ScrollbarParams {
|
||||
bool overlay = false;
|
||||
bool rolledOver = false;
|
||||
bool small = false;
|
||||
bool horizontal = false;
|
||||
bool rtl = false;
|
||||
bool onDarkBackground = false;
|
||||
bool custom = false;
|
||||
// Two colors only used when custom is true.
|
||||
nscolor trackColor = NS_RGBA(0, 0, 0, 0);
|
||||
nscolor faceColor = NS_RGBA(0, 0, 0, 0);
|
||||
};
|
||||
|
||||
static DPIRatio GetDPIRatioForScrollbarPart(nsPresContext*);
|
||||
|
||||
static nsIFrame* GetParentScrollbarFrame(nsIFrame* aFrame);
|
||||
static bool IsParentScrollbarRolledOver(nsIFrame* aFrame);
|
||||
static bool IsParentScrollbarHoveredOrActive(nsIFrame* aFrame);
|
||||
|
||||
static bool IsScrollbarWidthThin(const ComputedStyle& aStyle);
|
||||
static bool IsScrollbarWidthThin(nsIFrame* aFrame);
|
||||
|
||||
virtual ScrollbarSizes GetScrollbarSizes(nsPresContext*, StyleScrollbarWidth,
|
||||
Overlay);
|
||||
virtual LayoutDeviceIntSize GetMinimumWidgetSize(nsPresContext*,
|
||||
StyleAppearance aAppearance,
|
||||
nsIFrame* aFrame) = 0;
|
||||
virtual Maybe<nsITheme::Transparency> GetScrollbarPartTransparency(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) {
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
static bool IsScrollbarTrackOpaque(nsIFrame*);
|
||||
static sRGBColor ComputeScrollbarTrackColor(nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&);
|
||||
static sRGBColor ComputeScrollbarThumbColor(nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&);
|
||||
|
||||
static ScrollbarParams ComputeScrollbarParams(nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
bool aIsHorizontal);
|
||||
static bool ShouldUseDarkScrollbar(nsIFrame*, const ComputedStyle&);
|
||||
|
||||
static nscolor GetScrollbarButtonColor(nscolor aTrackColor, EventStates);
|
||||
static Maybe<nscolor> GetScrollbarArrowColor(nscolor aButtonColor);
|
||||
|
||||
// Returned colors are button, arrow.
|
||||
std::pair<sRGBColor, sRGBColor> ComputeScrollbarButtonColors(
|
||||
nsIFrame*, StyleAppearance, const ComputedStyle&,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors&);
|
||||
|
||||
bool PaintScrollbarButton(DrawTarget&, StyleAppearance,
|
||||
const LayoutDeviceRect&, nsIFrame*,
|
||||
const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio&);
|
||||
|
||||
virtual bool PaintScrollbarThumb(DrawTarget&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*,
|
||||
const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&, const DPIRatio&) = 0;
|
||||
virtual bool PaintScrollbarThumb(WebRenderBackendData&,
|
||||
const LayoutDeviceRect&, bool aHorizontal,
|
||||
nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&, const DPIRatio&) = 0;
|
||||
|
||||
template <typename PaintBackendData>
|
||||
bool DoPaintDefaultScrollbar(PaintBackendData&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*,
|
||||
const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio&);
|
||||
virtual bool PaintScrollbar(DrawTarget&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio&);
|
||||
virtual bool PaintScrollbar(WebRenderBackendData&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio&);
|
||||
|
||||
virtual bool PaintScrollbarTrack(DrawTarget&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*,
|
||||
const ComputedStyle&,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&, const DPIRatio&) {
|
||||
// Draw nothing by default. Subclasses can override this.
|
||||
return true;
|
||||
}
|
||||
virtual bool PaintScrollbarTrack(WebRenderBackendData&,
|
||||
const LayoutDeviceRect&, bool aHorizontal,
|
||||
nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&, const DPIRatio&) {
|
||||
// Draw nothing by default. Subclasses can override this.
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename PaintBackendData>
|
||||
bool DoPaintDefaultScrollCorner(PaintBackendData&, const LayoutDeviceRect&,
|
||||
nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&, const DPIRatio&);
|
||||
virtual bool PaintScrollCorner(DrawTarget&, const LayoutDeviceRect&,
|
||||
nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&, const DPIRatio&);
|
||||
virtual bool PaintScrollCorner(WebRenderBackendData&, const LayoutDeviceRect&,
|
||||
nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&, const DPIRatio&);
|
||||
|
||||
static void RecomputeScrollbarParams();
|
||||
|
||||
virtual bool ShouldDrawScrollbarButtons() { return true; }
|
||||
|
||||
static uint32_t sHorizontalScrollbarHeight;
|
||||
static uint32_t sVerticalScrollbarWidth;
|
||||
};
|
||||
|
||||
} // namespace mozilla::widget
|
||||
|
||||
#endif
|
||||
@@ -3,46 +3,42 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsNativeBasicThemeAndroid.h"
|
||||
#include "ScrollbarDrawingAndroid.h"
|
||||
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsNativeTheme.h"
|
||||
|
||||
auto nsNativeBasicThemeAndroid::GetScrollbarSizes(nsPresContext* aPresContext,
|
||||
StyleScrollbarWidth aWidth,
|
||||
Overlay aOverlay)
|
||||
-> ScrollbarSizes {
|
||||
// We force auto-width scrollbars because scrollbars on android are already
|
||||
// thin enough.
|
||||
return nsNativeBasicTheme::GetScrollbarSizes(
|
||||
aPresContext, StyleScrollbarWidth::Auto, aOverlay);
|
||||
}
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNativeBasicThemeAndroid::GetMinimumWidgetSize(
|
||||
nsPresContext* aPresContext, nsIFrame* aFrame, StyleAppearance aAppearance,
|
||||
mozilla::LayoutDeviceIntSize* aResult, bool* aIsOverridable) {
|
||||
if (!IsWidgetScrollbarPart(aAppearance)) {
|
||||
return nsNativeBasicTheme::GetMinimumWidgetSize(
|
||||
aPresContext, aFrame, aAppearance, aResult, aIsOverridable);
|
||||
}
|
||||
LayoutDeviceIntSize ScrollbarDrawingAndroid::GetMinimumWidgetSize(
|
||||
nsPresContext* aPresContext, StyleAppearance aAppearance,
|
||||
nsIFrame* aFrame) {
|
||||
MOZ_ASSERT(nsNativeTheme::IsWidgetScrollbarPart(aAppearance));
|
||||
|
||||
auto sizes =
|
||||
GetScrollbarSizes(aPresContext, StyleScrollbarWidth::Auto, Overlay::Yes);
|
||||
aResult->SizeTo(sizes.mHorizontal, sizes.mHorizontal);
|
||||
MOZ_ASSERT(sizes.mHorizontal == sizes.mVertical);
|
||||
|
||||
*aIsOverridable = true;
|
||||
return NS_OK;
|
||||
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);
|
||||
}
|
||||
|
||||
template <typename PaintBackendData>
|
||||
void nsNativeBasicThemeAndroid::DoPaintScrollbarThumb(
|
||||
void ScrollbarDrawingAndroid::DoPaintScrollbarThumb(
|
||||
PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors& aColors, DPIRatio aDpiRatio) {
|
||||
const Colors& aColors, const DPIRatio& aDpiRatio) {
|
||||
// TODO(emilio): Maybe do like macOS and draw a stroke?
|
||||
const auto color = ComputeScrollbarThumbColor(aFrame, aStyle, aElementState,
|
||||
aDocumentState, aColors);
|
||||
@@ -59,48 +55,27 @@ void nsNativeBasicThemeAndroid::DoPaintScrollbarThumb(
|
||||
|
||||
const LayoutDeviceCoord radius =
|
||||
(aHorizontal ? thumbRect.height : thumbRect.width) / 2.0f;
|
||||
PaintRoundedRectWithRadius(aPaintData, thumbRect, color,
|
||||
sRGBColor::White(0.0f), 0.0f, radius / aDpiRatio,
|
||||
aDpiRatio);
|
||||
ThemeDrawing::PaintRoundedRectWithRadius(aPaintData, thumbRect, color,
|
||||
sRGBColor::White(0.0f), 0.0f,
|
||||
radius / aDpiRatio, aDpiRatio);
|
||||
}
|
||||
|
||||
bool nsNativeBasicThemeAndroid::PaintScrollbarThumb(
|
||||
bool ScrollbarDrawingAndroid::PaintScrollbarThumb(
|
||||
DrawTarget& aDt, const LayoutDeviceRect& aRect, bool aHorizontal,
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors& aColors, DPIRatio aDpiRatio) {
|
||||
const Colors& aColors, const DPIRatio& aDpiRatio) {
|
||||
DoPaintScrollbarThumb(aDt, aRect, aHorizontal, aFrame, aStyle, aElementState,
|
||||
aDocumentState, aColors, aDpiRatio);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nsNativeBasicThemeAndroid::PaintScrollbarThumb(
|
||||
bool ScrollbarDrawingAndroid::PaintScrollbarThumb(
|
||||
WebRenderBackendData& aWrData, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors& aColors, DPIRatio aDpiRatio) {
|
||||
const Colors& aColors, const DPIRatio& aDpiRatio) {
|
||||
DoPaintScrollbarThumb(aWrData, aRect, aHorizontal, aFrame, aStyle,
|
||||
aElementState, aDocumentState, aColors, aDpiRatio);
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<nsITheme> do_GetAndroidNonNativeThemeDoNotUseDirectly() {
|
||||
static mozilla::StaticRefPtr<nsITheme> gInstance;
|
||||
if (MOZ_UNLIKELY(!gInstance)) {
|
||||
gInstance = new nsNativeBasicThemeAndroid();
|
||||
ClearOnShutdown(&gInstance);
|
||||
}
|
||||
return do_AddRef(gInstance);
|
||||
}
|
||||
|
||||
|
||||
#ifdef ANDROID
|
||||
already_AddRefed<nsITheme> do_GetBasicNativeThemeDoNotUseDirectly() {
|
||||
return do_GetAndroidNonNativeThemeDoNotUseDirectly();
|
||||
}
|
||||
|
||||
already_AddRefed<nsITheme> do_GetNativeThemeDoNotUseDirectly() {
|
||||
// Android doesn't have a native theme.
|
||||
return do_GetBasicNativeThemeDoNotUseDirectly();
|
||||
}
|
||||
#endif
|
||||
51
widget/ScrollbarDrawingAndroid.h
Normal file
51
widget/ScrollbarDrawingAndroid.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_widget_ScrollbarDrawingAndroid_h
|
||||
#define mozilla_widget_ScrollbarDrawingAndroid_h
|
||||
|
||||
#include "nsITheme.h"
|
||||
#include "ScrollbarDrawing.h"
|
||||
|
||||
namespace mozilla::widget {
|
||||
|
||||
class ScrollbarDrawingAndroid final : public ScrollbarDrawing {
|
||||
public:
|
||||
ScrollbarDrawingAndroid() = default;
|
||||
virtual ~ScrollbarDrawingAndroid() = default;
|
||||
|
||||
LayoutDeviceIntSize GetMinimumWidgetSize(nsPresContext*,
|
||||
StyleAppearance aAppearance,
|
||||
nsIFrame* aFrame) override;
|
||||
|
||||
ScrollbarSizes GetScrollbarSizes(nsPresContext*, StyleScrollbarWidth,
|
||||
Overlay) override;
|
||||
|
||||
template <typename PaintBackendData>
|
||||
void DoPaintScrollbarThumb(PaintBackendData&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio&);
|
||||
bool PaintScrollbarThumb(DrawTarget&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio&) override;
|
||||
bool PaintScrollbarThumb(WebRenderBackendData&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio&) override;
|
||||
|
||||
bool ShouldDrawScrollbarButtons() override { return false; }
|
||||
};
|
||||
|
||||
} // namespace mozilla::widget
|
||||
|
||||
#endif
|
||||
@@ -4,63 +4,26 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ScrollbarDrawingMac.h"
|
||||
#include "ScrollbarDrawingCocoa.h"
|
||||
|
||||
#include "mozilla/gfx/Helpers.h"
|
||||
#include "mozilla/RelativeLuminanceUtils.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsLookAndFeel.h"
|
||||
#include "mozilla/StaticPrefs_widget.h"
|
||||
#include "nsContainerFrame.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsLookAndFeel.h"
|
||||
#include "nsNativeTheme.h"
|
||||
|
||||
namespace mozilla {
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
using namespace gfx;
|
||||
LayoutDeviceIntSize ScrollbarDrawingCocoa::GetMinimumWidgetSize(
|
||||
nsPresContext* aPresContext, StyleAppearance aAppearance,
|
||||
nsIFrame* aFrame) {
|
||||
MOZ_ASSERT(nsNativeTheme::IsWidgetScrollbarPart(aAppearance));
|
||||
|
||||
namespace widget {
|
||||
|
||||
static nsIFrame* GetParentScrollbarFrame(nsIFrame* aFrame) {
|
||||
// Walk our parents to find a scrollbar frame
|
||||
nsIFrame* scrollbarFrame = aFrame;
|
||||
do {
|
||||
if (scrollbarFrame->IsScrollbarFrame()) {
|
||||
break;
|
||||
}
|
||||
} while ((scrollbarFrame = scrollbarFrame->GetParent()));
|
||||
|
||||
// We return null if we can't find a parent scrollbar frame
|
||||
return scrollbarFrame;
|
||||
}
|
||||
|
||||
static bool IsParentScrollbarRolledOver(nsIFrame* aFrame) {
|
||||
nsIFrame* scrollbarFrame = GetParentScrollbarFrame(aFrame);
|
||||
return nsLookAndFeel::GetInt(LookAndFeel::IntID::UseOverlayScrollbars) != 0
|
||||
? nsNativeTheme::CheckBooleanAttr(scrollbarFrame, nsGkAtoms::hover)
|
||||
: nsNativeTheme::GetContentState(scrollbarFrame,
|
||||
StyleAppearance::None)
|
||||
.HasState(NS_EVENT_STATE_HOVER);
|
||||
}
|
||||
|
||||
CSSIntCoord ScrollbarDrawingMac::GetScrollbarSize(StyleScrollbarWidth aWidth,
|
||||
bool aOverlay) {
|
||||
bool isSmall = aWidth == StyleScrollbarWidth::Thin;
|
||||
if (aOverlay) {
|
||||
return isSmall ? 14 : 16;
|
||||
}
|
||||
return isSmall ? 11 : 15;
|
||||
}
|
||||
|
||||
LayoutDeviceIntCoord ScrollbarDrawingMac::GetScrollbarSize(
|
||||
StyleScrollbarWidth aWidth, bool aOverlay, float aDpiRatio) {
|
||||
CSSIntCoord size = GetScrollbarSize(aWidth, aOverlay);
|
||||
if (aDpiRatio >= 2.0f) {
|
||||
return int32_t(size) * 2;
|
||||
}
|
||||
return int32_t(size);
|
||||
}
|
||||
|
||||
LayoutDeviceIntSize ScrollbarDrawingMac::GetMinimumWidgetSize(
|
||||
StyleAppearance aAppearance, nsIFrame* aFrame, float aDpiRatio) {
|
||||
auto minSize = [&] {
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::ScrollbarthumbHorizontal:
|
||||
@@ -78,11 +41,6 @@ LayoutDeviceIntSize ScrollbarDrawingMac::GetMinimumWidgetSize(
|
||||
LookAndFeel::GetInt(LookAndFeel::IntID::UseOverlayScrollbars));
|
||||
return IntSize{size, size};
|
||||
}
|
||||
case StyleAppearance::MozMenulistArrowButton: {
|
||||
auto size =
|
||||
GetScrollbarSize(StyleScrollbarWidth::Auto, /* aOverlay = */ false);
|
||||
return IntSize{size, size};
|
||||
}
|
||||
case StyleAppearance::ScrollbarbuttonUp:
|
||||
case StyleAppearance::ScrollbarbuttonDown:
|
||||
return IntSize{15, 16};
|
||||
@@ -94,42 +52,46 @@ LayoutDeviceIntSize ScrollbarDrawingMac::GetMinimumWidgetSize(
|
||||
}
|
||||
}();
|
||||
|
||||
if (aDpiRatio >= 2.0f) {
|
||||
auto dpi = GetDPIRatioForScrollbarPart(aPresContext).scale;
|
||||
if (dpi >= 2.0f) {
|
||||
return LayoutDeviceIntSize{minSize.width * 2, minSize.height * 2};
|
||||
}
|
||||
return LayoutDeviceIntSize{minSize.width, minSize.height};
|
||||
}
|
||||
|
||||
ScrollbarParams ScrollbarDrawingMac::ComputeScrollbarParams(
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle, bool aIsHorizontal) {
|
||||
ScrollbarParams params;
|
||||
params.overlay =
|
||||
nsLookAndFeel::GetInt(LookAndFeel::IntID::UseOverlayScrollbars) != 0;
|
||||
params.rolledOver = IsParentScrollbarRolledOver(aFrame);
|
||||
params.small =
|
||||
aStyle.StyleUIReset()->mScrollbarWidth == StyleScrollbarWidth::Thin;
|
||||
params.rtl = nsNativeTheme::IsFrameRTL(aFrame);
|
||||
params.horizontal = aIsHorizontal;
|
||||
params.onDarkBackground = !StaticPrefs::widget_disable_dark_scrollbar() &&
|
||||
nsNativeTheme::IsDarkBackground(aFrame);
|
||||
// Don't use custom scrollbars for overlay scrollbars since they are
|
||||
// generally good enough for use cases of custom scrollbars.
|
||||
if (!params.overlay) {
|
||||
const nsStyleUI* ui = aStyle.StyleUI();
|
||||
if (ui->HasCustomScrollbars()) {
|
||||
const auto& colors = ui->mScrollbarColor.AsColors();
|
||||
params.custom = true;
|
||||
params.trackColor = colors.track.CalcColor(aStyle);
|
||||
params.faceColor = colors.thumb.CalcColor(aStyle);
|
||||
}
|
||||
/*static*/
|
||||
CSSIntCoord ScrollbarDrawingCocoa::GetScrollbarSize(StyleScrollbarWidth aWidth,
|
||||
bool aOverlay) {
|
||||
bool isSmall = aWidth == StyleScrollbarWidth::Thin;
|
||||
if (aOverlay) {
|
||||
return isSmall ? 14 : 16;
|
||||
}
|
||||
|
||||
return params;
|
||||
return isSmall ? 11 : 15;
|
||||
}
|
||||
|
||||
auto ScrollbarDrawingMac::GetThumbRect(const Rect& aRect,
|
||||
const ScrollbarParams& aParams,
|
||||
float aScale) -> ThumbRect {
|
||||
/*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};
|
||||
}
|
||||
|
||||
/*static*/
|
||||
auto ScrollbarDrawingCocoa::GetThumbRect(const Rect& aRect,
|
||||
const ScrollbarParams& aParams,
|
||||
float aScale) -> ThumbRect {
|
||||
// This matches the sizing checks in GetMinimumWidgetSize etc.
|
||||
aScale = aScale >= 2.0f ? 2.0f : 1.0f;
|
||||
|
||||
@@ -224,10 +186,10 @@ static ScrollbarTrackDecorationColors ComputeScrollbarTrackDecorationColors(
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ScrollbarDrawingMac::GetScrollbarTrackRects(const Rect& aRect,
|
||||
const ScrollbarParams& aParams,
|
||||
float aScale,
|
||||
ScrollbarTrackRects& aRects) {
|
||||
/*static*/
|
||||
bool ScrollbarDrawingCocoa::GetScrollbarTrackRects(
|
||||
const Rect& aRect, const ScrollbarParams& aParams, float aScale,
|
||||
ScrollbarTrackRects& aRects) {
|
||||
if (aParams.overlay && !aParams.rolledOver) {
|
||||
// Non-hovered overlay scrollbars don't have a track. Draw nothing.
|
||||
return false;
|
||||
@@ -293,10 +255,11 @@ bool ScrollbarDrawingMac::GetScrollbarTrackRects(const Rect& aRect,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScrollbarDrawingMac::GetScrollCornerRects(const Rect& aRect,
|
||||
const ScrollbarParams& aParams,
|
||||
float aScale,
|
||||
ScrollCornerRects& aRects) {
|
||||
/*static*/
|
||||
bool ScrollbarDrawingCocoa::GetScrollCornerRects(const Rect& aRect,
|
||||
const ScrollbarParams& aParams,
|
||||
float aScale,
|
||||
ScrollCornerRects& aRects) {
|
||||
if (aParams.overlay && !aParams.rolledOver) {
|
||||
// Non-hovered overlay scrollbars don't have a corner. Draw nothing.
|
||||
return false;
|
||||
@@ -360,5 +323,129 @@ bool ScrollbarDrawingMac::GetScrollCornerRects(const Rect& aRect,
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
template <typename PaintBackendData>
|
||||
void ScrollbarDrawingCocoa::DoPaintScrollbarThumb(
|
||||
PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const DPIRatio& aDpiRatio) {
|
||||
ScrollbarParams params = ComputeScrollbarParams(aFrame, aStyle, aHorizontal);
|
||||
auto thumb = GetThumbRect(aRect.ToUnknownRect(), params, aDpiRatio.scale);
|
||||
auto thumbRect = LayoutDeviceRect::FromUnknownRect(thumb.mRect);
|
||||
LayoutDeviceCoord radius =
|
||||
(params.horizontal ? thumbRect.Height() : thumbRect.Width()) / 2.0f;
|
||||
ThemeDrawing::PaintRoundedRectWithRadius(
|
||||
aPaintData, thumbRect, thumbRect, sRGBColor::FromABGR(thumb.mFillColor),
|
||||
sRGBColor::White(0.0f), 0.0f, radius / aDpiRatio, aDpiRatio);
|
||||
if (!thumb.mStrokeColor) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Paint the stroke if needed.
|
||||
thumbRect.Inflate(thumb.mStrokeOutset + thumb.mStrokeWidth);
|
||||
radius = (params.horizontal ? thumbRect.Height() : thumbRect.Width()) / 2.0f;
|
||||
ThemeDrawing::PaintRoundedRectWithRadius(
|
||||
aPaintData, thumbRect, sRGBColor::White(0.0f),
|
||||
sRGBColor::FromABGR(thumb.mStrokeColor), thumb.mStrokeWidth,
|
||||
radius / aDpiRatio, aDpiRatio);
|
||||
}
|
||||
|
||||
bool ScrollbarDrawingCocoa::PaintScrollbarThumb(
|
||||
DrawTarget& aDt, const LayoutDeviceRect& aRect, bool aHorizontal,
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors&, const DPIRatio& aDpiRatio) {
|
||||
// TODO: Maybe respect the UseSystemColors setting?
|
||||
DoPaintScrollbarThumb(aDt, aRect, aHorizontal, aFrame, aStyle, aElementState,
|
||||
aDocumentState, aDpiRatio);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScrollbarDrawingCocoa::PaintScrollbarThumb(
|
||||
WebRenderBackendData& aWrData, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors&, const DPIRatio& aDpiRatio) {
|
||||
// TODO: Maybe respect the UseSystemColors setting?
|
||||
DoPaintScrollbarThumb(aWrData, aRect, aHorizontal, aFrame, aStyle,
|
||||
aElementState, aDocumentState, aDpiRatio);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename PaintBackendData>
|
||||
void ScrollbarDrawingCocoa::DoPaintScrollbarTrack(
|
||||
PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const DPIRatio& aDpiRatio) {
|
||||
ScrollbarParams params = ComputeScrollbarParams(aFrame, aStyle, aHorizontal);
|
||||
ScrollbarTrackRects rects;
|
||||
if (GetScrollbarTrackRects(aRect.ToUnknownRect(), params, aDpiRatio.scale,
|
||||
rects)) {
|
||||
for (const auto& rect : rects) {
|
||||
ThemeDrawing::FillRect(aPaintData,
|
||||
LayoutDeviceRect::FromUnknownRect(rect.mRect),
|
||||
sRGBColor::FromABGR(rect.mColor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ScrollbarDrawingCocoa::PaintScrollbarTrack(
|
||||
DrawTarget& aDt, const LayoutDeviceRect& aRect, bool aHorizontal,
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio& aDpiRatio) {
|
||||
// TODO: Maybe respect the UseSystemColors setting?
|
||||
DoPaintScrollbarTrack(aDt, aRect, aHorizontal, aFrame, aStyle, aDocumentState,
|
||||
aDpiRatio);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScrollbarDrawingCocoa::PaintScrollbarTrack(
|
||||
WebRenderBackendData& aWrData, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio& aDpiRatio) {
|
||||
// TODO: Maybe respect the UseSystemColors setting?
|
||||
DoPaintScrollbarTrack(aWrData, aRect, aHorizontal, aFrame, aStyle,
|
||||
aDocumentState, aDpiRatio);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename PaintBackendData>
|
||||
void ScrollbarDrawingCocoa::DoPaintScrollCorner(
|
||||
PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const DPIRatio& aDpiRatio) {
|
||||
ScrollbarParams params = ComputeScrollbarParams(aFrame, aStyle, false);
|
||||
ScrollCornerRects rects;
|
||||
if (GetScrollCornerRects(aRect.ToUnknownRect(), params, aDpiRatio.scale,
|
||||
rects)) {
|
||||
for (const auto& rect : rects) {
|
||||
ThemeDrawing::FillRect(aPaintData,
|
||||
LayoutDeviceRect::FromUnknownRect(rect.mRect),
|
||||
sRGBColor::FromABGR(rect.mColor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ScrollbarDrawingCocoa::PaintScrollCorner(
|
||||
DrawTarget& aDt, const LayoutDeviceRect& aRect, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle, const EventStates& aDocumentState,
|
||||
const Colors&, const DPIRatio& aDpiRatio) {
|
||||
// TODO: Maybe respect the UseSystemColors setting?
|
||||
DoPaintScrollCorner(aDt, aRect, aFrame, aStyle, aDocumentState, aDpiRatio);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScrollbarDrawingCocoa::PaintScrollCorner(WebRenderBackendData& aWrData,
|
||||
const LayoutDeviceRect& aRect,
|
||||
nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&,
|
||||
const DPIRatio& aDpiRatio) {
|
||||
// TODO: Maybe respect the UseSystemColors setting?
|
||||
DoPaintScrollCorner(aWrData, aRect, aFrame, aStyle, aDocumentState,
|
||||
aDpiRatio);
|
||||
return true;
|
||||
}
|
||||
111
widget/ScrollbarDrawingCocoa.h
Normal file
111
widget/ScrollbarDrawingCocoa.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_widget_ScrollbarDrawingCocoa_h
|
||||
#define mozilla_widget_ScrollbarDrawingCocoa_h
|
||||
|
||||
#include "ScrollbarDrawing.h"
|
||||
|
||||
#include "mozilla/Array.h"
|
||||
#include "nsNativeBasicTheme.h"
|
||||
|
||||
namespace mozilla::widget {
|
||||
|
||||
class ScrollbarDrawingCocoa final : public ScrollbarDrawing {
|
||||
public:
|
||||
ScrollbarDrawingCocoa() = default;
|
||||
virtual ~ScrollbarDrawingCocoa() = default;
|
||||
|
||||
struct FillRectType {
|
||||
gfx::Rect mRect;
|
||||
nscolor mColor;
|
||||
};
|
||||
|
||||
// The caller can draw this rectangle with rounded corners as appropriate.
|
||||
struct ThumbRect {
|
||||
gfx::Rect mRect;
|
||||
nscolor mFillColor;
|
||||
nscolor mStrokeColor;
|
||||
float mStrokeWidth;
|
||||
float mStrokeOutset;
|
||||
};
|
||||
|
||||
using ScrollbarTrackRects = Array<FillRectType, 4>;
|
||||
using ScrollCornerRects = Array<FillRectType, 7>;
|
||||
|
||||
LayoutDeviceIntSize GetMinimumWidgetSize(nsPresContext*,
|
||||
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 ThumbRect GetThumbRect(const gfx::Rect& aRect,
|
||||
const ScrollbarParams& aParams, float aScale);
|
||||
static bool GetScrollbarTrackRects(const gfx::Rect& aRect,
|
||||
const ScrollbarParams& aParams,
|
||||
float aScale, ScrollbarTrackRects& aRects);
|
||||
static bool GetScrollCornerRects(const gfx::Rect& aRect,
|
||||
const ScrollbarParams& aParams, float aScale,
|
||||
ScrollCornerRects& aRects);
|
||||
|
||||
template <typename PaintBackendData>
|
||||
void DoPaintScrollbarThumb(PaintBackendData&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState,
|
||||
const DPIRatio&);
|
||||
bool PaintScrollbarThumb(DrawTarget&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio&) override;
|
||||
bool PaintScrollbarThumb(WebRenderBackendData&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio&) override;
|
||||
|
||||
template <typename PaintBackendData>
|
||||
void DoPaintScrollbarTrack(PaintBackendData&, const LayoutDeviceRect&, bool,
|
||||
nsIFrame*, const ComputedStyle&,
|
||||
const EventStates&, const DPIRatio&);
|
||||
bool PaintScrollbarTrack(DrawTarget&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio&) override;
|
||||
bool PaintScrollbarTrack(WebRenderBackendData&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio&) override;
|
||||
|
||||
template <typename PaintBackendData>
|
||||
void DoPaintScrollCorner(PaintBackendData&, const LayoutDeviceRect&,
|
||||
nsIFrame*, const ComputedStyle&, const EventStates&,
|
||||
const DPIRatio&);
|
||||
bool PaintScrollCorner(DrawTarget&, const LayoutDeviceRect& aRect,
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio&) override;
|
||||
bool PaintScrollCorner(WebRenderBackendData&, const LayoutDeviceRect& aRect,
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio&) override;
|
||||
|
||||
bool ShouldDrawScrollbarButtons() override { return false; }
|
||||
};
|
||||
|
||||
} // namespace mozilla::widget
|
||||
|
||||
#endif
|
||||
@@ -3,59 +3,27 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsNativeBasicThemeGTK.h"
|
||||
#include "ScrollbarDrawingGTK.h"
|
||||
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsContainerFrame.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/gfx/Helpers.h"
|
||||
#include "mozilla/StaticPrefs_widget.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsNativeTheme.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
already_AddRefed<nsITheme> do_GetBasicNativeThemeDoNotUseDirectly() {
|
||||
static StaticRefPtr<nsITheme> gInstance;
|
||||
if (MOZ_UNLIKELY(!gInstance)) {
|
||||
gInstance = new nsNativeBasicThemeGTK();
|
||||
ClearOnShutdown(&gInstance);
|
||||
}
|
||||
return do_AddRef(gInstance);
|
||||
}
|
||||
LayoutDeviceIntSize ScrollbarDrawingGTK::GetMinimumWidgetSize(
|
||||
nsPresContext* aPresContext, StyleAppearance aAppearance,
|
||||
nsIFrame* aFrame) {
|
||||
MOZ_ASSERT(nsNativeTheme::IsWidgetScrollbarPart(aAppearance));
|
||||
|
||||
nsITheme::Transparency nsNativeBasicThemeGTK::GetWidgetTransparency(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) {
|
||||
if (!aFrame->PresContext()->UseOverlayScrollbars() &&
|
||||
(aAppearance == StyleAppearance::ScrollbarVertical ||
|
||||
aAppearance == StyleAppearance::ScrollbarHorizontal) &&
|
||||
IsScrollbarTrackOpaque(aFrame)) {
|
||||
return eOpaque;
|
||||
}
|
||||
return nsNativeBasicTheme::GetWidgetTransparency(aFrame, aAppearance);
|
||||
}
|
||||
|
||||
bool nsNativeBasicThemeGTK::ThemeSupportsScrollbarButtons() {
|
||||
return StaticPrefs::widget_non_native_theme_gtk_scrollbar_allow_buttons();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNativeBasicThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance,
|
||||
LayoutDeviceIntSize* aResult,
|
||||
bool* aIsOverridable) {
|
||||
if (!IsWidgetScrollbarPart(aAppearance)) {
|
||||
return nsNativeBasicTheme::GetMinimumWidgetSize(
|
||||
aPresContext, aFrame, aAppearance, aResult, aIsOverridable);
|
||||
}
|
||||
|
||||
DPIRatio dpiRatio = GetDPIRatioForScrollbarPart(aPresContext);
|
||||
ComputedStyle* style = nsLayoutUtils::StyleForScrollbar(aFrame);
|
||||
const ComputedStyle* style = nsLayoutUtils::StyleForScrollbar(aFrame);
|
||||
auto sizes = GetScrollbarSizes(
|
||||
aPresContext, style->StyleUIReset()->mScrollbarWidth, Overlay::No);
|
||||
MOZ_ASSERT(sizes.mHorizontal == sizes.mVertical);
|
||||
aResult->SizeTo(sizes.mHorizontal, sizes.mHorizontal);
|
||||
|
||||
LayoutDeviceIntSize size{sizes.mHorizontal, sizes.mVertical};
|
||||
if (aAppearance == StyleAppearance::ScrollbarHorizontal ||
|
||||
aAppearance == StyleAppearance::ScrollbarVertical ||
|
||||
aAppearance == StyleAppearance::ScrollbarthumbHorizontal ||
|
||||
@@ -65,52 +33,41 @@ nsNativeBasicThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext,
|
||||
const bool isVertical =
|
||||
aAppearance == StyleAppearance::ScrollbarVertical ||
|
||||
aAppearance == StyleAppearance::ScrollbarthumbVertical;
|
||||
auto dpi = GetDPIRatioForScrollbarPart(aPresContext);
|
||||
if (isVertical) {
|
||||
aResult->height = thumbSize * dpiRatio;
|
||||
size.height = thumbSize * dpi;
|
||||
} else {
|
||||
aResult->width = thumbSize * dpiRatio;
|
||||
size.width = thumbSize * dpi;
|
||||
}
|
||||
}
|
||||
|
||||
*aIsOverridable = true;
|
||||
return NS_OK;
|
||||
return size;
|
||||
}
|
||||
|
||||
static nsIFrame* GetParentScrollbarFrame(nsIFrame* aFrame) {
|
||||
// Walk our parents to find a scrollbar frame
|
||||
nsIFrame* scrollbarFrame = aFrame;
|
||||
do {
|
||||
if (scrollbarFrame->IsScrollbarFrame()) {
|
||||
break;
|
||||
}
|
||||
} while ((scrollbarFrame = scrollbarFrame->GetParent()));
|
||||
Maybe<nsITheme::Transparency> ScrollbarDrawingGTK::GetScrollbarPartTransparency(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) {
|
||||
if (!aFrame->PresContext()->UseOverlayScrollbars() &&
|
||||
(aAppearance == StyleAppearance::ScrollbarVertical ||
|
||||
aAppearance == StyleAppearance::ScrollbarHorizontal) &&
|
||||
IsScrollbarTrackOpaque(aFrame)) {
|
||||
return Some(nsITheme::eOpaque);
|
||||
}
|
||||
|
||||
// We return null if we can't find a parent scrollbar frame
|
||||
return scrollbarFrame;
|
||||
}
|
||||
|
||||
static bool IsParentScrollbarHoveredOrActive(nsIFrame* aFrame) {
|
||||
nsIFrame* scrollbarFrame = GetParentScrollbarFrame(aFrame);
|
||||
return scrollbarFrame && scrollbarFrame->GetContent()
|
||||
->AsElement()
|
||||
->State()
|
||||
.HasAtLeastOneOfStates(NS_EVENT_STATE_HOVER |
|
||||
NS_EVENT_STATE_ACTIVE);
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
template <typename PaintBackendData>
|
||||
bool nsNativeBasicThemeGTK::DoPaintScrollbarThumb(
|
||||
bool ScrollbarDrawingGTK::DoPaintScrollbarThumb(
|
||||
PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors& aColors, DPIRatio aDpiRatio) {
|
||||
const Colors& aColors, const DPIRatio& aDpiRatio) {
|
||||
sRGBColor thumbColor = ComputeScrollbarThumbColor(
|
||||
aFrame, aStyle, aElementState, aDocumentState, aColors);
|
||||
|
||||
LayoutDeviceRect thumbRect(aRect);
|
||||
|
||||
if (aFrame->PresContext()->UseOverlayScrollbars() &&
|
||||
!IsParentScrollbarHoveredOrActive(aFrame)) {
|
||||
!ScrollbarDrawing::IsParentScrollbarHoveredOrActive(aFrame)) {
|
||||
if (aHorizontal) {
|
||||
thumbRect.height *= 0.5;
|
||||
thumbRect.y += thumbRect.height;
|
||||
@@ -135,27 +92,35 @@ bool nsNativeBasicThemeGTK::DoPaintScrollbarThumb(
|
||||
? (aHorizontal ? thumbRect.height : thumbRect.width) / 2.0f
|
||||
: 0.0f;
|
||||
|
||||
PaintRoundedRectWithRadius(aPaintData, thumbRect, thumbColor, sRGBColor(), 0,
|
||||
radius / aDpiRatio, aDpiRatio);
|
||||
ThemeDrawing::PaintRoundedRectWithRadius(aPaintData, thumbRect, thumbColor,
|
||||
sRGBColor(), 0, radius / aDpiRatio,
|
||||
aDpiRatio);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nsNativeBasicThemeGTK::PaintScrollbarThumb(
|
||||
bool ScrollbarDrawingGTK::PaintScrollbarThumb(
|
||||
DrawTarget& aDrawTarget, const LayoutDeviceRect& aRect, bool aHorizontal,
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors& aColors, DPIRatio aDpiRatio) {
|
||||
const Colors& aColors, const DPIRatio& aDpiRatio) {
|
||||
return DoPaintScrollbarThumb(aDrawTarget, aRect, aHorizontal, aFrame, aStyle,
|
||||
aElementState, aDocumentState, aColors,
|
||||
aDpiRatio);
|
||||
}
|
||||
|
||||
bool nsNativeBasicThemeGTK::PaintScrollbarThumb(
|
||||
bool ScrollbarDrawingGTK::PaintScrollbarThumb(
|
||||
WebRenderBackendData& aWrData, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors& aColors, DPIRatio aDpiRatio) {
|
||||
const Colors& aColors, const DPIRatio& aDpiRatio) {
|
||||
return DoPaintScrollbarThumb(aWrData, aRect, aHorizontal, aFrame, aStyle,
|
||||
aElementState, aDocumentState, aColors,
|
||||
aDpiRatio);
|
||||
}
|
||||
|
||||
bool ScrollbarDrawingGTK::ShouldDrawScrollbarButtons() {
|
||||
if (StaticPrefs::widget_non_native_theme_enabled()) {
|
||||
return StaticPrefs::widget_non_native_theme_gtk_scrollbar_allow_buttons();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1,48 +1,51 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsNativeBasicThemeGTK_h
|
||||
#define nsNativeBasicThemeGTK_h
|
||||
#ifndef mozilla_widget_ScrollbarDrawingGTK_h
|
||||
#define mozilla_widget_ScrollbarDrawingGTK_h
|
||||
|
||||
#include "nsNativeBasicTheme.h"
|
||||
#include "nsITheme.h"
|
||||
#include "nsNativeTheme.h"
|
||||
#include "ScrollbarDrawing.h"
|
||||
|
||||
class nsNativeBasicThemeGTK : public nsNativeBasicTheme {
|
||||
namespace mozilla::widget {
|
||||
|
||||
class ScrollbarDrawingGTK final : public ScrollbarDrawing {
|
||||
public:
|
||||
nsNativeBasicThemeGTK() = default;
|
||||
ScrollbarDrawingGTK() = default;
|
||||
virtual ~ScrollbarDrawingGTK() = default;
|
||||
|
||||
Transparency GetWidgetTransparency(nsIFrame*, StyleAppearance) override;
|
||||
LayoutDeviceIntSize GetMinimumWidgetSize(nsPresContext*,
|
||||
StyleAppearance aAppearance,
|
||||
nsIFrame* aFrame) override;
|
||||
|
||||
NS_IMETHOD GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame*,
|
||||
StyleAppearance,
|
||||
mozilla::LayoutDeviceIntSize* aResult,
|
||||
bool* aIsOverridable) override;
|
||||
Maybe<nsITheme::Transparency> GetScrollbarPartTransparency(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) override;
|
||||
|
||||
bool PaintScrollbarThumb(DrawTarget&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio) override;
|
||||
bool PaintScrollbarThumb(WebRenderBackendData&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio) override;
|
||||
template <typename PaintBackendData>
|
||||
bool DoPaintScrollbarThumb(PaintBackendData&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio);
|
||||
const DPIRatio&);
|
||||
bool PaintScrollbarThumb(DrawTarget&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio&) override;
|
||||
bool PaintScrollbarThumb(WebRenderBackendData&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio&) override;
|
||||
|
||||
bool ThemeSupportsScrollbarButtons() override;
|
||||
|
||||
protected:
|
||||
virtual ~nsNativeBasicThemeGTK() = default;
|
||||
bool ShouldDrawScrollbarButtons() override;
|
||||
};
|
||||
|
||||
} // namespace mozilla::widget
|
||||
|
||||
#endif
|
||||
@@ -1,79 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_widget_ScrollbarDrawing_h
|
||||
#define mozilla_widget_ScrollbarDrawing_h
|
||||
|
||||
#include "nsColor.h"
|
||||
#include "nsITheme.h"
|
||||
#include "Units.h"
|
||||
#include "mozilla/Array.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
class DrawTarget;
|
||||
}
|
||||
|
||||
namespace widget {
|
||||
|
||||
struct ScrollbarParams {
|
||||
bool overlay = false;
|
||||
bool rolledOver = false;
|
||||
bool small = false;
|
||||
bool horizontal = false;
|
||||
bool rtl = false;
|
||||
bool onDarkBackground = false;
|
||||
bool custom = false;
|
||||
// Two colors only used when custom is true.
|
||||
nscolor trackColor = NS_RGBA(0, 0, 0, 0);
|
||||
nscolor faceColor = NS_RGBA(0, 0, 0, 0);
|
||||
};
|
||||
|
||||
class ScrollbarDrawingMac final {
|
||||
public:
|
||||
struct FillRect {
|
||||
gfx::Rect mRect;
|
||||
nscolor mColor;
|
||||
};
|
||||
|
||||
static CSSIntCoord GetScrollbarSize(StyleScrollbarWidth, bool aOverlay);
|
||||
|
||||
static LayoutDeviceIntCoord GetScrollbarSize(StyleScrollbarWidth,
|
||||
bool aOverlay, float aDpiRatio);
|
||||
static LayoutDeviceIntSize GetMinimumWidgetSize(StyleAppearance aAppearance,
|
||||
nsIFrame* aFrame,
|
||||
float aDpiRatio);
|
||||
static ScrollbarParams ComputeScrollbarParams(nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
bool aIsHorizontal);
|
||||
|
||||
// The caller can draw this rectangle with rounded corners as appropriate.
|
||||
struct ThumbRect {
|
||||
gfx::Rect mRect;
|
||||
nscolor mFillColor;
|
||||
nscolor mStrokeColor;
|
||||
float mStrokeWidth;
|
||||
float mStrokeOutset;
|
||||
};
|
||||
|
||||
static ThumbRect GetThumbRect(const gfx::Rect& aRect,
|
||||
const ScrollbarParams& aParams, float aScale);
|
||||
|
||||
using ScrollbarTrackRects = Array<FillRect, 4>;
|
||||
static bool GetScrollbarTrackRects(const gfx::Rect& aRect,
|
||||
const ScrollbarParams& aParams,
|
||||
float aScale, ScrollbarTrackRects&);
|
||||
|
||||
using ScrollCornerRects = Array<FillRect, 7>;
|
||||
static bool GetScrollCornerRects(const gfx::Rect& aRect,
|
||||
const ScrollbarParams& aParams, float aScale,
|
||||
ScrollCornerRects&);
|
||||
};
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
152
widget/ScrollbarDrawingWin.cpp
Normal file
152
widget/ScrollbarDrawingWin.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ScrollbarDrawingWin.h"
|
||||
|
||||
#include "mozilla/gfx/Helpers.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/StaticPrefs_widget.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsNativeBasicTheme.h"
|
||||
#include "nsNativeTheme.h"
|
||||
|
||||
using mozilla::ComputedStyle;
|
||||
using mozilla::EventStates;
|
||||
using mozilla::Maybe;
|
||||
using mozilla::Nothing;
|
||||
using mozilla::Some;
|
||||
using mozilla::StyleAppearance;
|
||||
using mozilla::StyleScrollbarWidth;
|
||||
|
||||
LayoutDeviceIntSize ScrollbarDrawingWin::GetMinimumWidgetSize(
|
||||
nsPresContext* aPresContext, StyleAppearance aAppearance,
|
||||
nsIFrame* aFrame) {
|
||||
MOZ_ASSERT(nsNativeTheme::IsWidgetScrollbarPart(aAppearance));
|
||||
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::ScrollbarbuttonUp:
|
||||
case StyleAppearance::ScrollbarbuttonDown:
|
||||
case StyleAppearance::ScrollbarbuttonLeft:
|
||||
case StyleAppearance::ScrollbarbuttonRight:
|
||||
// For scrollbar-width:thin, we don't display the buttons.
|
||||
if (IsScrollbarWidthThin(aFrame)) {
|
||||
return LayoutDeviceIntSize{};
|
||||
}
|
||||
[[fallthrough]];
|
||||
case StyleAppearance::ScrollbarthumbVertical:
|
||||
case StyleAppearance::ScrollbarthumbHorizontal: {
|
||||
auto* style = nsLayoutUtils::StyleForScrollbar(aFrame);
|
||||
auto width = style->StyleUIReset()->mScrollbarWidth;
|
||||
auto sizes = GetScrollbarSizes(aPresContext, width, Overlay::No);
|
||||
// TODO: for short scrollbars it could be nice if the thumb could shrink
|
||||
// under this size.
|
||||
const bool isHorizontal =
|
||||
aAppearance == StyleAppearance::ScrollbarthumbHorizontal ||
|
||||
aAppearance == StyleAppearance::ScrollbarbuttonLeft ||
|
||||
aAppearance == StyleAppearance::ScrollbarbuttonRight;
|
||||
const auto size = isHorizontal ? sizes.mHorizontal : sizes.mVertical;
|
||||
return LayoutDeviceIntSize{size, size};
|
||||
}
|
||||
default:
|
||||
return LayoutDeviceIntSize{};
|
||||
}
|
||||
}
|
||||
|
||||
Maybe<nsITheme::Transparency> ScrollbarDrawingWin::GetScrollbarPartTransparency(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) {
|
||||
if (nsNativeTheme::IsWidgetScrollbarPart(aAppearance)) {
|
||||
if (ComputedStyle* style = GetCustomScrollbarStyle(aFrame)) {
|
||||
auto* ui = style->StyleUI();
|
||||
if (ui->mScrollbarColor.IsAuto() ||
|
||||
ui->mScrollbarColor.AsColors().track.MaybeTransparent()) {
|
||||
return Some(nsITheme::eTransparent);
|
||||
}
|
||||
// These widgets may be thinner than the track, so we need to return
|
||||
// transparent for them to make the track visible.
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::ScrollbarthumbHorizontal:
|
||||
case StyleAppearance::ScrollbarthumbVertical:
|
||||
case StyleAppearance::ScrollbarbuttonUp:
|
||||
case StyleAppearance::ScrollbarbuttonDown:
|
||||
case StyleAppearance::ScrollbarbuttonLeft:
|
||||
case StyleAppearance::ScrollbarbuttonRight:
|
||||
return Some(nsITheme::eTransparent);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::ScrollbarHorizontal:
|
||||
case StyleAppearance::ScrollbarVertical:
|
||||
case StyleAppearance::Scrollcorner:
|
||||
case StyleAppearance::Statusbar:
|
||||
// Knowing that scrollbars and statusbars are opaque improves
|
||||
// performance, because we create layers for them. This better be
|
||||
// true across all Windows themes! If it's not true, we should
|
||||
// paint an opaque background for them to make it true!
|
||||
return Some(nsITheme::eOpaque);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
// Returns the style for custom scrollbar if the scrollbar part frame should
|
||||
// use the custom drawing path, nullptr otherwise.
|
||||
//
|
||||
// Optionally the caller can pass a pointer to aDarkScrollbar for whether
|
||||
// custom scrollbar may be drawn due to dark background.
|
||||
/*static*/
|
||||
ComputedStyle* ScrollbarDrawingWin::GetCustomScrollbarStyle(
|
||||
nsIFrame* aFrame, bool* aDarkScrollbar) {
|
||||
ComputedStyle* style = nsLayoutUtils::StyleForScrollbar(aFrame);
|
||||
if (style->StyleUI()->HasCustomScrollbars()) {
|
||||
return style;
|
||||
}
|
||||
bool useDarkScrollbar = !StaticPrefs::widget_disable_dark_scrollbar() &&
|
||||
nsNativeTheme::IsDarkBackground(aFrame);
|
||||
if (useDarkScrollbar || IsScrollbarWidthThin(*style)) {
|
||||
if (aDarkScrollbar) {
|
||||
*aDarkScrollbar = useDarkScrollbar;
|
||||
}
|
||||
return style;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename PaintBackendData>
|
||||
bool ScrollbarDrawingWin::DoPaintScrollbarThumb(
|
||||
PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors& aColors, const DPIRatio& aDpiRatio) {
|
||||
sRGBColor thumbColor = ComputeScrollbarThumbColor(
|
||||
aFrame, aStyle, aElementState, aDocumentState, aColors);
|
||||
ThemeDrawing::FillRect(aPaintData, aRect, thumbColor);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScrollbarDrawingWin::PaintScrollbarThumb(
|
||||
DrawTarget& aDrawTarget, const LayoutDeviceRect& aRect, bool aHorizontal,
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors& aColors, const DPIRatio& aDpiRatio) {
|
||||
return DoPaintScrollbarThumb(aDrawTarget, aRect, aHorizontal, aFrame, aStyle,
|
||||
aElementState, aDocumentState, aColors,
|
||||
aDpiRatio);
|
||||
}
|
||||
|
||||
bool ScrollbarDrawingWin::PaintScrollbarThumb(
|
||||
WebRenderBackendData& aWrData, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors& aColors, const DPIRatio& aDpiRatio) {
|
||||
return DoPaintScrollbarThumb(aWrData, aRect, aHorizontal, aFrame, aStyle,
|
||||
aElementState, aDocumentState, aColors,
|
||||
aDpiRatio);
|
||||
}
|
||||
50
widget/ScrollbarDrawingWin.h
Normal file
50
widget/ScrollbarDrawingWin.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_widget_ScrollbarDrawingWin_h
|
||||
#define mozilla_widget_ScrollbarDrawingWin_h
|
||||
|
||||
#include "nsITheme.h"
|
||||
#include "nsNativeTheme.h"
|
||||
#include "ScrollbarDrawing.h"
|
||||
|
||||
namespace mozilla::widget {
|
||||
|
||||
class ScrollbarDrawingWin final : public ScrollbarDrawing {
|
||||
public:
|
||||
ScrollbarDrawingWin() = default;
|
||||
virtual ~ScrollbarDrawingWin() = default;
|
||||
|
||||
LayoutDeviceIntSize GetMinimumWidgetSize(nsPresContext*,
|
||||
StyleAppearance aAppearance,
|
||||
nsIFrame* aFrame) override;
|
||||
|
||||
Maybe<nsITheme::Transparency> GetScrollbarPartTransparency(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) override;
|
||||
|
||||
static ComputedStyle* GetCustomScrollbarStyle(nsIFrame* aFrame,
|
||||
bool* aDarkScrollbar = nullptr);
|
||||
|
||||
template <typename PaintBackendData>
|
||||
bool DoPaintScrollbarThumb(PaintBackendData&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio&);
|
||||
bool PaintScrollbarThumb(DrawTarget&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio&) override;
|
||||
bool PaintScrollbarThumb(WebRenderBackendData&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
const DPIRatio&) override;
|
||||
};
|
||||
|
||||
} // namespace mozilla::widget
|
||||
|
||||
#endif
|
||||
233
widget/ThemeColors.cpp
Normal file
233
widget/ThemeColors.cpp
Normal file
@@ -0,0 +1,233 @@
|
||||
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ThemeColors.h"
|
||||
|
||||
#include "mozilla/RelativeLuminanceUtils.h"
|
||||
#include "mozilla/StaticPrefs_widget.h"
|
||||
#include "ThemeDrawing.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
struct ColorPalette {
|
||||
ColorPalette(nscolor aAccent, nscolor aForeground);
|
||||
|
||||
constexpr ColorPalette(sRGBColor aAccent, sRGBColor aForeground,
|
||||
sRGBColor aLight, sRGBColor aDark, sRGBColor aDarker)
|
||||
: mAccent(aAccent),
|
||||
mForeground(aForeground),
|
||||
mAccentLight(aLight),
|
||||
mAccentDark(aDark),
|
||||
mAccentDarker(aDarker) {}
|
||||
|
||||
constexpr static ColorPalette Default() {
|
||||
return ColorPalette(
|
||||
sDefaultAccent, sDefaultAccentForeground,
|
||||
sRGBColor::UnusualFromARGB(0x4d008deb), // Luminance: 25.04791%
|
||||
sRGBColor::UnusualFromARGB(0xff0250bb), // Luminance: 9.33808%
|
||||
sRGBColor::UnusualFromARGB(0xff054096) // Luminance: 5.90106%
|
||||
);
|
||||
}
|
||||
|
||||
// Ensure accent color is opaque by blending with white. This serves two
|
||||
// purposes: On one hand, it avoids surprises if we overdraw. On the other, it
|
||||
// makes our math below make more sense, as we want to match the browser
|
||||
// style, which has an opaque accent color.
|
||||
static nscolor EnsureOpaque(nscolor aAccent) {
|
||||
if (NS_GET_A(aAccent) != 0xff) {
|
||||
return NS_ComposeColors(NS_RGB(0xff, 0xff, 0xff), aAccent);
|
||||
}
|
||||
return aAccent;
|
||||
}
|
||||
|
||||
static nscolor GetLight(nscolor aAccent) {
|
||||
// The luminance from the light color divided by the one of the accent color
|
||||
// in the default palette.
|
||||
constexpr float kLightLuminanceScale = 25.048f / 13.693f;
|
||||
const float lightLuminanceAdjust = ThemeColors::ScaleLuminanceBy(
|
||||
RelativeLuminanceUtils::Compute(aAccent), kLightLuminanceScale);
|
||||
nscolor lightColor =
|
||||
RelativeLuminanceUtils::Adjust(aAccent, lightLuminanceAdjust);
|
||||
return NS_RGBA(NS_GET_R(lightColor), NS_GET_G(lightColor),
|
||||
NS_GET_B(lightColor), 0x4d);
|
||||
}
|
||||
|
||||
static nscolor GetDark(nscolor aAccent) {
|
||||
// Same deal as above (but without the alpha).
|
||||
constexpr float kDarkLuminanceScale = 9.338f / 13.693f;
|
||||
const float darkLuminanceAdjust = ThemeColors::ScaleLuminanceBy(
|
||||
RelativeLuminanceUtils::Compute(aAccent), kDarkLuminanceScale);
|
||||
return RelativeLuminanceUtils::Adjust(aAccent, darkLuminanceAdjust);
|
||||
}
|
||||
|
||||
static nscolor GetDarker(nscolor aAccent) {
|
||||
// Same deal as above.
|
||||
constexpr float kDarkerLuminanceScale = 5.901f / 13.693f;
|
||||
const float darkerLuminanceAdjust = ThemeColors::ScaleLuminanceBy(
|
||||
RelativeLuminanceUtils::Compute(aAccent), kDarkerLuminanceScale);
|
||||
return RelativeLuminanceUtils::Adjust(aAccent, darkerLuminanceAdjust);
|
||||
}
|
||||
|
||||
sRGBColor mAccent;
|
||||
sRGBColor mForeground;
|
||||
|
||||
// Note that depending on the exact accent color, lighter/darker might really
|
||||
// be inverted.
|
||||
sRGBColor mAccentLight;
|
||||
sRGBColor mAccentDark;
|
||||
sRGBColor mAccentDarker;
|
||||
};
|
||||
|
||||
static nscolor ThemedAccentColor(bool aBackground) {
|
||||
MOZ_ASSERT(StaticPrefs::widget_non_native_theme_use_theme_accent());
|
||||
// TODO(emilio): In the future we should probably add dark-color-scheme
|
||||
// support for non-native form controls.
|
||||
return ColorPalette::EnsureOpaque(LookAndFeel::Color(
|
||||
aBackground ? LookAndFeel::ColorID::MozAccentColor
|
||||
: LookAndFeel::ColorID::MozAccentColorForeground,
|
||||
LookAndFeel::ColorScheme::Light, LookAndFeel::UseStandins::No));
|
||||
}
|
||||
|
||||
static ColorPalette sDefaultPalette = ColorPalette::Default();
|
||||
|
||||
ColorPalette::ColorPalette(nscolor aAccent, nscolor aForeground) {
|
||||
mAccent = sRGBColor::FromABGR(aAccent);
|
||||
mForeground = sRGBColor::FromABGR(aForeground);
|
||||
mAccentLight = sRGBColor::FromABGR(GetLight(aAccent));
|
||||
mAccentDark = sRGBColor::FromABGR(GetDark(aAccent));
|
||||
mAccentDarker = sRGBColor::FromABGR(GetDarker(aAccent));
|
||||
}
|
||||
|
||||
ThemeAccentColor::ThemeAccentColor(const ComputedStyle& aStyle) {
|
||||
const auto& color = aStyle.StyleUI()->mAccentColor;
|
||||
if (color.IsColor()) {
|
||||
mAccentColor.emplace(
|
||||
ColorPalette::EnsureOpaque(color.AsColor().CalcColor(aStyle)));
|
||||
} else {
|
||||
MOZ_ASSERT(color.IsAuto());
|
||||
}
|
||||
}
|
||||
|
||||
sRGBColor ThemeAccentColor::Get() const {
|
||||
if (!mAccentColor) {
|
||||
return sDefaultPalette.mAccent;
|
||||
}
|
||||
return sRGBColor::FromABGR(*mAccentColor);
|
||||
}
|
||||
|
||||
sRGBColor ThemeAccentColor::GetForeground() const {
|
||||
if (!mAccentColor) {
|
||||
return sDefaultPalette.mForeground;
|
||||
}
|
||||
return sRGBColor::FromABGR(
|
||||
ThemeColors::ComputeCustomAccentForeground(*mAccentColor));
|
||||
}
|
||||
|
||||
sRGBColor ThemeAccentColor::GetLight() const {
|
||||
if (!mAccentColor) {
|
||||
return sDefaultPalette.mAccentLight;
|
||||
}
|
||||
return sRGBColor::FromABGR(ColorPalette::GetLight(*mAccentColor));
|
||||
}
|
||||
|
||||
sRGBColor ThemeAccentColor::GetDark() const {
|
||||
if (!mAccentColor) {
|
||||
return sDefaultPalette.mAccentDark;
|
||||
}
|
||||
return sRGBColor::FromABGR(ColorPalette::GetDark(*mAccentColor));
|
||||
}
|
||||
|
||||
sRGBColor ThemeAccentColor::GetDarker() const {
|
||||
if (!mAccentColor) {
|
||||
return sDefaultPalette.mAccentDarker;
|
||||
}
|
||||
return sRGBColor::FromABGR(ColorPalette::GetDarker(*mAccentColor));
|
||||
}
|
||||
|
||||
bool ThemeColors::ShouldBeHighContrast(const nsPresContext& aPc) {
|
||||
// We make sure that we're drawing backgrounds, since otherwise layout will
|
||||
// darken our used text colors etc anyways, and that can cause contrast issues
|
||||
// with dark high-contrast themes.
|
||||
return aPc.GetBackgroundColorDraw() &&
|
||||
PreferenceSheet::PrefsFor(*aPc.Document())
|
||||
.NonNativeThemeShouldBeHighContrast();
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void ThemeColors::RecomputeAccentColors() {
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!StaticPrefs::widget_non_native_theme_use_theme_accent()) {
|
||||
sDefaultPalette = ColorPalette::Default();
|
||||
return;
|
||||
}
|
||||
|
||||
sDefaultPalette =
|
||||
ColorPalette(ThemedAccentColor(true), ThemedAccentColor(false));
|
||||
}
|
||||
|
||||
/*static*/
|
||||
nscolor ThemeColors::ComputeCustomAccentForeground(nscolor aColor) {
|
||||
// Contrast ratio is defined in
|
||||
// https://www.w3.org/TR/WCAG20/#contrast-ratiodef as:
|
||||
//
|
||||
// (L1 + 0.05) / (L2 + 0.05)
|
||||
//
|
||||
// Where L1 is the lighter color, and L2 is the darker one. So we determine
|
||||
// whether we're dark or light and resolve the equation for the target ratio.
|
||||
//
|
||||
// So when lightening:
|
||||
//
|
||||
// L1 = k * (L2 + 0.05) - 0.05
|
||||
//
|
||||
// And when darkening:
|
||||
//
|
||||
// L2 = (L1 + 0.05) / k - 0.05
|
||||
//
|
||||
const float luminance = RelativeLuminanceUtils::Compute(aColor);
|
||||
|
||||
// We generally prefer white unless we can't because the color is really light
|
||||
// and we can't provide reasonable contrast.
|
||||
const float ratioWithWhite = 1.05f / (luminance + 0.05f);
|
||||
const bool canBeWhite =
|
||||
ratioWithWhite >=
|
||||
StaticPrefs::layout_css_accent_color_min_contrast_ratio();
|
||||
if (canBeWhite) {
|
||||
return NS_RGB(0xff, 0xff, 0xff);
|
||||
}
|
||||
const float targetRatio =
|
||||
StaticPrefs::layout_css_accent_color_darkening_target_contrast_ratio();
|
||||
const float targetLuminance = (luminance + 0.05f) / targetRatio - 0.05f;
|
||||
return RelativeLuminanceUtils::Adjust(aColor, targetLuminance);
|
||||
}
|
||||
|
||||
nscolor ThemeColors::AdjustUnthemedScrollbarThumbColor(nscolor aFaceColor,
|
||||
EventStates aStates) {
|
||||
// In Windows 10, scrollbar thumb has the following colors:
|
||||
//
|
||||
// State | Color | Luminance
|
||||
// -------+----------+----------
|
||||
// Normal | Gray 205 | 61.0%
|
||||
// Hover | Gray 166 | 38.1%
|
||||
// Active | Gray 96 | 11.7%
|
||||
//
|
||||
// This function is written based on the ratios between the values.
|
||||
bool isActive = aStates.HasState(NS_EVENT_STATE_ACTIVE);
|
||||
bool isHover = aStates.HasState(NS_EVENT_STATE_HOVER);
|
||||
if (!isActive && !isHover) {
|
||||
return aFaceColor;
|
||||
}
|
||||
float luminance = RelativeLuminanceUtils::Compute(aFaceColor);
|
||||
if (isActive) {
|
||||
// 11.7 / 61.0
|
||||
luminance = ScaleLuminanceBy(luminance, 0.192f);
|
||||
} else {
|
||||
// 38.1 / 61.0
|
||||
luminance = ScaleLuminanceBy(luminance, 0.625f);
|
||||
}
|
||||
return RelativeLuminanceUtils::Adjust(aFaceColor, luminance);
|
||||
}
|
||||
106
widget/ThemeColors.h
Normal file
106
widget/ThemeColors.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_widget_ThemeColors_h
|
||||
#define mozilla_widget_ThemeColors_h
|
||||
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/gfx/Types.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
#include "nsIFrame.h"
|
||||
|
||||
namespace mozilla::widget {
|
||||
|
||||
static constexpr gfx::sRGBColor sDefaultAccent(
|
||||
gfx::sRGBColor::UnusualFromARGB(0xff0060df)); // Luminance: 13.69346%
|
||||
static constexpr gfx::sRGBColor sDefaultAccentForeground(
|
||||
gfx::sRGBColor::OpaqueWhite());
|
||||
|
||||
class ThemeAccentColor {
|
||||
protected:
|
||||
using sRGBColor = mozilla::gfx::sRGBColor;
|
||||
using ComputedStyle = mozilla::ComputedStyle;
|
||||
|
||||
Maybe<nscolor> mAccentColor;
|
||||
|
||||
public:
|
||||
explicit ThemeAccentColor(const ComputedStyle& aStyle);
|
||||
virtual ~ThemeAccentColor() = default;
|
||||
|
||||
sRGBColor Get() const;
|
||||
sRGBColor GetForeground() const;
|
||||
sRGBColor GetLight() const;
|
||||
sRGBColor GetDark() const;
|
||||
sRGBColor GetDarker() const;
|
||||
};
|
||||
|
||||
// Widget color information associated to a particular frame.
|
||||
class ThemeColors {
|
||||
protected:
|
||||
using Document = mozilla::dom::Document;
|
||||
using sRGBColor = mozilla::gfx::sRGBColor;
|
||||
using LookAndFeel = mozilla::LookAndFeel;
|
||||
using StyleSystemColor = mozilla::StyleSystemColor;
|
||||
using AccentColor = ThemeAccentColor;
|
||||
|
||||
const AccentColor mAccentColor;
|
||||
const Document& mDoc;
|
||||
const bool mHighContrast;
|
||||
const LookAndFeel::ColorScheme mColorScheme;
|
||||
|
||||
public:
|
||||
explicit ThemeColors(const nsIFrame* aFrame)
|
||||
: mAccentColor(*aFrame->Style()),
|
||||
mDoc(*aFrame->PresContext()->Document()),
|
||||
mHighContrast(ShouldBeHighContrast(*aFrame->PresContext())),
|
||||
mColorScheme(LookAndFeel::ColorSchemeForFrame(aFrame)) {}
|
||||
virtual ~ThemeColors() = default;
|
||||
|
||||
[[nodiscard]] static float ScaleLuminanceBy(float aLuminance, float aFactor) {
|
||||
return aLuminance >= 0.18f ? aLuminance * aFactor : aLuminance / aFactor;
|
||||
}
|
||||
|
||||
const AccentColor& Accent() const { return mAccentColor; }
|
||||
bool HighContrast() const { return mHighContrast; }
|
||||
bool IsDark() const { return mColorScheme == LookAndFeel::ColorScheme::Dark; }
|
||||
|
||||
nscolor SystemNs(StyleSystemColor aColor) const {
|
||||
return LookAndFeel::Color(aColor, mColorScheme,
|
||||
LookAndFeel::ShouldUseStandins(mDoc, aColor));
|
||||
}
|
||||
|
||||
sRGBColor System(StyleSystemColor aColor) const {
|
||||
return sRGBColor::FromABGR(SystemNs(aColor));
|
||||
}
|
||||
|
||||
template <typename Compute>
|
||||
sRGBColor SystemOrElse(StyleSystemColor aColor, Compute aCompute) const {
|
||||
if (auto color = LookAndFeel::GetColor(
|
||||
aColor, mColorScheme,
|
||||
LookAndFeel::ShouldUseStandins(mDoc, aColor))) {
|
||||
return sRGBColor::FromABGR(*color);
|
||||
}
|
||||
return aCompute();
|
||||
}
|
||||
|
||||
std::pair<sRGBColor, sRGBColor> SystemPair(StyleSystemColor aFirst,
|
||||
StyleSystemColor aSecond) const {
|
||||
return std::make_pair(System(aFirst), System(aSecond));
|
||||
}
|
||||
|
||||
// Whether we should use system colors (for high contrast mode).
|
||||
static bool ShouldBeHighContrast(const nsPresContext&);
|
||||
|
||||
static void RecomputeAccentColors();
|
||||
|
||||
static nscolor ComputeCustomAccentForeground(nscolor aColor);
|
||||
|
||||
static nscolor AdjustUnthemedScrollbarThumbColor(nscolor aFaceColor,
|
||||
EventStates aStates);
|
||||
};
|
||||
|
||||
} // namespace mozilla::widget
|
||||
|
||||
#endif
|
||||
178
widget/ThemeDrawing.cpp
Normal file
178
widget/ThemeDrawing.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ThemeDrawing.h"
|
||||
|
||||
/*static*/
|
||||
void ThemeDrawing::FillRect(DrawTarget& aDt, const LayoutDeviceRect& aRect,
|
||||
const sRGBColor& aColor) {
|
||||
aDt.FillRect(aRect.ToUnknownRect(), ColorPattern(ToDeviceColor(aColor)));
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void ThemeDrawing::FillRect(WebRenderBackendData& aWrData,
|
||||
const LayoutDeviceRect& aRect,
|
||||
const sRGBColor& aColor) {
|
||||
const bool kBackfaceIsVisible = true;
|
||||
auto dest = wr::ToLayoutRect(aRect);
|
||||
aWrData.mBuilder.PushRect(dest, dest, kBackfaceIsVisible,
|
||||
wr::ToColorF(ToDeviceColor(aColor)));
|
||||
}
|
||||
|
||||
/*static*/
|
||||
LayoutDeviceIntCoord ThemeDrawing::SnapBorderWidth(const CSSCoord& aCssWidth,
|
||||
const DPIRatio& aDpiRatio) {
|
||||
if (aCssWidth == 0.0f) {
|
||||
return 0;
|
||||
}
|
||||
return std::max(LayoutDeviceIntCoord(1), (aCssWidth * aDpiRatio).Truncated());
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void ThemeDrawing::PaintArrow(DrawTarget& aDrawTarget,
|
||||
const LayoutDeviceRect& aRect,
|
||||
const float aArrowPolygonX[],
|
||||
const float aArrowPolygonY[],
|
||||
const float aArrowPolygonSize,
|
||||
const int32_t aArrowNumPoints,
|
||||
const sRGBColor aFillColor) {
|
||||
const float scale = ScaleToFillRect(aRect, aArrowPolygonSize);
|
||||
|
||||
auto center = aRect.Center().ToUnknownPoint();
|
||||
|
||||
RefPtr<PathBuilder> builder = aDrawTarget.CreatePathBuilder();
|
||||
Point p =
|
||||
center + Point(aArrowPolygonX[0] * scale, aArrowPolygonY[0] * scale);
|
||||
builder->MoveTo(p);
|
||||
for (int32_t i = 1; i < aArrowNumPoints; i++) {
|
||||
p = center + Point(aArrowPolygonX[i] * scale, aArrowPolygonY[i] * scale);
|
||||
builder->LineTo(p);
|
||||
}
|
||||
RefPtr<Path> path = builder->Finish();
|
||||
|
||||
aDrawTarget.Fill(path, ColorPattern(ToDeviceColor(aFillColor)));
|
||||
}
|
||||
|
||||
void ThemeDrawing::PaintRoundedRectWithRadius(
|
||||
WebRenderBackendData& aWrData, const LayoutDeviceRect& aRect,
|
||||
const LayoutDeviceRect& aClipRect, const sRGBColor& aBackgroundColor,
|
||||
const sRGBColor& aBorderColor, const CSSCoord& aBorderWidth,
|
||||
const CSSCoord& aRadius, const DPIRatio& aDpiRatio) {
|
||||
const bool kBackfaceIsVisible = true;
|
||||
const LayoutDeviceCoord borderWidth(SnapBorderWidth(aBorderWidth, aDpiRatio));
|
||||
const LayoutDeviceCoord radius(aRadius * aDpiRatio);
|
||||
const wr::LayoutRect dest = wr::ToLayoutRect(aRect);
|
||||
const wr::LayoutRect clip = wr::ToLayoutRect(aClipRect);
|
||||
|
||||
// Push the background.
|
||||
if (aBackgroundColor.a != 0.0f) {
|
||||
auto backgroundColor = wr::ToColorF(ToDeviceColor(aBackgroundColor));
|
||||
wr::LayoutRect backgroundRect = [&] {
|
||||
LayoutDeviceRect bg = aRect;
|
||||
bg.Deflate(borderWidth);
|
||||
return wr::ToLayoutRect(bg);
|
||||
}();
|
||||
if (radius == 0.0f) {
|
||||
aWrData.mBuilder.PushRect(backgroundRect, clip, kBackfaceIsVisible,
|
||||
backgroundColor);
|
||||
} else {
|
||||
// NOTE(emilio): This follows DisplayListBuilder::PushRoundedRect and
|
||||
// draws the rounded fill as an extra thick rounded border instead of a
|
||||
// rectangle that's clipped to a rounded clip. Refer to that method for a
|
||||
// justification. See bug 1694269.
|
||||
LayoutDeviceCoord backgroundRadius =
|
||||
std::max(0.0f, float(radius) - float(borderWidth));
|
||||
wr::BorderSide side = {backgroundColor, wr::BorderStyle::Solid};
|
||||
const wr::BorderSide sides[4] = {side, side, side, side};
|
||||
float h = backgroundRect.width() * 0.6f;
|
||||
float v = backgroundRect.height() * 0.6f;
|
||||
wr::LayoutSideOffsets widths = {v, h, v, h};
|
||||
wr::BorderRadius radii = {{backgroundRadius, backgroundRadius},
|
||||
{backgroundRadius, backgroundRadius},
|
||||
{backgroundRadius, backgroundRadius},
|
||||
{backgroundRadius, backgroundRadius}};
|
||||
aWrData.mBuilder.PushBorder(backgroundRect, clip, kBackfaceIsVisible,
|
||||
widths, {sides, 4}, radii);
|
||||
}
|
||||
}
|
||||
|
||||
if (borderWidth != 0.0f && aBorderColor.a != 0.0f) {
|
||||
// Push the border.
|
||||
const auto borderColor = ToDeviceColor(aBorderColor);
|
||||
const auto side = wr::ToBorderSide(borderColor, StyleBorderStyle::Solid);
|
||||
const wr::BorderSide sides[4] = {side, side, side, side};
|
||||
const LayoutDeviceSize sideRadius(radius, radius);
|
||||
const auto widths =
|
||||
wr::ToBorderWidths(borderWidth, borderWidth, borderWidth, borderWidth);
|
||||
const auto wrRadius =
|
||||
wr::ToBorderRadius(sideRadius, sideRadius, sideRadius, sideRadius);
|
||||
aWrData.mBuilder.PushBorder(dest, clip, kBackfaceIsVisible, widths,
|
||||
{sides, 4}, wrRadius);
|
||||
}
|
||||
}
|
||||
|
||||
void ThemeDrawing::PaintRoundedRectWithRadius(
|
||||
DrawTarget& aDrawTarget, const LayoutDeviceRect& aRect,
|
||||
const LayoutDeviceRect& aClipRect, const sRGBColor& aBackgroundColor,
|
||||
const sRGBColor& aBorderColor, const CSSCoord& aBorderWidth,
|
||||
const CSSCoord& aRadius, const DPIRatio& aDpiRatio) {
|
||||
const LayoutDeviceCoord borderWidth(SnapBorderWidth(aBorderWidth, aDpiRatio));
|
||||
const bool needsClip = !(aRect == aClipRect);
|
||||
if (needsClip) {
|
||||
aDrawTarget.PushClipRect(aClipRect.ToUnknownRect());
|
||||
}
|
||||
|
||||
LayoutDeviceRect rect(aRect);
|
||||
// Deflate the rect by half the border width, so that the middle of the
|
||||
// stroke fills exactly the area we want to fill and not more.
|
||||
rect.Deflate(borderWidth * 0.5f);
|
||||
|
||||
LayoutDeviceCoord radius(aRadius * aDpiRatio - borderWidth * 0.5f);
|
||||
// Fix up the radius if it's too large with the rect we're going to paint.
|
||||
{
|
||||
LayoutDeviceCoord min = std::min(rect.width, rect.height);
|
||||
if (radius * 2.0f > min) {
|
||||
radius = min * 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
Maybe<ColorPattern> backgroundPattern;
|
||||
if (aBackgroundColor.a != 0.0f) {
|
||||
backgroundPattern.emplace(ToDeviceColor(aBackgroundColor));
|
||||
}
|
||||
Maybe<ColorPattern> borderPattern;
|
||||
if (borderWidth != 0.0f && aBorderColor.a != 0.0f) {
|
||||
borderPattern.emplace(ToDeviceColor(aBorderColor));
|
||||
}
|
||||
|
||||
if (borderPattern || backgroundPattern) {
|
||||
if (radius != 0.0f) {
|
||||
RectCornerRadii radii(radius, radius, radius, radius);
|
||||
RefPtr<Path> roundedRect =
|
||||
MakePathForRoundedRect(aDrawTarget, rect.ToUnknownRect(), radii);
|
||||
|
||||
if (backgroundPattern) {
|
||||
aDrawTarget.Fill(roundedRect, *backgroundPattern);
|
||||
}
|
||||
if (borderPattern) {
|
||||
aDrawTarget.Stroke(roundedRect, *borderPattern,
|
||||
StrokeOptions(borderWidth));
|
||||
}
|
||||
} else {
|
||||
if (backgroundPattern) {
|
||||
aDrawTarget.FillRect(rect.ToUnknownRect(), *backgroundPattern);
|
||||
}
|
||||
if (borderPattern) {
|
||||
aDrawTarget.StrokeRect(rect.ToUnknownRect(), *borderPattern,
|
||||
StrokeOptions(borderWidth));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (needsClip) {
|
||||
aDrawTarget.PopClip();
|
||||
}
|
||||
}
|
||||
79
widget/ThemeDrawing.h
Normal file
79
widget/ThemeDrawing.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_widget_ThemeDrawing_h
|
||||
#define mozilla_widget_ThemeDrawing_h
|
||||
|
||||
#include "mozilla/layers/IpcResourceUpdateQueue.h"
|
||||
#include "mozilla/layers/RenderRootStateManager.h"
|
||||
#include "mozilla/layers/StackingContextHelper.h"
|
||||
#include "RetainedDisplayListBuilder.h"
|
||||
|
||||
namespace mozilla::widget {
|
||||
|
||||
struct WebRenderBackendData {
|
||||
wr::DisplayListBuilder& mBuilder;
|
||||
wr::IpcResourceUpdateQueue& mResources;
|
||||
const layers::StackingContextHelper& mSc;
|
||||
layers::RenderRootStateManager* mManager;
|
||||
};
|
||||
|
||||
class ThemeDrawing {
|
||||
protected:
|
||||
using DrawTarget = gfx::DrawTarget;
|
||||
using sRGBColor = gfx::sRGBColor;
|
||||
using DPIRatio = CSSToLayoutDeviceScale;
|
||||
|
||||
public:
|
||||
virtual ~ThemeDrawing() = 0;
|
||||
|
||||
static void FillRect(DrawTarget&, const LayoutDeviceRect&, const sRGBColor&);
|
||||
static void FillRect(WebRenderBackendData&, const LayoutDeviceRect&,
|
||||
const sRGBColor&);
|
||||
|
||||
// Returns the right scale for points in a aSize x aSize sized box, centered
|
||||
// at 0x0 to fill aRect in the smaller dimension.
|
||||
static float ScaleToFillRect(const LayoutDeviceRect& aRect,
|
||||
const float& aSize) {
|
||||
return std::min(aRect.width, aRect.height) / aSize;
|
||||
}
|
||||
|
||||
static LayoutDeviceIntCoord SnapBorderWidth(const CSSCoord& aCssWidth,
|
||||
const DPIRatio& aDpiRatio);
|
||||
|
||||
static void PaintArrow(DrawTarget&, const LayoutDeviceRect&,
|
||||
const float aArrowPolygonX[],
|
||||
const float aArrowPolygonY[],
|
||||
const float aArrowPolygonSize,
|
||||
const int32_t aArrowNumPoints,
|
||||
const sRGBColor aFillColor);
|
||||
|
||||
static void PaintRoundedRectWithRadius(
|
||||
DrawTarget&, const LayoutDeviceRect& aRect,
|
||||
const LayoutDeviceRect& aClipRect, const sRGBColor& aBackgroundColor,
|
||||
const sRGBColor& aBorderColor, const CSSCoord& aBorderWidth,
|
||||
const CSSCoord& aRadius, const DPIRatio&);
|
||||
static void PaintRoundedRectWithRadius(
|
||||
WebRenderBackendData&, const LayoutDeviceRect& aRect,
|
||||
const LayoutDeviceRect& aClipRect, const sRGBColor& aBackgroundColor,
|
||||
const sRGBColor& aBorderColor, const CSSCoord& aBorderWidth,
|
||||
const CSSCoord& aRadius, const DPIRatio&);
|
||||
template <typename PaintBackendData>
|
||||
static void PaintRoundedRectWithRadius(PaintBackendData& aData,
|
||||
const LayoutDeviceRect& aRect,
|
||||
const sRGBColor& aBackgroundColor,
|
||||
const sRGBColor& aBorderColor,
|
||||
const CSSCoord& aBorderWidth,
|
||||
const CSSCoord& aRadius,
|
||||
const DPIRatio& aDpiRatio) {
|
||||
PaintRoundedRectWithRadius(aData, aRect, aRect, aBackgroundColor,
|
||||
aBorderColor, aBorderWidth, aRadius, aDpiRatio);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mozilla::widget
|
||||
|
||||
#endif
|
||||
@@ -16,8 +16,10 @@
|
||||
#include "mozilla/java/GeckoAppShellWrappers.h"
|
||||
#include "mozilla/java/GeckoRuntimeWrappers.h"
|
||||
#include "mozilla/java/GeckoSystemStateListenerWrappers.h"
|
||||
#include "ThemeColors.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
static const char16_t UNICODE_BULLET = 0x2022;
|
||||
|
||||
@@ -191,10 +193,9 @@ nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme aColorScheme,
|
||||
case ColorID::MozCellhighlighttext:
|
||||
case ColorID::Selecteditemtext:
|
||||
case ColorID::MozAccentColorForeground:
|
||||
aColor = UseNativeAccent()
|
||||
? nsNativeBasicTheme::ComputeCustomAccentForeground(
|
||||
mSystemColors.colorAccent)
|
||||
: widget::sDefaultAccentForeground.ToABGR();
|
||||
aColor = UseNativeAccent() ? ThemeColors::ComputeCustomAccentForeground(
|
||||
mSystemColors.colorAccent)
|
||||
: widget::sDefaultAccentForeground.ToABGR();
|
||||
break;
|
||||
case ColorID::Fieldtext:
|
||||
aColor = NS_RGB(0x1a, 0x1a, 0x1a);
|
||||
|
||||
@@ -64,7 +64,6 @@ UNIFIED_SOURCES += [
|
||||
"nsMenuItemX.mm",
|
||||
"nsMenuUtilsX.mm",
|
||||
"nsMenuX.mm",
|
||||
"nsNativeBasicThemeCocoa.cpp",
|
||||
"nsPrintDialogX.mm",
|
||||
"nsPrintSettingsServiceX.mm",
|
||||
"nsPrintSettingsX.mm",
|
||||
@@ -113,6 +112,7 @@ include("/ipc/chromium/chromium-config.mozbuild")
|
||||
|
||||
FINAL_LIBRARY = "xul"
|
||||
LOCAL_INCLUDES += [
|
||||
"/dom/events",
|
||||
"/dom/media/platforms/apple",
|
||||
"/layout/base",
|
||||
"/layout/forms",
|
||||
|
||||
@@ -1,192 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsNativeBasicThemeCocoa.h"
|
||||
#include "mozilla/gfx/Helpers.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
#include "mozilla/ServoStyleConsts.h"
|
||||
#include "MacThemeGeometryType.h"
|
||||
|
||||
already_AddRefed<nsITheme> do_GetBasicNativeThemeDoNotUseDirectly() {
|
||||
static mozilla::StaticRefPtr<nsITheme> gInstance;
|
||||
if (MOZ_UNLIKELY(!gInstance)) {
|
||||
gInstance = new nsNativeBasicThemeCocoa();
|
||||
ClearOnShutdown(&gInstance);
|
||||
}
|
||||
return do_AddRef(gInstance);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNativeBasicThemeCocoa::GetMinimumWidgetSize(
|
||||
nsPresContext* aPresContext, nsIFrame* aFrame, StyleAppearance aAppearance,
|
||||
mozilla::LayoutDeviceIntSize* aResult, bool* aIsOverridable) {
|
||||
if (!IsWidgetScrollbarPart(aAppearance)) {
|
||||
return nsNativeBasicTheme::GetMinimumWidgetSize(
|
||||
aPresContext, aFrame, aAppearance, aResult, aIsOverridable);
|
||||
}
|
||||
|
||||
DPIRatio dpiRatio = GetDPIRatioForScrollbarPart(aPresContext);
|
||||
*aIsOverridable = false;
|
||||
*aResult = ScrollbarDrawingMac::GetMinimumWidgetSize(aAppearance, aFrame,
|
||||
dpiRatio.scale);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool nsNativeBasicThemeCocoa::ThemeSupportsWidget(nsPresContext* aPc,
|
||||
nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance) {
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::Tooltip:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return nsNativeBasicTheme::ThemeSupportsWidget(aPc, aFrame, aAppearance);
|
||||
}
|
||||
|
||||
nsITheme::ThemeGeometryType nsNativeBasicThemeCocoa::ThemeGeometryTypeForWidget(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) {
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::Tooltip:
|
||||
return eThemeGeometryTypeTooltip;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return nsNativeBasicTheme::ThemeGeometryTypeForWidget(aFrame, aAppearance);
|
||||
}
|
||||
|
||||
auto nsNativeBasicThemeCocoa::GetScrollbarSizes(nsPresContext* aPresContext,
|
||||
StyleScrollbarWidth aWidth,
|
||||
Overlay aOverlay)
|
||||
-> ScrollbarSizes {
|
||||
auto size = ScrollbarDrawingMac::GetScrollbarSize(
|
||||
aWidth, aOverlay == Overlay::Yes,
|
||||
GetDPIRatioForScrollbarPart(aPresContext).scale);
|
||||
return {size, size};
|
||||
}
|
||||
|
||||
template <typename PaintBackendData>
|
||||
void nsNativeBasicThemeCocoa::DoPaintScrollbarThumb(
|
||||
PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
DPIRatio aDpiRatio) {
|
||||
ScrollbarParams params =
|
||||
ScrollbarDrawingMac::ComputeScrollbarParams(aFrame, aStyle, aHorizontal);
|
||||
auto thumb = ScrollbarDrawingMac::GetThumbRect(aRect.ToUnknownRect(), params,
|
||||
aDpiRatio.scale);
|
||||
auto thumbRect = LayoutDeviceRect::FromUnknownRect(thumb.mRect);
|
||||
LayoutDeviceCoord radius =
|
||||
(params.horizontal ? thumbRect.Height() : thumbRect.Width()) / 2.0f;
|
||||
PaintRoundedRectWithRadius(
|
||||
aPaintData, thumbRect, thumbRect, sRGBColor::FromABGR(thumb.mFillColor),
|
||||
sRGBColor::White(0.0f), 0.0f, radius / aDpiRatio, aDpiRatio);
|
||||
if (!thumb.mStrokeColor) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Paint the stroke if needed.
|
||||
thumbRect.Inflate(thumb.mStrokeOutset + thumb.mStrokeWidth);
|
||||
radius = (params.horizontal ? thumbRect.Height() : thumbRect.Width()) / 2.0f;
|
||||
PaintRoundedRectWithRadius(aPaintData, thumbRect, sRGBColor::White(0.0f),
|
||||
sRGBColor::FromABGR(thumb.mStrokeColor),
|
||||
thumb.mStrokeWidth, radius / aDpiRatio, aDpiRatio);
|
||||
}
|
||||
|
||||
bool nsNativeBasicThemeCocoa::PaintScrollbarThumb(
|
||||
DrawTarget& aDt, const LayoutDeviceRect& aRect, bool aHorizontal,
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors&, DPIRatio aDpiRatio) {
|
||||
// TODO: Maybe respect the UseSystemColors setting?
|
||||
DoPaintScrollbarThumb(aDt, aRect, aHorizontal, aFrame, aStyle, aElementState,
|
||||
aDocumentState, aDpiRatio);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nsNativeBasicThemeCocoa::PaintScrollbarThumb(
|
||||
WebRenderBackendData& aWrData, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors&, DPIRatio aDpiRatio) {
|
||||
// TODO: Maybe respect the UseSystemColors setting?
|
||||
DoPaintScrollbarThumb(aWrData, aRect, aHorizontal, aFrame, aStyle,
|
||||
aElementState, aDocumentState, aDpiRatio);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename PaintBackendData>
|
||||
void nsNativeBasicThemeCocoa::DoPaintScrollbarTrack(
|
||||
PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, DPIRatio aDpiRatio) {
|
||||
ScrollbarParams params =
|
||||
ScrollbarDrawingMac::ComputeScrollbarParams(aFrame, aStyle, aHorizontal);
|
||||
ScrollbarDrawingMac::ScrollbarTrackRects rects;
|
||||
if (ScrollbarDrawingMac::GetScrollbarTrackRects(aRect.ToUnknownRect(), params,
|
||||
aDpiRatio.scale, rects)) {
|
||||
for (const auto& rect : rects) {
|
||||
FillRect(aPaintData, LayoutDeviceRect::FromUnknownRect(rect.mRect),
|
||||
sRGBColor::FromABGR(rect.mColor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool nsNativeBasicThemeCocoa::PaintScrollbarTrack(
|
||||
DrawTarget& aDt, const LayoutDeviceRect& aRect, bool aHorizontal,
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const Colors&, DPIRatio aDpiRatio) {
|
||||
// TODO: Maybe respect the UseSystemColors setting?
|
||||
DoPaintScrollbarTrack(aDt, aRect, aHorizontal, aFrame, aStyle, aDocumentState,
|
||||
aDpiRatio);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nsNativeBasicThemeCocoa::PaintScrollbarTrack(
|
||||
WebRenderBackendData& aWrData, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const Colors&, DPIRatio aDpiRatio) {
|
||||
// TODO: Maybe respect the UseSystemColors setting?
|
||||
DoPaintScrollbarTrack(aWrData, aRect, aHorizontal, aFrame, aStyle,
|
||||
aDocumentState, aDpiRatio);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename PaintBackendData>
|
||||
void nsNativeBasicThemeCocoa::DoPaintScrollCorner(
|
||||
PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, DPIRatio aDpiRatio) {
|
||||
ScrollbarParams params =
|
||||
ScrollbarDrawingMac::ComputeScrollbarParams(aFrame, aStyle, false);
|
||||
ScrollbarDrawingMac::ScrollCornerRects rects;
|
||||
if (ScrollbarDrawingMac::GetScrollCornerRects(aRect.ToUnknownRect(), params,
|
||||
aDpiRatio.scale, rects)) {
|
||||
for (const auto& rect : rects) {
|
||||
FillRect(aPaintData, LayoutDeviceRect::FromUnknownRect(rect.mRect),
|
||||
sRGBColor::FromABGR(rect.mColor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool nsNativeBasicThemeCocoa::PaintScrollCorner(
|
||||
DrawTarget& aDt, const LayoutDeviceRect& aRect, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle, const EventStates& aDocumentState,
|
||||
const Colors&, DPIRatio aDpiRatio) {
|
||||
// TODO: Maybe respect the UseSystemColors setting?
|
||||
DoPaintScrollCorner(aDt, aRect, aFrame, aStyle, aDocumentState, aDpiRatio);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nsNativeBasicThemeCocoa::PaintScrollCorner(
|
||||
WebRenderBackendData& aWrData, const LayoutDeviceRect& aRect,
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const Colors&, DPIRatio aDpiRatio) {
|
||||
// TODO: Maybe respect the UseSystemColors setting?
|
||||
DoPaintScrollCorner(aWrData, aRect, aFrame, aStyle, aDocumentState,
|
||||
aDpiRatio);
|
||||
return true;
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsNativeBasicThemeCocoa_h
|
||||
#define nsNativeBasicThemeCocoa_h
|
||||
|
||||
#include "nsNativeBasicTheme.h"
|
||||
|
||||
#include "ScrollbarDrawingMac.h"
|
||||
|
||||
class nsNativeBasicThemeCocoa : public nsNativeBasicTheme {
|
||||
public:
|
||||
nsNativeBasicThemeCocoa() = default;
|
||||
|
||||
using ScrollbarParams = mozilla::widget::ScrollbarParams;
|
||||
using ScrollbarDrawingMac = mozilla::widget::ScrollbarDrawingMac;
|
||||
|
||||
NS_IMETHOD GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance,
|
||||
mozilla::LayoutDeviceIntSize* aResult,
|
||||
bool* aIsOverridable) override;
|
||||
|
||||
ScrollbarSizes GetScrollbarSizes(nsPresContext*, StyleScrollbarWidth,
|
||||
Overlay) override;
|
||||
|
||||
template <typename PaintBackendData>
|
||||
void DoPaintScrollbarThumb(PaintBackendData&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, DPIRatio);
|
||||
bool PaintScrollbarThumb(DrawTarget&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio) override;
|
||||
bool PaintScrollbarThumb(WebRenderBackendData&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio) override;
|
||||
|
||||
template <typename PaintBackendData>
|
||||
void DoPaintScrollbarTrack(PaintBackendData&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState,
|
||||
DPIRatio aDpiRatio);
|
||||
bool PaintScrollbarTrack(DrawTarget&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio) override;
|
||||
bool PaintScrollbarTrack(WebRenderBackendData&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio) override;
|
||||
|
||||
bool PaintScrollbar(DrawTarget&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio) override {
|
||||
// Draw nothing; the scrollbar track is drawn in PaintScrollbarTrack.
|
||||
return true;
|
||||
}
|
||||
bool PaintScrollbar(WebRenderBackendData&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio) override {
|
||||
// Draw nothing; the scrollbar track is drawn in PaintScrollbarTrack.
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename PaintBackendData>
|
||||
void DoPaintScrollCorner(PaintBackendData&, const LayoutDeviceRect& aRect,
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState,
|
||||
DPIRatio aDpiRatio);
|
||||
|
||||
bool PaintScrollCorner(DrawTarget&, const LayoutDeviceRect& aRect,
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio aDpiRatio) override;
|
||||
bool PaintScrollCorner(WebRenderBackendData&, const LayoutDeviceRect& aRect,
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio aDpiRatio) override;
|
||||
|
||||
ThemeGeometryType ThemeGeometryTypeForWidget(nsIFrame*,
|
||||
StyleAppearance) override;
|
||||
bool ThemeSupportsWidget(nsPresContext*, nsIFrame*, StyleAppearance) override;
|
||||
|
||||
protected:
|
||||
virtual ~nsNativeBasicThemeCocoa() = default;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -16,7 +16,8 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsAtom.h"
|
||||
#include "nsNativeTheme.h"
|
||||
#include "ScrollbarDrawingMac.h"
|
||||
#include "nsNativeBasicThemeCocoa.h"
|
||||
#include "ScrollbarDrawingCocoa.h"
|
||||
|
||||
@class MOZCellDrawWindow;
|
||||
@class MOZCellDrawView;
|
||||
@@ -32,7 +33,10 @@ class DrawTarget;
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
class nsNativeThemeCocoa : private nsNativeTheme, public nsITheme {
|
||||
class nsNativeThemeCocoa : public nsNativeBasicThemeCocoa {
|
||||
protected:
|
||||
using ScrollbarDrawingCocoa = mozilla::widget::ScrollbarDrawingCocoa;
|
||||
|
||||
public:
|
||||
enum class MenuIcon : uint8_t {
|
||||
eCheckmark,
|
||||
@@ -168,7 +172,7 @@ class nsNativeThemeCocoa : private nsNativeTheme, public nsITheme {
|
||||
bool reverse = false;
|
||||
};
|
||||
|
||||
using ScrollbarParams = mozilla::widget::ScrollbarParams;
|
||||
using ScrollbarParams = mozilla::widget::ScrollbarDrawing::ScrollbarParams;
|
||||
|
||||
enum Widget : uint8_t {
|
||||
eColorFill, // mozilla::gfx::sRGBColor
|
||||
@@ -308,9 +312,7 @@ class nsNativeThemeCocoa : private nsNativeTheme, public nsITheme {
|
||||
enum Widget mWidget;
|
||||
};
|
||||
|
||||
using ScrollbarDrawingMac = mozilla::widget::ScrollbarDrawingMac;
|
||||
|
||||
nsNativeThemeCocoa();
|
||||
explicit nsNativeThemeCocoa(mozilla::UniquePtr<ScrollbarDrawing>&& aScrollbarDrawingCocoa);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using mozilla::dom::HTMLMeterElement;
|
||||
using ScrollbarDrawingCocoa = mozilla::widget::ScrollbarDrawingCocoa;
|
||||
|
||||
#define DRAW_IN_FRAME_DEBUG 0
|
||||
#define SCROLLBARS_VISUAL_DEBUG 0
|
||||
@@ -400,7 +401,9 @@ static bool IsInSourceList(nsIFrame* aFrame) {
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(nsNativeThemeCocoa, nsNativeTheme, nsITheme)
|
||||
|
||||
nsNativeThemeCocoa::nsNativeThemeCocoa() {
|
||||
nsNativeThemeCocoa::nsNativeThemeCocoa(
|
||||
mozilla::UniquePtr<ScrollbarDrawing>&& aScrollbarDrawingCocoa)
|
||||
: nsNativeBasicThemeCocoa(std::move(aScrollbarDrawingCocoa)) {
|
||||
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
|
||||
|
||||
kMaxFocusRingWidth = 7;
|
||||
@@ -2513,7 +2516,7 @@ Maybe<nsNativeThemeCocoa::WidgetInfo> nsNativeThemeCocoa::ComputeWidgetInfo(
|
||||
case StyleAppearance::Scrollcorner: {
|
||||
bool isHorizontal = aAppearance == StyleAppearance::ScrollbarthumbHorizontal ||
|
||||
aAppearance == StyleAppearance::ScrollbartrackHorizontal;
|
||||
ScrollbarParams params = ScrollbarDrawingMac::ComputeScrollbarParams(
|
||||
ScrollbarParams params = GetScrollbarDrawing().ComputeScrollbarParams(
|
||||
aFrame, *nsLayoutUtils::StyleForScrollbar(aFrame), isHorizontal);
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::ScrollbarthumbVertical:
|
||||
@@ -2629,7 +2632,7 @@ void nsNativeThemeCocoa::RenderWidget(const WidgetInfo& aWidgetInfo,
|
||||
}
|
||||
case Widget::eScrollbarThumb: {
|
||||
ScrollbarParams params = aWidgetInfo.Params<ScrollbarParams>();
|
||||
auto thumb = ScrollbarDrawingMac::GetThumbRect(aWidgetRect, params, aScale);
|
||||
auto thumb = ScrollbarDrawingCocoa::GetThumbRect(aWidgetRect, params, aScale);
|
||||
float cornerRadius = (params.horizontal ? thumb.mRect.Height() : thumb.mRect.Width()) / 2.0f;
|
||||
aDrawTarget.FillRoundedRect(RoundedRect(thumb.mRect, RectCornerRadii(cornerRadius)),
|
||||
ColorPattern(ToDeviceColor(thumb.mFillColor)));
|
||||
@@ -2646,8 +2649,8 @@ void nsNativeThemeCocoa::RenderWidget(const WidgetInfo& aWidgetInfo,
|
||||
}
|
||||
case Widget::eScrollbarTrack: {
|
||||
ScrollbarParams params = aWidgetInfo.Params<ScrollbarParams>();
|
||||
ScrollbarDrawingMac::ScrollbarTrackRects rects;
|
||||
if (ScrollbarDrawingMac::GetScrollbarTrackRects(aWidgetRect, params, aScale, rects)) {
|
||||
ScrollbarDrawingCocoa::ScrollbarTrackRects rects;
|
||||
if (ScrollbarDrawingCocoa::GetScrollbarTrackRects(aWidgetRect, params, aScale, rects)) {
|
||||
for (const auto& rect : rects) {
|
||||
aDrawTarget.FillRect(rect.mRect, ColorPattern(ToDeviceColor(rect.mColor)));
|
||||
}
|
||||
@@ -2656,8 +2659,8 @@ void nsNativeThemeCocoa::RenderWidget(const WidgetInfo& aWidgetInfo,
|
||||
}
|
||||
case Widget::eScrollCorner: {
|
||||
ScrollbarParams params = aWidgetInfo.Params<ScrollbarParams>();
|
||||
ScrollbarDrawingMac::ScrollCornerRects rects;
|
||||
if (ScrollbarDrawingMac::GetScrollCornerRects(aWidgetRect, params, aScale, rects)) {
|
||||
ScrollbarDrawingCocoa::ScrollCornerRects rects;
|
||||
if (ScrollbarDrawingCocoa::GetScrollCornerRects(aWidgetRect, params, aScale, rects)) {
|
||||
for (const auto& rect : rects) {
|
||||
aDrawTarget.FillRect(rect.mRect, ColorPattern(ToDeviceColor(rect.mColor)));
|
||||
}
|
||||
@@ -2913,7 +2916,7 @@ bool nsNativeThemeCocoa::CreateWebRenderCommandsForWidget(
|
||||
case StyleAppearance::ScrollbartrackHorizontal:
|
||||
case StyleAppearance::ScrollbartrackVertical: {
|
||||
const ComputedStyle& style = *nsLayoutUtils::StyleForScrollbar(aFrame);
|
||||
ScrollbarParams params = ScrollbarDrawingMac::ComputeScrollbarParams(
|
||||
ScrollbarParams params = GetScrollbarDrawing().ComputeScrollbarParams(
|
||||
aFrame, style, aAppearance == StyleAppearance::ScrollbartrackHorizontal);
|
||||
if (params.overlay && !params.rolledOver) {
|
||||
// There is no scrollbar track, draw nothing and return true.
|
||||
@@ -3145,7 +3148,7 @@ bool nsNativeThemeCocoa::GetWidgetOverflow(nsDeviceContext* aContext, nsIFrame*
|
||||
|
||||
auto nsNativeThemeCocoa::GetScrollbarSizes(nsPresContext* aPresContext, StyleScrollbarWidth aWidth,
|
||||
Overlay aOverlay) -> ScrollbarSizes {
|
||||
auto size = ScrollbarDrawingMac::GetScrollbarSize(aWidth, aOverlay == Overlay::Yes);
|
||||
auto size = ScrollbarDrawingCocoa::GetScrollbarSize(aWidth, aOverlay == Overlay::Yes);
|
||||
if (IsHiDPIContext(aPresContext->DeviceContext())) {
|
||||
size *= 2;
|
||||
}
|
||||
@@ -3161,6 +3164,11 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame*
|
||||
aResult->SizeTo(0, 0);
|
||||
*aIsOverridable = true;
|
||||
|
||||
if (IsWidgetScrollbarPart(aAppearance)) {
|
||||
return nsNativeBasicThemeCocoa::GetMinimumWidgetSize(aPresContext, aFrame, aAppearance, aResult,
|
||||
aIsOverridable);
|
||||
}
|
||||
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::Button: {
|
||||
aResult->SizeTo(pushButtonSettings.minimumSizes[miniControlSize].width,
|
||||
@@ -3291,24 +3299,9 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame*
|
||||
break;
|
||||
}
|
||||
|
||||
case StyleAppearance::ScrollbarthumbHorizontal:
|
||||
case StyleAppearance::ScrollbarthumbVertical:
|
||||
case StyleAppearance::ScrollbarHorizontal:
|
||||
case StyleAppearance::ScrollbarVertical:
|
||||
case StyleAppearance::ScrollbartrackVertical:
|
||||
case StyleAppearance::ScrollbartrackHorizontal:
|
||||
case StyleAppearance::ScrollbarbuttonUp:
|
||||
case StyleAppearance::ScrollbarbuttonDown:
|
||||
case StyleAppearance::ScrollbarbuttonLeft:
|
||||
case StyleAppearance::ScrollbarbuttonRight: {
|
||||
*aIsOverridable = false;
|
||||
*aResult = ScrollbarDrawingMac::GetMinimumWidgetSize(aAppearance, aFrame, 1.0f);
|
||||
break;
|
||||
}
|
||||
|
||||
case StyleAppearance::MozMenulistArrowButton:
|
||||
*aResult = ScrollbarDrawingMac::GetMinimumWidgetSize(aAppearance, aFrame, 1.0f);
|
||||
break;
|
||||
return nsNativeBasicThemeCocoa::GetMinimumWidgetSize(aPresContext, aFrame, aAppearance,
|
||||
aResult, aIsOverridable);
|
||||
|
||||
case StyleAppearance::Resizer: {
|
||||
HIThemeGrowBoxDrawInfo drawInfo;
|
||||
@@ -3663,7 +3656,7 @@ already_AddRefed<nsITheme> do_GetNativeThemeDoNotUseDirectly() {
|
||||
static nsCOMPtr<nsITheme> inst;
|
||||
|
||||
if (!inst) {
|
||||
inst = new nsNativeThemeCocoa();
|
||||
inst = new nsNativeThemeCocoa(MakeUnique<ScrollbarDrawingCocoa>());
|
||||
ClearOnShutdown(&inst);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ extern mozilla::LazyLogModule gWidgetWaylandLog;
|
||||
# define LOGWAYLAND(args)
|
||||
#endif /* MOZ_LOGGING */
|
||||
|
||||
using namespace mozilla::gl;
|
||||
|
||||
namespace mozilla::widget {
|
||||
|
||||
#define BUFFER_BPP 4
|
||||
|
||||
@@ -55,7 +55,6 @@ UNIFIED_SOURCES += [
|
||||
"nsGtkKeyUtils.cpp",
|
||||
"nsImageToPixbuf.cpp",
|
||||
"nsLookAndFeel.cpp",
|
||||
"nsNativeBasicThemeGTK.cpp",
|
||||
"nsSound.cpp",
|
||||
"nsToolkit.cpp",
|
||||
"nsWidgetFactory.cpp",
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/WidgetUtilsGtk.h"
|
||||
#include "ScreenHelperGTK.h"
|
||||
#include "nsNativeBasicThemeGTK.h"
|
||||
#include "ScrollbarDrawing.h"
|
||||
|
||||
#include "gtkdrawing.h"
|
||||
#include "nsStyleConsts.h"
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "nsCSSColorUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
#ifdef MOZ_LOGGING
|
||||
# include "mozilla/Logging.h"
|
||||
@@ -1518,12 +1519,11 @@ void nsLookAndFeel::PerThemeData::Init() {
|
||||
mMozScrollbar = mThemedScrollbar = widget::sScrollbarColor.ToABGR();
|
||||
mThemedScrollbarInactive = widget::sScrollbarColor.ToABGR();
|
||||
mThemedScrollbarThumb = widget::sScrollbarThumbColor.ToABGR();
|
||||
mThemedScrollbarThumbHover =
|
||||
nsNativeBasicTheme::AdjustUnthemedScrollbarThumbColor(
|
||||
mThemedScrollbarThumb, NS_EVENT_STATE_HOVER);
|
||||
mThemedScrollbarThumbHover = ThemeColors::AdjustUnthemedScrollbarThumbColor(
|
||||
mThemedScrollbarThumb, NS_EVENT_STATE_HOVER);
|
||||
mThemedScrollbarThumbActive =
|
||||
nsNativeBasicTheme::AdjustUnthemedScrollbarThumbColor(
|
||||
mThemedScrollbarThumb, NS_EVENT_STATE_ACTIVE);
|
||||
ThemeColors::AdjustUnthemedScrollbarThumbColor(mThemedScrollbarThumb,
|
||||
NS_EVENT_STATE_ACTIVE);
|
||||
mThemedScrollbarThumbInactive = mThemedScrollbarThumb;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "nsWindow.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsNativeBasicTheme.h"
|
||||
#include "ScrollbarDrawingGTK.h"
|
||||
|
||||
#ifdef MOZ_X11
|
||||
# ifdef CAIRO_HAS_XLIB_SURFACE
|
||||
@@ -58,6 +59,7 @@ using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::widget;
|
||||
using mozilla::dom::HTMLInputElement;
|
||||
using ScrollbarDrawingGTK = mozilla::widget::ScrollbarDrawingGTK;
|
||||
|
||||
static int gLastGdkError;
|
||||
|
||||
@@ -96,7 +98,9 @@ static inline gint GetMonitorScaleFactor(nsIFrame* aFrame) {
|
||||
return GetMonitorScaleFactor(aFrame->PresContext());
|
||||
}
|
||||
|
||||
nsNativeThemeGTK::nsNativeThemeGTK() {
|
||||
nsNativeThemeGTK::nsNativeThemeGTK(
|
||||
mozilla::UniquePtr<ScrollbarDrawing>&& aScrollbarDrawingGTK)
|
||||
: nsNativeBasicTheme(std::move(aScrollbarDrawingGTK)) {
|
||||
if (moz_gtk_init() != MOZ_GTK_SUCCESS) {
|
||||
memset(mDisabledWidgetTypes, 0xff, sizeof(mDisabledWidgetTypes));
|
||||
return;
|
||||
@@ -1049,7 +1053,7 @@ nsNativeThemeGTK::DrawWidgetBackground(gfxContext* aContext, nsIFrame* aFrame,
|
||||
const nsRect& aDirtyRect,
|
||||
DrawOverflow aDrawOverflow) {
|
||||
if (IsWidgetNonNative(aFrame, aAppearance) != NonNative::No) {
|
||||
return nsNativeBasicThemeGTK::DrawWidgetBackground(
|
||||
return nsNativeBasicTheme::DrawWidgetBackground(
|
||||
aContext, aFrame, aAppearance, aRect, aDirtyRect, aDrawOverflow);
|
||||
}
|
||||
|
||||
@@ -1178,7 +1182,7 @@ bool nsNativeThemeGTK::CreateWebRenderCommandsForWidget(
|
||||
mozilla::layers::RenderRootStateManager* aManager, nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance, const nsRect& aRect) {
|
||||
if (IsWidgetNonNative(aFrame, aAppearance) != NonNative::No) {
|
||||
return nsNativeBasicThemeGTK::CreateWebRenderCommandsForWidget(
|
||||
return nsNativeBasicTheme::CreateWebRenderCommandsForWidget(
|
||||
aBuilder, aResources, aSc, aManager, aFrame, aAppearance, aRect);
|
||||
}
|
||||
return false;
|
||||
@@ -1389,8 +1393,8 @@ bool nsNativeThemeGTK::GetWidgetOverflow(nsDeviceContext* aContext,
|
||||
StyleAppearance aAppearance,
|
||||
nsRect* aOverflowRect) {
|
||||
if (IsWidgetNonNative(aFrame, aAppearance) != NonNative::No) {
|
||||
return nsNativeBasicThemeGTK::GetWidgetOverflow(aContext, aFrame,
|
||||
aAppearance, aOverflowRect);
|
||||
return nsNativeBasicTheme::GetWidgetOverflow(aContext, aFrame, aAppearance,
|
||||
aOverflowRect);
|
||||
}
|
||||
|
||||
nsIntMargin extraSize;
|
||||
@@ -1418,8 +1422,8 @@ auto nsNativeThemeGTK::IsWidgetNonNative(nsIFrame* aFrame,
|
||||
return NonNative::Always;
|
||||
}
|
||||
// We can't draw light widgets if the current GTK theme is dark or vice versa.
|
||||
if (nsNativeBasicThemeGTK::ThemeSupportsWidget(aFrame->PresContext(), aFrame,
|
||||
aAppearance) &&
|
||||
if (nsNativeBasicTheme::ThemeSupportsWidget(aFrame->PresContext(), aFrame,
|
||||
aAppearance) &&
|
||||
LookAndFeel::ColorSchemeForFrame(aFrame) !=
|
||||
LookAndFeel::ColorSchemeForChrome()) {
|
||||
return NonNative::BecauseColorMismatch;
|
||||
@@ -1434,7 +1438,7 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext,
|
||||
LayoutDeviceIntSize* aResult,
|
||||
bool* aIsOverridable) {
|
||||
if (IsWidgetNonNative(aFrame, aAppearance) == NonNative::Always) {
|
||||
return nsNativeBasicThemeGTK::GetMinimumWidgetSize(
|
||||
return nsNativeBasicTheme::GetMinimumWidgetSize(
|
||||
aPresContext, aFrame, aAppearance, aResult, aIsOverridable);
|
||||
}
|
||||
|
||||
@@ -1683,7 +1687,7 @@ nsNativeThemeGTK::WidgetStateChanged(nsIFrame* aFrame,
|
||||
*aShouldRepaint = false;
|
||||
|
||||
if (IsWidgetNonNative(aFrame, aAppearance) != NonNative::No) {
|
||||
return nsNativeBasicThemeGTK::WidgetStateChanged(
|
||||
return nsNativeBasicTheme::WidgetStateChanged(
|
||||
aFrame, aAppearance, aAttribute, aShouldRepaint, aOldValue);
|
||||
}
|
||||
|
||||
@@ -1794,8 +1798,8 @@ nsNativeThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext,
|
||||
}
|
||||
|
||||
if (IsWidgetNonNative(aFrame, aAppearance) == NonNative::Always) {
|
||||
return nsNativeBasicThemeGTK::ThemeSupportsWidget(aPresContext, aFrame,
|
||||
aAppearance);
|
||||
return nsNativeBasicTheme::ThemeSupportsWidget(aPresContext, aFrame,
|
||||
aAppearance);
|
||||
}
|
||||
|
||||
if (IsWidgetScrollbarPart(aAppearance)) {
|
||||
@@ -1946,7 +1950,7 @@ bool nsNativeThemeGTK::ThemeNeedsComboboxDropmarker() { return false; }
|
||||
nsITheme::Transparency nsNativeThemeGTK::GetWidgetTransparency(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) {
|
||||
if (IsWidgetNonNative(aFrame, aAppearance) != NonNative::No) {
|
||||
return nsNativeBasicThemeGTK::GetWidgetTransparency(aFrame, aAppearance);
|
||||
return nsNativeBasicTheme::GetWidgetTransparency(aFrame, aAppearance);
|
||||
}
|
||||
|
||||
switch (aAppearance) {
|
||||
@@ -1973,8 +1977,8 @@ auto nsNativeThemeGTK::GetScrollbarSizes(nsPresContext* aPresContext,
|
||||
StyleScrollbarWidth aWidth,
|
||||
Overlay aOverlay) -> ScrollbarSizes {
|
||||
if (StaticPrefs::widget_non_native_theme_enabled()) {
|
||||
return nsNativeBasicThemeGTK::GetScrollbarSizes(aPresContext, aWidth,
|
||||
aOverlay);
|
||||
return nsNativeBasicTheme::GetScrollbarSizes(aPresContext, aWidth,
|
||||
aOverlay);
|
||||
}
|
||||
|
||||
CSSIntCoord vertical;
|
||||
@@ -1994,13 +1998,6 @@ auto nsNativeThemeGTK::GetScrollbarSizes(nsPresContext* aPresContext,
|
||||
return {int32_t(vertical) * scale, int32_t(horizontal) * scale};
|
||||
}
|
||||
|
||||
bool nsNativeThemeGTK::ThemeSupportsScrollbarButtons() {
|
||||
if (StaticPrefs::widget_non_native_theme_enabled()) {
|
||||
return nsNativeBasicThemeGTK::ThemeSupportsScrollbarButtons();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<nsITheme> do_GetNativeThemeDoNotUseDirectly() {
|
||||
static nsCOMPtr<nsITheme> inst;
|
||||
|
||||
@@ -2008,7 +2005,7 @@ already_AddRefed<nsITheme> do_GetNativeThemeDoNotUseDirectly() {
|
||||
if (gfxPlatform::IsHeadless()) {
|
||||
inst = new HeadlessThemeGTK();
|
||||
} else {
|
||||
inst = new nsNativeThemeGTK();
|
||||
inst = new nsNativeThemeGTK(MakeUnique<ScrollbarDrawingGTK>());
|
||||
}
|
||||
ClearOnShutdown(&inst);
|
||||
}
|
||||
|
||||
@@ -11,12 +11,13 @@
|
||||
#include "nsAtom.h"
|
||||
#include "nsNativeTheme.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsNativeBasicThemeGTK.h"
|
||||
#include "nsNativeBasicTheme.h"
|
||||
#include "ScrollbarDrawingGTK.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "gtkdrawing.h"
|
||||
|
||||
class nsNativeThemeGTK final : public nsNativeBasicThemeGTK {
|
||||
class nsNativeThemeGTK final : public nsNativeBasicTheme {
|
||||
public:
|
||||
// The nsITheme interface.
|
||||
NS_IMETHOD DrawWidgetBackground(gfxContext* aContext, nsIFrame* aFrame,
|
||||
@@ -84,9 +85,8 @@ class nsNativeThemeGTK final : public nsNativeBasicThemeGTK {
|
||||
ScrollbarSizes GetScrollbarSizes(nsPresContext*, StyleScrollbarWidth,
|
||||
Overlay) override;
|
||||
|
||||
bool ThemeSupportsScrollbarButtons() override;
|
||||
|
||||
nsNativeThemeGTK();
|
||||
explicit nsNativeThemeGTK(
|
||||
mozilla::UniquePtr<ScrollbarDrawing>&& aScrollbarDrawingGTK);
|
||||
|
||||
protected:
|
||||
virtual ~nsNativeThemeGTK();
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "nsIPrintSettingsService.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIGIOService.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "WidgetUtils.h"
|
||||
#include "WidgetUtilsGtk.h"
|
||||
#include "nsIObserverService.h"
|
||||
|
||||
@@ -54,6 +54,8 @@ class HeadlessThemeGTK final : private nsNativeTheme, public nsITheme {
|
||||
ScrollbarSizes GetScrollbarSizes(nsPresContext*, StyleScrollbarWidth,
|
||||
Overlay) override;
|
||||
|
||||
bool ThemeSupportsScrollbarButtons() override { return true; }
|
||||
|
||||
protected:
|
||||
virtual ~HeadlessThemeGTK() = default;
|
||||
};
|
||||
|
||||
@@ -201,8 +201,7 @@ UNIFIED_SOURCES += [
|
||||
"nsHTMLFormatConverter.cpp",
|
||||
"nsIWidgetListener.cpp",
|
||||
"nsNativeBasicTheme.cpp",
|
||||
# Android non-native theme is built on all platforms for RDM.
|
||||
"nsNativeBasicThemeAndroid.cpp",
|
||||
"nsNativeBasicThemeCocoa.cpp",
|
||||
"nsPrimitiveHelpers.cpp",
|
||||
"nsPrintSettingsImpl.cpp",
|
||||
"nsSoundProxy.cpp",
|
||||
@@ -213,9 +212,15 @@ UNIFIED_SOURCES += [
|
||||
"PuppetWidget.cpp",
|
||||
"RemoteLookAndFeel.cpp",
|
||||
"Screen.cpp",
|
||||
"ScrollbarDrawingMac.cpp",
|
||||
"ScrollbarDrawing.cpp",
|
||||
"ScrollbarDrawingAndroid.cpp",
|
||||
"ScrollbarDrawingCocoa.cpp",
|
||||
"ScrollbarDrawingGTK.cpp",
|
||||
"ScrollbarDrawingWin.cpp",
|
||||
"SharedWidgetUtils.cpp",
|
||||
"TextEventDispatcher.cpp",
|
||||
"ThemeColors.cpp",
|
||||
"ThemeDrawing.cpp",
|
||||
"TouchResampler.cpp",
|
||||
"VsyncDispatcher.cpp",
|
||||
"WidgetEventImpl.cpp",
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "nsClipboardHelper.h"
|
||||
|
||||
// basics
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "PermissionMessageUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
@@ -51,8 +51,8 @@ nsresult nsDragServiceProxy::InvokeDragSessionImpl(
|
||||
|
||||
nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
|
||||
cookieJarSettings = mSourceDocument->CookieJarSettings();
|
||||
net::CookieJarSettingsArgs csArgs;
|
||||
net::CookieJarSettings::Cast(cookieJarSettings)->Serialize(csArgs);
|
||||
mozilla::net::CookieJarSettingsArgs csArgs;
|
||||
mozilla::net::CookieJarSettings::Cast(cookieJarSettings)->Serialize(csArgs);
|
||||
|
||||
LayoutDeviceIntRect dragRect;
|
||||
if (mHasImage || mSelection) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,7 @@
|
||||
#include "mozilla/gfx/Types.h"
|
||||
#include "nsITheme.h"
|
||||
#include "nsNativeTheme.h"
|
||||
#include "ScrollbarDrawing.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@@ -20,11 +21,6 @@ enum class StyleSystemColor : uint8_t;
|
||||
|
||||
namespace widget {
|
||||
|
||||
static constexpr gfx::sRGBColor sDefaultAccent(
|
||||
gfx::sRGBColor::UnusualFromARGB(0xff0060df)); // Luminance: 13.69346%
|
||||
static constexpr gfx::sRGBColor sDefaultAccentForeground(
|
||||
gfx::sRGBColor::OpaqueWhite());
|
||||
|
||||
static constexpr gfx::sRGBColor sColorGrey10(
|
||||
gfx::sRGBColor::UnusualFromARGB(0xffe9e9ed));
|
||||
static constexpr gfx::sRGBColor sColorGrey10Alpha50(
|
||||
@@ -55,13 +51,6 @@ static constexpr gfx::sRGBColor sColorMeterRed10(
|
||||
static constexpr gfx::sRGBColor sColorMeterRed20(
|
||||
gfx::sRGBColor::UnusualFromARGB(0xff810220));
|
||||
|
||||
static constexpr gfx::sRGBColor sScrollbarColor(
|
||||
gfx::sRGBColor::UnusualFromARGB(0xfff0f0f0));
|
||||
static constexpr gfx::sRGBColor sScrollbarBorderColor(gfx::sRGBColor(1.0f, 1.0f,
|
||||
1.0f));
|
||||
static constexpr gfx::sRGBColor sScrollbarThumbColor(
|
||||
gfx::sRGBColor::UnusualFromARGB(0xffcdcdcd));
|
||||
|
||||
static const CSSCoord kMinimumColorPickerHeight = 32.0f;
|
||||
static const CSSCoord kMinimumRangeThumbSize = 20.0f;
|
||||
static const CSSCoord kMinimumDropdownArrowButtonWidth = 18.0f;
|
||||
@@ -96,10 +85,16 @@ class nsNativeBasicTheme : protected nsNativeTheme, public nsITheme {
|
||||
using RectCornerRadii = mozilla::gfx::RectCornerRadii;
|
||||
using LayoutDeviceCoord = mozilla::LayoutDeviceCoord;
|
||||
using LayoutDeviceRect = mozilla::LayoutDeviceRect;
|
||||
class AccentColor;
|
||||
class Colors;
|
||||
using Colors = mozilla::widget::ThemeColors;
|
||||
using AccentColor = mozilla::widget::ThemeAccentColor;
|
||||
using ScrollbarDrawing = mozilla::widget::ScrollbarDrawing;
|
||||
using WebRenderBackendData = mozilla::widget::WebRenderBackendData;
|
||||
|
||||
public:
|
||||
explicit nsNativeBasicTheme(
|
||||
mozilla::UniquePtr<ScrollbarDrawing>&& aScrollbarDrawing)
|
||||
: mScrollbarDrawing(std::move(aScrollbarDrawing)) {}
|
||||
|
||||
static void Init();
|
||||
static void Shutdown();
|
||||
static void LookAndFeelChanged();
|
||||
@@ -114,13 +109,6 @@ class nsNativeBasicTheme : protected nsNativeTheme, public nsITheme {
|
||||
const nsRect& aDirtyRect,
|
||||
DrawOverflow) override;
|
||||
|
||||
struct WebRenderBackendData {
|
||||
mozilla::wr::DisplayListBuilder& mBuilder;
|
||||
mozilla::wr::IpcResourceUpdateQueue& mResources;
|
||||
const mozilla::layers::StackingContextHelper& mSc;
|
||||
mozilla::layers::RenderRootStateManager* mManager;
|
||||
};
|
||||
|
||||
bool CreateWebRenderCommandsForWidget(
|
||||
mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
||||
@@ -163,24 +151,15 @@ class nsNativeBasicTheme : protected nsNativeTheme, public nsITheme {
|
||||
bool ThemeNeedsComboboxDropmarker() override;
|
||||
ScrollbarSizes GetScrollbarSizes(nsPresContext*, StyleScrollbarWidth,
|
||||
Overlay) override;
|
||||
static nscolor AdjustUnthemedScrollbarThumbColor(nscolor, EventStates);
|
||||
static nscolor GetScrollbarButtonColor(nscolor aTrackColor, EventStates);
|
||||
static mozilla::Maybe<nscolor> GetScrollbarArrowColor(nscolor aButtonColor);
|
||||
static nscolor ComputeCustomAccentForeground(nscolor aAccent);
|
||||
|
||||
nscoord GetCheckboxRadioPrefSize() override;
|
||||
|
||||
protected:
|
||||
nsNativeBasicTheme() = default;
|
||||
virtual ~nsNativeBasicTheme() = default;
|
||||
|
||||
static DPIRatio GetDPIRatioForScrollbarPart(nsPresContext*);
|
||||
static DPIRatio GetDPIRatio(nsPresContext*, StyleAppearance);
|
||||
static DPIRatio GetDPIRatio(nsIFrame*, StyleAppearance);
|
||||
|
||||
// Whether we should use system colors (for high contrast mode).
|
||||
static bool ShouldBeHighContrast(const nsPresContext&);
|
||||
|
||||
std::pair<sRGBColor, sRGBColor> ComputeCheckboxColors(const EventStates&,
|
||||
StyleAppearance,
|
||||
const Colors&);
|
||||
@@ -207,21 +186,6 @@ class nsNativeBasicTheme : protected nsNativeTheme, public nsITheme {
|
||||
const EventStates& aMeterState, const Colors&);
|
||||
std::array<sRGBColor, 3> ComputeFocusRectColors(const Colors&);
|
||||
|
||||
static bool ShouldUseDarkScrollbar(nsIFrame*, const ComputedStyle&);
|
||||
bool IsScrollbarTrackOpaque(nsIFrame*);
|
||||
sRGBColor ComputeScrollbarTrackColor(nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&);
|
||||
sRGBColor ComputeScrollbarThumbColor(nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&);
|
||||
// Returned colors are button, arrow.
|
||||
std::pair<sRGBColor, sRGBColor> ComputeScrollbarButtonColors(
|
||||
nsIFrame*, StyleAppearance, const ComputedStyle&,
|
||||
const EventStates& aElementState, const EventStates& aDocumentState,
|
||||
const Colors&);
|
||||
|
||||
template <typename PaintBackendData>
|
||||
void PaintRoundedFocusRect(PaintBackendData&, const LayoutDeviceRect&,
|
||||
const Colors&, DPIRatio, CSSCoord aRadius,
|
||||
@@ -230,35 +194,6 @@ class nsNativeBasicTheme : protected nsNativeTheme, public nsITheme {
|
||||
void PaintAutoStyleOutline(nsIFrame*, PaintBackendData&,
|
||||
const LayoutDeviceRect&, const Colors&, DPIRatio);
|
||||
|
||||
static void PaintRoundedRectWithRadius(DrawTarget&,
|
||||
const LayoutDeviceRect& aRect,
|
||||
const LayoutDeviceRect& aClipRect,
|
||||
const sRGBColor& aBackgroundColor,
|
||||
const sRGBColor& aBorderColor,
|
||||
CSSCoord aBorderWidth,
|
||||
CSSCoord aRadius, DPIRatio);
|
||||
static void PaintRoundedRectWithRadius(WebRenderBackendData&,
|
||||
const LayoutDeviceRect& aRect,
|
||||
const LayoutDeviceRect& aClipRect,
|
||||
const sRGBColor& aBackgroundColor,
|
||||
const sRGBColor& aBorderColor,
|
||||
CSSCoord aBorderWidth,
|
||||
CSSCoord aRadius, DPIRatio);
|
||||
template <typename PaintBackendData>
|
||||
static void PaintRoundedRectWithRadius(PaintBackendData& aData,
|
||||
const LayoutDeviceRect& aRect,
|
||||
const sRGBColor& aBackgroundColor,
|
||||
const sRGBColor& aBorderColor,
|
||||
CSSCoord aBorderWidth,
|
||||
CSSCoord aRadius, DPIRatio aDpiRatio) {
|
||||
PaintRoundedRectWithRadius(aData, aRect, aRect, aBackgroundColor,
|
||||
aBorderColor, aBorderWidth, aRadius, aDpiRatio);
|
||||
}
|
||||
|
||||
static void FillRect(DrawTarget&, const LayoutDeviceRect&, const sRGBColor&);
|
||||
static void FillRect(WebRenderBackendData&, const LayoutDeviceRect&,
|
||||
const sRGBColor&);
|
||||
|
||||
void PaintCheckboxControl(DrawTarget& aDrawTarget, const LayoutDeviceRect&,
|
||||
const EventStates&, const Colors&, DPIRatio);
|
||||
void PaintCheckMark(DrawTarget&, const LayoutDeviceRect&, const EventStates&,
|
||||
@@ -295,10 +230,6 @@ class nsNativeBasicTheme : protected nsNativeTheme, public nsITheme {
|
||||
template <typename PaintBackendData>
|
||||
void PaintMenulist(PaintBackendData&, const LayoutDeviceRect&,
|
||||
const EventStates&, const Colors&, DPIRatio);
|
||||
void PaintArrow(DrawTarget&, const LayoutDeviceRect&,
|
||||
const float aArrowPolygonX[], const float aArrowPolygonY[],
|
||||
const float aArrowPolygonSize, const int32_t aArrowNumPoints,
|
||||
const sRGBColor aFillColor);
|
||||
void PaintMenulistArrowButton(nsIFrame*, DrawTarget&, const LayoutDeviceRect&,
|
||||
const EventStates&);
|
||||
void PaintSpinnerButton(nsIFrame*, DrawTarget&, const LayoutDeviceRect&,
|
||||
@@ -316,88 +247,12 @@ class nsNativeBasicTheme : protected nsNativeTheme, public nsITheme {
|
||||
void PaintButton(nsIFrame*, PaintBackendData&, const LayoutDeviceRect&,
|
||||
const EventStates&, const Colors&, DPIRatio);
|
||||
|
||||
void PaintScrollbarButton(DrawTarget&, StyleAppearance,
|
||||
const LayoutDeviceRect&, nsIFrame*,
|
||||
const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio);
|
||||
|
||||
virtual bool PaintScrollbarThumb(DrawTarget&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*,
|
||||
const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&, DPIRatio);
|
||||
virtual bool PaintScrollbarThumb(WebRenderBackendData&,
|
||||
const LayoutDeviceRect&, bool aHorizontal,
|
||||
nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&, DPIRatio);
|
||||
template <typename PaintBackendData>
|
||||
bool DoPaintDefaultScrollbarThumb(PaintBackendData&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*,
|
||||
const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&, DPIRatio);
|
||||
|
||||
virtual bool PaintScrollbar(DrawTarget&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio);
|
||||
virtual bool PaintScrollbar(WebRenderBackendData&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio);
|
||||
template <typename PaintBackendData>
|
||||
bool DoPaintDefaultScrollbar(PaintBackendData&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*,
|
||||
const ComputedStyle&,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio);
|
||||
|
||||
virtual bool PaintScrollbarTrack(DrawTarget&, const LayoutDeviceRect&,
|
||||
bool aHorizontal, nsIFrame*,
|
||||
const ComputedStyle&,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&, DPIRatio) {
|
||||
// Draw nothing by default. Subclasses can override this.
|
||||
return true;
|
||||
}
|
||||
virtual bool PaintScrollbarTrack(WebRenderBackendData&,
|
||||
const LayoutDeviceRect&, bool aHorizontal,
|
||||
nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&, DPIRatio) {
|
||||
// Draw nothing by default. Subclasses can override this.
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool PaintScrollCorner(DrawTarget&, const LayoutDeviceRect&,
|
||||
nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&, DPIRatio);
|
||||
virtual bool PaintScrollCorner(WebRenderBackendData&, const LayoutDeviceRect&,
|
||||
nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&, DPIRatio);
|
||||
template <typename PaintBackendData>
|
||||
bool DoPaintDefaultScrollCorner(PaintBackendData&, const LayoutDeviceRect&,
|
||||
nsIFrame*, const ComputedStyle&,
|
||||
const EventStates& aDocumentState,
|
||||
const Colors&, DPIRatio);
|
||||
|
||||
static CSSIntCoord sHorizontalScrollbarHeight;
|
||||
static CSSIntCoord sVerticalScrollbarWidth;
|
||||
|
||||
static void PrefChangedCallback(const char*, void*) { LookAndFeelChanged(); }
|
||||
static void RecomputeAccentColors();
|
||||
static void RecomputeScrollbarParams();
|
||||
|
||||
ScrollbarDrawing& GetScrollbarDrawing() const { return *mScrollbarDrawing; }
|
||||
mozilla::UniquePtr<ScrollbarDrawing> mScrollbarDrawing;
|
||||
|
||||
bool ThemeSupportsScrollbarButtons() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsNativeBasicThemeAndroid_h
|
||||
#define nsNativeBasicThemeAndroid_h
|
||||
|
||||
#include "nsNativeBasicTheme.h"
|
||||
|
||||
class nsNativeBasicThemeAndroid final : public nsNativeBasicTheme {
|
||||
public:
|
||||
nsNativeBasicThemeAndroid() = default;
|
||||
|
||||
NS_IMETHOD GetMinimumWidgetSize(nsPresContext*, nsIFrame*, StyleAppearance,
|
||||
mozilla::LayoutDeviceIntSize* aResult,
|
||||
bool* aIsOverridable) override;
|
||||
|
||||
ScrollbarSizes GetScrollbarSizes(nsPresContext*, StyleScrollbarWidth,
|
||||
Overlay) override;
|
||||
|
||||
template <typename PaintBackendData>
|
||||
void DoPaintScrollbarThumb(PaintBackendData&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio);
|
||||
bool PaintScrollbarThumb(DrawTarget&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio) override;
|
||||
bool PaintScrollbarThumb(WebRenderBackendData&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio) override;
|
||||
|
||||
bool PaintScrollbarTrack(DrawTarget&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio) override {
|
||||
// There's no visible track on android.
|
||||
return true;
|
||||
}
|
||||
bool PaintScrollbarTrack(WebRenderBackendData&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio) override {
|
||||
// There's no visible track on Android.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PaintScrollbar(DrawTarget&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio) override {
|
||||
// Draw nothing, we only draw the thumb.
|
||||
return true;
|
||||
}
|
||||
bool PaintScrollbar(WebRenderBackendData&, const LayoutDeviceRect& aRect,
|
||||
bool aHorizontal, nsIFrame* aFrame,
|
||||
const ComputedStyle& aStyle,
|
||||
const EventStates& aElementState,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio) override {
|
||||
// Draw nothing, we only draw the thumb.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PaintScrollCorner(DrawTarget&, const LayoutDeviceRect& aRect,
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio aDpiRatio) override {
|
||||
// Draw nothing, we only draw the thumb.
|
||||
return true;
|
||||
}
|
||||
bool PaintScrollCorner(WebRenderBackendData&, const LayoutDeviceRect& aRect,
|
||||
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
||||
const EventStates& aDocumentState, const Colors&,
|
||||
DPIRatio aDpiRatio) override {
|
||||
// Draw nothing, we only draw the thumb.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ThemeSupportsScrollbarButtons() override { return false; }
|
||||
|
||||
protected:
|
||||
virtual ~nsNativeBasicThemeAndroid() = default;
|
||||
};
|
||||
|
||||
#endif
|
||||
55
widget/nsNativeBasicThemeCocoa.cpp
Normal file
55
widget/nsNativeBasicThemeCocoa.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsNativeBasicThemeCocoa.h"
|
||||
|
||||
#include "cocoa/MacThemeGeometryType.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/gfx/Helpers.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
#include "mozilla/ServoStyleConsts.h"
|
||||
|
||||
using ScrollbarDrawingCocoa = mozilla::widget::ScrollbarDrawingCocoa;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNativeBasicThemeCocoa::GetMinimumWidgetSize(
|
||||
nsPresContext* aPresContext, nsIFrame* aFrame, StyleAppearance aAppearance,
|
||||
mozilla::LayoutDeviceIntSize* aResult, bool* aIsOverridable) {
|
||||
if (aAppearance == StyleAppearance::MozMenulistArrowButton) {
|
||||
auto size = ScrollbarDrawingCocoa::GetScrollbarSize(
|
||||
StyleScrollbarWidth::Auto, /* aOverlay = */ false,
|
||||
GetDPIRatio(aFrame, aAppearance));
|
||||
aResult->SizeTo(size, size);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return nsNativeBasicTheme::GetMinimumWidgetSize(
|
||||
aPresContext, aFrame, aAppearance, aResult, aIsOverridable);
|
||||
}
|
||||
|
||||
nsITheme::ThemeGeometryType nsNativeBasicThemeCocoa::ThemeGeometryTypeForWidget(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) {
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::Tooltip:
|
||||
return eThemeGeometryTypeTooltip;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return nsNativeBasicTheme::ThemeGeometryTypeForWidget(aFrame, aAppearance);
|
||||
}
|
||||
|
||||
bool nsNativeBasicThemeCocoa::ThemeSupportsWidget(nsPresContext* aPc,
|
||||
nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance) {
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::Tooltip:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return nsNativeBasicTheme::ThemeSupportsWidget(aPc, aFrame, aAppearance);
|
||||
}
|
||||
36
widget/nsNativeBasicThemeCocoa.h
Normal file
36
widget/nsNativeBasicThemeCocoa.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsNativeBasicThemeCocoa_h
|
||||
#define nsNativeBasicThemeCocoa_h
|
||||
|
||||
#include "nsNativeBasicTheme.h"
|
||||
|
||||
#include "ScrollbarDrawingCocoa.h"
|
||||
|
||||
class nsNativeBasicThemeCocoa : public nsNativeBasicTheme {
|
||||
protected:
|
||||
using ScrollbarDrawingCocoa = mozilla::widget::ScrollbarDrawingCocoa;
|
||||
|
||||
public:
|
||||
explicit nsNativeBasicThemeCocoa(
|
||||
mozilla::UniquePtr<ScrollbarDrawing>&& aScrollbarDrawing)
|
||||
: nsNativeBasicTheme(std::move(aScrollbarDrawing)) {}
|
||||
|
||||
NS_IMETHOD GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance,
|
||||
mozilla::LayoutDeviceIntSize* aResult,
|
||||
bool* aIsOverridable) override;
|
||||
|
||||
ThemeGeometryType ThemeGeometryTypeForWidget(nsIFrame*,
|
||||
StyleAppearance) override;
|
||||
bool ThemeSupportsWidget(nsPresContext*, nsIFrame*, StyleAppearance) override;
|
||||
|
||||
protected:
|
||||
virtual ~nsNativeBasicThemeCocoa() = default;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -5,7 +5,9 @@
|
||||
|
||||
#include "nsPrinterCUPS.h"
|
||||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/GkRustUtils.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/StaticPrefs_print.h"
|
||||
#include "nsTHashtable.h"
|
||||
#include "nsPaper.h"
|
||||
@@ -14,6 +16,7 @@
|
||||
#include "plstr.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using MarginDouble = mozilla::gfx::MarginDouble;
|
||||
|
||||
// Requested attributes for IPP requests, just the CUPS version now.
|
||||
static constexpr Array<const char* const, 1> requestedAttributes{
|
||||
|
||||
@@ -6,12 +6,19 @@
|
||||
#include "nsPrinterListBase.h"
|
||||
#include "PrintBackgroundTask.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/gfx/Rect.h"
|
||||
#include "mozilla/IntegerRange.h"
|
||||
#include "mozilla/intl/Localization.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "xpcpublic.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
using mozilla::ErrorResult;
|
||||
using mozilla::intl::Localization;
|
||||
using PrinterInfo = nsPrinterListBase::PrinterInfo;
|
||||
using MarginDouble = mozilla::gfx::MarginDouble;
|
||||
|
||||
nsPrinterListBase::nsPrinterListBase() = default;
|
||||
nsPrinterListBase::~nsPrinterListBase() = default;
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ScrollbarUtil.h"
|
||||
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/RelativeLuminanceUtils.h"
|
||||
#include "mozilla/StaticPrefs_widget.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsNativeTheme.h"
|
||||
#include "nsNativeBasicTheme.h"
|
||||
|
||||
using mozilla::ComputedStyle;
|
||||
using mozilla::EventStates;
|
||||
using mozilla::Maybe;
|
||||
using mozilla::Nothing;
|
||||
using mozilla::RelativeLuminanceUtils;
|
||||
using mozilla::Some;
|
||||
using mozilla::StyleAppearance;
|
||||
using mozilla::StyleScrollbarWidth;
|
||||
|
||||
namespace StaticPrefs = mozilla::StaticPrefs;
|
||||
|
||||
/*static*/
|
||||
bool ScrollbarUtil::IsScrollbarWidthThin(ComputedStyle* aStyle) {
|
||||
auto scrollbarWidth = aStyle->StyleUIReset()->mScrollbarWidth;
|
||||
return scrollbarWidth == StyleScrollbarWidth::Thin;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
bool ScrollbarUtil::IsScrollbarWidthThin(nsIFrame* aFrame) {
|
||||
ComputedStyle* style = nsLayoutUtils::StyleForScrollbar(aFrame);
|
||||
return IsScrollbarWidthThin(style);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
ComputedStyle* ScrollbarUtil::GetCustomScrollbarStyle(nsIFrame* aFrame,
|
||||
bool* aDarkScrollbar) {
|
||||
ComputedStyle* style = nsLayoutUtils::StyleForScrollbar(aFrame);
|
||||
if (style->StyleUI()->HasCustomScrollbars()) {
|
||||
return style;
|
||||
}
|
||||
bool useDarkScrollbar = !StaticPrefs::widget_disable_dark_scrollbar() &&
|
||||
nsNativeTheme::IsDarkBackground(aFrame);
|
||||
if (useDarkScrollbar || IsScrollbarWidthThin(style)) {
|
||||
if (aDarkScrollbar) {
|
||||
*aDarkScrollbar = useDarkScrollbar;
|
||||
}
|
||||
return style;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
nscolor ScrollbarUtil::GetScrollbarTrackColor(nsIFrame* aFrame) {
|
||||
bool darkScrollbar = false;
|
||||
ComputedStyle* style = GetCustomScrollbarStyle(aFrame, &darkScrollbar);
|
||||
if (style) {
|
||||
const nsStyleUI* ui = style->StyleUI();
|
||||
auto* customColors = ui->mScrollbarColor.IsAuto()
|
||||
? nullptr
|
||||
: &ui->mScrollbarColor.AsColors();
|
||||
if (customColors) {
|
||||
return customColors->track.CalcColor(*style);
|
||||
}
|
||||
}
|
||||
return darkScrollbar ? NS_RGBA(20, 20, 25, 77) : NS_RGB(240, 240, 240);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
nscolor ScrollbarUtil::GetScrollbarThumbColor(nsIFrame* aFrame,
|
||||
EventStates aEventStates) {
|
||||
bool darkScrollbar = false;
|
||||
ComputedStyle* style = GetCustomScrollbarStyle(aFrame, &darkScrollbar);
|
||||
nscolor color =
|
||||
darkScrollbar ? NS_RGBA(249, 249, 250, 102) : NS_RGB(205, 205, 205);
|
||||
if (style) {
|
||||
const nsStyleUI* ui = style->StyleUI();
|
||||
auto* customColors = ui->mScrollbarColor.IsAuto()
|
||||
? nullptr
|
||||
: &ui->mScrollbarColor.AsColors();
|
||||
if (customColors) {
|
||||
color = customColors->thumb.CalcColor(*style);
|
||||
}
|
||||
}
|
||||
return nsNativeBasicTheme::AdjustUnthemedScrollbarThumbColor(color,
|
||||
aEventStates);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
Maybe<nsITheme::Transparency> ScrollbarUtil::GetScrollbarPartTransparency(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) {
|
||||
if (nsNativeTheme::IsWidgetScrollbarPart(aAppearance)) {
|
||||
if (ComputedStyle* style = ScrollbarUtil::GetCustomScrollbarStyle(aFrame)) {
|
||||
auto* ui = style->StyleUI();
|
||||
if (ui->mScrollbarColor.IsAuto() ||
|
||||
ui->mScrollbarColor.AsColors().track.MaybeTransparent()) {
|
||||
return Some(nsITheme::eTransparent);
|
||||
}
|
||||
// These widgets may be thinner than the track, so we need to return
|
||||
// transparent for them to make the track visible.
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::ScrollbarthumbHorizontal:
|
||||
case StyleAppearance::ScrollbarthumbVertical:
|
||||
case StyleAppearance::ScrollbarbuttonUp:
|
||||
case StyleAppearance::ScrollbarbuttonDown:
|
||||
case StyleAppearance::ScrollbarbuttonLeft:
|
||||
case StyleAppearance::ScrollbarbuttonRight:
|
||||
return Some(nsITheme::eTransparent);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::ScrollbarHorizontal:
|
||||
case StyleAppearance::ScrollbarVertical:
|
||||
case StyleAppearance::Scrollcorner:
|
||||
case StyleAppearance::Statusbar:
|
||||
// Knowing that scrollbars and statusbars are opaque improves
|
||||
// performance, because we create layers for them. This better be
|
||||
// true across all Windows themes! If it's not true, we should
|
||||
// paint an opaque background for them to make it true!
|
||||
return Some(nsITheme::eOpaque);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Nothing();
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef ScrollbarUtil_h
|
||||
#define ScrollbarUtil_h
|
||||
|
||||
#include "nsITheme.h"
|
||||
#include "nsNativeTheme.h"
|
||||
|
||||
class ScrollbarUtil {
|
||||
public:
|
||||
static bool IsScrollbarWidthThin(mozilla::ComputedStyle* aStyle);
|
||||
static bool IsScrollbarWidthThin(nsIFrame* aFrame);
|
||||
|
||||
// Returns the style for custom scrollbar if the scrollbar part frame should
|
||||
// use the custom drawing path, nullptr otherwise.
|
||||
//
|
||||
// Optionally the caller can pass a pointer to aDarkScrollbar for whether
|
||||
// custom scrollbar may be drawn due to dark background.
|
||||
static mozilla::ComputedStyle* GetCustomScrollbarStyle(
|
||||
nsIFrame* aFrame, bool* aDarkScrollbar = nullptr);
|
||||
|
||||
static nscolor GetScrollbarTrackColor(nsIFrame* aFrame);
|
||||
static nscolor GetScrollbarThumbColor(nsIFrame* aFrame,
|
||||
mozilla::EventStates aEventStates);
|
||||
static mozilla::Maybe<nsITheme::Transparency> GetScrollbarPartTransparency(
|
||||
nsIFrame* aFrame, mozilla::StyleAppearance aAppearance);
|
||||
|
||||
protected:
|
||||
ScrollbarUtil() = default;
|
||||
virtual ~ScrollbarUtil() = default;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -75,7 +75,6 @@ UNIFIED_SOURCES += [
|
||||
"nsDataObjCollection.cpp",
|
||||
"nsDragService.cpp",
|
||||
"nsLookAndFeel.cpp",
|
||||
"nsNativeBasicThemeWin.cpp",
|
||||
"nsNativeDragSource.cpp",
|
||||
"nsNativeDragTarget.cpp",
|
||||
"nsNativeThemeWin.cpp",
|
||||
@@ -92,7 +91,6 @@ UNIFIED_SOURCES += [
|
||||
"OSKVRManager.cpp",
|
||||
"RemoteBackbuffer.cpp",
|
||||
"ScreenHelperWin.cpp",
|
||||
"ScrollbarUtil.cpp",
|
||||
"SystemStatusBar.cpp",
|
||||
"TaskbarPreview.cpp",
|
||||
"TaskbarPreviewButton.cpp",
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsNativeBasicThemeWin.h"
|
||||
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "ScrollbarUtil.h"
|
||||
|
||||
nsITheme::Transparency nsNativeBasicThemeWin::GetWidgetTransparency(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) {
|
||||
if (auto transparency =
|
||||
ScrollbarUtil::GetScrollbarPartTransparency(aFrame, aAppearance)) {
|
||||
return *transparency;
|
||||
}
|
||||
return nsNativeBasicTheme::GetWidgetTransparency(aFrame, aAppearance);
|
||||
}
|
||||
|
||||
already_AddRefed<nsITheme> do_GetBasicNativeThemeDoNotUseDirectly() {
|
||||
static mozilla::StaticRefPtr<nsITheme> gInstance;
|
||||
if (MOZ_UNLIKELY(!gInstance)) {
|
||||
gInstance = new nsNativeBasicThemeWin();
|
||||
ClearOnShutdown(&gInstance);
|
||||
}
|
||||
return do_AddRef(gInstance);
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsNativeBasicThemeWin_h
|
||||
#define nsNativeBasicThemeWin_h
|
||||
|
||||
#include "nsNativeBasicTheme.h"
|
||||
|
||||
class nsNativeBasicThemeWin : public nsNativeBasicTheme {
|
||||
public:
|
||||
nsNativeBasicThemeWin() = default;
|
||||
|
||||
Transparency GetWidgetTransparency(nsIFrame*, StyleAppearance) override;
|
||||
|
||||
protected:
|
||||
virtual ~nsNativeBasicThemeWin() = default;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -5,57 +5,59 @@
|
||||
|
||||
#include "nsNativeThemeWin.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "gfxContext.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "gfxWindowsNativeDrawing.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#include "gfxWindowsSurface.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/EventStates.h"
|
||||
#include "mozilla/gfx/Types.h" // for Color::FromABGR
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/RelativeLuminanceUtils.h"
|
||||
#include "mozilla/StaticPrefs_layout.h"
|
||||
#include "mozilla/StaticPrefs_widget.h"
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
#include "mozilla/gfx/Types.h" // for Color::FromABGR
|
||||
#include "nsNativeBasicTheme.h"
|
||||
#include "nsColor.h"
|
||||
#include "nsComboboxControlFrame.h"
|
||||
#include "nsDeviceContext.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsSize.h"
|
||||
#include "nsTransform2D.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIContentInlines.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsNameSpaceManager.h"
|
||||
#include "nsLookAndFeel.h"
|
||||
#include "nsMenuFrame.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include <malloc.h>
|
||||
#include "nsWindow.h"
|
||||
#include "nsComboboxControlFrame.h"
|
||||
#include "prinrval.h"
|
||||
#include "ScrollbarUtil.h"
|
||||
#include "WinUtils.h"
|
||||
|
||||
#include "gfxPlatform.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#include "gfxWindowsSurface.h"
|
||||
#include "gfxWindowsNativeDrawing.h"
|
||||
|
||||
#include "nsNameSpaceManager.h"
|
||||
#include "nsNativeBasicTheme.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsSize.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsTransform2D.h"
|
||||
#include "nsUXThemeData.h"
|
||||
#include "nsUXThemeConstants.h"
|
||||
#include <algorithm>
|
||||
#include "nsWindow.h"
|
||||
#include "prinrval.h"
|
||||
#include "WinUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
using ScrollbarDrawingWin = mozilla::widget::ScrollbarDrawingWin;
|
||||
|
||||
extern mozilla::LazyLogModule gWindowsLog;
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(nsNativeThemeWin, nsNativeTheme, nsITheme)
|
||||
|
||||
nsNativeThemeWin::nsNativeThemeWin()
|
||||
: mProgressDeterminateTimeStamp(TimeStamp::Now()),
|
||||
nsNativeThemeWin::nsNativeThemeWin(
|
||||
mozilla::UniquePtr<ScrollbarDrawing>&& aScrollbarDrawingWin)
|
||||
: nsNativeBasicTheme(std::move(aScrollbarDrawingWin)),
|
||||
mProgressDeterminateTimeStamp(TimeStamp::Now()),
|
||||
mProgressIndeterminateTimeStamp(TimeStamp::Now()),
|
||||
mBorderCacheValid(),
|
||||
mMinimumWidgetSizeCacheValid(),
|
||||
@@ -71,8 +73,8 @@ bool nsNativeThemeWin::IsWidgetNonNative(nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance) {
|
||||
// We only know how to draw light widgets, so we defer to the non-native
|
||||
// theme when appropriate.
|
||||
return nsNativeBasicThemeWin::ThemeSupportsWidget(aFrame->PresContext(),
|
||||
aFrame, aAppearance) &&
|
||||
return nsNativeBasicTheme::ThemeSupportsWidget(aFrame->PresContext(), aFrame,
|
||||
aAppearance) &&
|
||||
LookAndFeel::ColorSchemeForFrame(aFrame) ==
|
||||
LookAndFeel::ColorScheme::Dark;
|
||||
}
|
||||
@@ -1492,7 +1494,7 @@ nsNativeThemeWin::DrawWidgetBackground(gfxContext* aContext, nsIFrame* aFrame,
|
||||
const nsRect& aDirtyRect,
|
||||
DrawOverflow aDrawOverflow) {
|
||||
if (IsWidgetNonNative(aFrame, aAppearance)) {
|
||||
return nsNativeBasicThemeWin::DrawWidgetBackground(
|
||||
return nsNativeBasicTheme::DrawWidgetBackground(
|
||||
aContext, aFrame, aAppearance, aRect, aDirtyRect, aDrawOverflow);
|
||||
}
|
||||
|
||||
@@ -1891,7 +1893,7 @@ bool nsNativeThemeWin::CreateWebRenderCommandsForWidget(
|
||||
layers::RenderRootStateManager* aManager, nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance, const nsRect& aRect) {
|
||||
if (IsWidgetNonNative(aFrame, aAppearance)) {
|
||||
return nsNativeBasicThemeWin::CreateWebRenderCommandsForWidget(
|
||||
return nsNativeBasicTheme::CreateWebRenderCommandsForWidget(
|
||||
aBuilder, aResources, aSc, aManager, aFrame, aAppearance, aRect);
|
||||
}
|
||||
return false;
|
||||
@@ -2148,8 +2150,8 @@ bool nsNativeThemeWin::GetWidgetOverflow(nsDeviceContext* aContext,
|
||||
StyleAppearance aAppearance,
|
||||
nsRect* aOverflowRect) {
|
||||
if (IsWidgetNonNative(aFrame, aAppearance)) {
|
||||
return nsNativeBasicThemeWin::GetWidgetOverflow(aContext, aFrame,
|
||||
aAppearance, aOverflowRect);
|
||||
return nsNativeBasicTheme::GetWidgetOverflow(aContext, aFrame, aAppearance,
|
||||
aOverflowRect);
|
||||
}
|
||||
|
||||
/* This is disabled for now, because it causes invalidation problems --
|
||||
@@ -2591,11 +2593,11 @@ nsITheme::ThemeGeometryType nsNativeThemeWin::ThemeGeometryTypeForWidget(
|
||||
nsITheme::Transparency nsNativeThemeWin::GetWidgetTransparency(
|
||||
nsIFrame* aFrame, StyleAppearance aAppearance) {
|
||||
if (IsWidgetNonNative(aFrame, aAppearance)) {
|
||||
return nsNativeBasicThemeWin::GetWidgetTransparency(aFrame, aAppearance);
|
||||
return nsNativeBasicTheme::GetWidgetTransparency(aFrame, aAppearance);
|
||||
}
|
||||
|
||||
if (auto transparency =
|
||||
ScrollbarUtil::GetScrollbarPartTransparency(aFrame, aAppearance)) {
|
||||
if (auto transparency = GetScrollbarDrawing().GetScrollbarPartTransparency(
|
||||
aFrame, aAppearance)) {
|
||||
return *transparency;
|
||||
}
|
||||
|
||||
@@ -2826,7 +2828,7 @@ nsresult nsNativeThemeWin::ClassicGetMinimumWidgetSize(
|
||||
case StyleAppearance::ScrollbarbuttonUp:
|
||||
case StyleAppearance::ScrollbarbuttonDown:
|
||||
// For scrollbar-width:thin, we don't display the buttons.
|
||||
if (!ScrollbarUtil::IsScrollbarWidthThin(aFrame)) {
|
||||
if (!ScrollbarDrawing::IsScrollbarWidthThin(aFrame)) {
|
||||
(*aResult).width = ::GetSystemMetrics(SM_CXVSCROLL);
|
||||
(*aResult).height = ::GetSystemMetrics(SM_CYVSCROLL);
|
||||
}
|
||||
@@ -2835,7 +2837,7 @@ nsresult nsNativeThemeWin::ClassicGetMinimumWidgetSize(
|
||||
case StyleAppearance::ScrollbarbuttonLeft:
|
||||
case StyleAppearance::ScrollbarbuttonRight:
|
||||
// For scrollbar-width:thin, we don't display the buttons.
|
||||
if (!ScrollbarUtil::IsScrollbarWidthThin(aFrame)) {
|
||||
if (!ScrollbarDrawing::IsScrollbarWidthThin(aFrame)) {
|
||||
(*aResult).width = ::GetSystemMetrics(SM_CXHSCROLL);
|
||||
(*aResult).height = ::GetSystemMetrics(SM_CYHSCROLL);
|
||||
}
|
||||
@@ -2903,7 +2905,7 @@ nsresult nsNativeThemeWin::ClassicGetMinimumWidgetSize(
|
||||
}
|
||||
// If scrollbar-width is thin, divide the thickness by two to make
|
||||
// it look more compact.
|
||||
if (ScrollbarUtil::IsScrollbarWidthThin(aFrame)) {
|
||||
if (ScrollbarDrawing::IsScrollbarWidthThin(aFrame)) {
|
||||
aResult->width >>= 1;
|
||||
}
|
||||
*aIsOverridable = false;
|
||||
@@ -2918,7 +2920,7 @@ nsresult nsNativeThemeWin::ClassicGetMinimumWidgetSize(
|
||||
}
|
||||
// If scrollbar-width is thin, divide the thickness by two to make
|
||||
// it look more compact.
|
||||
if (ScrollbarUtil::IsScrollbarWidthThin(aFrame)) {
|
||||
if (ScrollbarDrawing::IsScrollbarWidthThin(aFrame)) {
|
||||
aResult->height >>= 1;
|
||||
}
|
||||
*aIsOverridable = false;
|
||||
@@ -3920,13 +3922,48 @@ uint32_t nsNativeThemeWin::GetWidgetNativeDrawingFlags(
|
||||
}
|
||||
}
|
||||
|
||||
static nscolor GetScrollbarTrackColor(nsIFrame* aFrame) {
|
||||
bool darkScrollbar = false;
|
||||
ComputedStyle* style =
|
||||
ScrollbarDrawingWin::GetCustomScrollbarStyle(aFrame, &darkScrollbar);
|
||||
if (style) {
|
||||
const nsStyleUI* ui = style->StyleUI();
|
||||
auto* customColors = ui->mScrollbarColor.IsAuto()
|
||||
? nullptr
|
||||
: &ui->mScrollbarColor.AsColors();
|
||||
if (customColors) {
|
||||
return customColors->track.CalcColor(*style);
|
||||
}
|
||||
}
|
||||
return darkScrollbar ? NS_RGBA(20, 20, 25, 77) : NS_RGB(240, 240, 240);
|
||||
}
|
||||
|
||||
static nscolor GetScrollbarThumbColor(nsIFrame* aFrame,
|
||||
EventStates aEventStates) {
|
||||
bool darkScrollbar = false;
|
||||
ComputedStyle* style =
|
||||
ScrollbarDrawingWin::GetCustomScrollbarStyle(aFrame, &darkScrollbar);
|
||||
nscolor color =
|
||||
darkScrollbar ? NS_RGBA(249, 249, 250, 102) : NS_RGB(205, 205, 205);
|
||||
if (style) {
|
||||
const nsStyleUI* ui = style->StyleUI();
|
||||
auto* customColors = ui->mScrollbarColor.IsAuto()
|
||||
? nullptr
|
||||
: &ui->mScrollbarColor.AsColors();
|
||||
if (customColors) {
|
||||
color = customColors->thumb.CalcColor(*style);
|
||||
}
|
||||
}
|
||||
return ThemeColors::AdjustUnthemedScrollbarThumbColor(color, aEventStates);
|
||||
}
|
||||
|
||||
// This tries to draw a Windows 10 style scrollbar with given colors.
|
||||
bool nsNativeThemeWin::MayDrawCustomScrollbarPart(gfxContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
StyleAppearance aAppearance,
|
||||
const nsRect& aRect,
|
||||
const nsRect& aClipRect) {
|
||||
ComputedStyle* style = ScrollbarUtil::GetCustomScrollbarStyle(aFrame);
|
||||
ComputedStyle* style = ScrollbarDrawingWin::GetCustomScrollbarStyle(aFrame);
|
||||
if (!style) {
|
||||
return false;
|
||||
}
|
||||
@@ -3941,7 +3978,7 @@ bool nsNativeThemeWin::MayDrawCustomScrollbarPart(gfxContext* aContext,
|
||||
gfxRect clipRect = ThebesRect(NSRectToSnappedRect(aClipRect, p2a, *dt));
|
||||
ctx->Clip(clipRect);
|
||||
|
||||
nscolor trackColor = ScrollbarUtil::GetScrollbarTrackColor(aFrame);
|
||||
nscolor trackColor = GetScrollbarTrackColor(aFrame);
|
||||
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::ScrollbarHorizontal:
|
||||
@@ -3977,8 +4014,7 @@ bool nsNativeThemeWin::MayDrawCustomScrollbarPart(gfxContext* aContext,
|
||||
switch (aAppearance) {
|
||||
case StyleAppearance::ScrollbarthumbVertical:
|
||||
case StyleAppearance::ScrollbarthumbHorizontal: {
|
||||
nscolor faceColor =
|
||||
ScrollbarUtil::GetScrollbarThumbColor(aFrame, eventStates);
|
||||
nscolor faceColor = GetScrollbarThumbColor(aFrame, eventStates);
|
||||
ctx->SetColor(sRGBColor::FromABGR(faceColor));
|
||||
ctx->Rectangle(bgRect);
|
||||
ctx->Fill();
|
||||
@@ -3989,7 +4025,7 @@ bool nsNativeThemeWin::MayDrawCustomScrollbarPart(gfxContext* aContext,
|
||||
case StyleAppearance::ScrollbarbuttonLeft:
|
||||
case StyleAppearance::ScrollbarbuttonRight: {
|
||||
nscolor buttonColor =
|
||||
nsNativeBasicTheme::GetScrollbarButtonColor(trackColor, eventStates);
|
||||
ScrollbarDrawingWin::GetScrollbarButtonColor(trackColor, eventStates);
|
||||
ctx->SetColor(sRGBColor::FromABGR(buttonColor));
|
||||
ctx->Rectangle(bgRect);
|
||||
ctx->Fill();
|
||||
@@ -4035,11 +4071,9 @@ bool nsNativeThemeWin::MayDrawCustomScrollbarPart(gfxContext* aContext,
|
||||
ctx->ClosePath();
|
||||
// And paint the arrow.
|
||||
nscolor arrowColor =
|
||||
nsNativeBasicTheme::GetScrollbarArrowColor(buttonColor)
|
||||
.valueOrFrom([&] {
|
||||
return ScrollbarUtil::GetScrollbarThumbColor(aFrame,
|
||||
eventStates);
|
||||
});
|
||||
ScrollbarDrawingWin::GetScrollbarArrowColor(buttonColor)
|
||||
.valueOrFrom(
|
||||
[&] { return GetScrollbarThumbColor(aFrame, eventStates); });
|
||||
ctx->SetColor(sRGBColor::FromABGR(arrowColor));
|
||||
ctx->Fill();
|
||||
break;
|
||||
@@ -4058,7 +4092,7 @@ already_AddRefed<nsITheme> do_GetNativeThemeDoNotUseDirectly() {
|
||||
static nsCOMPtr<nsITheme> inst;
|
||||
|
||||
if (!inst) {
|
||||
inst = new nsNativeThemeWin();
|
||||
inst = new nsNativeThemeWin(MakeUnique<ScrollbarDrawingWin>());
|
||||
ClearOnShutdown(&inst);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,21 +7,27 @@
|
||||
#ifndef nsNativeThemeWin_h
|
||||
#define nsNativeThemeWin_h
|
||||
|
||||
#include "nsITheme.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include <windows.h>
|
||||
|
||||
#include "gfxTypes.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsAtom.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsITheme.h"
|
||||
#include "nsNativeBasicTheme.h"
|
||||
#include "nsNativeTheme.h"
|
||||
#include "nsSize.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsUXThemeConstants.h"
|
||||
#include "nsUXThemeData.h"
|
||||
#include "nsNativeBasicThemeWin.h"
|
||||
#include "gfxTypes.h"
|
||||
#include <windows.h>
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsSize.h"
|
||||
#include "ScrollbarDrawingWin.h"
|
||||
|
||||
class nsNativeThemeWin : public nsNativeBasicThemeWin {
|
||||
namespace mozilla::widget {
|
||||
|
||||
class nsNativeThemeWin : public nsNativeBasicTheme {
|
||||
protected:
|
||||
using ScrollbarDrawingWin = mozilla::widget::ScrollbarDrawingWin;
|
||||
virtual ~nsNativeThemeWin();
|
||||
|
||||
public:
|
||||
@@ -99,7 +105,8 @@ class nsNativeThemeWin : public nsNativeBasicThemeWin {
|
||||
ScrollbarSizes GetScrollbarSizes(nsPresContext*, StyleScrollbarWidth,
|
||||
Overlay) override;
|
||||
|
||||
nsNativeThemeWin();
|
||||
explicit nsNativeThemeWin(
|
||||
mozilla::UniquePtr<ScrollbarDrawing>&& aScrollbarDrawingWin);
|
||||
|
||||
protected:
|
||||
mozilla::Maybe<nsUXThemeClass> GetThemeClass(StyleAppearance aAppearance);
|
||||
@@ -181,4 +188,6 @@ class nsNativeThemeWin : public nsNativeBasicThemeWin {
|
||||
SIZE mGutterSizeCache;
|
||||
};
|
||||
|
||||
} // namespace mozilla::widget
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user