fix(icons): give the launcher artwork room inside the icon mask - #1161
fix(icons): give the launcher artwork room inside the icon mask#1161simonoppowa wants to merge 2 commits into
Conversation
The two logo PNGs are a tight crop (~5% margin top and bottom) that also serves as the in-app logo, so both launcher pipelines shipped artwork that sat ~3dp from the Android mask edge and 5% from the iOS canvas edge (#1151). Android: set `adaptive_icon_foreground_inset` to 23. The 16% that shipped since v1.4.0 is flutter_launcher_icons' default, which replaced the earlier hand-written 25% when #447 regenerated the icons. At 23% the composition is 52.7dp tall — on the 52dp keyline and 6.7dp inside the 66dp safe zone. iOS: the tool has no inset option and copies the PNG into the asset catalog as-is, so add pre-padded copies of the two logo PNGs (composition at 80% of the canvas height on a transparent canvas, so the dark and tinted variants keep their alpha) and the script that regenerates them. The in-app logo PNGs are untouched.
`dart run flutter_launcher_icons` with the new inset and iOS sources. Only the adaptive-icon XML and the iOS PNGs change; the Android PNGs, colors.xml and Contents.json come out byte-identical.
There was a problem hiding this comment.
🟡 Changes recommended
Address legacy Android icons and provide an actionable Pillow dependency message.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This pull request adds platform-specific padding to launcher artwork while preserving the existing in-app logos.
Changes:
- Sets the Android adaptive-icon inset to 23%.
- Adds a Pillow-based generator for padded iOS launcher sources.
- Regenerates iOS launcher variants.
File summaries
| File | Summary |
|---|---|
tools/icons/pad_ios_launcher_icon.py |
Generates centered, padded iOS launcher sources; Pillow dependency handling needs improvement. |
pubspec.yaml |
Configures launcher padding and sources; legacy Android icons remain unchanged for API 21–25. |
android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml |
Applies the 23% inset to adaptive color and monochrome layers. |
Review details
Suppressed comments (1)
pubspec.yaml:182
- Because
min_sdk_androidis 21, API 21–25 cannot usemipmap-anydpi-v26/ic_launcher.xml; they select the density-specificmipmap-*/ic_launcher.pngfiles instead. Those legacy PNGs are unchanged by this regeneration, so supported pre-adaptive devices still receive the tight-cropped artwork. Please generate padded legacy PNGs as well, or explicitly scope this fix to API 26+.
- Files reviewed: 3/53 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| import sys | ||
| from pathlib import Path | ||
|
|
||
| from PIL import Image |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 933c147b38
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| import sys | ||
| from pathlib import Path | ||
|
|
||
| from PIL import Image |
There was a problem hiding this comment.
Document or declare the Pillow dependency
On a clean checkout, the documented python3 tools/icons/pad_ios_launcher_icon.py regeneration command fails immediately at tools/icons/pad_ios_launcher_icon.py:35 with ModuleNotFoundError: No module named 'PIL', because Pillow is neither declared nor included by the repository setup. Please declare the tooling dependency or catch the import and provide an installation instruction, as the existing screenshot tooling does.
Useful? React with 👍 / 👎.
Summary
The launcher icon artwork sat ~3dp from the Android adaptive-icon mask edge and 5% from the iOS canvas edge, so it looked cramped next to its neighbours (#1151). Both pipelines are fed by the tight-cropped logo PNGs that also serve as the in-app logo, so the padding is added where each platform lets it be added without touching those files.
Type of change
Related issues
Fixes #1151
Changes
adaptive_icon_foreground_inset: 23inpubspec.yaml. The 16% that shipped since v1.4.0 isflutter_launcher_icons' default, which replaced the earlier hand-written 25% when feat(icons): add iOS dark/tinted appearance and Android themed app icons #447 regenerated the icons. At 23% the composition is 52.7dp tall — on the 52dp keyline and 6.7dp inside the 66dp safe zone (was 66.3dp, 0.15dp outside it). The same inset drives the monochrome layer, so the Android 13+ themed icon moves with it.image_path_ios*now point at pre-padded copies of the two logo PNGs (assets/icon/ont_launcher_ios_color_{back,white}_1024x1024.png): composition at 80% of the canvas height, centred, on a transparent canvas so the dark and tinted variants keep their alpha.tools/icons/pad_ios_launcher_icon.pyregenerates them (idempotent, Pillow only).dart run flutter_launcher_icons: onlymipmap-anydpi-v26/ic_launcher.xmland the 48 iOS PNGs change; the Android PNGs,colors.xmlandContents.jsoncome out byte-identical.DynamicOntLogofallback) are untouched, and the new PNGs are not influtter: assets:, so nothing is bundled into the app.Out of scope, noticed on the way: the Play listing icon at
fastlane/metadata/android/en-US/images/icon.pnghas the same tight crop.Screenshots / recordings
Measured from the committed files (PIL, ≥50% alpha):
The device screenshot is on #1151; a rendered before/after under circle, rounded-square, themed and iOS light/dark masks was reviewed locally.
Test plan
Steps
python3 tools/icons/pad_ios_launcher_icon.pytwice — output hashes identical.dart run flutter_launcher_icons—git statusshows onlyic_launcher.xmland the iOS PNGs.Checklist
just format(dart format's default 80-column width; nothing configures a wider one) — no Dart changedSemantics(identifier: '...')where needed — n/alib/l10n/intl_*.arbwith a real translation, not the English string (lib/generated/is gitignored — do not edit or commit it) — n/ajust build) — n/a.envvalues committedfeat:,fix:,chore:)