зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
fbca5d1be2
Коммит
6e4df5e067
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче