diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index 687e7bc31bdd..7a52f4f58f6b 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -10938,6 +10938,27 @@ value: false mirror: always +# Whether selection colors get passed from the real GTK theme even if +# allow-gtk-dark-theme is false. +- name: widget.content.allow-gtk-dark-theme.selection + type: bool + value: true + mirror: always + +# Whether form control accent colors get passed from the real GTK theme even if +# allow-gtk-dark-theme is false. +- name: widget.content.allow-gtk-dark-theme.accent + type: bool + value: true + mirror: always + +# Whether scrollbars colors get passed from the real GTK theme even if +# allow-gtk-dark-theme is false. +- name: widget.content.allow-gtk-dark-theme.scrollbars + type: bool + value: true + mirror: always + # Whether to use gtk high contrast themes to disable content styling like on # windows high contrast mode. - name: widget.content.gtk-high-contrast.enabled diff --git a/widget/RemoteLookAndFeel.cpp b/widget/RemoteLookAndFeel.cpp index 57bf3fafb3a7..ab5916f0bd16 100644 --- a/widget/RemoteLookAndFeel.cpp +++ b/widget/RemoteLookAndFeel.cpp @@ -154,18 +154,22 @@ static bool AddIDsToMap(nsXPLookAndFeel* aImpl, FullLookAndFeel* aLf, NS_SUCCEEDED(rv) ? Some(theInt) : Nothing{}); } - // The rest of IDs only come from the child content theme. - if (aFromParentTheme) { - return anyFromOtherTheme; - } - for (auto id : MakeEnumeratedRange(ColorID::End)) { + if (aDifferentTheme && aImpl->FromParentTheme(id) != aFromParentTheme) { + anyFromOtherTheme = true; + continue; + } nscolor theColor; nsresult rv = aImpl->NativeGetColor(id, theColor); AddToMap(aLf->tables().colors(), aLf->tables().colorMap(), id, NS_SUCCEEDED(rv) ? Some(theColor) : Nothing{}); } + // The rest of IDs only come from the child content theme. + if (aFromParentTheme) { + return anyFromOtherTheme; + } + for (auto id : MakeEnumeratedRange(FloatID::End)) { float theFloat; nsresult rv = aImpl->NativeGetFloat(id, theFloat); diff --git a/widget/gtk/nsLookAndFeel.cpp b/widget/gtk/nsLookAndFeel.cpp index 3b6ccb8de63b..f5678e9605f3 100644 --- a/widget/gtk/nsLookAndFeel.cpp +++ b/widget/gtk/nsLookAndFeel.cpp @@ -347,11 +347,52 @@ void nsLookAndFeel::DoSetCache(const LookAndFeelCache& aCache) { } } +static bool IsSelectionColorForeground(LookAndFeel::ColorID aID) { + using ColorID = LookAndFeel::ColorID; + switch (aID) { + case ColorID::WidgetSelectForeground: + case ColorID::TextSelectForeground: + case ColorID::IMESelectedRawTextForeground: + case ColorID::IMESelectedConvertedTextForeground: + case ColorID::Highlighttext: + case ColorID::MozHtmlCellhighlighttext: + return true; + default: + return false; + } +} + +static bool IsSelectionColorBackground(LookAndFeel::ColorID aID) { + using ColorID = LookAndFeel::ColorID; + switch (aID) { + case ColorID::WidgetSelectBackground: + case ColorID::TextSelectBackground: + case ColorID::IMESelectedRawTextBackground: + case ColorID::IMESelectedConvertedTextBackground: + case ColorID::MozDragtargetzone: + case ColorID::MozHtmlCellhighlight: + case ColorID::Highlight: + return true; + default: + return false; + } +} + nsresult nsLookAndFeel::NativeGetColor(ColorID aID, nscolor& aColor) { EnsureInit(); nsresult res = NS_OK; + if (IsSelectionColorBackground(aID)) { + aColor = mTextSelectedBackground; + return NS_OK; + } + + if (IsSelectionColorForeground(aID)) { + aColor = mTextSelectedText; + return NS_OK; + } + switch (aID) { // These colors don't seem to be used for anything anymore in Mozilla // (except here at least TextSelectBackground and TextSelectForeground) @@ -392,14 +433,6 @@ nsresult nsLookAndFeel::NativeGetColor(ColorID aID, nscolor& aColor) { case ColorID::MozAccentColorForeground: aColor = mAccentColorForeground; break; - case ColorID::WidgetSelectForeground: - case ColorID::TextSelectForeground: - case ColorID::IMESelectedRawTextForeground: - case ColorID::IMESelectedConvertedTextForeground: - case ColorID::Highlighttext: - case ColorID::MozHtmlCellhighlighttext: - aColor = mTextSelectedText; - break; case ColorID::MozCellhighlight: aColor = mMozCellHighlightBackground; break; @@ -895,7 +928,7 @@ static void GetSystemFontInfo(GtkStyleContext* aStyle, nsString* aFontName, bool nsLookAndFeel::NativeGetFont(FontID aID, nsString& aFontName, gfxFontStyle& aFontStyle) { switch (aID) { - case FontID::Menu: // css2 + case FontID::Menu: // css2 case FontID::MozPullDownMenu: // css3 aFontName = mMenuFontName; aFontStyle = mMenuFontStyle; @@ -1082,6 +1115,26 @@ bool nsLookAndFeel::FromParentTheme(IntID aID) { } } +bool nsLookAndFeel::FromParentTheme(ColorID aID) { + if (IsSelectionColorBackground(aID) || IsSelectionColorForeground(aID)) { + return StaticPrefs::widget_content_allow_gtk_dark_theme_selection(); + } + switch (aID) { + case ColorID::ThemedScrollbar: + case ColorID::ThemedScrollbarInactive: + case ColorID::ThemedScrollbarThumb: + case ColorID::ThemedScrollbarThumbHover: + case ColorID::ThemedScrollbarThumbActive: + case ColorID::ThemedScrollbarThumbInactive: + return StaticPrefs::widget_content_allow_gtk_dark_theme_scrollbars(); + case ColorID::MozAccentColor: + case ColorID::MozAccentColorForeground: + return StaticPrefs::widget_content_allow_gtk_dark_theme_accent(); + default: + return false; + } +} + bool nsLookAndFeel::ConfigureContentGtkTheme() { bool changed = false; @@ -1345,9 +1398,10 @@ void nsLookAndFeel::EnsureInit() { GrabSelectionColors(style); } - // Accent is the darker of the selection background / foreground. mAccentColor = mTextSelectedBackground; mAccentColorForeground = mTextSelectedText; + + // Accent is the darker of the selection background / foreground. if (RelativeLuminanceUtils::Compute(mAccentColor) > RelativeLuminanceUtils::Compute(mAccentColorForeground)) { std::swap(mAccentColor, mAccentColorForeground); diff --git a/widget/gtk/nsLookAndFeel.h b/widget/gtk/nsLookAndFeel.h index 76e08d3ac6cb..f8592071713b 100644 --- a/widget/gtk/nsLookAndFeel.h +++ b/widget/gtk/nsLookAndFeel.h @@ -38,6 +38,7 @@ class nsLookAndFeel final : public nsXPLookAndFeel { void WithThemeConfiguredForContent( const std::function& aFn) override; bool FromParentTheme(IntID) override; + bool FromParentTheme(ColorID) override; static void ConfigureTheme(const LookAndFeelTheme& aTheme); diff --git a/widget/nsXPLookAndFeel.h b/widget/nsXPLookAndFeel.h index 4a3b0f1c2864..aa58bbfd9c01 100644 --- a/widget/nsXPLookAndFeel.h +++ b/widget/nsXPLookAndFeel.h @@ -80,6 +80,12 @@ class nsXPLookAndFeel : public mozilla::LookAndFeel { "theme"); return false; } + virtual bool FromParentTheme(ColorID) { + MOZ_ASSERT_UNREACHABLE( + "Should override if WithThemeConfiguredForContent can change the " + "theme"); + return false; + } protected: nsXPLookAndFeel() = default;