Bug 1739699 - Use preferred color scheme when forcing colors with system colors (except windows HCM). r=morgan

This causes (among other things) pages to be dark when using regular
windows system colors and forcing colors to "always", which is nice.

Differential Revision: https://phabricator.services.mozilla.com/D131165
This commit is contained in:
Emilio Cobos Álvarez 2021-11-16 22:30:26 +00:00
parent 046281aa8b
commit 2d8ab09b73
11 changed files with 55 additions and 24 deletions

View File

@ -379,6 +379,12 @@ class nsPresContext : public nsISupports, public mozilla::SupportsWeakPtr {
const mozilla::PreferenceSheet::Prefs& PrefSheetPrefs() const {
return mozilla::PreferenceSheet::PrefsFor(*mDocument);
}
bool ForcingColors() const {
return mozilla::PreferenceSheet::MayForceColors() &&
!PrefSheetPrefs().mUseDocumentColors;
}
nscolor DefaultBackgroundColor() const;
nsISupports* GetContainerWeak() const;

View File

@ -7024,8 +7024,7 @@ void nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// (A) the backplate feature is preffed on
// (B) we are not honoring the document colors
if (StaticPrefs::browser_display_permit_backplate() &&
!PresContext()->PrefSheetPrefs().mUseDocumentColors &&
!IsComboboxControlFrame()) {
PresContext()->ForcingColors() && !IsComboboxControlFrame()) {
backplateColor.emplace(GetBackplateColor(this));
}

View File

@ -494,7 +494,7 @@ void nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// conform to their HCM background color when a solid color is rendered,
// and some websites use solid-color images instead of an overwritable
// background color.
if (!PresContext()->PrefSheetPrefs().mUseDocumentColors &&
if (PresContext()->ForcingColors() &&
StaticPrefs::
browser_display_suppress_canvas_background_image_on_forced_colors()) {
return true;

View File

@ -2329,7 +2329,7 @@ already_AddRefed<ComputedStyle> nsIFrame::ComputeSelectionStyle(
// When in high-contrast mode, the style system ends up ignoring the color
// declarations, which means that the ::selection style becomes the inherited
// color, and default background. That's no good.
if (!PresContext()->PrefSheetPrefs().mUseDocumentColors) {
if (PresContext()->ForcingColors()) {
return nullptr;
}
Element* element = FindElementAncestorForMozSelection(GetContent());

View File

@ -87,6 +87,8 @@ test-pref(browser.display.document_color_use,0) == forced-colors-002.html prefer
== forced-colors-001.html prefers-contrast-black-ref.html
test-pref(browser.display.document_color_use,0) != forced-colors-001.html prefers-contrast-black-ref.html
pref(browser.display.use_system_colors,true) pref(browser.display.document_color_use,0) test-pref(layout.css.prefers-color-scheme.content-override,0) != about:blank about:blank
!= system-colors.html system-colors-notref.html
== border-color-transparent.html border-color-transparent-ref.html

View File

@ -89,6 +89,8 @@ struct PreferenceSheet {
return PrefsKindFor(aDocument) == PrefsKind::Chrome;
}
static bool MayForceColors() { return !ContentPrefs().mUseDocumentColors; }
static const Prefs& PrefsFor(const dom::Document& aDocument) {
switch (PrefsKindFor(aDocument)) {
case PrefsKind::Chrome:

View File

@ -1108,7 +1108,7 @@
mirror: always
- name: browser.display.use_system_colors
type: bool
type: RelaxedAtomicBool
#ifdef XP_WIN
value: true
#else

View File

@ -12,7 +12,8 @@ use crate::gecko_bindings::structs;
use crate::media_queries::MediaType;
use crate::properties::ComputedValues;
use crate::string_cache::Atom;
use crate::values::computed::Length;
use crate::values::computed::{Length, ColorScheme};
use crate::values::specified::color::SystemColor;
use crate::values::specified::font::FONT_MEDIUM_PX;
use crate::values::{CustomIdent, KeyframesName};
use app_units::{Au, AU_PER_PX};
@ -315,19 +316,28 @@ impl Device {
self.pref_sheet_prefs().mUseDocumentColors
}
/// Computes a system color and returns it as an nscolor.
pub(crate) fn system_nscolor(&self, system_color: SystemColor, color_scheme: &ColorScheme) -> u32 {
unsafe {
bindings::Gecko_ComputeSystemColor(system_color, self.document(), color_scheme)
}
}
/// Returns the default background color.
///
/// This is only for forced-colors/high-contrast, so looking at light colors
/// is ok.
pub fn default_background_color_for_forced_colors(&self) -> RGBA {
convert_nscolor_to_rgba(self.pref_sheet_prefs().mLightColors.mDefaultBackground)
pub fn default_background_color(&self) -> RGBA {
let normal = ColorScheme::normal();
convert_nscolor_to_rgba(self.system_nscolor(SystemColor::Canvas, &normal))
}
/// Returns the default foreground color.
///
/// See above for looking at light colors only.
pub fn default_color_for_forced_colors(&self) -> RGBA {
convert_nscolor_to_rgba(self.pref_sheet_prefs().mLightColors.mDefault)
pub fn default_color(&self) -> RGBA {
let normal = ColorScheme::normal();
convert_nscolor_to_rgba(self.system_nscolor(SystemColor::Canvastext, &normal))
}
/// Returns the current effective text zoom.

View File

@ -437,7 +437,7 @@ fn tweak_when_ignoring_colors(
// widget background color's rgb channels but not alpha...
let alpha = alpha_channel(color, context);
if alpha != 0 {
let mut color = context.builder.device.default_background_color_for_forced_colors();
let mut color = context.builder.device.default_background_color();
color.alpha = alpha;
declarations_to_apply_unless_overriden
.push(PropertyDeclaration::BackgroundColor(color.into()))
@ -455,7 +455,7 @@ fn tweak_when_ignoring_colors(
// override this with a non-transparent color, then override it with
// the default color. Otherwise just let it inherit through.
if context.builder.get_parent_inherited_text().clone_color().alpha == 0 {
let color = context.builder.device.default_color_for_forced_colors();
let color = context.builder.device.default_color();
declarations_to_apply_unless_overriden.push(PropertyDeclaration::Color(
specified::ColorPropertyValue(color.into()),
))

View File

@ -5,8 +5,6 @@
//! Specified color values.
use super::AllowQuirks;
#[cfg(feature = "gecko")]
use crate::gecko_bindings::structs::nscolor;
use crate::parser::{Parse, ParserContext};
use crate::values::computed::{Color as ComputedColor, Context, ToComputedValue};
use crate::values::generics::color::{GenericCaretColor, GenericColorOrAuto};
@ -440,18 +438,17 @@ impl SystemColor {
#[inline]
fn compute(&self, cx: &Context) -> ComputedColor {
use crate::gecko_bindings::bindings;
use crate::gecko::values::convert_nscolor_to_rgba;
// TODO: We should avoid cloning here most likely, though it's
// cheap-ish.
let style_color_scheme =
cx.style().get_inherited_ui().clone_color_scheme();
let color = unsafe {
bindings::Gecko_ComputeSystemColor(*self, cx.device().document(), &style_color_scheme)
};
let color = cx.device().system_nscolor(*self, &style_color_scheme);
if color == bindings::NS_SAME_AS_FOREGROUND_COLOR {
return ComputedColor::currentcolor();
}
convert_nscolor_to_computedcolor(color)
ComputedColor::rgba(convert_nscolor_to_rgba(color))
}
}
@ -718,12 +715,6 @@ impl Color {
}
}
#[cfg(feature = "gecko")]
fn convert_nscolor_to_computedcolor(color: nscolor) -> ComputedColor {
use crate::gecko::values::convert_nscolor_to_rgba;
ComputedColor::rgba(convert_nscolor_to_rgba(color))
}
impl Color {
/// Converts this Color into a ComputedColor.
///

View File

@ -1121,6 +1121,27 @@ void LookAndFeel::RecomputeColorSchemes() {
ColorScheme LookAndFeel::ColorSchemeForStyle(
const dom::Document& aDoc, const StyleColorSchemeFlags& aFlags) {
if (PreferenceSheet::MayForceColors()) {
auto& prefs = PreferenceSheet::PrefsFor(aDoc);
if (!prefs.mUseDocumentColors) {
// When forcing colors, we can use our preferred color-scheme. Do this
// only if we're using system colors, as dark preference colors are not
// exposed on the UI.
//
// Also, use light if we're using a high-contrast-theme on Windows, since
// Windows overrides the light colors with HCM colors when HCM is active.
#ifdef XP_WIN
if (prefs.mUseAccessibilityTheme) {
return ColorScheme::Light;
}
#endif
if (StaticPrefs::browser_display_use_system_colors()) {
return aDoc.PreferredColorScheme();
}
return ColorScheme::Light;
}
}
StyleColorSchemeFlags style(aFlags);
if (!style) {
style.bits = aDoc.GetColorSchemeBits();