diff --git a/atom/browser/api/atom_api_system_preferences.cc b/atom/browser/api/atom_api_system_preferences.cc index d008405fde98..2acaf4a72ea8 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::IsHighContrastColorScheme() { + 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::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 04fd31f7159d..47e166046ff0 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 IsHighContrastColorScheme(); 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 0a24d1abf45f..424bf0d950a2 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::IsHighContrastColorScheme() { + 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_ = IsHighContrastColorScheme(); // 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 = 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); + } + Emit("color-changed"); } diff --git a/docs/api/system-preferences.md b/docs/api/system-preferences.md index c7dae037280a..31d35291a4d5 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_