fix(desktop): correct Windows tray icon theme and DPI rendering - #791
Merged
Conversation
The Windows tray ignores PNG scale-factor representations (electron/electron#33044) and upscales the 16px bitmap on >100% displays, so make-icons.mjs now also emits one .ico per tray variant with 16/20/24/32/48 frames (20 covers the common 125% scaling). The PNGs stay for the Linux representation path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two fixes for the washed-out / blurry tray icon on Windows: - Pick the light/dark glyph from the *system* (taskbar) theme via nativeTheme.shouldUseDarkColorsForSystemIntegratedUI instead of shouldUseDarkColors, which tracks the separately-configurable *apps* theme. With mixed themes (dark taskbar + light apps is common) the tray wore a near-invisible glyph that read as the offline icon. The poll re-checks the theme too, since Windows does not reliably emit nativeTheme 'updated' for system-theme-only flips. - Load the tray image from the multi-size .ico on win32 so Electron serves a DPI-correct frame; scale-factor PNG representations are ignored by the Windows tray (electron/electron#33044) and the 16px bitmap got upscaled on >100% displays. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The Windows tray icon looked washed-out and blurry — it read as the gray "offline" glyph even while the control plane was running. Two independent rendering bugs, both Windows-specific:
nativeTheme.shouldUseDarkColors, which on Windows tracks the apps theme. The taskbar follows the separately-configurable system theme. With mixed themes (dark taskbar + light apps is a common Windows setup) the tray wore a near-black glyph on a dark taskbar — effectively invisible, reading as the inactive/offline icon.Changes
tray-model.ts: newdarkTaskbar()helper picks the theme source per platform —shouldUseDarkColorsForSystemIntegratedUI(the system/taskbar theme) on win32,shouldUseDarkColorselsewhere. Pure function, unit-tested.tray.ts: on win32, load the tray image withnativeImage.createFromPath(<ico>)so Electron serves a DPI-correct frame (it only does this for path-loaded.ico); Linux keeps the PNG-representation path. The 5s poll now re-checks the taskbar theme too, since Windows doesn't reliably emitnativeThemeupdatedwhen only the system theme flips; the icon/menu still only re-render on actual change.make-icons.mjs: emits one multi-size.icoper tray variant (16/20/24/32/48 frames; 20 covers 125% scaling), mirroring the existing icns builder. The four generated.icofiles are committed alongside the existing PNGs.Packaged builds need no electron-builder changes: Electron's
ReadICOFromPathextracts asar-packed icos to a temp file before the Win32LoadImagecall.Test plan
npm run typecheck,npm test(223 passing, incl. newdarkTaskbarcontract tests: dark taskbar + light apps → light glyph, and vice versa).icofiles parse as well-formed 5-frame icons with matching directory/IHDR dimensionsnpm run dist:dirpackages successfully; app.asar contains the icos🤖 Generated with Claude Code