Repository navigation
fix: ship the app icon at every size Windows asks for - #31
Merged
Merged
Conversation
icon4.ico contained a single 32x32 image. Windows wants 256 for shortcuts and toast notifications, 48 for Explorer and 24/32 for the taskbar, so it upscaled a 32px bitmap for all of them - which is why the icon looked soft in the app, in shortcuts and worst of all in notifications, where the gap between 32 and 256 is largest. The fix needed a real source rather than an upscale. icon4.icns was added in 98637ad and later dropped from the tree; it holds genuine renders up to 1024x1024. Recovered it, kept it in the repo as the master, and generated the .ico from it with scripts/build_icon.py: 16, 24, 32, 48, 64, 128, 256, taking the native .icns entry at each size where one exists and resampling from the 1024 bitmap only for 16, 24 and 48. Confirmed the .icns is genuinely high-resolution rather than an upscale of something small: measured mean gradient falls off by roughly half per doubling (12.59 at 32px down to 0.67 at 1024), which is what per-size renders of the same artwork look like. An upscaled source would be uniformly soft. Everything routed through this one file - the exe icon, the Tk window icon via iconphoto, and plyer's notification app_icon - so all three improve. PIL now opens the .ico at 256 rather than 32, which is what iconphoto and the notification path read. The spec picks the .icns on macOS, where it is the native format, and the .ico elsewhere. Guard test asserts the .ico still carries 16/32/48/256 and that the .icns master stays in the repo - losing it is how this became 32px-only in the first place. Verified the guard fails against the old file.
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.
No bump tag — lands on
mainfor a future release, as you asked.Cause
icon4.icocontained a single 32×32 image:Windows wants 256 for shortcuts and toast notifications, 48 for Explorer, 24/32 for the taskbar. So it upscaled a 32px bitmap for all of them — hence soft in the app, softer in shortcuts, worst in notifications where the gap is largest.
You were right that it's the same shape of problem as the pi-control app.
Fix
A real fix needed a real source, not an upscale.
icon4.icnswas added in98637adand later dropped from the tree — it holds genuine renders up to 1024×1024. Recovered it, kept it as the master, and generate the.icofrom it:.icnsentryI checked the master is genuinely high-res rather than an upscale of something small — mean gradient falls off by about half per doubling (12.59 at 32px → 0.67 at 1024), which is what per-size renders of one artwork look like. An upscaled source would be uniformly soft.
Why all three places improve
Everything routed through this one file: the exe icon (spec), the Tk window icon (
iconphoto), and plyer's notificationapp_icon. PIL now opens the.icoat 256 instead of 32 — which is exactly whaticonphotoand the notification path read.The spec now picks the
.icnson macOS, where it's the native format.Regeneration and guard
scripts/build_icon.pyrebuilds it from the master. A guard test asserts the.icostill carries 16/32/48/256 and that the.icnsstays in the repo — losing it is how this became 32px-only. I verified the guard fails against the old file before trusting it.291 tests, dry-run set green.
🤖 Generated with Claude Code