diff --git a/shell/browser/api/electron_api_base_window.cc b/shell/browser/api/electron_api_base_window.cc index 27f4279f4cae..1e6530a446f7 100644 --- a/shell/browser/api/electron_api_base_window.cc +++ b/shell/browser/api/electron_api_base_window.cc @@ -656,7 +656,7 @@ bool BaseWindow::IsTabletMode() const { } void BaseWindow::SetBackgroundColor(const std::string& color_name) { - SkColor color = ParseCSSColor(color_name); + SkColor color = ParseCSSColor(color_name).value_or(SK_ColorWHITE); window_->SetBackgroundColor(color); } diff --git a/shell/browser/api/electron_api_browser_window.cc b/shell/browser/api/electron_api_browser_window.cc index c352ee79a5de..4af43407d845 100644 --- a/shell/browser/api/electron_api_browser_window.cc +++ b/shell/browser/api/electron_api_browser_window.cc @@ -234,7 +234,7 @@ void BrowserWindow::Blur() { void BrowserWindow::SetBackgroundColor(const std::string& color_name) { BaseWindow::SetBackgroundColor(color_name); - SkColor color = ParseCSSColor(color_name); + SkColor color = ParseCSSColor(color_name).value_or(SK_ColorWHITE); if (api_web_contents_) { api_web_contents_->SetBackgroundColor(color); // Also update the web preferences object otherwise the view will be reset @@ -242,7 +242,7 @@ void BrowserWindow::SetBackgroundColor(const std::string& color_name) { auto* web_preferences = WebContentsPreferences::From(api_web_contents_->web_contents()); if (web_preferences) { - web_preferences->SetBackgroundColor(ParseCSSColor(color_name)); + web_preferences->SetBackgroundColor(color); } } } diff --git a/shell/browser/api/electron_api_web_contents.cc b/shell/browser/api/electron_api_web_contents.cc index 9bc48c5185be..fe9d0a78f80d 100644 --- a/shell/browser/api/electron_api_web_contents.cc +++ b/shell/browser/api/electron_api_web_contents.cc @@ -864,9 +864,10 @@ WebContents::WebContents(v8::Isolate* isolate, // webPreferences does not have a transparent option, so if the window needs // to be transparent, that will be set at electron_api_browser_window.cc#L57 // and we then need to pull it back out and check it here. - std::string background_color; - options.GetHidden(options::kBackgroundColor, &background_color); - bool transparent = ParseCSSColor(background_color) == SK_ColorTRANSPARENT; + std::string background_color_str; + options.GetHidden(options::kBackgroundColor, &background_color_str); + SkColor bc = ParseCSSColor(background_color_str).value_or(SK_ColorWHITE); + bool transparent = bc == SK_ColorTRANSPARENT; content::WebContents::CreateParams params(session->browser_context()); auto* view = new OffScreenWebContentsView( diff --git a/shell/browser/native_window.cc b/shell/browser/native_window.cc index c63253aa138b..f69be2feb605 100644 --- a/shell/browser/native_window.cc +++ b/shell/browser/native_window.cc @@ -235,7 +235,7 @@ void NativeWindow::InitFromOptions(const gin_helper::Dictionary& options) { SkColor background_color = SK_ColorWHITE; if (std::string color; options.Get(options::kBackgroundColor, &color)) { - background_color = ParseCSSColor(color); + background_color = ParseCSSColor(color).value_or(SK_ColorWHITE); } else if (IsTranslucent()) { background_color = SK_ColorTRANSPARENT; } diff --git a/shell/browser/native_window_views.cc b/shell/browser/native_window_views.cc index c7b68140383a..00a9e8639bb9 100644 --- a/shell/browser/native_window_views.cc +++ b/shell/browser/native_window_views.cc @@ -218,7 +218,9 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options, overlay_symbol_color_ = color_utils::GetSysSkColor(COLOR_BTNTEXT); if (std::string str; options.Get(options::kAccentColor, &str)) { - accent_color_ = ParseCSSColor(str); + std::optional parsed_color = ParseCSSColor(str); + if (parsed_color.has_value()) + accent_color_ = parsed_color.value(); } else if (bool flag; options.Get(options::kAccentColor, &flag)) { accent_color_ = flag; } diff --git a/shell/browser/native_window_views_win.cc b/shell/browser/native_window_views_win.cc index c7f3456f2f20..21fbdcfed846 100644 --- a/shell/browser/native_window_views_win.cc +++ b/shell/browser/native_window_views_win.cc @@ -574,43 +574,36 @@ void NativeWindowViews::UpdateWindowAccentColor() { if (base::win::GetVersion() < base::win::Version::WIN11) return; - COLORREF border_color; + std::optional border_color; bool should_apply_accent = false; - if (std::holds_alternative(accent_color_)) { - bool force_accent = std::get(accent_color_); - if (!force_accent) { - should_apply_accent = false; - } else { - std::optional accent_color = GetAccentColor(); - if (accent_color.has_value()) { - border_color = RGB(GetRValue(accent_color.value()), - GetGValue(accent_color.value()), - GetBValue(accent_color.value())); - should_apply_accent = true; - } - } - } else if (std::holds_alternative(accent_color_)) { + if (std::holds_alternative(accent_color_)) { + // If the user has explicitly set an accent color, use it + // regardless of whether the system accent color is enabled. SkColor color = std::get(accent_color_); border_color = RGB(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color)); should_apply_accent = true; + } else if (std::holds_alternative(accent_color_)) { + // Allow the user to optionally force system color on/off. + should_apply_accent = std::get(accent_color_); } else if (std::holds_alternative(accent_color_)) { - if (IsAccentColorOnTitleBarsEnabled()) { - std::optional accent_color = GetAccentColor(); - if (accent_color.has_value()) { - border_color = RGB(GetRValue(accent_color.value()), - GetGValue(accent_color.value()), - GetBValue(accent_color.value())); - should_apply_accent = true; - } + // If no explicit color was set, default to the system accent color. + should_apply_accent = IsAccentColorOnTitleBarsEnabled(); + } + + // Use system accent color as fallback if no explicit color was set. + if (!border_color.has_value() && should_apply_accent) { + std::optional system_accent_color = GetAccentColor(); + if (system_accent_color.has_value()) { + border_color = RGB(GetRValue(system_accent_color.value()), + GetGValue(system_accent_color.value()), + GetBValue(system_accent_color.value())); } } - // Reset to default system colors when accent color should not be applied. - if (!should_apply_accent) - border_color = DWMWA_COLOR_DEFAULT; - SetWindowBorderAndCaptionColor(GetAcceleratedWidget(), border_color); + COLORREF final_color = border_color.value_or(DWMWA_COLOR_DEFAULT); + SetWindowBorderAndCaptionColor(GetAcceleratedWidget(), final_color); } void NativeWindowViews::ResetWindowControls() { diff --git a/shell/browser/ui/cocoa/electron_touch_bar.mm b/shell/browser/ui/cocoa/electron_touch_bar.mm index ee198098f3ba..8fb63c7c823a 100644 --- a/shell/browser/ui/cocoa/electron_touch_bar.mm +++ b/shell/browser/ui/cocoa/electron_touch_bar.mm @@ -338,7 +338,7 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item"; } - (NSColor*)colorFromHexColorString:(const std::string&)colorString { - SkColor color = electron::ParseCSSColor(colorString); + SkColor color = electron::ParseCSSColor(colorString).value_or(SK_ColorWHITE); return skia::SkColorToDeviceNSColor(color); } diff --git a/shell/browser/web_contents_preferences.cc b/shell/browser/web_contents_preferences.cc index 7096c8bc5f81..f4601a08bd9b 100644 --- a/shell/browser/web_contents_preferences.cc +++ b/shell/browser/web_contents_preferences.cc @@ -216,7 +216,7 @@ void WebContentsPreferences::SetFromDictionary( } std::string background_color; if (web_preferences.GetHidden(options::kBackgroundColor, &background_color)) - background_color_ = ParseCSSColor(background_color); + background_color_ = ParseCSSColor(background_color).value_or(SK_ColorWHITE); std::string safe_dialogs_message; if (web_preferences.Get("safeDialogsMessage", &safe_dialogs_message)) safe_dialogs_message_ = safe_dialogs_message; diff --git a/shell/common/color_util.cc b/shell/common/color_util.cc index d8b169a4e4d4..66669a38c5bb 100644 --- a/shell/common/color_util.cc +++ b/shell/common/color_util.cc @@ -28,7 +28,7 @@ bool IsHexFormatWithAlpha(const std::string& str) { namespace electron { -SkColor ParseCSSColor(const std::string& color_string) { +std::optional ParseCSSColor(const std::string& color_string) { // ParseCssColorString expects RGBA and we historically use ARGB // so we need to convert before passing to ParseCssColorString. std::string converted_color_str; @@ -42,7 +42,7 @@ SkColor ParseCSSColor(const std::string& color_string) { SkColor color; if (!content::ParseCssColorString(converted_color_str, &color)) - color = SK_ColorWHITE; + return std::nullopt; return color; } diff --git a/shell/common/color_util.h b/shell/common/color_util.h index 8ea422e75b1b..c1e880d8fe4a 100644 --- a/shell/common/color_util.h +++ b/shell/common/color_util.h @@ -5,6 +5,7 @@ #ifndef ELECTRON_SHELL_COMMON_COLOR_UTIL_H_ #define ELECTRON_SHELL_COMMON_COLOR_UTIL_H_ +#include #include #include "third_party/skia/include/core/SkColor.h" @@ -22,7 +23,7 @@ namespace electron { // Parses a CSS-style color string from hex, rgb(), rgba(), // hsl(), hsla(), or color name formats. -SkColor ParseCSSColor(const std::string& color_string); +std::optional ParseCSSColor(const std::string& color_string); // Convert color to RGB hex value like "#RRGGBB". std::string ToRGBHex(SkColor color); diff --git a/shell/common/gin_converters/gfx_converter.cc b/shell/common/gin_converters/gfx_converter.cc index c54ec7062eab..2af4e8a097e8 100644 --- a/shell/common/gin_converters/gfx_converter.cc +++ b/shell/common/gin_converters/gfx_converter.cc @@ -226,7 +226,7 @@ bool Converter::FromV8(v8::Isolate* isolate, std::string str; if (!gin::ConvertFromV8(isolate, val, &str)) return false; - *out = electron::ParseCSSColor(str); + *out = electron::ParseCSSColor(str).value_or(SK_ColorWHITE); return true; }