Repository: electron/electron
Pull request: feat: enable resetting accent color

Backport of #48274.

See that PR for details.

Notes: Enables resetting accent color to follow system accent settings if a previous color has been set via `window.setAccentColor(null)`.

Changed files:
filename: docs/api/base-window.md
patch: @@ -1262,15 +1262,16 @@ Sets the properties for the window's taskbar button.
 
 #### `win.setAccentColor(accentColor)` _Windows_
 
-* `accentColor` boolean | string - The accent color for the window. By default, follows user preference in System Settings.
+* `accentColor` boolean | string | null - The accent color for the window. By default, follows user preference in System Settings. To reset to system default, pass `null`.
 
 Sets the system accent color and highlighting of active window border.
 
 The `accentColor` parameter accepts the following values:
 
-* **Color string** - Sets a custom accent color using standard CSS color formats (Hex, RGB, RGBA, HSL, HSLA, or named colors). Alpha values in RGBA/HSLA formats are ignored and the color is treated as fully opaque.
-* **`true`** - Uses the system's default accent color from user preferences in System Settings.
-* **`false`** - Explicitly disables accent color highlighting for the window.
+* **Color string** - Like `true`, but sets a custom accent color using standard CSS color formats (Hex, RGB, RGBA, HSL, HSLA, or named colors). Alpha values in RGBA/HSLA formats are ignored and the color is treated as fully opaque.
+* **`true`** - Enable accent color highlighting for the window with the system accent color regardless of whether accent colors are enabled for windows in System `Settings.`
+* **`false`** - Disable accent color highlighting for the window regardless of whether accent colors are currently enabled for windows in System Settings.
+* **`null`** - Reset window accent color behavior to follow behavior set in System Settings.
 
 Examples:
 
@@ -1283,11 +1284,14 @@ win.setAccentColor('#ff0000')
 // RGB format (alpha ignored if present).
 win.setAccentColor('rgba(255,0,0,0.5)')
 
-// Use system accent color.
+// Enable accent color, using the color specified in System Settings.
 win.setAccentColor(true)
 
 // Disable accent color.
 win.setAccentColor(false)
+
+// Reset window accent color behavior to follow behavior set in System Settings.
+win.setAccentColor(null)
 ```
 
 #### `win.getAccentColor()` _Windows_

filename: docs/api/browser-window.md
patch: @@ -1467,15 +1467,16 @@ Sets the properties for the window's taskbar button.
 
 #### `win.setAccentColor(accentColor)` _Windows_
 
-* `accentColor` boolean | string - The accent color for the window. By default, follows user preference in System Settings.
+* `accentColor` boolean | string | null - The accent color for the window. By default, follows user preference in System Settings. To reset to system default, pass `null`.
 
 Sets the system accent color and highlighting of active window border.
 
 The `accentColor` parameter accepts the following values:
 
-* **Color string** - Sets a custom accent color using standard CSS color formats (Hex, RGB, RGBA, HSL, HSLA, or named colors). Alpha values in RGBA/HSLA formats are ignored and the color is treated as fully opaque.
-* **`true`** - Uses the system's default accent color from user preferences in System Settings.
-* **`false`** - Explicitly disables accent color highlighting for the window.
+* **Color string** - Like `true`, but sets a custom accent color using standard CSS color formats (Hex, RGB, RGBA, HSL, HSLA, or named colors). Alpha values in RGBA/HSLA formats are ignored and the color is treated as fully opaque.
+* **`true`** - Enable accent color highlighting for the window with the system accent color regardless of whether accent colors are enabled for windows in System `Settings.`
+* **`false`** - Disable accent color highlighting for the window regardless of whether accent colors are currently enabled for windows in System Settings.
+* **`null`** - Reset window accent color behavior to follow behavior set in System Settings.
 
 Examples:
 
@@ -1488,11 +1489,14 @@ win.setAccentColor('#ff0000')
 // RGB format (alpha ignored if present).
 win.setAccentColor('rgba(255,0,0,0.5)')
 
-// Use system accent color.
+// Enable accent color, using the color specified in System Settings.
 win.setAccentColor(true)
 
 // Disable accent color.
 win.setAccentColor(false)
+
+// Reset window accent color behavior to follow behavior set in System Settings.
+win.setAccentColor(null)
 ```
 
 #### `win.getAccentColor()` _Windows_

filename: shell/browser/api/electron_api_base_window.cc
patch: @@ -40,6 +40,7 @@
 #endif
 
 #if BUILDFLAG(IS_WIN)
+#include <variant>
 #include "shell/browser/ui/views/win_frame_view.h"
 #include "shell/browser/ui/win/taskbar_host.h"
 #include "ui/base/win/shell.h"
@@ -1096,7 +1097,11 @@ bool BaseWindow::IsSnapped() const {
 void BaseWindow::SetAccentColor(gin_helper::Arguments* args) {
   bool accent_color = false;
   std::string accent_color_string;
-  if (args->GetNext(&accent_color_string)) {
+  if (!args->PeekNext().IsEmpty() && args->PeekNext()->IsNull()) {
+    window_->SetAccentColor(std::monostate{});
+    window_->UpdateWindowAccentColor(window_->IsActive());
+  } else if (args->GetNext(&accent_color_string) &&
+             !accent_color_string.empty()) {
     std::optional<SkColor> maybe_color = ParseCSSColor(accent_color_string);
     if (maybe_color.has_value()) {
       window_->SetAccentColor(maybe_color.value());
@@ -1107,7 +1112,7 @@ void BaseWindow::SetAccentColor(gin_helper::Arguments* args) {
     window_->UpdateWindowAccentColor(window_->IsActive());
   } else {
     args->ThrowError(
-        "Invalid accent color value - must be a string or boolean");
+        "Invalid accent color value - must be null, hex string, or boolean");
   }
 }
 

filename: spec/api-browser-window-spec.ts
patch: @@ -2562,7 +2562,23 @@ describe('BrowserWindow module', () => {
       expect(() => {
         // @ts-ignore this is wrong on purpose.
         w.setAccentColor([1, 2, 3]);
-      }).to.throw('Invalid accent color value - must be a string or boolean');
+      }).to.throw('Invalid accent color value - must be null, hex string, or boolean');
+    });
+
+    it('throws if called with an invalid parameter', () => {
+      const w = new BrowserWindow({ show: false });
+      expect(() => {
+        // @ts-ignore this is wrong on purpose.
+        w.setAccentColor(new Date());
+      }).to.throw('Invalid accent color value - must be null, hex string, or boolean');
+    });
+
+    it('can be reset with null', () => {
+      const w = new BrowserWindow({ show: false });
+      w.setAccentColor('#FF0000');
+      expect(w.getAccentColor()).to.equal('#FF0000');
+      w.setAccentColor(null);
+      expect(w.getAccentColor()).to.not.equal('#FF0000');
     });
 
     it('returns the accent color after setting it to a string', () => {