fix: default to system accent color on invalid user color (#47684)

fix: default to system accent color on invalid user color"

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
This commit is contained in:
trop[bot] 2025-07-08 15:21:44 +02:00 committed by GitHub
parent 130f00dfcd
commit 0b77096f2a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 38 additions and 41 deletions

View file

@ -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);
}

View file

@ -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);
}
}
}

View file

@ -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(

View file

@ -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;
}

View file

@ -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<SkColor> 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;
}

View file

@ -574,43 +574,36 @@ void NativeWindowViews::UpdateWindowAccentColor() {
if (base::win::GetVersion() < base::win::Version::WIN11)
return;
COLORREF border_color;
std::optional<COLORREF> border_color;
bool should_apply_accent = false;
if (std::holds_alternative<bool>(accent_color_)) {
bool force_accent = std::get<bool>(accent_color_);
if (!force_accent) {
should_apply_accent = false;
} else {
std::optional<DWORD> 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<SkColor>(accent_color_)) {
if (std::holds_alternative<SkColor>(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<SkColor>(accent_color_);
border_color =
RGB(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color));
should_apply_accent = true;
} else if (std::holds_alternative<bool>(accent_color_)) {
// Allow the user to optionally force system color on/off.
should_apply_accent = std::get<bool>(accent_color_);
} else if (std::holds_alternative<std::monostate>(accent_color_)) {
if (IsAccentColorOnTitleBarsEnabled()) {
std::optional<DWORD> 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<DWORD> 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() {

View file

@ -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);
}

View file

@ -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;

View file

@ -28,7 +28,7 @@ bool IsHexFormatWithAlpha(const std::string& str) {
namespace electron {
SkColor ParseCSSColor(const std::string& color_string) {
std::optional<SkColor> 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;
}

View file

@ -5,6 +5,7 @@
#ifndef ELECTRON_SHELL_COMMON_COLOR_UTIL_H_
#define ELECTRON_SHELL_COMMON_COLOR_UTIL_H_
#include <optional>
#include <string>
#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<SkColor> ParseCSSColor(const std::string& color_string);
// Convert color to RGB hex value like "#RRGGBB".
std::string ToRGBHex(SkColor color);

View file

@ -226,7 +226,7 @@ bool Converter<WrappedSkColor>::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;
}