Backed out 2 changesets (bug 1707872, bug 1707957) for causing valgrind failures. CLOSED TREE

Backed out changeset 0fb0e3d056f8 (bug 1707957)
Backed out changeset 03767acc6135 (bug 1707872)
This commit is contained in:
Butkovits Atila 2021-04-28 07:46:21 +03:00
Родитель fbca5d1be2
Коммит 6e4df5e067
6 изменённых файлов: 403 добавлений и 421 удалений

Просмотреть файл

@ -11163,20 +11163,6 @@
value: false
mirror: always
# Whether system colors follow the document theme rather than the system on
# chrome documents.
- name: widget.system-colors-follow-theme
type: RelaxedAtomicBool
#ifdef XP_MACOSX
value: true
#else
# TODO(emilio): In order to enable this on GTK we need to teach
# nsNativeThemeGTK to draw non-system-themed widgets, which seems a bit hard,
# or alternatively do this only for documents which use the non-native theme.
value: false
#endif
mirror: always
- name: widget.window-transforms.disabled
type: RelaxedAtomicBool
value: false
@ -11200,32 +11186,33 @@
value: false
mirror: always
# Whether selection colors for the non-system theme get passed from the system
# GTK theme.
- name: widget.gtk.alt-theme.selection
# 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 for the non-system theme get passed from
# the system GTK theme.
- name: widget.gtk.alt-theme.accent
# 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 the scrollbar thumb active color from the non-system theme gets
# passed from the system GTK theme.
- name: widget.gtk.alt-theme.scrollbar_active
# Whether the scrollbar thumb active color gets passed from the real GTK theme
# even if allow-gtk-dark-theme is false.
- name: widget.content.allow-gtk-dark-theme.scrollbar_active
type: bool
value: true
mirror: always
# Whether other scrollbar colors get passed from the real GTK theme.
# Whether other scrollbar colors get passed from the real GTK theme even if
# allow-gtk-dark-theme is false.
#
# This is default false because light scrollbars usually match better websites,
# and we have automatic scrollbar darkening.
- name: widget.gtk.alt-theme.scrollbar
- name: widget.content.allow-gtk-dark-theme.scrollbar
type: bool
value: false
mirror: always

Просмотреть файл

@ -163,7 +163,8 @@ char16_t RemoteLookAndFeel::GetPasswordCharacterImpl() {
bool RemoteLookAndFeel::GetEchoPasswordImpl() { return mTables.passwordEcho(); }
static bool AddIDsToMap(nsXPLookAndFeel* aImpl, FullLookAndFeel* aLf) {
static bool AddIDsToMap(nsXPLookAndFeel* aImpl, FullLookAndFeel* aLf,
bool aDifferentTheme, bool aFromParentTheme) {
using IntID = LookAndFeel::IntID;
using FontID = LookAndFeel::FontID;
using FloatID = LookAndFeel::FloatID;
@ -175,6 +176,10 @@ static bool AddIDsToMap(nsXPLookAndFeel* aImpl, FullLookAndFeel* aLf) {
if (!IsNeededInChildProcess(id)) {
continue;
}
if (aDifferentTheme && aImpl->FromParentTheme(id) != aFromParentTheme) {
anyFromOtherTheme = true;
continue;
}
int32_t theInt;
nsresult rv = aImpl->NativeGetInt(id, theInt);
AddToMap(aLf->tables().ints(), aLf->tables().intMap(), id,
@ -182,6 +187,10 @@ static bool AddIDsToMap(nsXPLookAndFeel* aImpl, FullLookAndFeel* aLf) {
}
for (auto id : MakeEnumeratedRange(ColorID::End)) {
if (aDifferentTheme && aImpl->FromParentTheme(id) != aFromParentTheme) {
anyFromOtherTheme = true;
continue;
}
nscolor theColor;
nsresult rv = aImpl->NativeGetColor(id, ColorScheme::Light, theColor);
AddToMap(aLf->tables().lightColors(), aLf->tables().lightColorMap(), id,
@ -191,6 +200,11 @@ static bool AddIDsToMap(nsXPLookAndFeel* aImpl, FullLookAndFeel* aLf) {
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);
@ -233,11 +247,23 @@ const FullLookAndFeel* RemoteLookAndFeel::ExtractData() {
FullLookAndFeel* lf = new FullLookAndFeel{};
nsXPLookAndFeel* impl = nsXPLookAndFeel::GetInstance();
bool anyFromParent = false;
impl->WithThemeConfiguredForContent([&](const LookAndFeelTheme& aTheme,
bool aDifferentTheme) {
anyFromParent =
AddIDsToMap(impl, lf, aDifferentTheme, /* aFromParentTheme = */ false);
MOZ_ASSERT_IF(anyFromParent, aDifferentTheme);
lf->tables().passwordChar() = impl->GetPasswordCharacterImpl();
lf->tables().passwordEcho() = impl->GetEchoPasswordImpl();
#ifdef MOZ_WIDGET_GTK
impl->GetGtkContentTheme(lf->theme());
lf->theme() = aTheme;
#endif
});
AddIDsToMap(impl, lf);
if (anyFromParent) {
AddIDsToMap(impl, lf, /* aDifferentTheme = */ true,
/* aFromParentTheme = */ true);
}
// This assignment to sCachedLookAndFeelData must be done after the
// WithThemeConfiguredForContent call, since it can end up calling RefreshImpl

Просмотреть файл

@ -7,7 +7,6 @@
// for strtod()
#include <stdlib.h>
#include <dlfcn.h>
#include "nsLookAndFeel.h"
@ -213,14 +212,14 @@ static bool GetBorderColors(GtkStyleContext* aContext, nscolor* aLightColor,
// Finds ideal cell highlight colors used for unfocused+selected cells distinct
// from both Highlight, used as focused+selected background, and the listbox
// background which is assumed to be similar to -moz-field
void nsLookAndFeel::PerThemeData::InitCellHighlightColors() {
nsresult nsLookAndFeel::InitCellHighlightColors() {
int32_t minLuminosityDifference = NS_SUFFICIENT_LUMINOSITY_DIFFERENCE_BG;
int32_t backLuminosityDifference =
NS_LUMINOSITY_DIFFERENCE(mMozWindowBackground, mFieldBackground);
if (backLuminosityDifference >= minLuminosityDifference) {
mMozCellHighlightBackground = mMozWindowBackground;
mMozCellHighlightText = mMozWindowText;
return;
return NS_OK;
}
uint16_t hue, sat, luminance;
@ -255,6 +254,7 @@ void nsLookAndFeel::PerThemeData::InitCellHighlightColors() {
}
}
NS_HSV2RGB(mMozCellHighlightBackground, hue, sat, luminance, alpha);
return NS_OK;
}
void nsLookAndFeel::NativeInit() { EnsureInit(); }
@ -297,16 +297,10 @@ static bool IsSelectionColorBackground(LookAndFeel::ColorID aID) {
}
}
nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme aScheme,
nsresult nsLookAndFeel::NativeGetColor(ColorID aID, ColorScheme,
nscolor& aColor) {
EnsureInit();
auto& theme = aScheme == ColorScheme::Light ? LightTheme() : DarkTheme();
return theme.GetColor(aID, aColor);
}
nsresult nsLookAndFeel::PerThemeData::GetColor(ColorID aID,
nscolor& aColor) const {
nsresult res = NS_OK;
if (IsSelectionColorBackground(aID)) {
@ -697,7 +691,7 @@ nsresult nsLookAndFeel::NativeGetInt(IntID aID, int32_t& aResult) {
break;
case IntID::MenuBarDrag:
EnsureInit();
aResult = mSystemTheme.mMenuSupportsDrag;
aResult = mMenuSupportsDrag;
break;
case IntID::ScrollbarButtonAutoRepeatBehavior:
aResult = 1;
@ -748,7 +742,7 @@ nsresult nsLookAndFeel::NativeGetInt(IntID aID, int32_t& aResult) {
}
case IntID::SystemUsesDarkTheme: {
EnsureInit();
aResult = mSystemTheme.mIsDark;
aResult = mSystemUsesDarkTheme;
break;
}
case IntID::GTKCSDMaximizeButtonPosition:
@ -762,7 +756,7 @@ nsresult nsLookAndFeel::NativeGetInt(IntID aID, int32_t& aResult) {
break;
case IntID::UseAccessibilityTheme: {
EnsureInit();
aResult = mSystemTheme.mHighContrast;
aResult = mHighContrast;
break;
}
case IntID::AllowOverlayScrollbarsOverlap: {
@ -800,7 +794,7 @@ nsresult nsLookAndFeel::NativeGetFloat(FloatID aID, float& aResult) {
break;
case FloatID::CaretAspectRatio:
EnsureInit();
aResult = mSystemTheme.mCaretRatio;
aResult = mCaretRatio;
break;
case FloatID::TextScaleFactor:
aResult = gfxPlatformGtk::GetFontScaleFactor();
@ -850,11 +844,6 @@ static void GetSystemFontInfo(GtkStyleContext* aStyle, nsString* aFontName,
bool nsLookAndFeel::NativeGetFont(FontID aID, nsString& aFontName,
gfxFontStyle& aFontStyle) {
return mSystemTheme.GetFont(aID, aFontName, aFontStyle);
}
bool nsLookAndFeel::PerThemeData::GetFont(FontID aID, nsString& aFontName,
gfxFontStyle& aFontStyle) const {
switch (aID) {
case FontID::Menu: // css2
case FontID::MozPullDownMenu: // css3
@ -968,18 +957,6 @@ static bool GetPreferDarkTheme() {
return preferDarkTheme == TRUE;
}
// It seems GTK doesn't have an API to query if the current theme is "light" or
// "dark", so we synthesize it from the CSS2 Window/WindowText colors instead,
// by comparing their luminosity.
static bool GetThemeIsDark() {
GdkRGBA bg, fg;
GtkStyleContext* style = GetStyleContext(MOZ_GTK_WINDOW);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &bg);
gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &fg);
return RelativeLuminanceUtils::Compute(GDK_RGBA_TO_NS_RGBA(bg)) <
RelativeLuminanceUtils::Compute(GDK_RGBA_TO_NS_RGBA(fg));
}
void nsLookAndFeel::ConfigureTheme(const LookAndFeelTheme& aTheme) {
MOZ_ASSERT(XRE_IsContentProcess());
GtkSettings* settings = gtk_settings_get_default();
@ -988,75 +965,133 @@ void nsLookAndFeel::ConfigureTheme(const LookAndFeelTheme& aTheme) {
aTheme.preferDarkTheme() ? TRUE : FALSE, nullptr);
}
void nsLookAndFeel::WithAltThemeConfigured(
const std::function<void(bool)>& aFn) {
void nsLookAndFeel::WithThemeConfiguredForContent(
const std::function<void(const LookAndFeelTheme&, bool)>& aFn) {
nsWindow::WithSettingsChangesIgnored([&]() {
// Available on Gtk 3.20+.
static auto sGtkSettingsResetProperty =
(void (*)(GtkSettings*, const gchar*))dlsym(
RTLD_DEFAULT, "gtk_settings_reset_property");
GtkSettings* settings = gtk_settings_get_default();
nsCString themeName;
bool preferDarkTheme = false;
bool fellBackToDefaultTheme = false;
if (!sGtkSettingsResetProperty) {
// When gtk_settings_reset_property is not available, we instead
// record the current theme name and variant and explicitly restore
// them afterwards. This means we won't respond to any subsequent
// theme settings changes, which is unfortunate. (It's possible we
// could listen to xsettings changes and update the GtkSettings object
// ourselves in response, if we wanted to fix this.)
themeName = GetGtkTheme();
preferDarkTheme = GetPreferDarkTheme();
}
// Try to select the opposite variant of the current theme first...
LOG((" toggling gtk-application-prefer-dark-theme\n"));
g_object_set(settings, "gtk-application-prefer-dark-theme",
!mSystemTheme.mIsDark, nullptr);
moz_gtk_refresh();
bool changed = ConfigureContentGtkTheme();
if (changed) {
RefreshImpl();
}
// Toggling gtk-application-prefer-dark-theme is not enough generally to
// switch from dark to light theme. If the theme didn't change, and we have
// a dark theme, try to first remove -Dark{,er,est} from the theme name to
// find the light variant.
if (mSystemTheme.mIsDark && mSystemTheme.mIsDark == GetThemeIsDark()) {
nsCString potentialLightThemeName = mSystemTheme.mName;
constexpr nsLiteralCString kSubstringsToRemove[] = {
"-dark"_ns, "-darker"_ns, "-darkest"_ns, "-Dark"_ns,
"-Darker"_ns, "-Darkest"_ns, "_dark"_ns, "_darker"_ns,
"_darkest"_ns, "_Dark"_ns, "_Darker"_ns, "_Darkest"_ns,
};
bool found = false;
for (auto& s : kSubstringsToRemove) {
potentialLightThemeName = mSystemTheme.mName;
potentialLightThemeName.ReplaceSubstring(s, ""_ns);
if (potentialLightThemeName.Length() != mSystemTheme.mName.Length()) {
found = true;
break;
}
}
if (found) {
g_object_set(settings, "gtk-theme-name", potentialLightThemeName.get(),
nullptr);
moz_gtk_refresh();
LookAndFeelTheme theme;
theme.themeName() = GetGtkTheme();
theme.preferDarkTheme() = GetPreferDarkTheme();
aFn(theme, changed);
if (changed) {
GtkSettings* settings = gtk_settings_get_default();
if (sGtkSettingsResetProperty) {
sGtkSettingsResetProperty(settings, "gtk-theme-name");
sGtkSettingsResetProperty(settings,
"gtk-application-prefer-dark-theme");
} else {
g_object_set(settings, "gtk-theme-name", themeName.get(),
"gtk-application-prefer-dark-theme",
preferDarkTheme ? TRUE : FALSE, nullptr);
}
RefreshImpl();
}
if (mSystemTheme.mIsDark == GetThemeIsDark()) {
// If the theme still didn't change enough, fall back to either Adwaita or
// Adwaita Dark.
g_object_set(settings, "gtk-theme-name",
mSystemTheme.mIsDark ? "Adwaita" : "Adwaita Dark", nullptr);
moz_gtk_refresh();
fellBackToDefaultTheme = true;
}
aFn(fellBackToDefaultTheme);
// Restore the system theme.
if (sGtkSettingsResetProperty) {
sGtkSettingsResetProperty(settings, "gtk-theme-name");
sGtkSettingsResetProperty(settings, "gtk-application-prefer-dark-theme");
} else {
g_object_set(settings, "gtk-theme-name", mSystemTheme.mName.get(),
"gtk-application-prefer-dark-theme",
mSystemTheme.mPreferDarkTheme, nullptr);
}
moz_gtk_refresh();
});
}
bool nsLookAndFeel::FromParentTheme(IntID aID) {
switch (aID) {
case IntID::SystemUsesDarkTheme:
case IntID::UseAccessibilityTheme:
// We want to take SystemUsesDarkTheme and UseAccessibilityTheme from the
// parent process theme rather than the content configured theme.
//
// This ensures that media queries like (prefers-color-scheme: dark) will
// match correctly in content processes.
return true;
default:
return false;
}
}
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::ThemedScrollbarThumbInactive:
return StaticPrefs::widget_content_allow_gtk_dark_theme_scrollbar();
case ColorID::ThemedScrollbarThumbActive:
return StaticPrefs::
widget_content_allow_gtk_dark_theme_scrollbar_active();
case ColorID::MozAccentColor:
case ColorID::MozAccentColorForeground:
return StaticPrefs::widget_content_allow_gtk_dark_theme_accent();
default:
return false;
}
}
bool nsLookAndFeel::ConfigureContentGtkTheme() {
bool changed = false;
GtkSettings* settings = gtk_settings_get_default();
nsAutoCString themeOverride;
mozilla::Preferences::GetCString("widget.content.gtk-theme-override",
themeOverride);
if (!themeOverride.IsEmpty()) {
g_object_set(settings, "gtk-theme-name", themeOverride.get(), nullptr);
changed = true;
LOG(("ConfigureContentGtkTheme(%s)\n", themeOverride.get()));
} else {
LOG(("ConfigureContentGtkTheme(%s)\n", GetGtkTheme().get()));
}
// Dark theme is active but user explicitly enables it, or we're on
// high-contrast (in which case we prevent content to mess up with the colors
// of the page), so we're done now.
if (!themeOverride.IsEmpty() || mHighContrast ||
StaticPrefs::widget_content_allow_gtk_dark_theme()) {
return changed;
}
// Try to select the light variant of the current theme first...
if (GetPreferDarkTheme()) {
LOG((" disabling gtk-application-prefer-dark-theme\n"));
g_object_set(settings, "gtk-application-prefer-dark-theme", FALSE, nullptr);
changed = true;
}
// ...and use a default Gtk theme as a fallback.
if (!IsGtkThemeCompatibleWithHTMLColors()) {
LOG((" Non-compatible dark theme, default to Adwaita\n"));
g_object_set(settings, "gtk-theme-name", "Adwaita", nullptr);
changed = true;
}
return changed;
}
static bool AnyColorChannelIsDifferent(nscolor aColor) {
return NS_GET_R(aColor) != NS_GET_G(aColor) ||
NS_GET_R(aColor) != NS_GET_B(aColor);
@ -1081,184 +1116,89 @@ void nsLookAndFeel::EnsureInit() {
// gtk does non threadsafe refcounting
MOZ_ASSERT(NS_IsMainThread());
gboolean enableAnimations = false;
g_object_get(settings, "gtk-enable-animations", &enableAnimations, nullptr);
mPrefersReducedMotion = !enableAnimations;
gint blink_time;
gboolean blink;
g_object_get(settings, "gtk-cursor-blink-time", &blink_time,
"gtk-cursor-blink", &blink, nullptr);
mCaretBlinkTime = blink ? (int32_t)blink_time : 0;
mCSDAvailable =
nsWindow::GtkWindowDecoration() != nsWindow::GTK_DECORATION_NONE;
mCSDHideTitlebarByDefault = nsWindow::HideTitlebarByDefault();
mSystemTheme.Init();
mCSDCloseButton = false;
mCSDMinimizeButton = false;
mCSDMaximizeButton = false;
mCSDCloseButtonPosition = 0;
mCSDMinimizeButtonPosition = 0;
mCSDMaximizeButtonPosition = 0;
// We need to initialize whole CSD config explicitly because it's queried
// as -moz-gtk* media features.
ButtonLayout buttonLayout[TOOLBAR_BUTTONS];
size_t activeButtons =
GetGtkHeaderBarButtonLayout(Span(buttonLayout), &mCSDReversedPlacement);
for (size_t i = 0; i < activeButtons; i++) {
// We check if a button is represented on the right side of the tabbar.
// Then we assign it a value from 3 to 5, instead of 0 to 2 when it is on
// the left side.
const ButtonLayout& layout = buttonLayout[i];
int32_t* pos = nullptr;
switch (layout.mType) {
case MOZ_GTK_HEADER_BAR_BUTTON_MINIMIZE:
mCSDMinimizeButton = true;
pos = &mCSDMinimizeButtonPosition;
break;
case MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE:
mCSDMaximizeButton = true;
pos = &mCSDMaximizeButtonPosition;
break;
case MOZ_GTK_HEADER_BAR_BUTTON_CLOSE:
mCSDCloseButton = true;
pos = &mCSDCloseButtonPosition;
break;
default:
break;
}
if (pos) {
*pos = i;
if (layout.mAtRight) {
*pos += TOOLBAR_BUTTONS;
}
}
}
WithAltThemeConfigured([&](bool aFellBackToDefaultTheme) {
mAltTheme.Init();
// Some of the alt theme colors we can grab from the system theme, if we
// fell back to the default light / dark themes.
if (aFellBackToDefaultTheme) {
if (StaticPrefs::widget_gtk_alt_theme_selection()) {
mAltTheme.mTextSelectedText = mSystemTheme.mTextSelectedText;
mAltTheme.mTextSelectedBackground =
mSystemTheme.mTextSelectedBackground;
}
if (StaticPrefs::widget_gtk_alt_theme_scrollbar()) {
mAltTheme.mThemedScrollbar = mSystemTheme.mThemedScrollbar;
mAltTheme.mThemedScrollbarInactive =
mSystemTheme.mThemedScrollbarInactive;
mAltTheme.mThemedScrollbarThumb = mSystemTheme.mThemedScrollbarThumb;
mAltTheme.mThemedScrollbarThumbHover =
mSystemTheme.mThemedScrollbarThumbHover;
mAltTheme.mThemedScrollbarThumbInactive =
mSystemTheme.mThemedScrollbarThumbInactive;
}
if (StaticPrefs::widget_gtk_alt_theme_scrollbar_active()) {
mAltTheme.mThemedScrollbarThumbActive =
mSystemTheme.mThemedScrollbarThumbActive;
}
if (StaticPrefs::widget_gtk_alt_theme_selection()) {
mAltTheme.mAccentColor = mSystemTheme.mAccentColor;
mAltTheme.mAccentColorForeground = mSystemTheme.mAccentColorForeground;
}
}
});
LOG(("System Theme: %s. Alt Theme: %s\n", mSystemTheme.mName.get(),
mAltTheme.mName.get()));
RecordTelemetry();
}
void nsLookAndFeel::GetGtkContentTheme(LookAndFeelTheme& aTheme) {
if (NS_SUCCEEDED(Preferences::GetCString("widget.content.gtk-theme-override",
aTheme.themeName()))) {
return;
}
auto& theme = StaticPrefs::widget_content_allow_gtk_dark_theme()
? mSystemTheme
: LightTheme();
aTheme.preferDarkTheme() = theme.mPreferDarkTheme;
aTheme.themeName() = theme.mName;
}
void nsLookAndFeel::PerThemeData::Init() {
mName = GetGtkTheme();
GtkStyleContext* style;
mHighContrast = StaticPrefs::widget_content_gtk_high_contrast_enabled() &&
GetGtkTheme().Find("HighContrast"_ns) >= 0;
mPreferDarkTheme = GetPreferDarkTheme();
mIsDark = GetThemeIsDark();
mCompatibleWithHTMLLightColors =
!mIsDark && IsGtkThemeCompatibleWithHTMLColors();
GdkRGBA color;
// Colors that we pass to content processes through RemoteLookAndFeel.
if (ShouldHonorThemeScrollbarColors()) {
// Some themes style the <trough>, while others style the <scrollbar>
// itself, so we look at both and compose the colors.
style = GetStyleContext(MOZ_GTK_SCROLLBAR_VERTICAL);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL,
&color);
mThemedScrollbar = GDK_RGBA_TO_NS_RGBA(color);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_BACKDROP,
&color);
mThemedScrollbarInactive = GDK_RGBA_TO_NS_RGBA(color);
style = GetStyleContext(MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL,
&color);
mThemedScrollbar =
NS_ComposeColors(mThemedScrollbar, GDK_RGBA_TO_NS_RGBA(color));
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_BACKDROP,
&color);
mThemedScrollbarInactive =
NS_ComposeColors(mThemedScrollbarInactive, GDK_RGBA_TO_NS_RGBA(color));
mMozScrollbar = mThemedScrollbar;
style = GetStyleContext(MOZ_GTK_SCROLLBAR_THUMB_VERTICAL);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL,
&color);
mThemedScrollbarThumb = GDK_RGBA_TO_NS_RGBA(color);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_PRELIGHT,
&color);
mThemedScrollbarThumbHover = GDK_RGBA_TO_NS_RGBA(color);
gtk_style_context_get_background_color(
style, GtkStateFlags(GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_ACTIVE),
&color);
mThemedScrollbarThumbActive = GDK_RGBA_TO_NS_RGBA(color);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_BACKDROP,
&color);
mThemedScrollbarThumbInactive = GDK_RGBA_TO_NS_RGBA(color);
if (XRE_IsContentProcess()) {
LOG(("nsLookAndFeel::EnsureInit() [%p] Content process\n", (void*)this));
// Dark themes interacts poorly with widget styling (see bug 1216658).
// We disable dark themes by default for web content
// but allow user to overide it by prefs.
ConfigureContentGtkTheme();
} else {
mMozScrollbar = mThemedScrollbar = widget::sScrollbarColor.ToABGR();
mThemedScrollbarInactive = widget::sScrollbarColor.ToABGR();
mThemedScrollbarThumb = widget::sScrollbarThumbColor.ToABGR();
mThemedScrollbarThumbHover =
nsNativeBasicTheme::AdjustUnthemedScrollbarThumbColor(
mThemedScrollbarThumb, NS_EVENT_STATE_HOVER);
mThemedScrollbarThumbActive =
nsNativeBasicTheme::AdjustUnthemedScrollbarThumbColor(
mThemedScrollbarThumb, NS_EVENT_STATE_ACTIVE);
mThemedScrollbarThumbInactive = mThemedScrollbarThumb;
// It seems GTK doesn't have an API to query if the current theme is
// "light" or "dark", so we synthesize it from the CSS2 Window/WindowText
// colors instead, by comparing their luminosity.
GdkRGBA bg, fg;
style = GetStyleContext(MOZ_GTK_WINDOW);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &bg);
gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &fg);
LOG(("nsLookAndFeel::EnsureInit() [%p] Chrome process\n", (void*)this));
// Update mSystemUsesDarkTheme only in the parent process since in the child
// processes we forcibly set gtk-theme-name so that we can't get correct
// results. Instead mSystemUsesDarkTheme in the child processes is updated
// via our caching machinery.
mSystemUsesDarkTheme =
(RelativeLuminanceUtils::Compute(GDK_RGBA_TO_NS_RGBA(bg)) <
RelativeLuminanceUtils::Compute(GDK_RGBA_TO_NS_RGBA(fg)));
mHighContrast = StaticPrefs::widget_content_gtk_high_contrast_enabled() &&
GetGtkTheme().Find("HighContrast"_ns) >= 0;
gboolean enableAnimations = false;
g_object_get(settings, "gtk-enable-animations", &enableAnimations, nullptr);
mPrefersReducedMotion = !enableAnimations;
// Colors that we pass to content processes through RemoteLookAndFeel.
if (ShouldHonorThemeScrollbarColors()) {
// Some themes style the <trough>, while others style the <scrollbar>
// itself, so we look at both and compose the colors.
style = GetStyleContext(MOZ_GTK_SCROLLBAR_VERTICAL);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL,
&color);
mThemedScrollbar = GDK_RGBA_TO_NS_RGBA(color);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_BACKDROP,
&color);
mThemedScrollbarInactive = GDK_RGBA_TO_NS_RGBA(color);
style = GetStyleContext(MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL,
&color);
mThemedScrollbar =
NS_ComposeColors(mThemedScrollbar, GDK_RGBA_TO_NS_RGBA(color));
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_BACKDROP,
&color);
mThemedScrollbarInactive = NS_ComposeColors(mThemedScrollbarInactive,
GDK_RGBA_TO_NS_RGBA(color));
mMozScrollbar = mThemedScrollbar;
style = GetStyleContext(MOZ_GTK_SCROLLBAR_THUMB_VERTICAL);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL,
&color);
mThemedScrollbarThumb = GDK_RGBA_TO_NS_RGBA(color);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_PRELIGHT,
&color);
mThemedScrollbarThumbHover = GDK_RGBA_TO_NS_RGBA(color);
gtk_style_context_get_background_color(
style, GtkStateFlags(GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_ACTIVE),
&color);
mThemedScrollbarThumbActive = GDK_RGBA_TO_NS_RGBA(color);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_BACKDROP,
&color);
mThemedScrollbarThumbInactive = GDK_RGBA_TO_NS_RGBA(color);
} else {
mMozScrollbar = mThemedScrollbar = widget::sScrollbarColor.ToABGR();
mThemedScrollbarInactive = widget::sScrollbarColor.ToABGR();
mThemedScrollbarThumb = widget::sScrollbarThumbColor.ToABGR();
mThemedScrollbarThumbHover =
nsNativeBasicTheme::AdjustUnthemedScrollbarThumbColor(
mThemedScrollbarThumb, NS_EVENT_STATE_HOVER);
mThemedScrollbarThumbActive =
nsNativeBasicTheme::AdjustUnthemedScrollbarThumbColor(
mThemedScrollbarThumb, NS_EVENT_STATE_ACTIVE);
mThemedScrollbarThumbInactive = mThemedScrollbarThumb;
}
}
// The label is not added to a parent widget, but shared for constructing
@ -1510,17 +1450,73 @@ void nsLookAndFeel::PerThemeData::Init() {
// caret styles
gtk_widget_style_get(entry, "cursor-aspect-ratio", &mCaretRatio, nullptr);
gint blink_time;
gboolean blink;
g_object_get(settings, "gtk-cursor-blink-time", &blink_time,
"gtk-cursor-blink", &blink, nullptr);
mCaretBlinkTime = blink ? (int32_t)blink_time : 0;
GetSystemFontInfo(gtk_widget_get_style_context(entry), &mFieldFontName,
&mFieldFontStyle);
gtk_widget_destroy(window);
g_object_unref(labelWidget);
mCSDAvailable =
nsWindow::GtkWindowDecoration() != nsWindow::GTK_DECORATION_NONE;
mCSDHideTitlebarByDefault = nsWindow::HideTitlebarByDefault();
mCSDCloseButton = false;
mCSDMinimizeButton = false;
mCSDMaximizeButton = false;
mCSDCloseButtonPosition = 0;
mCSDMinimizeButtonPosition = 0;
mCSDMaximizeButtonPosition = 0;
// We need to initialize whole CSD config explicitly because it's queried
// as -moz-gtk* media features.
ButtonLayout buttonLayout[TOOLBAR_BUTTONS];
size_t activeButtons =
GetGtkHeaderBarButtonLayout(Span(buttonLayout), &mCSDReversedPlacement);
for (size_t i = 0; i < activeButtons; i++) {
// We check if a button is represented on the right side of the tabbar.
// Then we assign it a value from 3 to 5, instead of 0 to 2 when it is on
// the left side.
const ButtonLayout& layout = buttonLayout[i];
int32_t* pos = nullptr;
switch (layout.mType) {
case MOZ_GTK_HEADER_BAR_BUTTON_MINIMIZE:
mCSDMinimizeButton = true;
pos = &mCSDMinimizeButtonPosition;
break;
case MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE:
mCSDMaximizeButton = true;
pos = &mCSDMaximizeButtonPosition;
break;
case MOZ_GTK_HEADER_BAR_BUTTON_CLOSE:
mCSDCloseButton = true;
pos = &mCSDCloseButtonPosition;
break;
default:
break;
}
if (pos) {
*pos = i;
if (layout.mAtRight) {
*pos += TOOLBAR_BUTTONS;
}
}
}
RecordTelemetry();
}
// virtual
char16_t nsLookAndFeel::GetPasswordCharacterImpl() {
EnsureInit();
return mSystemTheme.mInvisibleCharacter;
return mInvisibleCharacter;
}
bool nsLookAndFeel::GetEchoPasswordImpl() { return false; }

Просмотреть файл

@ -32,9 +32,10 @@ class nsLookAndFeel final : public nsXPLookAndFeel {
char16_t GetPasswordCharacterImpl() override;
bool GetEchoPasswordImpl() override;
void WithAltThemeConfigured(const std::function<void(bool)>&);
void GetGtkContentTheme(LookAndFeelTheme&) override;
void WithThemeConfiguredForContent(
const std::function<void(const LookAndFeelTheme&, bool)>& aFn) override;
bool FromParentTheme(IntID) override;
bool FromParentTheme(ColorID) override;
static void ConfigureTheme(const LookAndFeelTheme& aTheme);
@ -44,111 +45,77 @@ class nsLookAndFeel final : public nsXPLookAndFeel {
static const nscolor kWhite = NS_RGB(255, 255, 255);
protected:
static bool WidgetUsesImage(WidgetNodeType aNodeType);
bool WidgetUsesImage(WidgetNodeType aNodeType);
void RecordLookAndFeelSpecificTelemetry() override;
static bool ShouldHonorThemeScrollbarColors();
bool ShouldHonorThemeScrollbarColors();
// We use up to two themes (one light, one dark), which might have different
// sets of fonts and colors.
struct PerThemeData {
nsCString mName;
bool mIsDark = false;
bool mHighContrast = false;
bool mPreferDarkTheme = false;
// NOTE(emilio): This is unused, but if we need to we can use it to override
// system colors with standins like we do for the non-native theme.
bool mCompatibleWithHTMLLightColors = false;
// Cached fonts
nsString mDefaultFontName;
nsString mButtonFontName;
nsString mFieldFontName;
nsString mMenuFontName;
gfxFontStyle mDefaultFontStyle;
gfxFontStyle mButtonFontStyle;
gfxFontStyle mFieldFontStyle;
gfxFontStyle mMenuFontStyle;
// Cached colors
nscolor mInfoBackground = kWhite;
nscolor mInfoText = kBlack;
nscolor mMenuBackground = kWhite;
nscolor mMenuBarText = kBlack;
nscolor mMenuBarHoverText = kBlack;
nscolor mMenuText = kBlack;
nscolor mMenuTextInactive = kWhite;
nscolor mMenuHover = kWhite;
nscolor mMenuHoverText = kBlack;
nscolor mButtonDefault = kWhite;
nscolor mButtonText = kBlack;
nscolor mButtonHoverText = kBlack;
nscolor mButtonHoverFace = kWhite;
nscolor mButtonActiveText = kBlack;
nscolor mFrameOuterLightBorder = kBlack;
nscolor mFrameInnerDarkBorder = kBlack;
nscolor mOddCellBackground = kWhite;
nscolor mNativeHyperLinkText = kBlack;
nscolor mComboBoxText = kBlack;
nscolor mComboBoxBackground = kWhite;
nscolor mFieldText = kBlack;
nscolor mFieldBackground = kWhite;
nscolor mMozWindowText = kBlack;
nscolor mMozWindowBackground = kWhite;
nscolor mMozWindowActiveBorder = kBlack;
nscolor mMozWindowInactiveBorder = kBlack;
nscolor mMozWindowInactiveCaption = kWhite;
nscolor mMozCellHighlightBackground = kWhite;
nscolor mMozCellHighlightText = kBlack;
nscolor mTextSelectedText = kBlack;
nscolor mTextSelectedBackground = kWhite;
nscolor mAccentColor = kWhite;
nscolor mAccentColorForeground = kWhite;
nscolor mMozScrollbar = kWhite;
nscolor mInfoBarText = kBlack;
nscolor mMozColHeaderText = kBlack;
nscolor mMozColHeaderHoverText = kBlack;
nscolor mThemedScrollbar = kWhite;
nscolor mThemedScrollbarInactive = kWhite;
nscolor mThemedScrollbarThumb = kBlack;
nscolor mThemedScrollbarThumbHover = kBlack;
nscolor mThemedScrollbarThumbActive = kBlack;
nscolor mThemedScrollbarThumbInactive = kBlack;
float mCaretRatio = 0.0f;
char16_t mInvisibleCharacter = 0;
bool mMenuSupportsDrag = false;
void Init();
nsresult GetColor(ColorID, nscolor&) const;
bool GetFont(FontID, nsString& aFontName, gfxFontStyle&) const;
void InitCellHighlightColors();
};
PerThemeData mSystemTheme;
// If the system theme is light, a dark theme. Otherwise, a light theme. The
// alternative theme to the current one is preferred, but otherwise we fall
// back to Adwaita / Adwaita Dark, respectively.
PerThemeData mAltTheme;
const PerThemeData& LightTheme() const {
return mSystemTheme.mIsDark ? mAltTheme : mSystemTheme;
}
const PerThemeData& DarkTheme() const {
return mSystemTheme.mIsDark ? mSystemTheme : mAltTheme;
}
// Cached fonts
nsString mDefaultFontName;
nsString mButtonFontName;
nsString mFieldFontName;
nsString mMenuFontName;
gfxFontStyle mDefaultFontStyle;
gfxFontStyle mButtonFontStyle;
gfxFontStyle mFieldFontStyle;
gfxFontStyle mMenuFontStyle;
// Cached colors
nscolor mInfoBackground = kWhite;
nscolor mInfoText = kBlack;
nscolor mMenuBackground = kWhite;
nscolor mMenuBarText = kBlack;
nscolor mMenuBarHoverText = kBlack;
nscolor mMenuText = kBlack;
nscolor mMenuTextInactive = kWhite;
nscolor mMenuHover = kWhite;
nscolor mMenuHoverText = kBlack;
nscolor mButtonDefault = kWhite;
nscolor mButtonText = kBlack;
nscolor mButtonHoverText = kBlack;
nscolor mButtonHoverFace = kWhite;
nscolor mButtonActiveText = kBlack;
nscolor mFrameOuterLightBorder = kBlack;
nscolor mFrameInnerDarkBorder = kBlack;
nscolor mOddCellBackground = kWhite;
nscolor mNativeHyperLinkText = kBlack;
nscolor mComboBoxText = kBlack;
nscolor mComboBoxBackground = kWhite;
nscolor mFieldText = kBlack;
nscolor mFieldBackground = kWhite;
nscolor mMozWindowText = kBlack;
nscolor mMozWindowBackground = kWhite;
nscolor mMozWindowActiveBorder = kBlack;
nscolor mMozWindowInactiveBorder = kBlack;
nscolor mMozWindowInactiveCaption = kWhite;
nscolor mMozCellHighlightBackground = kWhite;
nscolor mMozCellHighlightText = kBlack;
nscolor mTextSelectedText = kBlack;
nscolor mTextSelectedBackground = kWhite;
nscolor mAccentColor = kWhite;
nscolor mAccentColorForeground = kWhite;
nscolor mMozScrollbar = kWhite;
nscolor mInfoBarText = kBlack;
nscolor mMozColHeaderText = kBlack;
nscolor mMozColHeaderHoverText = kBlack;
nscolor mThemedScrollbar = kWhite;
nscolor mThemedScrollbarInactive = kWhite;
nscolor mThemedScrollbarThumb = kBlack;
nscolor mThemedScrollbarThumbHover = kBlack;
nscolor mThemedScrollbarThumbActive = kBlack;
nscolor mThemedScrollbarThumbInactive = kBlack;
char16_t mInvisibleCharacter = 0;
float mCaretRatio = 0.0f;
int32_t mCaretBlinkTime = 0;
bool mMenuSupportsDrag = false;
bool mCSDAvailable = false;
bool mCSDHideTitlebarByDefault = false;
bool mCSDMaximizeButton = false;
bool mCSDMinimizeButton = false;
bool mCSDCloseButton = false;
bool mCSDReversedPlacement = false;
bool mSystemUsesDarkTheme = false;
bool mPrefersReducedMotion = false;
bool mHighContrast = false;
bool mInitialized = false;
int32_t mCSDMaximizeButtonPosition = 0;
int32_t mCSDMinimizeButtonPosition = 0;
@ -157,6 +124,9 @@ class nsLookAndFeel final : public nsXPLookAndFeel {
void EnsureInit();
// Returns whether the current theme or theme variant was changed.
bool ConfigureContentGtkTheme();
private:
nsresult InitCellHighlightColors();
};
#endif

Просмотреть файл

@ -926,45 +926,30 @@ static bool ShouldUseStandinsForNativeColorForNonNativeTheme(
return false;
}
static bool ShouldRespectSystemAppearanceForChromeDoc() {
#ifdef XP_MACOSX
return StaticPrefs::widget_macos_respect_system_appearance();
#else
// GTK historically has behaved like this. Other platforms don't have support
// for light / dark color schemes yet so it doesn't matter for them.
return true;
#endif
}
static bool ShouldRespectThemeAppearanceForChromeDoc() {
return StaticPrefs::widget_system_colors_follow_theme();
}
LookAndFeel::ColorScheme LookAndFeel::ColorSchemeForDocument(
const dom::Document& aDoc) {
#ifdef XP_MACOSX
if (nsContentUtils::IsChromeDoc(&aDoc) &&
ShouldRespectSystemAppearanceForChromeDoc()) {
if (ShouldRespectThemeAppearanceForChromeDoc()) {
const auto* doc = &aDoc;
while (const auto* parent = doc->GetInProcessParentDocument()) {
doc = parent;
}
switch (doc->ThreadSafeGetDocumentLWTheme()) {
case dom::Document::Doc_Theme_Dark:
return ColorScheme::Light;
case dom::Document::Doc_Theme_Bright:
// NOTE(emilio): This looks backwards, but it's actually correct.
// Doc_Theme_Bright means that the theme has bright _text_ (and thus
// dark background). Tricky!
return ColorScheme::Dark;
case dom::Document::Doc_Theme_Neutral:
case dom::Document::Doc_Theme_None:
default:
break;
}
StaticPrefs::widget_macos_respect_system_appearance()) {
const auto* doc = &aDoc;
while (const auto* parent = doc->GetInProcessParentDocument()) {
doc = parent;
}
switch (doc->ThreadSafeGetDocumentLWTheme()) {
case dom::Document::Doc_Theme_None:
return LookAndFeel::SystemColorScheme();
case dom::Document::Doc_Theme_Dark:
return LookAndFeel::ColorScheme::Light;
case dom::Document::Doc_Theme_Bright:
// NOTE(emilio): This looks backwards, but it's actually correct.
// Doc_Theme_Bright means that the theme has bright _text_ (and thus
// dark background). Tricky!
return LookAndFeel::ColorScheme::Dark;
default:
break;
}
return SystemColorScheme();
}
#endif
return LookAndFeel::ColorScheme::Light;
}

Просмотреть файл

@ -61,7 +61,25 @@ class nsXPLookAndFeel : public mozilla::LookAndFeel {
virtual void NativeInit() = 0;
virtual void GetGtkContentTheme(LookAndFeelTheme&) {}
virtual void WithThemeConfiguredForContent(
const std::function<void(const LookAndFeelTheme&, bool aChanged)>& aFn) {
aFn(LookAndFeelTheme{}, false);
}
// Whether the color should be from the parent theme, if the theme differs
// between parent and content processes.
virtual bool FromParentTheme(IntID) {
MOZ_ASSERT_UNREACHABLE(
"Should override if WithThemeConfiguredForContent can change the "
"theme");
return false;
}
virtual bool FromParentTheme(ColorID) {
MOZ_ASSERT_UNREACHABLE(
"Should override if WithThemeConfiguredForContent can change the "
"theme");
return false;
}
protected:
nsXPLookAndFeel() = default;