Skip to content

fix: inset mac app icons onto the macOS icon grid - #480

Merged
shannah merged 1 commit into
masterfrom
claude/macos-icon-context-switch-eu2p2o
Sep 8, 2026
Merged

fix: inset mac app icons onto the macOS icon grid#480
shannah merged 1 commit into
masterfrom
claude/macos-icon-context-switch-eu2p2o

Conversation

@shannah

@shannah shannah commented Sep 8, 2026

Copy link
Copy Markdown
Owner

What this fixes

An installed jDeploy app's icon renders visibly larger than the apps beside it in the command-tab switcher, the Dock and Mission Control.

Apple's macOS icon template centres an 824×824 body in a 1024×1024 canvas — every icon macOS draws next to ours leaves that margin. jDeploy wrote the source artwork into every icns slice edge to edge, so at the same slot size it renders ~24% wider (1024/824) than its neighbours.

Why it showed up now

Before #475, macOS treated the single-slice icns as legacy and shrank it onto a plate — that supplied a margin by accident. With the full slice family in place macOS draws the artwork as authored, so a full-bleed source now shows at full slot width. #479 fixed the small-slice scrambling but not the size, which is why the icon came back uncorrupted and still oversized.

Approach

MacBundler.writeIcns now runs the source through fitToIconGrid before cutting slices:

  • The artwork is measured by its opaque bounds, not by the canvas, so an icon already authored to Apple's template is passed through untouched, and one carrying part of the margin is scaled the rest of the way rather than twice over.
  • Only sources that reach past the grid (plus a 2% tolerance) are re-composited; the scale/centre is done once at full canvas resolution with bicubic resampling, and every slice is cut from that.
  • Sources too small to fill any slice we emit keep their single native slice unchanged — insetting artwork that small would leave nothing of it.
  • Non-square, unreadable and fully transparent sources are left alone.
  • The intermediate icon-grid.png matches the existing thumbnail cleanup pattern, so it is removed with the rest.

Measured on jDeploy's own default icon.png (512×512, full bleed): artwork now spans 409×412 of the 512 canvas ≈ 80.1%, against 512×512 (100%) before.

Testing

MacBundlerIconTest gains three cases; all 237 shared-module tests pass.

  • insetsFullBleedArtworkOntoTheIconGrid — fails on the pre-fix code (expected: <824.0> but was: <1024.0>), and also checks the artwork is centred.
  • leavesArtworkThatAlreadySitsOnTheGridAlone — a 700-of-1024 source comes through at 700.
  • removesTheGridFittedSource — no leftover intermediate.

Delivery

The fix is in shared, so it reaches an installed .app through whichever component builds that bundle — the CLI at publish time for prebuilt platform bundles and for the local install paths, or jdeploy-installer when the installer builds the bundle on the end user's machine. The installer-built route tracks its own npm release rather than the CLI's: jdeploy-installer@latest is 6.1.5, whose MacBundler still has the pre-#475 single-slice createThumbnails(File, File), so that route only picks this up once a release carries it.

🤖 Generated with Claude Code

https://claude.ai/code/session_0133NB1qceV5MzfvRzdVPxm5

Apple's macOS icon template centres an 824x824 body in a 1024x1024 canvas,
so every icon macOS draws beside ours - in the Dock, the command-tab
switcher, Mission Control - leaves that margin. jDeploy wrote the source
artwork into every icns slice edge to edge, which renders about a quarter
wider than its neighbours at the same slot size.

#475 is what exposed it: before the full slice family, macOS treated the
single-slice icns as legacy and shrank it onto a plate, which supplied a
margin by accident. With a complete family macOS draws the artwork as
authored, so a full-bleed source now shows at full slot width.

Measure the source by its opaque bounds rather than its canvas, so an icon
already authored to the template is passed through untouched and one that
carries part of the margin is scaled the rest of the way rather than twice
over. Sources too small to fill any slice we emit keep their single native
slice unchanged - insetting artwork that small would leave nothing of it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133NB1qceV5MzfvRzdVPxm5
@shannah
shannah marked this pull request as ready for review September 8, 2026 20:50
@shannah
shannah merged commit 8ff89bd into master Sep 8, 2026
19 checks passed
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.

2 participants