feat: add {get|set}AccentColor
on Windows (#48017)
* feat: add setAccentColor on Windows Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> * refactor: unify GetSystemAccentColor Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> * refactor: remove redundant parsing Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> * chore: fixup documentation Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> * Update docs/api/browser-window.md Co-authored-by: Will Anderson <andersonw@dropbox.com> Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> * Update docs/api/base-window.md Co-authored-by: Will Anderson <andersonw@dropbox.com> Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> --------- 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:
parent
a84d77143f
commit
4b46b6e2f2
13 changed files with 265 additions and 24 deletions
|
@ -1256,6 +1256,43 @@ Sets the properties for the window's taskbar button.
|
||||||
> `relaunchCommand` and `relaunchDisplayName` must always be set
|
> `relaunchCommand` and `relaunchDisplayName` must always be set
|
||||||
> together. If one of those properties is not set, then neither will be used.
|
> together. If one of those properties is not set, then neither will be used.
|
||||||
|
|
||||||
|
#### `win.setAccentColor(accentColor)` _Windows_
|
||||||
|
|
||||||
|
* `accentColor` boolean | string - The accent color for the window. By default, follows user preference in System Settings.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const win = new BrowserWindow({ frame: false })
|
||||||
|
|
||||||
|
// Set red accent color.
|
||||||
|
win.setAccentColor('#ff0000')
|
||||||
|
|
||||||
|
// RGB format (alpha ignored if present).
|
||||||
|
win.setAccentColor('rgba(255,0,0,0.5)')
|
||||||
|
|
||||||
|
// Use system accent color.
|
||||||
|
win.setAccentColor(true)
|
||||||
|
|
||||||
|
// Disable accent color.
|
||||||
|
win.setAccentColor(false)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `win.getAccentColor()` _Windows_
|
||||||
|
|
||||||
|
Returns `string | boolean` - the system accent color and highlighting of active window border in Hex RGB format.
|
||||||
|
|
||||||
|
If a color has been set for the window that differs from the system accent color, the window accent color will
|
||||||
|
be returned. Otherwise, a boolean will be returned, with `true` indicating that the window uses the global system accent color, and `false` indicating that accent color highlighting is disabled for this window.
|
||||||
|
|
||||||
#### `win.setIcon(icon)` _Windows_ _Linux_
|
#### `win.setIcon(icon)` _Windows_ _Linux_
|
||||||
|
|
||||||
* `icon` [NativeImage](native-image.md) | string
|
* `icon` [NativeImage](native-image.md) | string
|
||||||
|
|
|
@ -1434,6 +1434,43 @@ Sets the properties for the window's taskbar button.
|
||||||
> `relaunchCommand` and `relaunchDisplayName` must always be set
|
> `relaunchCommand` and `relaunchDisplayName` must always be set
|
||||||
> together. If one of those properties is not set, then neither will be used.
|
> together. If one of those properties is not set, then neither will be used.
|
||||||
|
|
||||||
|
#### `win.setAccentColor(accentColor)` _Windows_
|
||||||
|
|
||||||
|
* `accentColor` boolean | string - The accent color for the window. By default, follows user preference in System Settings.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const win = new BrowserWindow({ frame: false })
|
||||||
|
|
||||||
|
// Set red accent color.
|
||||||
|
win.setAccentColor('#ff0000')
|
||||||
|
|
||||||
|
// RGB format (alpha ignored if present).
|
||||||
|
win.setAccentColor('rgba(255,0,0,0.5)')
|
||||||
|
|
||||||
|
// Use system accent color.
|
||||||
|
win.setAccentColor(true)
|
||||||
|
|
||||||
|
// Disable accent color.
|
||||||
|
win.setAccentColor(false)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `win.getAccentColor()` _Windows_
|
||||||
|
|
||||||
|
Returns `string | boolean` - the system accent color and highlighting of active window border in Hex RGB format.
|
||||||
|
|
||||||
|
If a color has been set for the window that differs from the system accent color, the window accent color will
|
||||||
|
be returned. Otherwise, a boolean will be returned, with `true` indicating that the window uses the global system accent color, and `false` indicating that accent color highlighting is disabled for this window.
|
||||||
|
|
||||||
#### `win.showDefinitionForSelection()` _macOS_
|
#### `win.showDefinitionForSelection()` _macOS_
|
||||||
|
|
||||||
Same as `webContents.showDefinitionForSelection()`.
|
Same as `webContents.showDefinitionForSelection()`.
|
||||||
|
|
|
@ -1089,6 +1089,33 @@ void BaseWindow::SetAppDetails(const gin_helper::Dictionary& options) {
|
||||||
bool BaseWindow::IsSnapped() const {
|
bool BaseWindow::IsSnapped() const {
|
||||||
return window_->IsSnapped();
|
return window_->IsSnapped();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BaseWindow::SetAccentColor(gin_helper::Arguments* args) {
|
||||||
|
bool accent_color = false;
|
||||||
|
std::string accent_color_string;
|
||||||
|
if (args->GetNext(&accent_color_string)) {
|
||||||
|
std::optional<SkColor> maybe_color = ParseCSSColor(accent_color_string);
|
||||||
|
if (maybe_color.has_value()) {
|
||||||
|
window_->SetAccentColor(maybe_color.value());
|
||||||
|
window_->UpdateWindowAccentColor(window_->IsActive());
|
||||||
|
}
|
||||||
|
} else if (args->GetNext(&accent_color)) {
|
||||||
|
window_->SetAccentColor(accent_color);
|
||||||
|
window_->UpdateWindowAccentColor(window_->IsActive());
|
||||||
|
} else {
|
||||||
|
args->ThrowError(
|
||||||
|
"Invalid accent color value - must be a string or boolean");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Local<v8::Value> BaseWindow::GetAccentColor() const {
|
||||||
|
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||||
|
auto accent_color = window_->GetAccentColor();
|
||||||
|
|
||||||
|
if (std::holds_alternative<bool>(accent_color))
|
||||||
|
return v8::Boolean::New(isolate, std::get<bool>(accent_color));
|
||||||
|
return gin::StringToV8(isolate, std::get<std::string>(accent_color));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
|
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
|
||||||
|
@ -1333,6 +1360,8 @@ void BaseWindow::BuildPrototype(v8::Isolate* isolate,
|
||||||
#if BUILDFLAG(IS_WIN)
|
#if BUILDFLAG(IS_WIN)
|
||||||
.SetMethod("isSnapped", &BaseWindow::IsSnapped)
|
.SetMethod("isSnapped", &BaseWindow::IsSnapped)
|
||||||
.SetProperty("snapped", &BaseWindow::IsSnapped)
|
.SetProperty("snapped", &BaseWindow::IsSnapped)
|
||||||
|
.SetMethod("setAccentColor", &BaseWindow::SetAccentColor)
|
||||||
|
.SetMethod("getAccentColor", &BaseWindow::GetAccentColor)
|
||||||
.SetMethod("hookWindowMessage", &BaseWindow::HookWindowMessage)
|
.SetMethod("hookWindowMessage", &BaseWindow::HookWindowMessage)
|
||||||
.SetMethod("isWindowMessageHooked", &BaseWindow::IsWindowMessageHooked)
|
.SetMethod("isWindowMessageHooked", &BaseWindow::IsWindowMessageHooked)
|
||||||
.SetMethod("unhookWindowMessage", &BaseWindow::UnhookWindowMessage)
|
.SetMethod("unhookWindowMessage", &BaseWindow::UnhookWindowMessage)
|
||||||
|
|
|
@ -255,6 +255,8 @@ class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
|
||||||
bool SetThumbnailToolTip(const std::string& tooltip);
|
bool SetThumbnailToolTip(const std::string& tooltip);
|
||||||
void SetAppDetails(const gin_helper::Dictionary& options);
|
void SetAppDetails(const gin_helper::Dictionary& options);
|
||||||
bool IsSnapped() const;
|
bool IsSnapped() const;
|
||||||
|
void SetAccentColor(gin_helper::Arguments* args);
|
||||||
|
v8::Local<v8::Value> GetAccentColor() const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
|
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
|
||||||
|
|
|
@ -56,7 +56,7 @@ class SystemPreferences final
|
||||||
const char* GetTypeName() override;
|
const char* GetTypeName() override;
|
||||||
|
|
||||||
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
|
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
|
||||||
std::string GetAccentColor();
|
static std::string GetAccentColor();
|
||||||
std::string GetColor(gin_helper::ErrorThrower thrower,
|
std::string GetColor(gin_helper::ErrorThrower thrower,
|
||||||
const std::string& color);
|
const std::string& color);
|
||||||
std::string GetMediaAccessStatus(gin_helper::ErrorThrower thrower,
|
std::string GetMediaAccessStatus(gin_helper::ErrorThrower thrower,
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
#include <dwmapi.h>
|
|
||||||
#include <windows.devices.enumeration.h>
|
#include <windows.devices.enumeration.h>
|
||||||
#include <wrl/client.h>
|
#include <wrl/client.h>
|
||||||
|
|
||||||
|
@ -84,14 +83,12 @@ std::string hexColorDWORDToRGBA(DWORD color) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SystemPreferences::GetAccentColor() {
|
std::string SystemPreferences::GetAccentColor() {
|
||||||
DWORD color = 0;
|
std::optional<DWORD> color = GetSystemAccentColor();
|
||||||
BOOL opaque = FALSE;
|
|
||||||
|
|
||||||
if (FAILED(DwmGetColorizationColor(&color, &opaque))) {
|
if (!color.has_value())
|
||||||
return "";
|
return "";
|
||||||
}
|
|
||||||
|
|
||||||
return hexColorDWORDToRGBA(color);
|
return hexColorDWORDToRGBA(color.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SystemPreferences::GetColor(gin_helper::ErrorThrower thrower,
|
std::string SystemPreferences::GetColor(gin_helper::ErrorThrower thrower,
|
||||||
|
|
|
@ -345,6 +345,10 @@ class NativeWindow : public base::SupportsUserData,
|
||||||
|
|
||||||
#if BUILDFLAG(IS_WIN)
|
#if BUILDFLAG(IS_WIN)
|
||||||
void NotifyWindowMessage(UINT message, WPARAM w_param, LPARAM l_param);
|
void NotifyWindowMessage(UINT message, WPARAM w_param, LPARAM l_param);
|
||||||
|
virtual void SetAccentColor(
|
||||||
|
std::variant<std::monostate, bool, SkColor> accent_color) = 0;
|
||||||
|
virtual std::variant<bool, std::string> GetAccentColor() const = 0;
|
||||||
|
virtual void UpdateWindowAccentColor(bool active) = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void AddObserver(NativeWindowObserver* obs) { observers_.AddObserver(obs); }
|
void AddObserver(NativeWindowObserver* obs) { observers_.AddObserver(obs); }
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "base/strings/utf_string_conversions.h"
|
#include "base/strings/utf_string_conversions.h"
|
||||||
#include "content/public/browser/desktop_media_id.h"
|
#include "content/public/browser/desktop_media_id.h"
|
||||||
#include "content/public/common/color_parser.h"
|
#include "content/public/common/color_parser.h"
|
||||||
|
#include "shell/browser/api/electron_api_system_preferences.h"
|
||||||
#include "shell/browser/api/electron_api_web_contents.h"
|
#include "shell/browser/api/electron_api_web_contents.h"
|
||||||
#include "shell/browser/ui/inspectable_web_contents_view.h"
|
#include "shell/browser/ui/inspectable_web_contents_view.h"
|
||||||
#include "shell/browser/ui/views/root_view.h"
|
#include "shell/browser/ui/views/root_view.h"
|
||||||
|
|
|
@ -170,6 +170,10 @@ class NativeWindowViews : public NativeWindow,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BUILDFLAG(IS_WIN)
|
#if BUILDFLAG(IS_WIN)
|
||||||
|
void SetAccentColor(
|
||||||
|
std::variant<std::monostate, bool, SkColor> accent_color) override;
|
||||||
|
std::variant<bool, std::string> GetAccentColor() const override;
|
||||||
|
void UpdateWindowAccentColor(bool active) override;
|
||||||
TaskbarHost& taskbar_host() { return taskbar_host_; }
|
TaskbarHost& taskbar_host() { return taskbar_host_; }
|
||||||
void UpdateThickFrame();
|
void UpdateThickFrame();
|
||||||
void SetLayered();
|
void SetLayered();
|
||||||
|
@ -211,7 +215,6 @@ class NativeWindowViews : public NativeWindow,
|
||||||
void ResetWindowControls();
|
void ResetWindowControls();
|
||||||
void SetRoundedCorners(bool rounded);
|
void SetRoundedCorners(bool rounded);
|
||||||
void SetForwardMouseMessages(bool forward);
|
void SetForwardMouseMessages(bool forward);
|
||||||
void UpdateWindowAccentColor(bool active);
|
|
||||||
static LRESULT CALLBACK SubclassProc(HWND hwnd,
|
static LRESULT CALLBACK SubclassProc(HWND hwnd,
|
||||||
UINT msg,
|
UINT msg,
|
||||||
WPARAM w_param,
|
WPARAM w_param,
|
||||||
|
|
|
@ -16,7 +16,9 @@
|
||||||
#include "shell/browser/native_window_views.h"
|
#include "shell/browser/native_window_views.h"
|
||||||
#include "shell/browser/ui/views/root_view.h"
|
#include "shell/browser/ui/views/root_view.h"
|
||||||
#include "shell/browser/ui/views/win_frame_view.h"
|
#include "shell/browser/ui/views/win_frame_view.h"
|
||||||
|
#include "shell/common/color_util.h"
|
||||||
#include "shell/common/electron_constants.h"
|
#include "shell/common/electron_constants.h"
|
||||||
|
#include "skia/ext/skia_utils_win.h"
|
||||||
#include "ui/display/display.h"
|
#include "ui/display/display.h"
|
||||||
#include "ui/display/screen.h"
|
#include "ui/display/screen.h"
|
||||||
#include "ui/gfx/geometry/resize_utils.h"
|
#include "ui/gfx/geometry/resize_utils.h"
|
||||||
|
@ -46,21 +48,6 @@ void SetWindowBorderAndCaptionColor(HWND hwnd, COLORREF color) {
|
||||||
LOG(WARNING) << "Failed to set border color";
|
LOG(WARNING) << "Failed to set border color";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<DWORD> GetAccentColor() {
|
|
||||||
base::win::RegKey key;
|
|
||||||
if (key.Open(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\DWM",
|
|
||||||
KEY_READ) != ERROR_SUCCESS) {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD accent_color = 0;
|
|
||||||
if (key.ReadValueDW(L"AccentColor", &accent_color) != ERROR_SUCCESS) {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
return accent_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsAccentColorOnTitleBarsEnabled() {
|
bool IsAccentColorOnTitleBarsEnabled() {
|
||||||
base::win::RegKey key;
|
base::win::RegKey key;
|
||||||
if (key.Open(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\DWM",
|
if (key.Open(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\DWM",
|
||||||
|
@ -594,7 +581,7 @@ void NativeWindowViews::UpdateWindowAccentColor(bool active) {
|
||||||
|
|
||||||
// Use system accent color as fallback if no explicit color was set.
|
// Use system accent color as fallback if no explicit color was set.
|
||||||
if (!border_color.has_value() && should_apply_accent) {
|
if (!border_color.has_value() && should_apply_accent) {
|
||||||
std::optional<DWORD> system_accent_color = GetAccentColor();
|
std::optional<DWORD> system_accent_color = GetSystemAccentColor();
|
||||||
if (system_accent_color.has_value()) {
|
if (system_accent_color.has_value()) {
|
||||||
border_color = RGB(GetRValue(system_accent_color.value()),
|
border_color = RGB(GetRValue(system_accent_color.value()),
|
||||||
GetGValue(system_accent_color.value()),
|
GetGValue(system_accent_color.value()),
|
||||||
|
@ -606,6 +593,39 @@ void NativeWindowViews::UpdateWindowAccentColor(bool active) {
|
||||||
SetWindowBorderAndCaptionColor(GetAcceleratedWidget(), final_color);
|
SetWindowBorderAndCaptionColor(GetAcceleratedWidget(), final_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeWindowViews::SetAccentColor(
|
||||||
|
std::variant<std::monostate, bool, SkColor> accent_color) {
|
||||||
|
accent_color_ = accent_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the window's accent color, per the following heuristic:
|
||||||
|
*
|
||||||
|
* - If |accent_color_| is an SkColor, return that color as a hex string.
|
||||||
|
* - If |accent_color_| is true, return the system accent color as a hex string.
|
||||||
|
* - If |accent_color_| is false, return false.
|
||||||
|
* - Otherwise, return the system accent color as a hex string.
|
||||||
|
*/
|
||||||
|
std::variant<bool, std::string> NativeWindowViews::GetAccentColor() const {
|
||||||
|
std::optional<DWORD> system_color = GetSystemAccentColor();
|
||||||
|
|
||||||
|
if (std::holds_alternative<SkColor>(accent_color_)) {
|
||||||
|
return ToRGBHex(std::get<SkColor>(accent_color_));
|
||||||
|
} else if (std::holds_alternative<bool>(accent_color_)) {
|
||||||
|
if (std::get<bool>(accent_color_)) {
|
||||||
|
if (!system_color.has_value())
|
||||||
|
return false;
|
||||||
|
return ToRGBHex(skia::COLORREFToSkColor(system_color.value()));
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!system_color.has_value())
|
||||||
|
return false;
|
||||||
|
return ToRGBHex(skia::COLORREFToSkColor(system_color.value()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NativeWindowViews::ResetWindowControls() {
|
void NativeWindowViews::ResetWindowControls() {
|
||||||
// If a given window was minimized and has since been
|
// If a given window was minimized and has since been
|
||||||
// unminimized (restored/maximized), ensure the WCO buttons
|
// unminimized (restored/maximized), ensure the WCO buttons
|
||||||
|
|
|
@ -10,6 +10,10 @@
|
||||||
#include "content/public/common/color_parser.h"
|
#include "content/public/common/color_parser.h"
|
||||||
#include "third_party/abseil-cpp/absl/strings/str_format.h"
|
#include "third_party/abseil-cpp/absl/strings/str_format.h"
|
||||||
|
|
||||||
|
#if BUILDFLAG(IS_WIN)
|
||||||
|
#include <dwmapi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool IsHexFormatWithAlpha(const std::string& str) {
|
bool IsHexFormatWithAlpha(const std::string& str) {
|
||||||
|
@ -62,4 +66,15 @@ std::string ToRGBAHex(SkColor color, bool include_hash) {
|
||||||
return color_str;
|
return color_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BUILDFLAG(IS_WIN)
|
||||||
|
std::optional<DWORD> GetSystemAccentColor() {
|
||||||
|
DWORD color = 0;
|
||||||
|
BOOL opaque = FALSE;
|
||||||
|
|
||||||
|
if (FAILED(DwmGetColorizationColor(&color, &opaque)))
|
||||||
|
return std::nullopt;
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace electron
|
} // namespace electron
|
||||||
|
|
|
@ -8,6 +8,12 @@
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "build/build_config.h"
|
||||||
|
|
||||||
|
#if BUILDFLAG(IS_WIN)
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "third_party/skia/include/core/SkColor.h"
|
#include "third_party/skia/include/core/SkColor.h"
|
||||||
|
|
||||||
// SkColor is a typedef for uint32_t, this wrapper is to tag an SkColor for
|
// SkColor is a typedef for uint32_t, this wrapper is to tag an SkColor for
|
||||||
|
@ -31,6 +37,10 @@ std::string ToRGBHex(SkColor color);
|
||||||
// Convert color to RGBA hex value like "#RRGGBBAA".
|
// Convert color to RGBA hex value like "#RRGGBBAA".
|
||||||
std::string ToRGBAHex(SkColor color, bool include_hash = true);
|
std::string ToRGBAHex(SkColor color, bool include_hash = true);
|
||||||
|
|
||||||
|
#if BUILDFLAG(IS_WIN)
|
||||||
|
std::optional<DWORD> GetSystemAccentColor();
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace electron
|
} // namespace electron
|
||||||
|
|
||||||
#endif // ELECTRON_SHELL_COMMON_COLOR_UTIL_H_
|
#endif // ELECTRON_SHELL_COMMON_COLOR_UTIL_H_
|
||||||
|
|
|
@ -2523,6 +2523,92 @@ describe('BrowserWindow module', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ifdescribe(process.platform === 'win32')('BrowserWindow.{get|set}AccentColor', () => {
|
||||||
|
afterEach(closeAllWindows);
|
||||||
|
|
||||||
|
it('throws if called with an invalid parameter', () => {
|
||||||
|
const w = new BrowserWindow({ show: false });
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the accent color after setting it to a string', () => {
|
||||||
|
const w = new BrowserWindow({ show: false });
|
||||||
|
const testColor = '#FF0000';
|
||||||
|
w.setAccentColor(testColor);
|
||||||
|
const accentColor = w.getAccentColor();
|
||||||
|
expect(accentColor).to.be.a('string');
|
||||||
|
expect(accentColor).to.equal(testColor);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the accent color after setting it to false', () => {
|
||||||
|
const w = new BrowserWindow({ show: false });
|
||||||
|
w.setAccentColor(false);
|
||||||
|
const accentColor = w.getAccentColor();
|
||||||
|
expect(accentColor).to.be.a('boolean');
|
||||||
|
expect(accentColor).to.equal(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns a system color when set to true', () => {
|
||||||
|
const w = new BrowserWindow({ show: false });
|
||||||
|
w.setAccentColor(true);
|
||||||
|
const accentColor = w.getAccentColor();
|
||||||
|
expect(accentColor).to.be.a('string');
|
||||||
|
expect(accentColor).to.match(/^#[0-9A-F]{6}$/i);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the correct accent color after multiple changes', () => {
|
||||||
|
const w = new BrowserWindow({ show: false });
|
||||||
|
|
||||||
|
const testColor1 = '#00FF00';
|
||||||
|
w.setAccentColor(testColor1);
|
||||||
|
expect(w.getAccentColor()).to.equal(testColor1);
|
||||||
|
|
||||||
|
w.setAccentColor(false);
|
||||||
|
expect(w.getAccentColor()).to.equal(false);
|
||||||
|
|
||||||
|
const testColor2 = '#0000FF';
|
||||||
|
w.setAccentColor(testColor2);
|
||||||
|
expect(w.getAccentColor()).to.equal(testColor2);
|
||||||
|
|
||||||
|
w.setAccentColor(true);
|
||||||
|
const systemColor = w.getAccentColor();
|
||||||
|
expect(systemColor).to.be.a('string');
|
||||||
|
expect(systemColor).to.match(/^#[0-9A-F]{6}$/i);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles CSS color names correctly', () => {
|
||||||
|
const w = new BrowserWindow({ show: false });
|
||||||
|
const testColor = 'red';
|
||||||
|
w.setAccentColor(testColor);
|
||||||
|
const accentColor = w.getAccentColor();
|
||||||
|
expect(accentColor).to.be.a('string');
|
||||||
|
expect(accentColor).to.equal('#FF0000');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles RGB color values correctly', () => {
|
||||||
|
const w = new BrowserWindow({ show: false });
|
||||||
|
const testColor = 'rgb(255, 128, 0)';
|
||||||
|
w.setAccentColor(testColor);
|
||||||
|
const accentColor = w.getAccentColor();
|
||||||
|
expect(accentColor).to.be.a('string');
|
||||||
|
expect(accentColor).to.equal('#FF8000');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('persists accent color across window operations', () => {
|
||||||
|
const w = new BrowserWindow({ show: false });
|
||||||
|
const testColor = '#ABCDEF';
|
||||||
|
w.setAccentColor(testColor);
|
||||||
|
|
||||||
|
w.show();
|
||||||
|
w.hide();
|
||||||
|
|
||||||
|
expect(w.getAccentColor()).to.equal(testColor);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('BrowserWindow.setAlwaysOnTop(flag, level)', () => {
|
describe('BrowserWindow.setAlwaysOnTop(flag, level)', () => {
|
||||||
let w: BrowserWindow;
|
let w: BrowserWindow;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue