Skip to content

fix(icons): give the launcher artwork room inside the icon mask - #1161

Open
simonoppowa wants to merge 2 commits into
developfrom
fix/launcher-icon-padding
Open

fix(icons): give the launcher artwork room inside the icon mask#1161
simonoppowa wants to merge 2 commits into
developfrom
fix/launcher-icon-padding

Conversation

@simonoppowa

Copy link
Copy Markdown
Owner

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

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Documentation
  • CI / tooling
  • Localization
  • Other

Related issues

Fixes #1151

Changes

  • Android: adaptive_icon_foreground_inset: 23 in pubspec.yaml. The 16% that shipped since v1.4.0 is flutter_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.
  • iOS: the tool has no inset option and copies the PNG into the asset catalog as-is, so 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.py regenerates them (idempotent, Pillow only).
  • Regenerated with dart run flutter_launcher_icons: only mipmap-anydpi-v26/ic_launcher.xml and the 48 iOS PNGs change; the Android PNGs, colors.xml and Contents.json come out byte-identical.
  • The in-app logo PNGs (Settings → About, DynamicOntLogo fallback) are untouched, and the new PNGs are not in flutter: 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.png has the same tight crop.

Screenshots / recordings

Measured from the committed files (PIL, ≥50% alpha):

before after
Android composition height (108dp canvas) 66.3dp, 0.15dp outside the 66dp safe zone 52.7dp, 6.7dp inside it
Android farthest artwork pixel from centre 33.2dp (safe zone r=33, mask r=36) 26.4dp
iOS artwork height / top margin 90% / 4.8% 80% / 10%

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

  • Described steps below were followed locally
  • Unit / widget tests added or updated (if applicable) — asset-only change, no Dart touched
  • Manual check on Android
  • Manual check on iOS (if applicable)

Steps

  1. python3 tools/icons/pad_ios_launcher_icon.py twice — output hashes identical.
  2. dart run flutter_launcher_iconsgit status shows only ic_launcher.xml and the iOS PNGs.
  3. Measured every 1024 iOS icon: light is opaque RGB on white, dark/tinted keep alpha, tinted is grayscale, artwork bbox (157,102)–(866,921) in all three.
  4. Rendered the adaptive icon at 23% under a 72dp circle and rounded-square mask and compared with 16%.

Checklist

  • Code follows project style — run just format (dart format's default 80-column width; nothing configures a wider one) — no Dart changed
  • New interactive widgets include Semantics(identifier: '...') where needed — n/a
  • Localization updated in every lib/l10n/intl_*.arb with a real translation, not the English string (lib/generated/ is gitignored — do not edit or commit it) — n/a
  • Codegen ran if DBOs/DTOs/env changed (just build) — n/a
  • No secrets or .env values committed
  • PR title follows conventional commit style (e.g. feat:, fix:, chore:)

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.
Copilot AI lite review requested due to automatic review settings September 11, 2026 07:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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_android is 21, API 21–25 cannot use mipmap-anydpi-v26/ic_launcher.xml; they select the density-specific mipmap-*/ic_launcher.png files 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

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

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