Bug 1916589 - Move forced-colors computation to nsPresContext. r=nchevobbe

Untested, but something like this is what I meant above.

Differential Revision: https://phabricator.services.mozilla.com/D221773
This commit is contained in:
Emilio Cobos Álvarez 2024-09-17 10:17:56 +00:00
parent 13b898da0f
commit a59875874c
6 changed files with 57 additions and 28 deletions

View File

@ -297,7 +297,8 @@ nsPresContext::nsPresContext(dom::Document* aDocument, nsPresContextType aType)
#ifdef DEBUG
mInitialized(false),
#endif
mOverriddenOrEmbedderColorScheme(dom::PrefersColorSchemeOverride::None) {
mOverriddenOrEmbedderColorScheme(dom::PrefersColorSchemeOverride::None),
mForcedColors(StyleForcedColors::None) {
#ifdef DEBUG
PodZero(&mLayoutPhaseCount);
#endif
@ -328,6 +329,7 @@ nsPresContext::nsPresContext(dom::Document* aDocument, nsPresContextType aType)
}
UpdateFontVisibility();
UpdateForcedColors(/* aNotify = */ false);
}
static const char* gExactCallbackPrefs[] = {
@ -617,6 +619,7 @@ void nsPresContext::PreferenceChanged(const char* aPrefName) {
if (PreferenceSheet::AffectedByPref(prefName)) {
restyleHint |= RestyleHint::RestyleSubtree();
PreferenceSheet::Refresh();
UpdateForcedColors();
}
// Same, this just frees a bunch of memory.
@ -736,6 +739,46 @@ nsresult nsPresContext::Init(nsDeviceContext* aDeviceContext) {
return NS_OK;
}
void nsPresContext::UpdateForcedColors(bool aNotify) {
auto old = mForcedColors;
mForcedColors = [&] {
if (Document()->IsBeingUsedAsImage()) {
return StyleForcedColors::None;
}
// TODO: Handle BrowsingContext override.
const auto& prefs = PrefSheetPrefs();
if (!prefs.mUseDocumentColors) {
return StyleForcedColors::Active;
}
// On Windows, having a high contrast theme also means that the OS is
// requesting the colors to be forced. This is mostly convenience for the
// front-end, which wants to reuse the forced-colors styles for chrome in
// this case as well, and it's a lot more convenient to use
// `(forced-colors)` than `(forced-colors) or ((-moz-platform: windows) and
// (prefers-contrast))`.
//
// TODO(emilio): We might want to factor in here the lwtheme attribute in
// the root element and so on.
#ifdef XP_WINDOWS
if (prefs.mUseAccessibilityTheme && prefs.mIsChrome) {
return StyleForcedColors::Requested;
}
#endif
return StyleForcedColors::None;
}();
if (aNotify && mForcedColors != old) {
MediaFeatureValuesChanged(
MediaFeatureChange::ForPreferredColorSchemeOrForcedColorsChange(),
MediaFeatureChangePropagation::JustThisDocument);
}
}
bool nsPresContext::ForcingColors() const {
return mForcedColors == StyleForcedColors::Active;
}
bool nsPresContext::UpdateFontVisibility() {
FontVisibility oldValue = mFontVisibility;
@ -924,7 +967,7 @@ void nsPresContext::SetColorSchemeOverride(
if (mDocument->PreferredColorScheme() != oldScheme) {
MediaFeatureValuesChanged(
MediaFeatureChange::ForPreferredColorSchemeChange(),
MediaFeatureChange::ForPreferredColorSchemeOrForcedColorsChange(),
MediaFeatureChangePropagation::JustThisDocument);
}
}
@ -963,6 +1006,8 @@ void nsPresContext::RecomputeBrowsingContextDependentData() {
return browsingContext->GetEmbedderColorSchemes().mPreferred;
}());
UpdateForcedColors();
SetInRDMPane(top->GetInRDMPane());
if (doc == mDocument) {
@ -1845,6 +1890,7 @@ void nsPresContext::ThemeChangedInternal() {
LookAndFeel::HandleGlobalThemeChange();
// Full zoom might have changed as a result of the text scale factor.
// Forced colors might also have changed.
RecomputeBrowsingContextDependentData();
// Changes to system metrics and other look and feel values can change media
@ -1949,7 +1995,7 @@ void nsPresContext::EmulateMedium(nsAtom* aMediaType) {
MediaFeatureChange change(MediaFeatureChangeReason::MediumChange);
if (oldScheme != mDocument->PreferredColorScheme()) {
change |= MediaFeatureChange::ForPreferredColorSchemeChange();
change |= MediaFeatureChange::ForPreferredColorSchemeOrForcedColorsChange();
}
MediaFeatureValuesChanged(change,
MediaFeatureChangePropagation::JustThisDocument);

View File

@ -85,6 +85,7 @@ class TimelineManager;
struct MediaFeatureChange;
enum class MediaFeatureChangePropagation : uint8_t;
enum class ColorScheme : uint8_t;
enum class StyleForcedColors : uint8_t;
namespace layers {
class ContainerLayer;
class LayerManager;
@ -377,10 +378,7 @@ class nsPresContext : public nsISupports, public mozilla::SupportsWeakPtr {
return mozilla::PreferenceSheet::PrefsFor(*mDocument);
}
bool ForcingColors() const {
return mozilla::PreferenceSheet::MayForceColors() &&
!PrefSheetPrefs().mUseDocumentColors;
}
bool ForcingColors() const;
mozilla::ColorScheme DefaultBackgroundColorScheme() const;
nscolor DefaultBackgroundColor() const;
@ -560,6 +558,7 @@ class nsPresContext : public nsISupports, public mozilla::SupportsWeakPtr {
void SetOverrideDPPX(float);
void SetInRDMPane(bool aInRDMPane);
void UpdateTopInnerSizeForRFP();
void UpdateForcedColors(bool aNotify = true);
public:
float GetFullZoom() { return mFullZoom; }
@ -1402,6 +1401,7 @@ class nsPresContext : public nsISupports, public mozilla::SupportsWeakPtr {
// that breaks bindgen in win32.
FontVisibility mFontVisibility = FontVisibility::Unknown;
mozilla::dom::PrefersColorSchemeOverride mOverriddenOrEmbedderColorScheme;
mozilla::StyleForcedColors mForcedColors;
protected:
virtual ~nsPresContext();

View File

@ -77,7 +77,7 @@ struct MediaFeatureChange {
return *this;
}
static MediaFeatureChange ForPreferredColorSchemeChange() {
static MediaFeatureChange ForPreferredColorSchemeOrForcedColorsChange() {
// We need to restyle because not only media queries have changed, system
// colors may as well via the prefers-color-scheme meta tag / effective
// color-scheme property value.

View File

@ -595,6 +595,7 @@ cbindgen-types = [
{ gecko = "StyleImageRendering", servo = "crate::values::computed::ImageRendering" },
{ gecko = "StylePrintColorAdjust", servo = "crate::values::computed::PrintColorAdjust" },
{ gecko = "StyleForcedColorAdjust", servo = "crate::values::computed::ForcedColorAdjust" },
{ gecko = "StyleForcedColors", servo = "crate::gecko::media_features::ForcedColors" },
{ gecko = "StyleScrollbarGutter", servo = "crate::values::computed::ScrollbarGutter" },
{ gecko = "StyleHyphenateCharacter", servo = "crate::values::computed::HyphenateCharacter" },
{ gecko = "StyleColumnCount", servo = "crate::values::computed::ColumnCount" },

View File

@ -500,26 +500,7 @@ impl Device {
/// Returns whether document colors are enabled.
#[inline]
pub fn forced_colors(&self) -> ForcedColors {
if self.document().mIsBeingUsedAsImage() {
// SVG images never force colors.
return ForcedColors::None;
}
let prefs = self.pref_sheet_prefs();
if !prefs.mUseDocumentColors {
return ForcedColors::Active;
}
// On Windows, having a high contrast theme also means that the OS is requesting the
// colors to be forced. This is mostly convenience for the front-end, which wants to
// reuse the forced-colors styles for chrome in this case as well, and it's a lot
// more convenient to use `(forced-colors)` than
// `(forced-colors) or ((-moz-platform: windows) and (prefers-contrast))`.
//
// TODO(emilio): We might want to factor in here the lwtheme attribute in the root element
// and so on.
if cfg!(target_os = "windows") && prefs.mUseAccessibilityTheme && prefs.mIsChrome {
return ForcedColors::Requested;
}
ForcedColors::None
self.pres_context().map_or(ForcedColors::None, |pc| pc.mForcedColors)
}
/// Computes a system color and returns it as an nscolor.

View File

@ -305,6 +305,7 @@ include = [
"ImageRendering",
"PrintColorAdjust",
"ForcedColorAdjust",
"ForcedColors",
"ScrollbarGutter",
"ScrollDirection",
"HyphenateCharacter",