From a7522ad2ca460155669e8b4b1a65625366016e29 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Wed, 31 Oct 2018 10:45:19 +0100 Subject: [PATCH 1/3] feat: add event and method to detect high contrast color mode --- .../api/atom_api_system_preferences.cc | 8 +++++ .../browser/api/atom_api_system_preferences.h | 3 ++ .../api/atom_api_system_preferences_win.cc | 29 +++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/atom/browser/api/atom_api_system_preferences.cc b/atom/browser/api/atom_api_system_preferences.cc index d008405fde98a..691a6e8262113 100644 --- a/atom/browser/api/atom_api_system_preferences.cc +++ b/atom/browser/api/atom_api_system_preferences.cc @@ -37,6 +37,12 @@ bool SystemPreferences::IsInvertedColorScheme() { return color_utils::IsInvertedColorScheme(); } +#if !defined(OS_WIN) +bool SystemPreferences::IsHighContractColorScheme() { + return false; +} +#endif // !defined(OS_WIN) + // static mate::Handle SystemPreferences::Create( v8::Isolate* isolate) { @@ -86,6 +92,8 @@ void SystemPreferences::BuildPrototype( #endif .SetMethod("isInvertedColorScheme", &SystemPreferences::IsInvertedColorScheme) + .SetMethod("isHighContrastColorScheme", + &SystemPreferences::IsHighContractColorScheme) .SetMethod("isDarkMode", &SystemPreferences::IsDarkMode); } diff --git a/atom/browser/api/atom_api_system_preferences.h b/atom/browser/api/atom_api_system_preferences.h index 04fd31f7159d6..ddfccc6f3d6ae 100644 --- a/atom/browser/api/atom_api_system_preferences.h +++ b/atom/browser/api/atom_api_system_preferences.h @@ -98,6 +98,7 @@ class SystemPreferences : public mate::EventEmitter #endif bool IsDarkMode(); bool IsInvertedColorScheme(); + bool IsHighContractColorScheme(); protected: explicit SystemPreferences(v8::Isolate* isolate); @@ -139,6 +140,8 @@ class SystemPreferences : public mate::EventEmitter bool invertered_color_scheme_; + bool high_contrast_color_scheme_; + std::unique_ptr color_change_listener_; #endif DISALLOW_COPY_AND_ASSIGN(SystemPreferences); diff --git a/atom/browser/api/atom_api_system_preferences_win.cc b/atom/browser/api/atom_api_system_preferences_win.cc index 0a24d1abf45fe..90958ae924f3c 100644 --- a/atom/browser/api/atom_api_system_preferences_win.cc +++ b/atom/browser/api/atom_api_system_preferences_win.cc @@ -20,6 +20,18 @@ namespace { const wchar_t kSystemPreferencesWindowClass[] = L"Electron_SystemPreferencesHostWindow"; +bool g_is_high_contract_color_scheme = false; +bool g_is_high_contract_color_scheme_initialized = false; + +void UpdateHighContrastColorScheme() { + HIGHCONTRAST high_contrast = {0}; + high_contrast.cbSize = sizeof(HIGHCONTRAST); + g_is_high_contract_color_scheme = + SystemParametersInfo(SPI_GETHIGHCONTRAST, 0, &high_contrast, 0) && + ((high_contrast.dwFlags & HCF_HIGHCONTRASTON) != 0); + g_is_high_contract_color_scheme_initialized = true; +} + } // namespace namespace api { @@ -28,6 +40,12 @@ bool SystemPreferences::IsAeroGlassEnabled() { return ui::win::IsAeroGlassEnabled(); } +bool SystemPreferences::IsHighContractColorScheme() { + if (!g_is_high_contract_color_scheme_initialized) + UpdateHighContrastColorScheme(); + return g_is_high_contract_color_scheme; +} + std::string hexColorDWORDToRGBA(DWORD color) { DWORD rgba = color << 8 | color >> 24; std::ostringstream stream; @@ -119,6 +137,7 @@ std::string SystemPreferences::GetColor(const std::string& color, void SystemPreferences::InitializeWindow() { invertered_color_scheme_ = IsInvertedColorScheme(); + high_contrast_color_scheme_ = IsHighContractColorScheme(); // Wait until app is ready before creating sys color listener // Creating this listener before the app is ready causes global shortcuts @@ -169,6 +188,9 @@ LRESULT CALLBACK SystemPreferences::WndProc(HWND hwnd, Emit("accent-color-changed", hexColorDWORDToRGBA(new_color)); current_color_ = new_color_string; } + } else if (message == WM_SYSCOLORCHANGE || + (message == WM_SETTINGCHANGE && wparam == SPI_SETHIGHCONTRAST)) { + UpdateHighContrastColorScheme(); } return ::DefWindowProc(hwnd, message, wparam, lparam); } @@ -179,6 +201,13 @@ void SystemPreferences::OnSysColorChange() { invertered_color_scheme_ = new_invertered_color_scheme; Emit("inverted-color-scheme-changed", new_invertered_color_scheme); } + + bool new_high_contrast_color_scheme = IsHighContractColorScheme(); + if (new_high_contrast_color_scheme != high_contrast_color_scheme_) { + high_contrast_color_scheme_ = new_high_contrast_color_scheme; + Emit("high-contrast-color-scheme-changed", new_high_contrast_color_scheme); + } + Emit("color-changed"); } From 26da0652159b96f252677b0b53a974d800487acd Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Wed, 31 Oct 2018 10:46:50 +0100 Subject: [PATCH 2/3] docs: add docs for isHighContrastColorScheme and high-contrast-color-scheme-changed --- docs/api/system-preferences.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/docs/api/system-preferences.md b/docs/api/system-preferences.md index c7dae037280a6..31d35291a4d54 100644 --- a/docs/api/system-preferences.md +++ b/docs/api/system-preferences.md @@ -32,8 +32,14 @@ Returns: Returns: * `event` Event -* `invertedColorScheme` Boolean - `true` if an inverted color scheme, such as - a high contrast theme, is being used, `false` otherwise. +* `invertedColorScheme` Boolean - `true` if an inverted color scheme (a high contrast color scheme with light text and dark backgrounds) is being used, `false` otherwise. + +### Event: 'high-contrast-color-scheme-changed' _Windows_ + +Returns: + +* `event` Event +* `highContrastColorScheme` Boolean - `true` if a high contrast theme is being used, `false` otherwise. ### Event: 'appearance-changed' _macOS_ @@ -276,12 +282,15 @@ const alpha = color.substr(6, 2) // "dd" Returns `String` - The system color setting in RGB hexadecimal form (`#ABCDEF`). See the [Windows docs][windows-colors] for more details. +[windows-colors]:https://msdn.microsoft.com/en-us/library/windows/desktop/ms724371(v=vs.85).aspx + ### `systemPreferences.isInvertedColorScheme()` _Windows_ -Returns `Boolean` - `true` if an inverted color scheme, such as a high contrast -theme, is active, `false` otherwise. +Returns `Boolean` - `true` if an inverted color scheme (a high contrast color scheme with light text and dark backgrounds) is active, `false` otherwise. -[windows-colors]:https://msdn.microsoft.com/en-us/library/windows/desktop/ms724371(v=vs.85).aspx +### `systemPreferences.isHighContrastColorScheme()` _Windows_ + +Returns `Boolean` - `true` if a high contrast theme is active, `false` otherwise. ### `systemPreferences.getEffectiveAppearance()` _macOS_ From aef4baadd2f73f2794d325fc30b54ee730ce4960 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Wed, 31 Oct 2018 10:48:02 +0100 Subject: [PATCH 3/3] refactor: correct type of contrast --- atom/browser/api/atom_api_system_preferences.cc | 4 ++-- atom/browser/api/atom_api_system_preferences.h | 2 +- atom/browser/api/atom_api_system_preferences_win.cc | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/atom/browser/api/atom_api_system_preferences.cc b/atom/browser/api/atom_api_system_preferences.cc index 691a6e8262113..2acaf4a72ea87 100644 --- a/atom/browser/api/atom_api_system_preferences.cc +++ b/atom/browser/api/atom_api_system_preferences.cc @@ -38,7 +38,7 @@ bool SystemPreferences::IsInvertedColorScheme() { } #if !defined(OS_WIN) -bool SystemPreferences::IsHighContractColorScheme() { +bool SystemPreferences::IsHighContrastColorScheme() { return false; } #endif // !defined(OS_WIN) @@ -93,7 +93,7 @@ void SystemPreferences::BuildPrototype( .SetMethod("isInvertedColorScheme", &SystemPreferences::IsInvertedColorScheme) .SetMethod("isHighContrastColorScheme", - &SystemPreferences::IsHighContractColorScheme) + &SystemPreferences::IsHighContrastColorScheme) .SetMethod("isDarkMode", &SystemPreferences::IsDarkMode); } diff --git a/atom/browser/api/atom_api_system_preferences.h b/atom/browser/api/atom_api_system_preferences.h index ddfccc6f3d6ae..47e166046ff00 100644 --- a/atom/browser/api/atom_api_system_preferences.h +++ b/atom/browser/api/atom_api_system_preferences.h @@ -98,7 +98,7 @@ class SystemPreferences : public mate::EventEmitter #endif bool IsDarkMode(); bool IsInvertedColorScheme(); - bool IsHighContractColorScheme(); + bool IsHighContrastColorScheme(); protected: explicit SystemPreferences(v8::Isolate* isolate); diff --git a/atom/browser/api/atom_api_system_preferences_win.cc b/atom/browser/api/atom_api_system_preferences_win.cc index 90958ae924f3c..424bf0d950a21 100644 --- a/atom/browser/api/atom_api_system_preferences_win.cc +++ b/atom/browser/api/atom_api_system_preferences_win.cc @@ -40,7 +40,7 @@ bool SystemPreferences::IsAeroGlassEnabled() { return ui::win::IsAeroGlassEnabled(); } -bool SystemPreferences::IsHighContractColorScheme() { +bool SystemPreferences::IsHighContrastColorScheme() { if (!g_is_high_contract_color_scheme_initialized) UpdateHighContrastColorScheme(); return g_is_high_contract_color_scheme; @@ -137,7 +137,7 @@ std::string SystemPreferences::GetColor(const std::string& color, void SystemPreferences::InitializeWindow() { invertered_color_scheme_ = IsInvertedColorScheme(); - high_contrast_color_scheme_ = IsHighContractColorScheme(); + high_contrast_color_scheme_ = IsHighContrastColorScheme(); // Wait until app is ready before creating sys color listener // Creating this listener before the app is ready causes global shortcuts @@ -202,7 +202,7 @@ void SystemPreferences::OnSysColorChange() { Emit("inverted-color-scheme-changed", new_invertered_color_scheme); } - bool new_high_contrast_color_scheme = IsHighContractColorScheme(); + bool new_high_contrast_color_scheme = IsHighContrastColorScheme(); if (new_high_contrast_color_scheme != high_contrast_color_scheme_) { high_contrast_color_scheme_ = new_high_contrast_color_scheme; Emit("high-contrast-color-scheme-changed", new_high_contrast_color_scheme);