Skip to content

Commit

Permalink
feat: detect high contrast color mode (#15493)
Browse files Browse the repository at this point in the history
* feat: add event and method to detect high contrast color mode

* docs: add docs for isHighContrastColorScheme and high-contrast-color-scheme-changed

* refactor: correct type of contrast
  • Loading branch information
brenca authored and John Kleinschmidt committed Oct 31, 2018
1 parent aa6f7a5 commit 6d2a088
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 5 deletions.
8 changes: 8 additions & 0 deletions atom/browser/api/atom_api_system_preferences.cc
Expand Up @@ -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> SystemPreferences::Create(
v8::Isolate* isolate) {
Expand Down Expand Up @@ -86,6 +92,8 @@ void SystemPreferences::BuildPrototype(
#endif
.SetMethod("isInvertedColorScheme",
&SystemPreferences::IsInvertedColorScheme)
.SetMethod("isHighContrastColorScheme",
&SystemPreferences::IsHighContrastColorScheme)
.SetMethod("isDarkMode", &SystemPreferences::IsDarkMode);
}

Expand Down
3 changes: 3 additions & 0 deletions atom/browser/api/atom_api_system_preferences.h
Expand Up @@ -98,6 +98,7 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>
#endif
bool IsDarkMode();
bool IsInvertedColorScheme();
bool IsHighContrastColorScheme();

protected:
explicit SystemPreferences(v8::Isolate* isolate);
Expand Down Expand Up @@ -139,6 +140,8 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences>

bool invertered_color_scheme_;

bool high_contrast_color_scheme_;

std::unique_ptr<gfx::ScopedSysColorChangeListener> color_change_listener_;
#endif
DISALLOW_COPY_AND_ASSIGN(SystemPreferences);
Expand Down
29 changes: 29 additions & 0 deletions atom/browser/api/atom_api_system_preferences_win.cc
Expand Up @@ -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 {
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}
Expand All @@ -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");
}

Expand Down
19 changes: 14 additions & 5 deletions docs/api/system-preferences.md
Expand Up @@ -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_

Expand Down Expand Up @@ -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_

Expand Down

0 comments on commit 6d2a088

Please sign in to comment.