mirror of
https://github.com/electron/electron.git
synced 2026-01-10 07:58:08 -05:00
feat: add {get|set}AccentColor on Windows (#47741)
* feat: add setAccentColor on Windows * refactor: unify GetSystemAccentColor * refactor: remove redundant parsing * chore: fixup documentation * Update docs/api/browser-window.md Co-authored-by: Will Anderson <andersonw@dropbox.com> * Update docs/api/base-window.md Co-authored-by: Will Anderson <andersonw@dropbox.com> --------- Co-authored-by: Will Anderson <andersonw@dropbox.com>
This commit is contained in:
@@ -1089,6 +1089,33 @@ void BaseWindow::SetAppDetails(const gin_helper::Dictionary& options) {
|
||||
bool BaseWindow::IsSnapped() const {
|
||||
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
|
||||
|
||||
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
|
||||
@@ -1277,6 +1304,8 @@ void BaseWindow::BuildPrototype(v8::Isolate* isolate,
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
.SetMethod("isSnapped", &BaseWindow::IsSnapped)
|
||||
.SetProperty("snapped", &BaseWindow::IsSnapped)
|
||||
.SetMethod("setAccentColor", &BaseWindow::SetAccentColor)
|
||||
.SetMethod("getAccentColor", &BaseWindow::GetAccentColor)
|
||||
.SetMethod("hookWindowMessage", &BaseWindow::HookWindowMessage)
|
||||
.SetMethod("isWindowMessageHooked", &BaseWindow::IsWindowMessageHooked)
|
||||
.SetMethod("unhookWindowMessage", &BaseWindow::UnhookWindowMessage)
|
||||
|
||||
@@ -255,6 +255,8 @@ class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
|
||||
bool SetThumbnailToolTip(const std::string& tooltip);
|
||||
void SetAppDetails(const gin_helper::Dictionary& options);
|
||||
bool IsSnapped() const;
|
||||
void SetAccentColor(gin_helper::Arguments* args);
|
||||
v8::Local<v8::Value> GetAccentColor() const;
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
|
||||
|
||||
@@ -56,7 +56,7 @@ class SystemPreferences final
|
||||
const char* GetTypeName() override;
|
||||
|
||||
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
|
||||
std::string GetAccentColor();
|
||||
static std::string GetAccentColor();
|
||||
std::string GetColor(gin_helper::ErrorThrower thrower,
|
||||
const std::string& color);
|
||||
std::string GetMediaAccessStatus(gin_helper::ErrorThrower thrower,
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <iomanip>
|
||||
#include <string_view>
|
||||
|
||||
#include <dwmapi.h>
|
||||
#include <windows.devices.enumeration.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
@@ -84,14 +83,12 @@ std::string hexColorDWORDToRGBA(DWORD color) {
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetAccentColor() {
|
||||
DWORD color = 0;
|
||||
BOOL opaque = FALSE;
|
||||
std::optional<DWORD> color = GetSystemAccentColor();
|
||||
|
||||
if (FAILED(DwmGetColorizationColor(&color, &opaque))) {
|
||||
if (!color.has_value())
|
||||
return "";
|
||||
}
|
||||
|
||||
return hexColorDWORDToRGBA(color);
|
||||
return hexColorDWORDToRGBA(color.value());
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetColor(gin_helper::ErrorThrower thrower,
|
||||
|
||||
@@ -347,6 +347,10 @@ class NativeWindow : public base::SupportsUserData,
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
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
|
||||
|
||||
void AddObserver(NativeWindowObserver* obs) { observers_.AddObserver(obs); }
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/public/browser/desktop_media_id.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/ui/inspectable_web_contents_view.h"
|
||||
#include "shell/browser/ui/views/root_view.h"
|
||||
|
||||
@@ -176,6 +176,10 @@ class NativeWindowViews : public NativeWindow,
|
||||
#endif
|
||||
|
||||
#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_; }
|
||||
void UpdateThickFrame();
|
||||
void SetLayered();
|
||||
@@ -223,7 +227,6 @@ class NativeWindowViews : public NativeWindow,
|
||||
void ResetWindowControls();
|
||||
void SetRoundedCorners(bool rounded);
|
||||
void SetForwardMouseMessages(bool forward);
|
||||
void UpdateWindowAccentColor(bool active);
|
||||
static LRESULT CALLBACK SubclassProc(HWND hwnd,
|
||||
UINT msg,
|
||||
WPARAM w_param,
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
#include "shell/browser/native_window_views.h"
|
||||
#include "shell/browser/ui/views/root_view.h"
|
||||
#include "shell/browser/ui/views/win_frame_view.h"
|
||||
#include "shell/common/color_util.h"
|
||||
#include "shell/common/electron_constants.h"
|
||||
#include "skia/ext/skia_utils_win.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/display/screen.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";
|
||||
}
|
||||
|
||||
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() {
|
||||
base::win::RegKey key;
|
||||
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.
|
||||
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()) {
|
||||
border_color = RGB(GetRValue(system_accent_color.value()),
|
||||
GetGValue(system_accent_color.value()),
|
||||
@@ -606,6 +593,39 @@ void NativeWindowViews::UpdateWindowAccentColor(bool active) {
|
||||
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() {
|
||||
// If a given window was minimized and has since been
|
||||
// unminimized (restored/maximized), ensure the WCO buttons
|
||||
|
||||
Reference in New Issue
Block a user