Skip to content

fix: ship the app icon at every size Windows asks for - #31

Merged
ThorSPB merged 1 commit into
mainfrom
fix/high-res-app-icon
Aug 22, 2026
Merged

ThorSPB merged 1 commit into
mainfrom
fix/high-res-app-icon

Conversation

@ThorSPB

@ThorSPB ThorSPB commented Aug 22, 2026

Copy link
Copy Markdown
Owner

No bump tag — lands on main for a future release, as you asked.

Cause

icon4.ico contained a single 32×32 image:

embedded sizes: [(32, 32)]

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.icns was added in 98637ad and later dropped from the tree — it holds genuine renders up to 1024×1024. Recovered it, kept it as the master, and generate the .ico from it:

size source
32, 64, 128, 256 native .icns entry
16, 24, 48 resampled from the 1024 bitmap

I 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 notification app_icon. PIL now opens the .ico at 256 instead of 32 — which is exactly what iconphoto and the notification path read.

The spec now picks the .icns on macOS, where it's the native format.

Regeneration and guard

scripts/build_icon.py rebuilds it from the master. A guard test asserts the .ico still carries 16/32/48/256 and that the .icns stays 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

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.
@ThorSPB
ThorSPB merged commit 6ce3a0f into main Aug 22, 2026
5 checks passed
@ThorSPB
ThorSPB deleted the fix/high-res-app-icon branch August 22, 2026 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant