fix(tray): monochrome template icon in the macOS menu bar - #19
Open
maerlin wants to merge 1 commit into
Open
Conversation
The green app mark was used verbatim as the tray icon on every platform. On macOS that is the one thing in the menu bar that does not follow the system: AppKit expects a template image (a silhouette in the alpha channel that it tints black on a light menu bar and white on a dark one). A full-colour icon therefore stays green regardless of appearance and reads as foreign next to every other status item. Ship a macOS-only pair of template assets (plain + unread) and set icon_as_template, keeping the colour icon on Windows and Linux, whose tray areas have no equivalent convention. Badge updates go through set_icon_with_as_template so the image and the template flag are applied in one step; setting them separately renders the icon twice and flickers. The assets are generated by scripts/make-tray-template.mjs (wired into regen-icons.sh) from the 512px render of icons/app-icon.svg, so the SVG stays the single source of truth. It recovers the silhouette from the raster rather than the path data: flood-fill inward from the border, and whatever the fill cannot reach is the bubble, walled off by its own white stroke; the handset is then the white blob that is not that stroke. The script has zero dependencies (PNG in/out via node:zlib, like the other scripts here), so regenerating the template does not need ImageMagick. Output is 36x36 (18pt @2x), the exact height tray-icon renders a status item at.
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.
Problem
The tray icon is the full-colour green app mark on every platform. On macOS that makes it the one item in the menu bar that does not follow the system appearance: AppKit expects a template image, a silhouette in the alpha channel that it tints black on a light menu bar and white on a dark one. A colour icon stays green either way and reads as foreign next to every other status item.
Windows and Linux tray areas have no equivalent convention, so they are untouched.
Change
icons/tray-macos-template.pngand-unread.png, selected with#[cfg(target_os = "macos")]. Everything else keepstray.png/tray-unread.png.TrayIconBuilder::icon_as_template(ICON_IS_TEMPLATE), where the constant iscfg!(target_os = "macos").set_icon_with_as_templateinstead ofset_icon. Setting the image and the template flag separately renders the icon twice and visibly flickers; Tauri documents the atomic call for exactly this, and it falls back toset_iconon Linux and Windows.How the assets are generated
scripts/make-tray-template.mjs, wired intoregen-icons.shafter the existing tray step. It reads the 512px render oficons/app-icon.svg, so the SVG stays the single source of truth for every icon in the repo.It recovers the silhouette from the raster rather than the path data: flood-fill the non-white pixels inward from the image border, and whatever the fill cannot reach is the bubble, walled off by its own white stroke. The handset is then the white blob that is not that stroke ring. Output is 36x36 (18pt @2x), which is the exact height
tray-iconrenders a status-item image at, so the bitmap lands 1:1 on a Retina menu bar.Zero dependencies, PNG in and out via
node:zlib, matching the other scripts here. Regenerating the template does not need ImageMagick.Testing
cargo build,cargo test(66 pass),cargo fmt --checkclean.Happy to attach a before/after menu-bar screenshot if useful.