Repository navigation
feat: add Menu.setHighlightColors() for Windows - #55074
Conversation
Lets apps set the background and text color of the hovered or keyboard-focused item in Views menus on Windows. The colors are skipped in high contrast and forced colors modes. Closes electron#54953 Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
d767145 to
68a4ef3
Compare
| ``` | ||
| --> | ||
|
|
||
| - `options` Object | null |
There was a problem hiding this comment.
Having the dark mode options be an optional override feels strange, since we're then making the simplest usage result in no differentiation between light/dark mode (which is likely not what people want most of the time).
I wonder if a more symmetrical API would be better:
- `light` (optional)
- `background` string (optional)
- `foreground` string (optional)
- `dark` (optional)
- `background` string (optional)
- `foreground` string (optional)
Or alternatively:
- `lightBackground` string (optional)
- `lightForeground` string (optional)
- `darkBackground` string (optional)
- `darkForeground` string (optional)
If someone specifically wants to use the same colors for light/dark mode, then it would force them to be more verbose, but otherwise these API shapes would make calls to setHighlightColors much more explanatory without someone having to look up the docs to understand the override/fallback behaviors.
There was a problem hiding this comment.
That makes sense, thanks for pointing that out! I've switched to the nested version, and each mode only uses its own colors (no fallback).
| if (gin::ConvertFromV8(isolate, value, &str)) | ||
| *out = ParseCSSColor(str); | ||
| if (!*out) { | ||
| thrower.ThrowTypeError(base::StrCat({"Invalid color for '", key, "'"})); |
There was a problem hiding this comment.
this comment might become outdated if you take my other suggestion to change the API shape, but I think this will produce an error like Invalid color for 'background' which won't be enough for someone to know if it was the light or dark "background" key.
There was a problem hiding this comment.
Error now includes the mode, thank you!
Light and dark colors are now set independently, with no fallback between modes, and validation errors name the mode (for example 'dark.background'). Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
|
@claude get us a review please |
|
Congrats on merging your first pull request! 🎉🎉🎉 |
|
Release Notes Persisted
|
|
I was unable to backport this PR to "44-x-y" cleanly; |
|
I have automatically backported this PR to "45-x-y", please check out #55493 |
|
I have automatically backported this PR to "46-x-y", please check out #55494 |
|
@ashleyhendrata has manually backported this PR to "44-x-y", please check out #55500 |
feat: add Menu.setHighlightColors() for Windows (#55074) * feat: add Menu.setHighlightColors() for Windows Lets apps set the background and text color of the hovered or keyboard-focused item in Views menus on Windows. The colors are skipped in high contrast and forced colors modes. Closes #54953 * docs: add API history for Menu.setHighlightColors * style: apply clang-format to menu_highlight_colors.cc * refactor: use symmetric light/dark options for Menu.setHighlightColors Light and dark colors are now set independently, with no fallback between modes, and validation errors name the mode (for example 'dark.background'). --------- (cherry picked from commit 77a943b) Co-authored-by: Claude <svc-devxp-claude@slack-corp.com>
Description of Change
Closes #54953
Adds
Menu.setHighlightColors(options)so apps can set the background and text color of the hovered or keyboard-focused item in menus on Windows. By default that highlight is about#f2f2f2on white (roughly 1.12:1), below the 3:1 that WCAG 1.4.11 asks for, and apps had no way to change it.The colors are applied by a color mixer registered after Chromium's in
ElectronBrowserMainParts::PreEarlyInitialization(), which overrideskColorMenuItemBackgroundSelectedandkColorMenuItemForegroundSelected. The mixer does nothing in high contrast or forced colors mode so the user's system colors win. Calling the method clears the color provider cache so menus opened afterwards pick up the change, andnullrestores the defaults.The mixer is only registered on Windows, so the method has no effect on macOS (which uses
NSMenu) or on Linux, where the GTK and Qt themes provide their own menu colors (ui/gtk/gtk_color_mixers.cc,ui/qt/qt_ui.cc).Light and dark colors are set independently: any color left unset keeps Chromium's default for that mode, and each call replaces the colors from previous calls.
Tested on Windows 11 ARM64 with the CI build from this PR:
#f2f2f2on#ffffffMenu.setHighlightColors({ light: { background: '#0067c0', foreground: '#ffffff' } })#0067c0on#ffffffChecked context menus and menu bar dropdowns, light and dark mode, that a mode left unset keeps the default highlight (light colors only, viewed in dark mode), keyboard navigation with the arrow keys, resetting with
null, and that a Windows contrast theme (Night sky) overrides the app's colors.#0067c0/#ffffff)Checklist
npm testpassesRelease Notes
Notes: Added
Menu.setHighlightColors()to set menu highlight colors on Windows.