Bug 1702676 - Change public LookAndFeel API to accept a color scheme. r=mstange

This shouldn't change behavior, but is the biggest cross-platform part
of the change so I'd like to get it landed sooner rather than later.

The two calls like:

  GetColor(ColorID::TextSelectBackground, color);
  if (color == 0x000000) {
    mColorTextSelectForeground = NS_RGB(0xff, 0xff, 0xff);
  } else {
    mColorTextSelectForeground = NS_DONT_CHANGE_COLOR;
  }

that I'm removing are just broken. They were calling the version of
GetColor the function that took a default value when the color wasn't
available, not the version of the color with the outparam.

To prevent such mistakes, add two signatures, GetColor(), returning a
Maybe<nscolor> and Color(), returning a color with a fallback.

Differential Revision: https://phabricator.services.mozilla.com/D110651
This commit is contained in:
Emilio Cobos Álvarez 2021-04-02 12:22:14 +00:00
parent e7d8e6bfae
commit 390c6943fe
18 changed files with 243 additions and 218 deletions

View File

@ -216,9 +216,10 @@ void nsListControlFrame::PaintFocus(DrawTarget* aDrawTarget, nsPoint aPt) {
} }
// set up back stop colors and then ask L&F service for the real colors // set up back stop colors and then ask L&F service for the real colors
nscolor color = LookAndFeel::GetColor( nscolor color = LookAndFeel::Color(
lastItemIsSelected ? LookAndFeel::ColorID::WidgetSelectForeground lastItemIsSelected ? LookAndFeel::ColorID::WidgetSelectForeground
: LookAndFeel::ColorID::WidgetSelectBackground); : LookAndFeel::ColorID::WidgetSelectBackground,
this);
nsCSSRendering::PaintFocus(presContext, aDrawTarget, fRect, color); nsCSSRendering::PaintFocus(presContext, aDrawTarget, fRect, color);
} }

View File

@ -443,7 +443,7 @@ DeviceColor nsDisplaySelectionOverlay::ComputeColor() const {
} }
return ApplyTransparencyIfNecessary( return ApplyTransparencyIfNecessary(
LookAndFeel::GetColor(colorID, NS_RGB(255, 255, 255))); LookAndFeel::Color(colorID, mFrame, NS_RGB(255, 255, 255)));
} }
void nsDisplaySelectionOverlay::Paint(nsDisplayListBuilder* aBuilder, void nsDisplaySelectionOverlay::Paint(nsDisplayListBuilder* aBuilder,

View File

@ -1363,17 +1363,17 @@ void nsHTMLFramesetBorderFrame::PaintBorder(DrawTarget* aDrawTarget,
if (widthInPixels <= 0) return; if (widthInPixels <= 0) return;
ColorPattern bgColor(ToDeviceColor(LookAndFeel::GetColor( ColorPattern bgColor(ToDeviceColor(LookAndFeel::Color(
LookAndFeel::ColorID::WidgetBackground, NS_RGB(200, 200, 200)))); LookAndFeel::ColorID::WidgetBackground, this, NS_RGB(200, 200, 200))));
ColorPattern fgColor(ToDeviceColor(LookAndFeel::GetColor( ColorPattern fgColor(ToDeviceColor(LookAndFeel::Color(
LookAndFeel::ColorID::WidgetForeground, NS_RGB(0, 0, 0)))); LookAndFeel::ColorID::WidgetForeground, this, NS_RGB(0, 0, 0))));
ColorPattern hltColor(ToDeviceColor(LookAndFeel::GetColor( ColorPattern hltColor(ToDeviceColor(LookAndFeel::Color(
LookAndFeel::ColorID::Widget3DHighlight, NS_RGB(255, 255, 255)))); LookAndFeel::ColorID::Widget3DHighlight, this, NS_RGB(255, 255, 255))));
ColorPattern sdwColor(ToDeviceColor(LookAndFeel::GetColor( ColorPattern sdwColor(ToDeviceColor(LookAndFeel::Color(
LookAndFeel::ColorID::Widget3DShadow, NS_RGB(128, 128, 128)))); LookAndFeel::ColorID::Widget3DShadow, this, NS_RGB(128, 128, 128))));
ColorPattern color(ToDeviceColor(NS_RGB(255, 255, 255))); // default to white ColorPattern color(ToDeviceColor(NS_RGB(255, 255, 255))); // default to white
if (mVisibility) { if (mVisibility) {

View File

@ -357,7 +357,7 @@ class nsTextPaintStyle {
float* aRelativeSize, uint8_t* aStyle); float* aRelativeSize, uint8_t* aStyle);
// if this returns false, we don't need to draw underline. // if this returns false, we don't need to draw underline.
static bool GetSelectionUnderline(nsPresContext* aPresContext, int32_t aIndex, static bool GetSelectionUnderline(nsIFrame*, int32_t aIndex,
nscolor* aLineColor, float* aRelativeSize, nscolor* aLineColor, float* aRelativeSize,
uint8_t* aStyle); uint8_t* aStyle);
@ -3899,14 +3899,13 @@ void nsTextPaintStyle::GetHighlightColors(nscolor* aForeColor,
} }
if (!customColors) { if (!customColors) {
nscolor backColor = nscolor backColor = LookAndFeel::Color(
LookAndFeel::GetColor(LookAndFeel::ColorID::TextHighlightBackground); LookAndFeel::ColorID::TextHighlightBackground, mFrame);
nscolor foreColor = nscolor foreColor = LookAndFeel::Color(
LookAndFeel::GetColor(LookAndFeel::ColorID::TextHighlightForeground); LookAndFeel::ColorID::TextHighlightForeground, mFrame);
EnsureSufficientContrast(&foreColor, &backColor); EnsureSufficientContrast(&foreColor, &backColor);
*aForeColor = foreColor; *aForeColor = foreColor;
*aBackColor = backColor; *aBackColor = backColor;
return; return;
} }
@ -4034,9 +4033,9 @@ void nsTextPaintStyle::InitCommonColors() {
mFrameBackgroundColor = NS_ComposeColors(defaultBgColor, bgColor); mFrameBackgroundColor = NS_ComposeColors(defaultBgColor, bgColor);
mSystemFieldForegroundColor = mSystemFieldForegroundColor =
LookAndFeel::GetColor(LookAndFeel::ColorID::Fieldtext); LookAndFeel::Color(LookAndFeel::ColorID::Fieldtext, mFrame);
mSystemFieldBackgroundColor = mSystemFieldBackgroundColor =
LookAndFeel::GetColor(LookAndFeel::ColorID::Field); LookAndFeel::Color(LookAndFeel::ColorID::Field, mFrame);
if (bgFrame->IsThemed()) { if (bgFrame->IsThemed()) {
// Assume a native widget has sufficient contrast always // Assume a native widget has sufficient contrast always
@ -4049,11 +4048,11 @@ void nsTextPaintStyle::InitCommonColors() {
"default background color is not opaque"); "default background color is not opaque");
nscolor defaultWindowBackgroundColor = nscolor defaultWindowBackgroundColor =
LookAndFeel::GetColor(LookAndFeel::ColorID::WindowBackground); LookAndFeel::Color(LookAndFeel::ColorID::WindowBackground, mFrame);
nscolor selectionTextColor = nscolor selectionTextColor =
LookAndFeel::GetColor(LookAndFeel::ColorID::TextSelectForeground); LookAndFeel::Color(LookAndFeel::ColorID::TextSelectForeground, mFrame);
nscolor selectionBGColor = nscolor selectionBGColor =
LookAndFeel::GetColor(LookAndFeel::ColorID::TextSelectBackground); LookAndFeel::Color(LookAndFeel::ColorID::TextSelectBackground, mFrame);
mSufficientContrast = std::min( mSufficientContrast = std::min(
std::min(NS_SUFFICIENT_LUMINOSITY_DIFFERENCE, std::min(NS_SUFFICIENT_LUMINOSITY_DIFFERENCE,
@ -4101,12 +4100,12 @@ bool nsTextPaintStyle::InitSelectionColorsAndShadow() {
} }
nscolor selectionBGColor = nscolor selectionBGColor =
LookAndFeel::GetColor(LookAndFeel::ColorID::TextSelectBackground); LookAndFeel::Color(LookAndFeel::ColorID::TextSelectBackground, mFrame);
switch (selectionStatus) { switch (selectionStatus) {
case nsISelectionController::SELECTION_ATTENTION: { case nsISelectionController::SELECTION_ATTENTION: {
mSelectionBGColor = LookAndFeel::GetColor( mSelectionBGColor = LookAndFeel::Color(
LookAndFeel::ColorID::TextSelectBackgroundAttention); LookAndFeel::ColorID::TextSelectBackgroundAttention, mFrame);
mSelectionBGColor = mSelectionBGColor =
EnsureDifferentColors(mSelectionBGColor, selectionBGColor); EnsureDifferentColors(mSelectionBGColor, selectionBGColor);
break; break;
@ -4116,8 +4115,8 @@ bool nsTextPaintStyle::InitSelectionColorsAndShadow() {
break; break;
} }
default: { default: {
mSelectionBGColor = LookAndFeel::GetColor( mSelectionBGColor = LookAndFeel::Color(
LookAndFeel::ColorID::TextSelectBackgroundDisabled); LookAndFeel::ColorID::TextSelectBackgroundDisabled, mFrame);
mSelectionBGColor = mSelectionBGColor =
EnsureDifferentColors(mSelectionBGColor, selectionBGColor); EnsureDifferentColors(mSelectionBGColor, selectionBGColor);
break; break;
@ -4125,7 +4124,7 @@ bool nsTextPaintStyle::InitSelectionColorsAndShadow() {
} }
mSelectionTextColor = mSelectionTextColor =
LookAndFeel::GetColor(LookAndFeel::ColorID::TextSelectForeground); LookAndFeel::Color(LookAndFeel::ColorID::TextSelectForeground, mFrame);
if (mResolveColors) { if (mResolveColors) {
// On MacOS X, only the background color gets set, // On MacOS X, only the background color gets set,
@ -4145,8 +4144,8 @@ bool nsTextPaintStyle::InitSelectionColorsAndShadow() {
: mFrame->GetVisitedDependentColor( : mFrame->GetVisitedDependentColor(
&nsStyleText::mWebkitTextFillColor); &nsStyleText::mWebkitTextFillColor);
if (frameColor == mSelectionBGColor) { if (frameColor == mSelectionBGColor) {
mSelectionTextColor = LookAndFeel::GetColor( mSelectionTextColor = LookAndFeel::Color(
LookAndFeel::ColorID::TextSelectForegroundCustom); LookAndFeel::ColorID::TextSelectForegroundCustom, mFrame);
} }
} else { } else {
EnsureSufficientContrast(&mSelectionTextColor, &mSelectionBGColor); EnsureSufficientContrast(&mSelectionTextColor, &mSelectionBGColor);
@ -4207,12 +4206,12 @@ void nsTextPaintStyle::InitSelectionStyle(int32_t aIndex) {
if (styleIDs->mForeground == LookAndFeel::ColorID::End) { if (styleIDs->mForeground == LookAndFeel::ColorID::End) {
foreColor = NS_SAME_AS_FOREGROUND_COLOR; foreColor = NS_SAME_AS_FOREGROUND_COLOR;
} else { } else {
foreColor = LookAndFeel::GetColor(styleIDs->mForeground); foreColor = LookAndFeel::Color(styleIDs->mForeground, mFrame);
} }
if (styleIDs->mBackground == LookAndFeel::ColorID::End) { if (styleIDs->mBackground == LookAndFeel::ColorID::End) {
backColor = NS_TRANSPARENT; backColor = NS_TRANSPARENT;
} else { } else {
backColor = LookAndFeel::GetColor(styleIDs->mBackground); backColor = LookAndFeel::Color(styleIDs->mBackground, mFrame);
} }
// Convert special color to actual color // Convert special color to actual color
@ -4233,8 +4232,7 @@ void nsTextPaintStyle::InitSelectionStyle(int32_t aIndex) {
nscolor lineColor; nscolor lineColor;
float relativeSize; float relativeSize;
uint8_t lineStyle; uint8_t lineStyle;
GetSelectionUnderline(mPresContext, aIndex, &lineColor, &relativeSize, GetSelectionUnderline(mFrame, aIndex, &lineColor, &relativeSize, &lineStyle);
&lineStyle);
if (mResolveColors) if (mResolveColors)
lineColor = GetResolvedForeColor(lineColor, foreColor, backColor); lineColor = GetResolvedForeColor(lineColor, foreColor, backColor);
@ -4248,19 +4246,18 @@ void nsTextPaintStyle::InitSelectionStyle(int32_t aIndex) {
} }
/* static */ /* static */
bool nsTextPaintStyle::GetSelectionUnderline(nsPresContext* aPresContext, bool nsTextPaintStyle::GetSelectionUnderline(nsIFrame* aFrame, int32_t aIndex,
int32_t aIndex,
nscolor* aLineColor, nscolor* aLineColor,
float* aRelativeSize, float* aRelativeSize,
uint8_t* aStyle) { uint8_t* aStyle) {
NS_ASSERTION(aPresContext, "aPresContext is null"); NS_ASSERTION(aFrame, "aFrame is null");
NS_ASSERTION(aRelativeSize, "aRelativeSize is null"); NS_ASSERTION(aRelativeSize, "aRelativeSize is null");
NS_ASSERTION(aStyle, "aStyle is null"); NS_ASSERTION(aStyle, "aStyle is null");
NS_ASSERTION(aIndex >= 0 && aIndex < 5, "Index out of range"); NS_ASSERTION(aIndex >= 0 && aIndex < 5, "Index out of range");
StyleIDs& styleID = SelectionStyleIDs[aIndex]; StyleIDs& styleID = SelectionStyleIDs[aIndex];
nscolor color = LookAndFeel::GetColor(styleID.mLine); nscolor color = LookAndFeel::Color(styleID.mLine, aFrame);
int32_t style = LookAndFeel::GetInt(styleID.mLineStyle); int32_t style = LookAndFeel::GetInt(styleID.mLineStyle);
if (style > NS_STYLE_TEXT_DECORATION_STYLE_MAX) { if (style > NS_STYLE_TEXT_DECORATION_STYLE_MAX) {
NS_ERROR("Invalid underline style value is specified"); NS_ERROR("Invalid underline style value is specified");
@ -7375,7 +7372,7 @@ bool nsTextFrame::CombineSelectionUnderlineRect(nsPresContext* aPresContext,
sd->mSelectionType); sd->mSelectionType);
if (sd->mSelectionType == SelectionType::eSpellCheck) { if (sd->mSelectionType == SelectionType::eSpellCheck) {
if (!nsTextPaintStyle::GetSelectionUnderline( if (!nsTextPaintStyle::GetSelectionUnderline(
aPresContext, index, nullptr, &relativeSize, &params.style)) { this, index, nullptr, &relativeSize, &params.style)) {
continue; continue;
} }
} else { } else {
@ -7389,8 +7386,7 @@ bool nsTextFrame::CombineSelectionUnderlineRect(nsPresContext* aPresContext,
params.style = ToStyleLineStyle(rangeStyle); params.style = ToStyleLineStyle(rangeStyle);
relativeSize = rangeStyle.mIsBoldLine ? 2.0f : 1.0f; relativeSize = rangeStyle.mIsBoldLine ? 2.0f : 1.0f;
} else if (!nsTextPaintStyle::GetSelectionUnderline( } else if (!nsTextPaintStyle::GetSelectionUnderline(
aPresContext, index, nullptr, &relativeSize, this, index, nullptr, &relativeSize, &params.style)) {
&params.style)) {
continue; continue;
} }
} }

View File

@ -1713,8 +1713,8 @@ void nsDisplayMathMLSelectionRect::Paint(nsDisplayListBuilder* aBuilder,
mFrame->PresContext()->AppUnitsPerDevPixel(), mFrame->PresContext()->AppUnitsPerDevPixel(),
*drawTarget); *drawTarget);
// get color to use for selection from the look&feel object // get color to use for selection from the look&feel object
nscolor bgColor = LookAndFeel::GetColor( nscolor bgColor =
LookAndFeel::ColorID::TextSelectBackground, NS_RGB(0, 0, 0)); LookAndFeel::Color(LookAndFeel::ColorID::TextSelectBackground, mFrame);
drawTarget->FillRect(rect, ColorPattern(ToDeviceColor(bgColor))); drawTarget->FillRect(rect, ColorPattern(ToDeviceColor(bgColor)));
} }
@ -1869,8 +1869,8 @@ void nsMathMLChar::PaintForeground(nsIFrame* aForFrame,
&nsStyleText::mWebkitTextFillColor); &nsStyleText::mWebkitTextFillColor);
if (aIsSelected) { if (aIsSelected) {
// get color to use for selection from the look&feel object // get color to use for selection from the look&feel object
fgColor = LookAndFeel::GetColor(LookAndFeel::ColorID::TextSelectForeground, fgColor = LookAndFeel::Color(LookAndFeel::ColorID::TextSelectForeground,
fgColor); aForFrame, fgColor);
} }
aRenderingContext.SetColor(sRGBColor::FromABGR(fgColor)); aRenderingContext.SetColor(sRGBColor::FromABGR(fgColor));
aRenderingContext.Save(); aRenderingContext.Save();

View File

@ -693,52 +693,10 @@ bool Gecko_IsDocumentBody(const Element* aElement) {
return doc && doc->GetBodyElement() == aElement; return doc && doc->GetBodyElement() == aElement;
} }
static bool ShouldUseStandinsForNativeColorForNonNativeTheme(
const Document& aDoc, LookAndFeel::ColorID aColor) {
using ColorID = LookAndFeel::ColorID;
if (!aDoc.ShouldAvoidNativeTheme()) {
return false;
}
// The native theme doesn't use system colors backgrounds etc, except when in
// high-contrast mode, so spoof some of the colors with stand-ins to prevent
// lack of contrast.
switch (aColor) {
case ColorID::Buttonface:
case ColorID::Buttontext:
case ColorID::MozButtonhoverface:
case ColorID::MozButtonhovertext:
case ColorID::MozGtkButtonactivetext:
case ColorID::MozCombobox:
case ColorID::MozComboboxtext:
case ColorID::Field:
case ColorID::Fieldtext:
case ColorID::Graytext:
return !PreferenceSheet::PrefsFor(aDoc)
.NonNativeThemeShouldUseSystemColors();
default:
break;
}
return false;
}
nscolor Gecko_GetLookAndFeelSystemColor(int32_t aId, const Document* aDoc) { nscolor Gecko_GetLookAndFeelSystemColor(int32_t aId, const Document* aDoc) {
auto colorId = static_cast<LookAndFeel::ColorID>(aId); auto colorId = static_cast<LookAndFeel::ColorID>(aId);
const bool useStandinsForNativeColors =
ShouldUseStandinsForNativeColorForNonNativeTheme(*aDoc, colorId) ||
(nsContentUtils::UseStandinsForNativeColors() &&
!nsContentUtils::IsChromeDoc(aDoc));
AutoWriteLock guard(*sServoFFILock); AutoWriteLock guard(*sServoFFILock);
nscolor result = 0; return LookAndFeel::Color(colorId, *aDoc);
LookAndFeel::GetColor(colorId, useStandinsForNativeColors, &result);
return result;
} }
bool Gecko_MatchLang(const Element* aElement, nsAtom* aOverrideLang, bool Gecko_MatchLang(const Element* aElement, nsAtom* aOverrideLang,

View File

@ -14,6 +14,7 @@
#include "mozilla/StaticPrefs_devtools.h" #include "mozilla/StaticPrefs_devtools.h"
#include "mozilla/Telemetry.h" #include "mozilla/Telemetry.h"
#include "mozilla/LookAndFeel.h" #include "mozilla/LookAndFeel.h"
#include "mozilla/ServoBindings.h"
#include "mozilla/dom/Document.h" #include "mozilla/dom/Document.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
@ -88,30 +89,28 @@ void PreferenceSheet::Prefs::Load(bool aIsChrome) {
mFocusRingStyle = StaticPrefs::browser_display_focus_ring_style(); mFocusRingStyle = StaticPrefs::browser_display_focus_ring_style();
mFocusRingOnAnything = StaticPrefs::browser_display_focus_ring_on_anything(); mFocusRingOnAnything = StaticPrefs::browser_display_focus_ring_on_anything();
const bool usePrefColors = !aIsChrome && !mUseAccessibilityTheme && const bool useStandins = nsContentUtils::UseStandinsForNativeColors();
const bool usePrefColors = !useStandins && !aIsChrome && !mUseAccessibilityTheme &&
!StaticPrefs::browser_display_use_system_colors(); !StaticPrefs::browser_display_use_system_colors();
if (usePrefColors) {
if (nsContentUtils::UseStandinsForNativeColors()) {
mDefaultColor = LookAndFeel::GetColorUsingStandins(
LookAndFeel::ColorID::Windowtext, mDefaultColor);
mDefaultBackgroundColor = LookAndFeel::GetColorUsingStandins(
LookAndFeel::ColorID::Window, mDefaultBackgroundColor);
mLinkColor = LookAndFeel::GetColorUsingStandins(
LookAndFeel::ColorID::MozNativehyperlinktext, mLinkColor);
} else if (usePrefColors) {
GetColor("browser.display.background_color", mDefaultBackgroundColor); GetColor("browser.display.background_color", mDefaultBackgroundColor);
GetColor("browser.display.foreground_color", mDefaultColor); GetColor("browser.display.foreground_color", mDefaultColor);
GetColor("browser.anchor_color", mLinkColor); GetColor("browser.anchor_color", mLinkColor);
} else { } else {
mDefaultColor = LookAndFeel::GetColor( using ColorID = LookAndFeel::ColorID;
LookAndFeel::ColorID::WindowForeground, mDefaultColor); const auto standins = LookAndFeel::UseStandins(useStandins);
mDefaultBackgroundColor = LookAndFeel::GetColor( // TODO(emilio): In the future we probably want to keep both sets of colors
LookAndFeel::ColorID::WindowBackground, mDefaultBackgroundColor); // around or something.
mLinkColor = LookAndFeel::GetColor( const auto scheme = LookAndFeel::ColorScheme::Light;
LookAndFeel::ColorID::MozNativehyperlinktext, mLinkColor); mDefaultColor = LookAndFeel::Color(
ColorID::WindowForeground, scheme, standins, mDefaultColor);
mDefaultBackgroundColor = LookAndFeel::Color(
ColorID::WindowBackground, scheme, standins, mDefaultBackgroundColor);
mLinkColor = LookAndFeel::Color(
ColorID::MozNativehyperlinktext, scheme, standins, mLinkColor);
} }
if (mUseAccessibilityTheme && !nsContentUtils::UseStandinsForNativeColors()) { if (mUseAccessibilityTheme && !useStandins) {
mActiveLinkColor = mLinkColor; mActiveLinkColor = mLinkColor;
// Visited link color is produced by preserving the foreground's green // Visited link color is produced by preserving the foreground's green
// and averaging the foreground and background for the red and blue. // and averaging the foreground and background for the red and blue.

View File

@ -294,8 +294,8 @@ void nsTableCellFrame::DecorateForSelection(DrawTarget* aDrawTarget,
if (displaySelection == nsISelectionController::SELECTION_DISABLED) { if (displaySelection == nsISelectionController::SELECTION_DISABLED) {
bordercolor = NS_RGB(176, 176, 176); // disabled color bordercolor = NS_RGB(176, 176, 176); // disabled color
} else { } else {
bordercolor = bordercolor = LookAndFeel::Color(
LookAndFeel::GetColor(LookAndFeel::ColorID::TextSelectBackground); LookAndFeel::ColorID::TextSelectBackground, this);
} }
nscoord threePx = nsPresContext::CSSPixelsToAppUnits(3); nscoord threePx = nsPresContext::CSSPixelsToAppUnits(3);
if ((mRect.width > threePx) && (mRect.height > threePx)) { if ((mRect.width > threePx) && (mRect.height > threePx)) {

View File

@ -55,7 +55,6 @@ using namespace mozilla;
using namespace mozilla::gfx; using namespace mozilla::gfx;
using mozilla::dom::Document; using mozilla::dom::Document;
using mozilla::dom::Event; using mozilla::dom::Event;
using mozilla::layers::APZCCallbackHelper;
using mozilla::layers::AsyncDragMetrics; using mozilla::layers::AsyncDragMetrics;
using mozilla::layers::InputAPZContext; using mozilla::layers::InputAPZContext;
using mozilla::layers::ScrollbarData; using mozilla::layers::ScrollbarData;
@ -293,7 +292,7 @@ void nsDisplaySliderMarks::PaintMarks(nsDisplayListBuilder* aDisplayListBuilder,
// Use the text highlight color for the tick marks. // Use the text highlight color for the tick marks.
nscolor highlightColor = nscolor highlightColor =
LookAndFeel::GetColor(LookAndFeel::ColorID::TextHighlightBackground); LookAndFeel::Color(LookAndFeel::ColorID::TextHighlightBackground, mFrame);
DeviceColor fillColor = ToDeviceColor(highlightColor); DeviceColor fillColor = ToDeviceColor(highlightColor);
fillColor.a = 0.3; // make the mark mostly transparent fillColor.a = 0.3; // make the mark mostly transparent

View File

@ -128,8 +128,11 @@ already_AddRefed<nsWebBrowser> nsWebBrowser::Create(
MOZ_ASSERT(browser->mDocShell == docShell); MOZ_ASSERT(browser->mDocShell == docShell);
// get the system default window background colour // get the system default window background colour
LookAndFeel::GetColor(LookAndFeel::ColorID::WindowBackground, //
&browser->mBackgroundColor); // TODO(emilio): Can we get the color-scheme from somewhere here?
browser->mBackgroundColor = LookAndFeel::Color(
LookAndFeel::ColorID::WindowBackground, LookAndFeel::ColorScheme::Light,
LookAndFeel::UseStandins::No);
// HACK ALERT - this registration registers the nsDocShellTreeOwner as a // HACK ALERT - this registration registers the nsDocShellTreeOwner as a
// nsIWebBrowserListener so it can setup its MouseListener in one of the // nsIWebBrowserListener so it can setup its MouseListener in one of the

View File

@ -14,12 +14,19 @@
#include "nsColor.h" #include "nsColor.h"
#include "nsString.h" #include "nsString.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "mozilla/Maybe.h"
#include "mozilla/widget/ThemeChangeKind.h" #include "mozilla/widget/ThemeChangeKind.h"
struct gfxFontStyle; struct gfxFontStyle;
class nsIFrame;
namespace mozilla { namespace mozilla {
namespace dom {
class Document;
}
namespace widget { namespace widget {
class FullLookAndFeel; class FullLookAndFeel;
} // namespace widget } // namespace widget
@ -422,31 +429,55 @@ class LookAndFeel {
using FontID = mozilla::StyleSystemFont; using FontID = mozilla::StyleSystemFont;
/** // Whether we should use a light or dark appearance.
* GetColor() return a native color value (might be overwritten by prefs) for //
* aID. Some platforms don't return an error even if the index doesn't // This is currently ignored (but won't be for long).
* match any system colors. And also some platforms may initialize the enum class ColorScheme : uint8_t { Light, Dark };
* return value even when it returns an error. Therefore, if you want to
* use a color for the default value, you should use the other GetColor()
* which returns nscolor directly.
*
* NOTE:
* ColorID::TextSelectForeground might return NS_DONT_CHANGE_COLOR.
* ColorID::IME* might return NS_TRANSPARENT, NS_SAME_AS_FOREGROUND_COLOR or
* NS_40PERCENT_FOREGROUND_COLOR.
* These values have particular meaning. Then, they are not an actual
* color value.
*/
static nsresult GetColor(ColorID aID, nscolor* aResult);
/** // Whether standins for native colors should be used (that is, colors faked,
* This variant of GetColor() takes an extra Boolean parameter that allows // taken from win7, mostly). This forces light appearance, effectively.
* the caller to ask that hard-coded color values be substituted for enum class UseStandins : bool { No, Yes };
* native colors (used when it is desireable to hide system colors to
* avoid system fingerprinting). // Returns a native color value (might be overwritten by prefs) for a given
*/ // color id.
static nsresult GetColor(ColorID aID, bool aUseStandinsForNativeColors, //
nscolor* aResult); // NOTE:
// ColorID::TextSelectForeground might return NS_DONT_CHANGE_COLOR.
// ColorID::IME* might return NS_TRANSPARENT, NS_SAME_AS_FOREGROUND_COLOR or
// NS_40PERCENT_FOREGROUND_COLOR.
// These values have particular meaning. Then, they are not an actual
// color value.
static Maybe<nscolor> GetColor(ColorID, ColorScheme, UseStandins);
// Gets the color with appropriate defaults for UseStandins, ColorScheme etc
// for a given document.
static Maybe<nscolor> GetColor(ColorID, const dom::Document&);
// Gets the color with appropriate defaults for UseStandins, ColorScheme etc
// for a given frame.
//
// TODO(emilio): This right now just peeks the document out of the frame's
// pres context, but in the future we actually want to look at the style to
// get the right color scheme, to implement the color-scheme property.
static Maybe<nscolor> GetColor(ColorID, const nsIFrame*);
// Versions of the above which returns the color if found, or a default (which
// defaults to opaque black) otherwise.
static nscolor Color(ColorID aId, ColorScheme aScheme,
UseStandins aUseStandins,
nscolor aDefault = NS_RGB(0, 0, 0)) {
return GetColor(aId, aScheme, aUseStandins).valueOr(aDefault);
}
static nscolor Color(ColorID aId, const dom::Document& aDoc,
nscolor aDefault = NS_RGB(0, 0, 0)) {
return GetColor(aId, aDoc).valueOr(aDefault);
}
static nscolor Color(ColorID aId, nsIFrame* aFrame,
nscolor aDefault = NS_RGB(0, 0, 0)) {
return GetColor(aId, aFrame).valueOr(aDefault);
}
/** /**
* GetInt() and GetFloat() return a int or float value for aID. The result * GetInt() and GetFloat() return a int or float value for aID. The result
@ -456,28 +487,9 @@ class LookAndFeel {
* use a value for the default value, you should use the other method which * use a value for the default value, you should use the other method which
* returns int or float directly. * returns int or float directly.
*/ */
static nsresult GetInt(IntID aID, int32_t* aResult); static nsresult GetInt(IntID, int32_t* aResult);
static nsresult GetFloat(FloatID aID, float* aResult); static nsresult GetFloat(FloatID aID, float* aResult);
static nscolor GetColor(ColorID aID, nscolor aDefault = NS_RGB(0, 0, 0)) {
nscolor result = NS_RGB(0, 0, 0);
if (NS_FAILED(GetColor(aID, &result))) {
return aDefault;
}
return result;
}
static nscolor GetColorUsingStandins(ColorID aID,
nscolor aDefault = NS_RGB(0, 0, 0)) {
nscolor result = NS_RGB(0, 0, 0);
if (NS_FAILED(GetColor(aID,
true, // aUseStandinsForNativeColors
&result))) {
return aDefault;
}
return result;
}
static int32_t GetInt(IntID aID, int32_t aDefault = 0) { static int32_t GetInt(IntID aID, int32_t aDefault = 0) {
int32_t result; int32_t result;
if (NS_FAILED(GetInt(aID, &result))) { if (NS_FAILED(GetInt(aID, &result))) {

View File

@ -33,7 +33,6 @@ class nsLookAndFeel final : public nsXPLookAndFeel {
nscolor mColorTextSelectBackground; nscolor mColorTextSelectBackground;
nscolor mColorTextSelectBackgroundDisabled; nscolor mColorTextSelectBackgroundDisabled;
nscolor mColorHighlight; nscolor mColorHighlight;
nscolor mColorTextSelectForeground;
nscolor mColorAlternateSelectedControlText; nscolor mColorAlternateSelectedControlText;
nscolor mColorControlText; nscolor mColorControlText;
nscolor mColorText; nscolor mColorText;

View File

@ -30,7 +30,6 @@ nsLookAndFeel::nsLookAndFeel()
mColorTextSelectBackground(0), mColorTextSelectBackground(0),
mColorTextSelectBackgroundDisabled(0), mColorTextSelectBackgroundDisabled(0),
mColorHighlight(0), mColorHighlight(0),
mColorTextSelectForeground(0),
mColorAlternateSelectedControlText(0), mColorAlternateSelectedControlText(0),
mColorControlText(0), mColorControlText(0),
mColorText(0), mColorText(0),
@ -167,7 +166,7 @@ nsresult nsLookAndFeel::NativeGetColor(ColorID aID, nscolor& aColor) {
aColor = mColorHighlight; aColor = mColorHighlight;
break; break;
case ColorID::TextSelectForeground: case ColorID::TextSelectForeground:
aColor = mColorTextSelectForeground; aColor = NS_DONT_CHANGE_COLOR;
break; break;
case ColorID::Highlighttext: // CSS2 color case ColorID::Highlighttext: // CSS2 color
case ColorID::MozAccentColorForeground: case ColorID::MozAccentColorForeground:
@ -602,8 +601,6 @@ void nsLookAndFeel::EnsureInit() {
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK NS_OBJC_BEGIN_TRY_IGNORE_BLOCK
nscolor color;
bool appearanceIsDark = false; bool appearanceIsDark = false;
if (@available(macOS 10.14, *)) { if (@available(macOS 10.14, *)) {
@ -627,13 +624,6 @@ void nsLookAndFeel::EnsureInit() {
mColorHighlight = GetColorFromNSColor([NSColor alternateSelectedControlColor]); mColorHighlight = GetColorFromNSColor([NSColor alternateSelectedControlColor]);
GetColor(ColorID::TextSelectBackground, color);
if (color == 0x000000) {
mColorTextSelectForeground = NS_RGB(0xff, 0xff, 0xff);
} else {
mColorTextSelectForeground = NS_DONT_CHANGE_COLOR;
}
mColorAlternateSelectedControlText = mColorAlternateSelectedControlText =
GetColorFromNSColor([NSColor alternateSelectedControlTextColor]); GetColorFromNSColor([NSColor alternateSelectedControlTextColor]);

View File

@ -211,6 +211,11 @@ const static bool kUseSimpleContextDefault = false;
* to refer selection colors of GtkTextView via our widget. * to refer selection colors of GtkTextView via our widget.
******************************************************************************/ ******************************************************************************/
static Maybe<nscolor> GetSystemColor(LookAndFeel::ColorID aId) {
return LookAndFeel::GetColor(aId, LookAndFeel::ColorScheme::Light,
LookAndFeel::UseStandins::No);
}
class SelectionStyleProvider final { class SelectionStyleProvider final {
public: public:
static SelectionStyleProvider* GetInstance() { static SelectionStyleProvider* GetInstance() {
@ -254,31 +259,27 @@ class SelectionStyleProvider final {
// colors can be controlled by a ":selected" CSS rule. // colors can be controlled by a ":selected" CSS rule.
nsAutoCString style(":selected{"); nsAutoCString style(":selected{");
// FYI: LookAndFeel always returns selection colors of GtkTextView. // FYI: LookAndFeel always returns selection colors of GtkTextView.
nscolor selectionForegroundColor; if (auto selectionForegroundColor =
if (NS_SUCCEEDED( GetSystemColor(LookAndFeel::ColorID::TextSelectForeground)) {
LookAndFeel::GetColor(LookAndFeel::ColorID::TextSelectForeground,
&selectionForegroundColor))) {
double alpha = double alpha =
static_cast<double>(NS_GET_A(selectionForegroundColor)) / 0xFF; static_cast<double>(NS_GET_A(*selectionForegroundColor)) / 0xFF;
style.AppendPrintf("color:rgba(%u,%u,%u,", style.AppendPrintf("color:rgba(%u,%u,%u,",
NS_GET_R(selectionForegroundColor), NS_GET_R(*selectionForegroundColor),
NS_GET_G(selectionForegroundColor), NS_GET_G(*selectionForegroundColor),
NS_GET_B(selectionForegroundColor)); NS_GET_B(*selectionForegroundColor));
// We can't use AppendPrintf here, because it does locale-specific // We can't use AppendPrintf here, because it does locale-specific
// formatting of floating-point values. // formatting of floating-point values.
style.AppendFloat(alpha); style.AppendFloat(alpha);
style.AppendPrintf(");"); style.AppendPrintf(");");
} }
nscolor selectionBackgroundColor; if (auto selectionBackgroundColor =
if (NS_SUCCEEDED( GetSystemColor(LookAndFeel::ColorID::TextSelectBackground)) {
LookAndFeel::GetColor(LookAndFeel::ColorID::TextSelectBackground,
&selectionBackgroundColor))) {
double alpha = double alpha =
static_cast<double>(NS_GET_A(selectionBackgroundColor)) / 0xFF; static_cast<double>(NS_GET_A(*selectionBackgroundColor)) / 0xFF;
style.AppendPrintf("background-color:rgba(%u,%u,%u,", style.AppendPrintf("background-color:rgba(%u,%u,%u,",
NS_GET_R(selectionBackgroundColor), NS_GET_R(*selectionBackgroundColor),
NS_GET_G(selectionBackgroundColor), NS_GET_G(*selectionBackgroundColor),
NS_GET_B(selectionBackgroundColor)); NS_GET_B(*selectionBackgroundColor));
style.AppendFloat(alpha); style.AppendFloat(alpha);
style.AppendPrintf(");"); style.AppendPrintf(");");
} }

View File

@ -1223,10 +1223,11 @@ bool nsNativeThemeGTK::CreateWebRenderCommandsForWidget(
switch (aAppearance) { switch (aAppearance) {
case StyleAppearance::Window: case StyleAppearance::Window:
case StyleAppearance::Dialog: case StyleAppearance::Dialog:
aBuilder.PushRect( aBuilder.PushRect(bounds, bounds, true,
bounds, bounds, true, wr::ToColorF(ToDeviceColor(LookAndFeel::Color(
wr::ToColorF(ToDeviceColor(LookAndFeel::GetColor( LookAndFeel::ColorID::WindowBackground,
LookAndFeel::ColorID::WindowBackground, NS_RGBA(0, 0, 0, 0))))); LookAndFeel::ColorScheme::Light,
LookAndFeel::UseStandins::No, NS_TRANSPARENT))));
return true; return true;
default: default:

View File

@ -85,11 +85,7 @@ nsresult HeadlessLookAndFeel::NativeGetColor(ColorID aID, nscolor& aColor) {
aColor = NS_RGB(0xaa, 0xaa, 0xaa); aColor = NS_RGB(0xaa, 0xaa, 0xaa);
break; break;
case ColorID::TextSelectForeground: case ColorID::TextSelectForeground:
GetColor(ColorID::TextSelectBackground, aColor); aColor = NS_DONT_CHANGE_COLOR;
if (aColor == 0x000000)
aColor = NS_RGB(0xff, 0xff, 0xff);
else
aColor = NS_DONT_CHANGE_COLOR;
break; break;
case ColorID::Widget3DHighlight: case ColorID::Widget3DHighlight:
aColor = NS_RGB(0xa0, 0xa0, 0xa0); aColor = NS_RGB(0xa0, 0xa0, 0xa0);

View File

@ -72,9 +72,12 @@ static LayoutDeviceIntCoord SnapBorderWidth(
static nscolor ThemedAccentColor(bool aBackground) { static nscolor ThemedAccentColor(bool aBackground) {
MOZ_ASSERT(StaticPrefs::widget_non_native_theme_use_theme_accent()); MOZ_ASSERT(StaticPrefs::widget_non_native_theme_use_theme_accent());
nscolor color = LookAndFeel::GetColor( // TODO(emilio): In the future we should probably add dark-color-scheme
// support for non-native form controls.
nscolor color = LookAndFeel::Color(
aBackground ? LookAndFeel::ColorID::MozAccentColor aBackground ? LookAndFeel::ColorID::MozAccentColor
: LookAndFeel::ColorID::MozAccentColorForeground); : LookAndFeel::ColorID::MozAccentColorForeground,
LookAndFeel::ColorScheme::Light, LookAndFeel::UseStandins::No);
if (NS_GET_A(color) != 0xff) { if (NS_GET_A(color) != 0xff) {
// Blend with white, ensuring the color is opaque to avoid surprises if we // Blend with white, ensuring the color is opaque to avoid surprises if we
// overdraw. // overdraw.
@ -196,7 +199,20 @@ static bool IsScrollbarWidthThin(nsIFrame* aFrame) {
} }
static sRGBColor SystemColor(StyleSystemColor aColor) { static sRGBColor SystemColor(StyleSystemColor aColor) {
return sRGBColor::FromABGR(LookAndFeel::GetColor(aColor)); // TODO(emilio): We could not hardcode light appearance here with a bit of
// work, but doesn't matter for now.
return sRGBColor::FromABGR(LookAndFeel::Color(
aColor, LookAndFeel::ColorScheme::Light, LookAndFeel::UseStandins::No));
}
template <typename Compute>
static sRGBColor SystemColorOrElse(StyleSystemColor aColor, Compute aCompute) {
if (auto color =
LookAndFeel::GetColor(aColor, LookAndFeel::ColorScheme::Light,
LookAndFeel::UseStandins::No)) {
return sRGBColor::FromABGR(*color);
}
return aCompute();
} }
static std::pair<sRGBColor, sRGBColor> SystemColorPair( static std::pair<sRGBColor, sRGBColor> SystemColorPair(
@ -539,17 +555,16 @@ sRGBColor nsNativeBasicTheme::ComputeScrollbarColor(
if (ShouldUseDarkScrollbar(aFrame, aStyle)) { if (ShouldUseDarkScrollbar(aFrame, aStyle)) {
return sRGBColor::FromU8(20, 20, 25, 77); return sRGBColor::FromU8(20, 20, 25, 77);
} }
nscolor color;
if (ui->mScrollbarColor.IsColors()) { if (ui->mScrollbarColor.IsColors()) {
color = ui->mScrollbarColor.AsColors().track.CalcColor(aStyle); return sRGBColor::FromABGR(
} else if (aDocumentState.HasAllStates(NS_DOCUMENT_STATE_WINDOW_INACTIVE)) { ui->mScrollbarColor.AsColors().track.CalcColor(aStyle));
color = LookAndFeel::GetColor(LookAndFeel::ColorID::ThemedScrollbarInactive,
sScrollbarColor.ToABGR());
} else {
color = LookAndFeel::GetColor(LookAndFeel::ColorID::ThemedScrollbar,
sScrollbarColor.ToABGR());
} }
return gfx::sRGBColor::FromABGR(color); if (aDocumentState.HasAllStates(NS_DOCUMENT_STATE_WINDOW_INACTIVE)) {
return SystemColorOrElse(StyleSystemColor::ThemedScrollbarInactive,
[] { return sScrollbarColor; });
}
return SystemColorOrElse(StyleSystemColor::ThemedScrollbar,
[] { return sScrollbarColor; });
} }
nscolor nsNativeBasicTheme::AdjustUnthemedScrollbarThumbColor( nscolor nsNativeBasicTheme::AdjustUnthemedScrollbarThumbColor(
@ -668,7 +683,6 @@ sRGBColor nsNativeBasicTheme::ComputeScrollbarThumbColor(
} }
const nsStyleUI* ui = aStyle.StyleUI(); const nsStyleUI* ui = aStyle.StyleUI();
nscolor color;
if (ui->mScrollbarColor.IsColors()) { if (ui->mScrollbarColor.IsColors()) {
return sRGBColor::FromABGR(AdjustUnthemedScrollbarThumbColor( return sRGBColor::FromABGR(AdjustUnthemedScrollbarThumbColor(
ui->mScrollbarColor.AsColors().thumb.CalcColor(aStyle), aElementState)); ui->mScrollbarColor.AsColors().thumb.CalcColor(aStyle), aElementState));
@ -696,11 +710,10 @@ sRGBColor nsNativeBasicTheme::ComputeScrollbarThumbColor(
return StyleSystemColor::ThemedScrollbarThumb; return StyleSystemColor::ThemedScrollbarThumb;
}(); }();
if (NS_FAILED(LookAndFeel::GetColor(systemColor, &color))) { return SystemColorOrElse(systemColor, [&] {
color = AdjustUnthemedScrollbarThumbColor(sScrollbarThumbColor.ToABGR(), return sRGBColor::FromABGR(AdjustUnthemedScrollbarThumbColor(
aElementState); sScrollbarThumbColor.ToABGR(), aElementState));
} });
return gfx::sRGBColor::FromABGR(color);
} }
std::pair<sRGBColor, sRGBColor> std::pair<sRGBColor, sRGBColor>

View File

@ -14,6 +14,7 @@
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsCRT.h" #include "nsCRT.h"
#include "nsFont.h" #include "nsFont.h"
#include "nsIFrame.h"
#include "nsIXULRuntime.h" #include "nsIXULRuntime.h"
#include "nsNativeBasicTheme.h" #include "nsNativeBasicTheme.h"
#include "mozilla/dom/ContentChild.h" #include "mozilla/dom/ContentChild.h"
@ -24,6 +25,8 @@
#include "mozilla/StaticPrefs_findbar.h" #include "mozilla/StaticPrefs_findbar.h"
#include "mozilla/StaticPrefs_ui.h" #include "mozilla/StaticPrefs_ui.h"
#include "mozilla/StaticPrefs_widget.h" #include "mozilla/StaticPrefs_widget.h"
#include "mozilla/dom/Document.h"
#include "mozilla/PreferenceSheet.h"
#include "mozilla/gfx/2D.h" #include "mozilla/gfx/2D.h"
#include "mozilla/widget/WidgetMessageUtils.h" #include "mozilla/widget/WidgetMessageUtils.h"
#include "mozilla/Telemetry.h" #include "mozilla/Telemetry.h"
@ -62,7 +65,7 @@ struct nsLookAndFeelFloatPref {
template <typename Index, typename Value, Index kEnd> template <typename Index, typename Value, Index kEnd>
class EnumeratedCache { class EnumeratedCache {
static constexpr uint32_t ChunkFor(Index aIndex) { static constexpr uint32_t ChunkFor(Index aIndex) {
return uint32_t(aIndex) >> 5; // >> 5 is the same as / 32. return uint32_t(aIndex) >> 5; // >> 5 is the same as / 32.
} }
static constexpr uint32_t BitFor(Index aIndex) { static constexpr uint32_t BitFor(Index aIndex) {
return 1u << (uint32_t(aIndex) & 31); return 1u << (uint32_t(aIndex) & 31);
@ -1047,15 +1050,69 @@ void LookAndFeel::NotifyChangedAllWindows(widget::ThemeChangeKind aKind) {
} }
} }
// static static bool ShouldUseStandinsForNativeColorForNonNativeTheme(
nsresult LookAndFeel::GetColor(ColorID aID, nscolor* aResult) { const dom::Document& aDoc, LookAndFeel::ColorID aColor) {
return nsLookAndFeel::GetInstance()->GetColorValue(aID, false, *aResult); using ColorID = LookAndFeel::ColorID;
if (!aDoc.ShouldAvoidNativeTheme()) {
return false;
}
// The native theme doesn't use system colors backgrounds etc, except when in
// high-contrast mode, so spoof some of the colors with stand-ins to prevent
// lack of contrast.
switch (aColor) {
case ColorID::Buttonface:
case ColorID::Buttontext:
case ColorID::MozButtonhoverface:
case ColorID::MozButtonhovertext:
case ColorID::MozGtkButtonactivetext:
case ColorID::MozCombobox:
case ColorID::MozComboboxtext:
case ColorID::Field:
case ColorID::Fieldtext:
case ColorID::Graytext:
return !PreferenceSheet::PrefsFor(aDoc)
.NonNativeThemeShouldUseSystemColors();
default:
break;
}
return false;
} }
nsresult LookAndFeel::GetColor(ColorID aID, bool aUseStandinsForNativeColors, static LookAndFeel::ColorScheme ColorSchemeForDocument(const dom::Document&) {
nscolor* aResult) { // TODO(emilio): Actually compute a useful color scheme.
return nsLookAndFeel::GetInstance()->GetColorValue( return LookAndFeel::ColorScheme::Light;
aID, aUseStandinsForNativeColors, *aResult); }
// static
Maybe<nscolor> LookAndFeel::GetColor(ColorID aId, ColorScheme,
UseStandins aUseStandins) {
// TODO(emilio): Actually use ColorScheme.
nscolor result;
nsresult rv = nsLookAndFeel::GetInstance()->GetColorValue(
aId, bool(aUseStandins), result);
if (NS_FAILED(rv)) {
return Nothing();
}
return Some(result);
}
Maybe<nscolor> LookAndFeel::GetColor(ColorID aId, const dom::Document& aDoc) {
const bool useStandins =
ShouldUseStandinsForNativeColorForNonNativeTheme(aDoc, aId) ||
(nsContentUtils::UseStandinsForNativeColors() &&
!nsContentUtils::IsChromeDoc(&aDoc));
return GetColor(aId, ColorSchemeForDocument(aDoc), UseStandins(useStandins));
}
Maybe<nscolor> LookAndFeel::GetColor(ColorID aId, const nsIFrame* aFrame) {
return GetColor(aId, *aFrame->PresContext()->Document());
} }
// static // static