Merge pull request #281 from XusBadia/dmg-background

macOS DMG: branded window background and icon layout
This commit is contained in:
Brandon Thomas authored and GitHub committed 2026-10-09 09:20:44 -04:00
commit 68d94b8031
8 files changed
+185 -1

No files matched your search

+3
View File
@@ -88,6 +88,9 @@ jobs:
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: packaging/macos/import-cert.sh
# Renders the DMG background from packaging/macos/dmg/background.svg (package.sh).
- name: Install resvg
run: cargo install resvg --locked --version 0.48.1
- name: Build, sign, notarize
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
+1
View File
@@ -17,6 +17,7 @@ iconography, images or other Adobe assets; open licences only; every asset attri
| `assets/fonts/NotoSerif-Regular.ttf` | The Noto Project Authors | https://github.com/notofonts/latin-greek-cyrillic | OFL-1.1 (`assets/fonts/OFL-NotoSerif.txt`) |
| `assets/fonts/JetBrainsMono-Regular.ttf` | The JetBrains Mono Project Authors | https://github.com/JetBrains/JetBrainsMono | OFL-1.1 (`assets/fonts/OFL-JetBrainsMono.txt`) |
| `apps/effectcraft-web/web/favicon.svg` | EffectCraft contributors | Original work: web app icon, a copy of `assets/app-icon/effectcraft-small.svg` (the unicorn app icon) | MIT OR Apache-2.0 (`assets/app-icon/LICENSE.txt`) |
| `packaging/macos/dmg/background.svg` | @XusBadia | Original work: macOS DMG Finder window background, derived from the EffectCraft app icon (`assets/app-icon/effectcraft.svg`); rendered to a TIFF by `packaging/macos/package.sh` at package time | MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`) |
| `assets/app-icon/effectcraft-1024.png` | EffectCraft contributors | Original work: effectCraft app icon, 1024 px (owner's ArtCraft unicorn drawing, vectorised) | MIT OR Apache-2.0 (`assets/app-icon/LICENSE.txt`) |
| `assets/app-icon/effectcraft-macos-512.png` | EffectCraft contributors | Original work: effectCraft runtime Dock icon (macOS) (owner's ArtCraft unicorn drawing, vectorised) | MIT OR Apache-2.0 (`assets/app-icon/LICENSE.txt`) |
| `assets/app-icon/effectcraft-small.svg` | EffectCraft contributors | Original work: effectCraft app icon, light vector (owner's ArtCraft unicorn drawing, vectorised) | MIT OR Apache-2.0 (`assets/app-icon/LICENSE.txt`) |
+44
View File
@@ -0,0 +1,44 @@
# macOS DMG window
What Finder shows when the DMG opens: a 660 × 400 pt background with the app icon and the
`Applications` link side by side. `package.sh` renders the background from `background.svg` and copies it
and the layout into the image, so no bitmap is committed. The DMG still builds with
`hdiutil makehybrid` (no mounted device, no Finder scripting on CI).
| File | What |
|---|---|
| `background.svg` | Source of the background: the app icon (`assets/app-icon/effectcraft.svg`, linked, not copied) cropped as a cover on the EffectCraft colour field (`#e0368f`), Ink and Paper. Its text (Inter, JetBrains Mono) is outlined, so rendering it needs no fonts. `package.sh` renders it with [resvg](https://github.com/linebender/resvg) 0.48.1 at 1x (660 × 400 px) and 2x (1320 × 800 px) and joins both into `.background/background.tiff` (`tiffutil -cathidpicheck`); `release.yml` installs that resvg on the macOS runner. |
| `dmg-layout.DS_Store` | Finder's view settings for the volume: window size, icon size 128, EffectCraft.app at (326, 205), `Applications` at (574, 205), and the background. Goes to `.DS_Store` in the image; named so it isn't mistaken for (or ignored like) a Finder-generated `.DS_Store`. |
| `generate.py` | Writes `dmg-layout.DS_Store` from the layout above. |
## The volume name has no version
The mounted volume is called `EffectCraft`, not `EffectCraft <version>`. The layout points at the background
through an alias that includes the volume name, and Finder resolves it by that name: with a
versioned name the window keeps its size and icon positions but shows no background (tested).
The DMG file name (`effectcraft-<version>-macos-<arch>.dmg`) still carries the version.
## Rules
- **Finder draws the icon labels in black in light and dark mode** when a window has a background,
so the area under both icons stays light (Paper).
- **Nothing goes inside the icon boxes:** artwork keeps 10 pt clear of each 128 pt icon box and of
the label strip under it.
## Regenerate
- **The background:** edit `background.svg`. `package.sh` renders it on every build; to preview it,
`resvg --skip-system-fonts -w 1320 background.svg /tmp/[email protected]`. If you add text, outline it
(`usvg` from resvg converts text to paths), since no fonts are loaded.
- **The layout:** edit the constants in `generate.py`, then run, on any OS:
```sh
pip install ds_store==1.3.3 mac_alias==2.2.3
python3 packaging/macos/dmg/generate.py
```
`dmg-layout.DS_Store` is written from scratch and byte-for-byte reproducible: its background
alias holds only the volume name and `/.background/background.tiff`, nothing from the machine that
ran it. The window is 660 × 432 with Finder's 32 pt title bar; the content area is 660 × 400.
This follows VectorCraft's `packaging/macos/dmg/` (storytold/vectorcraft#493).
+31
View File
@@ -0,0 +1,31 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="660" height="400" viewBox="0 0 660 400">
<defs><clipPath id="panel"><rect width="232" height="400"/></clipPath><pattern id="hatch" width="2.6" height="2.6" patternUnits="userSpaceOnUse" patternTransform="rotate(-38)">
<rect width="2.6" height="1.05" fill="#0b0b0c"/></pattern><filter id="grain" x="0" y="0" width="100%" height="100%">
<feTurbulence type="fractalNoise" baseFrequency="0.9" numOctaves="2" seed="7"/>
<feColorMatrix values="0 0 0 0 0.04 0 0 0 0 0.04 0 0 0 0 0.05 0.5 0 0 0 -0.225"/>
</filter></defs>
<rect width="660" height="400" fill="#efe9dc"/><rect width="660" height="400" filter="url(#grain)"/>
<g clip-path="url(#panel)"><rect width="232" height="400" fill="#e0368f"/><g transform="translate(-184.0,-30.0) scale(1.0)"><image href="../../../assets/app-icon/effectcraft.svg" width="512" height="512"/></g></g>
<line x1="232.5" y1="0" x2="232.5" y2="400" stroke="#0b0b0c" stroke-width="1.2"/>
<line x1="236.5" y1="0" x2="236.5" y2="400" stroke="#0b0b0c" stroke-width="0.5"/>
<line x1="267" y1="88.5" x2="624" y2="88.5" stroke="#0b0b0c" stroke-width="0.6"/>
<path d="M271.5,81.5 L276,88.5 L271.5,95.5 L267,88.5 Z" fill="#e0368f"/>
<path d="M414,215 Q434,175 454,193 T476,207" fill="none" stroke="#0b0b0c" stroke-width="1.4" stroke-dasharray="1.5 4" stroke-linecap="round"/><path d="M414,209 L420,215 L414,221 L408,215 Z" fill="#efe9dc" stroke="#0b0b0c" stroke-width="1.3"/><path d="M454,187 L460,193 L454,199 L448,193 Z" fill="#efe9dc" stroke="#0b0b0c" stroke-width="1.3"/><path d="M476,201 L482,207 L476,213 L470,207 Z" fill="#e0368f" stroke="#0b0b0c" stroke-width="1.3"/><path d="M496.9,207.0 L487.9,211.5 L487.9,202.5 Z" fill="#0b0b0c"/>
<line x1="267" y1="335.5" x2="624" y2="335.5" stroke="#0b0b0c" stroke-width="0.6"/>
<g id="text">
<g>
<path fill="#0b0b0c" stroke="none" d="M 268.19727 72 L 268.19727 50.17383 L 282.37695 50.17383 L 282.37695 53.469727 L 272.1084 53.469727 L 272.1084 59.3584 L 281.61523 59.3584 L 281.61523 62.61035 L 272.1084 62.61035 L 272.1084 68.7041 L 282.43555 68.7041 L 282.43555 72 Z M 294.29883 55.623047 L 294.29883 58.61133 L 290.7539 58.61133 L 290.7539 72 L 286.95996 72 L 286.95996 58.61133 L 283.95703 58.61133 L 283.95703 55.623047 L 286.95996 55.623047 L 286.95996 54.055664 Q 286.95996 52.429688 287.64844 51.33838 Q 288.3369 50.24707 289.48682 49.697758 Q 290.63672 49.148438 292.04297 49.148438 Q 293.0537 49.148438 293.83008 49.309566 Q 294.60645 49.470703 294.97266 49.60254 L 294.1963 52.561527 Q 293.94727 52.488277 293.58838 52.407715 Q 293.2295 52.32715 292.7461 52.32715 Q 291.67676 52.32715 291.21533 52.854492 Q 290.7539 53.381836 290.7539 54.348633 L 290.7539 55.623047 Z M 304.22852 55.623047 L 304.22852 58.61133 L 300.6836 58.61133 L 300.6836 72 L 296.88965 72 L 296.88965 58.61133 L 293.88672 58.61133 L 293.88672 55.623047 L 296.88965 55.623047 L 296.88965 54.055664 Q 296.88965 52.429688 297.57813 51.33838 Q 298.2666 50.24707 299.4165 49.697758 Q 300.5664 49.148438 301.97266 49.148438 Q 302.9834 49.148438 303.75977 49.309566 Q 304.53613 49.470703 304.90234 49.60254 L 304.12598 52.561527 Q 303.87695 52.488277 303.51807 52.407715 Q 303.15918 52.32715 302.67578 52.32715 Q 301.60645 52.32715 301.14502 52.854492 Q 300.6836 53.381836 300.6836 54.348633 L 300.6836 55.623047 Z M 313.29395 72.336914 Q 310.81836 72.336914 309.03857 71.296875 Q 307.2588 70.256836 306.29932 68.36719 Q 305.33984 66.47754 305.33984 63.914063 Q 305.33984 61.394527 306.28467 59.48291 Q 307.2295 57.571285 308.96533 56.49463 Q 310.70117 55.41797 313.04492 55.41797 Q 315.0371 55.41797 316.74365 56.28955 Q 318.4502 57.161133 319.49023 58.984863 Q 320.53027 60.80859 320.53027 63.679688 L 320.53027 64.88086 L 309.1338 64.88086 Q 309.20703 67.06348 310.35693 68.206055 Q 311.50684 69.34863 313.3379 69.34863 Q 314.59766 69.34863 315.49854 68.80664 Q 316.3994 68.26465 316.78027 67.22461 L 320.28125 67.94238 Q 319.6953 69.91992 317.85693 71.12842 Q 316.01855 72.336914 313.29395 72.336914 Z M 309.14844 62.288086 L 316.82422 62.288086 Q 316.64844 60.530273 315.7036 59.46826 Q 314.7588 58.40625 313.05957 58.40625 Q 311.3164 58.40625 310.29834 59.526855 Q 309.28027 60.64746 309.14844 62.288086 Z M 330.40137 72.336914 Q 328.01367 72.336914 326.25586 71.2749 Q 324.49805 70.21289 323.53857 68.31592 Q 322.5791 66.418945 322.5791 63.899414 Q 322.5791 61.350586 323.53857 59.438965 Q 324.49805 57.527344 326.25586 56.472656 Q 328.01367 55.41797 330.40137 55.41797 Q 333.14063 55.41797 335.0376 56.787598 Q 336.93457 58.157227 337.4619 60.55957 L 333.90234 61.30664 Q 333.59473 60.032227 332.70117 59.270508 Q 331.80762 58.50879 330.43066 58.50879 Q 328.43848 58.50879 327.4497 60.046875 Q 326.46094 61.58496 326.46094 63.884766 Q 326.46094 65.393555 326.9004 66.609375 Q 327.33984 67.825195 328.21875 68.535645 Q 329.09766 69.24609 330.43066 69.24609 Q 331.8369 69.24609 332.7378 68.447754 Q 333.63867 67.649414 333.9463 66.331055 L 337.50586 67.078125 Q 336.97852 69.524414 335.07422 70.930664 Q 333.16992 72.336914 330.40137 72.336914 Z M 347.8457 55.623047 L 347.8457 58.61133 L 344.68164 58.61133 L 344.68164 67.38574 Q 344.68164 68.2793 345.05518 68.69678 Q 345.4287 69.11426 346.30762 69.11426 Q 346.5713 69.11426 346.9961 69.04834 Q 347.42093 68.98242 347.6992 68.92383 L 348.2998 71.868164 Q 347.66992 72.05859 347.01074 72.13916 Q 346.35156 72.21973 345.75098 72.21973 Q 343.39258 72.21973 342.1328 71.04785 Q 340.87305 69.87598 340.87305 67.70801 L 340.87305 58.61133 L 338.54395 58.61133 L 338.54395 55.623047 L 340.87305 55.623047 L 340.87305 51.726563 L 344.68164 51.726563 L 344.68164 55.623047 Z M 359.84082 72.29297 Q 356.96973 72.29297 354.7139 70.95996 Q 352.458 69.62695 351.1543 67.12207 Q 349.8506 64.61719 349.8506 61.101563 Q 349.8506 57.571285 351.16162 55.059082 Q 352.47263 52.54688 354.72852 51.213863 Q 356.98438 49.88086 359.84082 49.88086 Q 362.22855 49.88086 364.18408 50.774414 Q 366.13965 51.66797 367.41406 53.359863 Q 368.6885 55.051754 369.04007 57.439453 L 365.0996 57.439453 Q 364.7334 55.50586 363.29782 54.443848 Q 361.8623 53.381836 359.8994 53.381836 Q 357.21875 53.381836 355.4976 55.381344 Q 353.77637 57.38086 353.77637 61.101563 Q 353.77637 64.86621 355.50485 66.8291 Q 357.23343 68.79199 359.88477 68.79199 Q 361.84766 68.79199 363.29053 67.72998 Q 364.7334 66.66797 365.0996 64.734375 L 369.0547 64.734375 Q 368.74707 66.8291 367.54593 68.54297 Q 366.34473 70.256836 364.38184 71.2749 Q 362.41895 72.29297 359.84082 72.29297 Z M 371.96774 72 L 371.96774 55.623047 L 375.65918 55.623047 L 375.65918 58.362305 L 375.83496 58.362305 Q 376.2744 56.941402 377.37305 56.172363 Q 378.47168 55.40332 379.87796 55.40332 Q 380.61035 55.40332 381.26953 55.50586 L 381.26953 59.006836 Q 381.03516 58.948246 380.50784 58.882324 Q 379.98047 58.816406 379.46777 58.Line truncated
</g>
<g>
<path fill="#0b0b0c" fill-opacity="0.7" stroke="none" d="M 267.828 112 L 267.828 105.42999 L 269.943 105.42999 Q 270.861 105.42999 271.4055 105.9565 Q 271.95 106.483 271.95 107.365 Q 271.95 108.247 271.4055 108.7735 Q 270.861 109.299995 269.943 109.299995 L 268.638 109.299995 L 268.638 112 Z M 268.638 108.571 L 269.943 108.571 Q 270.474 108.571 270.7935 108.2425 Q 271.113 107.914 271.113 107.365 Q 271.113 106.807 270.7935 106.483 Q 270.474 106.159004 269.943 106.159004 L 268.638 106.159004 Z M 275.1 112.072 Q 274.20898 112.072 273.6825 111.55 Q 273.156 111.028 273.156 110.092 L 273.156 108.958 Q 273.156 108.01301 273.678 107.4955 Q 274.19998 106.978 275.1 106.978 Q 276 106.978 276.522 107.4955 Q 277.044 108.01301 277.044 108.958 L 277.044 110.092 Q 277.044 111.028 276.5175 111.55 Q 275.991 112.072 275.1 112.072 Z M 275.1 111.35199 Q 275.63098 111.35199 275.9325 111.055 Q 276.234 110.758 276.234 110.182 L 276.234 108.868 Q 276.234 108.29201 275.9325 107.995 Q 275.63098 107.698006 275.1 107.698006 Q 274.578 107.698006 274.272 107.995 Q 273.966 108.29201 273.966 108.868 L 273.966 110.182 Q 273.966 110.758 274.272 111.055 Q 274.578 111.35199 275.1 111.35199 Z M 280.302 112.072 Q 279.474 112.072 279.0195 111.6985 Q 278.565 111.325 278.565 110.641 L 279.375 110.641 Q 279.375 110.983 279.61798 111.1765 Q 279.861 111.37 280.302 111.37 L 280.698 111.37 Q 281.14798 111.37 281.39548 111.172 Q 281.64297 110.97401 281.64297 110.614 Q 281.64297 109.975 281.05798 109.894 L 279.69 109.696 Q 279.18597 109.624 278.90698 109.277504 Q 278.628 108.931 278.628 108.364 Q 278.628 107.716 279.0735 107.34699 Q 279.51898 106.978 280.302 106.978 L 280.698 106.978 Q 281.418 106.978 281.8725 107.333496 Q 282.327 107.689 282.36298 108.265 L 281.54398 108.265 Q 281.526 108.00399 281.29648 107.83299 Q 281.067 107.661995 280.698 107.661995 L 280.302 107.661995 Q 279.888 107.661995 279.654 107.851 Q 279.41998 108.04 279.41998 108.364 Q 279.41998 108.88601 279.89697 108.958 L 281.175 109.138 Q 282.435 109.318 282.435 110.614 Q 282.435 111.307 281.9805 111.68951 Q 281.526 112.072 280.698 112.072 Z M 283.96503 112 L 283.96503 111.262 L 285.72 111.262 L 285.72 107.788 L 284.14502 107.788 L 284.14502 107.05 L 286.53 107.05 L 286.53 111.262 L 288.195 111.262 L 288.195 112 Z M 286.035 106.159004 Q 285.738 106.159004 285.56702 106.006 Q 285.39603 105.853 285.39603 105.592 Q 285.39603 105.32199 285.56702 105.16449 Q 285.738 105.007 286.035 105.007 Q 286.332 105.007 286.50302 105.16449 Q 286.674 105.32199 286.674 105.592 Q 286.674 105.853 286.50302 106.006 Q 286.332 106.159004 286.035 106.159004 Z M 291.795 112 Q 291.183 112 290.814 111.6445 Q 290.445 111.28901 290.445 110.69501 L 290.445 107.788 L 289.023 107.788 L 289.023 107.05 L 290.445 107.05 L 290.445 105.655 L 291.255 105.655 L 291.255 107.05 L 293.28 107.05 L 293.28 107.788 L 291.255 107.788 L 291.255 110.69501 Q 291.255 110.947 291.4035 111.1045 Q 291.552 111.262 291.795 111.262 L 293.23502 111.262 L 293.23502 112 Z M 294.765 112 L 294.765 111.262 L 296.52 111.262 L 296.52 107.788 L 294.945 107.788 L 294.945 107.05 L 297.33 107.05 L 297.33 111.262 L 298.995 111.262 L 298.995 112 Z M 296.835 106.159004 Q 296.538 106.159004 296.367 106.006 Q 296.196 105.853 296.196 105.592 Q 296.196 105.32199 296.367 105.16449 Q 296.538 105.007 296.835 105.007 Q 297.132 105.007 297.303 105.16449 Q 297.474 105.32199 297.474 105.592 Q 297.474 105.853 297.303 106.006 Q 297.132 106.159004 296.835 106.159004 Z M 302.1 112.072 Q 301.20898 112.072 300.6825 111.55 Q 300.156 111.028 300.156 110.092 L 300.156 108.958 Q 300.156 108.01301 300.678 107.4955 Q 301.19998 106.978 302.1 106.978 Q 303 106.978 303.522 107.4955 Q 304.044 108.01301 304.044 108.958 L 304.044 110.092 Q 304.044 111.028 303.5175 111.55 Q 302.991 112.072 302.1 112.072 Z M 302.1 111.35199 Q 302.63098 111.35199 302.9325 111.055 Q 303.234 110.758 303.234 110.182 L 303.234 108.868 Q 303.234 108.29201 302.9325 107.995 Q 302.63098 107.698006 302.1 107.698006 Q 301.578 107.698006 301.272 107.995 Q 300.966 108.29201 300.966 108.868 L 300.966 110.182 Q 300.966 110.758 301.272 111.055 Q 301.578 111.35199 302.1 111.35199 Z M 305.628 112 L 305.628 107.05 L 306.438 107.05 L 306.438 107.995 L 306.447 107.995 Q 306.50998 107.5 306.852 107.23 Q 307.194 106.95999 307.761 106.95999 Q 308.508 106.95999 308.94897 107.41901 Q 309.38998 107.878 309.38998 108.670006 L 309.38998 112 L 308.58 112 L 308.58 108.813995 Q 308.58 108.247 308.29648 107.9455 Q 308.013 107.644 307.52698 107.644 Q 307.02298 107.644 306.7305 107.959 Q 306.438 108.274 306.438 108.85 L 306.438 112 Z M 318.30002 109.66 Q 317.967 109.66 317.7645 109.462 Q 317.562 109.26399 317.562 108.949005 Q 317.562 108.616 317.7645 108.409 Q 317.967 108.202 318.30002 108.202 Q 318.633 108.202 318.8355 108.409 Q 319.038 108.616 319.038 108.949005 Q 319.038 109.26399 318.8355 109.462 Q 318.633 109.66 318.30002 109.66 Z M 329.001 112.09 Q 328.09198 112.09 327.561 111.581505 Q 327.03 111.07299 327.03 110.19999 L 327.8Line truncated
</g>
<g>
<path fill="#0b0b0c" fill-opacity="0.65" stroke="none" d="M 270.4912 358 L 267.88623 358 L 267.88623 349.99707 L 270.5664 349.99707 Q 271.74805 349.99707 272.5913 350.4778 Q 273.43457 350.9585 273.88574 351.8501 Q 274.3369 352.7417 274.3369 353.9878 Q 274.3369 355.23923 273.88306 356.13623 Q 273.4292 357.0332 272.56714 357.5166 Q 271.70508 358 270.4912 358 Z M 269.11084 356.92578 L 270.4214 356.92578 Q 271.78027 356.92578 272.45703 356.16574 Q 273.1338 355.40573 273.1338 353.9878 Q 273.1338 352.5752 272.4651 351.82327 Q 271.7964 351.07126 270.48584 351.07126 L 269.11084 351.07126 Z M 277.3247 358 L 277.3247 349.99707 L 280.19287 349.99707 Q 281.1167 349.99707 281.73438 350.31934 Q 282.35205 350.6416 282.6582 351.20825 Q 282.96436 351.77487 282.96436 352.51074 Q 282.96436 353.3164 282.59912 353.90457 Q 282.2339 354.49268 281.50342 354.7666 L 283.26514 358 L 281.87402 358 L 280.25195 354.97607 Q 280.21973 354.97607 280.18213 354.97607 L 278.54932 354.97607 L 278.54932 358 Z M 278.54932 353.9287 L 280.06396 353.9287 Q 280.94482 353.9287 281.33423 353.55542 Q 281.72363 353.18216 281.72363 352.51074 Q 281.72363 351.83398 281.33154 351.4392 Q 280.93945 351.04443 280.05322 351.04443 L 278.54932 351.04443 Z M 285.33984 358 L 288.18652 349.99707 L 289.69043 349.99707 L 292.59082 358 L 291.26416 358 L 290.52832 355.88916 L 287.38086 355.88916 L 286.6665 358 Z M 287.72998 354.86862 L 290.16846 354.86862 L 289.70654 353.54733 Q 289.5454 353.06934 289.35742 352.43823 Q 289.16943 351.80713 288.9331 350.9585 Q 288.69678 351.81784 288.51147 352.4543 Q 288.32617 353.09082 288.17578 353.54733 Z M 298.21045 358.10742 Q 297.1255 358.10742 296.3037 357.6079 Q 295.48193 357.1084 295.0254 356.1899 Q 294.56885 355.27148 294.56885 354.00388 Q 294.56885 352.72562 295.03345 351.80444 Q 295.49805 350.8833 296.30908 350.38647 Q 297.12012 349.88965 298.15674 349.88965 Q 299.02148 349.88965 299.7251 350.2253 Q 300.4287 350.56104 300.88794 351.15454 Q 301.34717 351.74805 301.48145 352.52686 L 300.2246 352.52686 Q 300.0044 351.82327 299.4807 351.41504 Q 298.95703 351.00684 298.16748 351.00684 Q 297.49072 351.00684 296.95093 351.3506 Q 296.41113 351.6943 296.09692 352.36304 Q 295.7827 353.03174 295.7827 353.99854 Q 295.7827 354.96533 296.09692 355.63135 Q 296.41113 356.29736 296.95898 356.6438 Q 297.50684 356.99023 298.21582 356.99023 Q 299.1665 356.99023 299.74927 356.42896 Q 300.33203 355.86768 300.35352 354.90625 L 298.39307 354.90625 L 298.39307 353.89648 L 301.55127 353.89648 L 301.55127 354.81494 Q 301.55127 355.8247 301.1189 356.56323 Q 300.68652 357.30173 299.93457 357.7046 Q 299.18262 358.10742 298.21045 358.10742 Z M 312.33936 358.10742 Q 311.30273 358.10742 310.48364 357.61328 Q 309.66455 357.11914 309.19458 356.20068 Q 308.7246 355.2822 308.7246 354.00388 Q 308.7246 352.7202 309.19458 351.7991 Q 309.66455 350.87793 310.48364 350.3838 Q 311.30273 349.88965 312.33936 349.88965 Q 313.37598 349.88965 314.1897 350.3838 Q 315.00342 350.87793 315.4734 351.7991 Q 315.94336 352.7202 315.94336 354.00388 Q 315.94336 355.2822 315.4734 356.20337 Q 315.00342 357.1245 314.1897 357.616 Q 313.37598 358.10742 312.33936 358.10742 Z M 312.33936 356.99023 Q 313.02148 356.99023 313.56128 356.6465 Q 314.10107 356.30273 314.41528 355.63672 Q 314.7295 354.9707 314.7295 354.00388 Q 314.7295 353.03174 314.41528 352.36304 Q 314.10107 351.6943 313.56128 351.3506 Q 313.02148 351.00684 312.33936 351.00684 Q 311.65186 351.00684 311.10938 351.3506 Q 310.5669 351.6943 310.2527 352.36304 Q 309.93848 353.03174 309.93848 354.00388 Q 309.93848 354.9707 310.2527 355.63672 Q 310.5669 356.30273 311.10938 356.6465 Q 311.65186 356.99023 312.33936 356.99023 Z M 318.93652 358 L 318.93652 349.99707 L 320.34912 349.99707 L 323.3623 354.76123 Q 323.5503 355.062 323.80273 355.51053 Q 324.05518 355.95898 324.32373 356.5337 Q 324.28076 355.9536 324.26196 355.42453 Q 324.24316 354.8955 324.24316 354.55176 L 324.24316 349.99707 L 325.4839 349.99707 L 325.4839 358 L 324.06592 358 L 321.36426 353.74072 Q 321.16553 353.4238 320.9856 353.1123 Q 320.80566 352.80078 320.59082 352.41135 Q 320.37598 352.02194 320.08594 351.48483 Q 320.12354 352.23682 320.1504 352.82764 Q 320.17725 353.41846 320.17725 353.72998 L 320.17725 358 Z M 328.35352 351.0498 L 328.35352 349.99707 L 334.56787 349.99707 L 334.56787 351.0498 L 332.08105 351.0498 L 332.08105 358 L 330.85107 358 L 330.85107 351.0498 Z M 340.43994 358.10742 Q 339.40332 358.10742 338.58423 357.61328 Q 337.76514 357.11914 337.29517 356.20068 Q 336.8252 355.2822 336.8252 354.00388 Q 336.8252 352.7202 337.29517 351.7991 Q 337.76514 350.87793 338.58423 350.3838 Q 339.40332 349.88965 340.43994 349.88965 Q 341.47656 349.88965 342.29028 350.3838 Q 343.104 350.87793 343.57397 351.7991 Q 344.0439 352.7202 344.0439 354.00388 Q 344.0439 355.2822 343.57397 356.20337 Q 343.104 357.1245 342.29028 357.616 Q 341.47656 358.10742 340.43994 358.10742 Z M 340.43994 356.99023 Q 341.12207 356.99023 341.66187 356.6465 Q 342.20166 356.30273 342.51587 35Line truncated
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 42 KiB

@@ -0,0 +1,8 @@
asset: background.svg
title: EffectCraft macOS DMG window background
author: @XusBadia
source: original work
license: MIT OR Apache-2.0
license-file: LICENSE-MIT, LICENSE-APACHE
added: 2026-10-08 by @XusBadia
notes: Original work for this repository, derived from the EffectCraft app icon (assets/app-icon/effectcraft.svg, referenced via <image>, not copied). Used for the Finder window of the macOS DMG; packaging/macos/package.sh renders it to a TIFF at package time. Text is outlined Inter/JetBrains Mono glyph paths.
Binary file not shown.
+87
View File
@@ -0,0 +1,87 @@
#!/usr/bin/env python3
"""Regenerate dmg-layout.DS_Store for the macOS DMG window (see README.md here).
Needs:
pip install ds_store==1.3.3 mac_alias==2.2.3
Runs on any OS, no Mac needed. The file comes from this script alone, so it carries nothing
from the machine that made it: no local paths, user or disk names, dates or volume UUIDs.
(background.tiff is rendered from background.svg by packaging/macos/package.sh at package time.)
python3 packaging/macos/dmg/generate.py
"""
import datetime
import os
from ds_store import DSStore
from mac_alias import Alias, TargetInfo, VolumeInfo
HERE = os.path.dirname(os.path.abspath(__file__))
# Keep in sync with package.sh (volume name) and README.md (layout).
VOLUME = "EffectCraft"
WIDTH, HEIGHT = 660, 400 # window content, pt; the background's 1x size
TITLE_BAR = 32
ICON_SIZE = 128
ICONS = {"EffectCraft.app": (326, 205), "Applications": (574, 205)}
# A fixed date for the alias. Finder never matches it against the image
# (each build is a new volume): it finds the background by volume name and path.
FIXED_DATE = datetime.datetime(2026, 10, 8, tzinfo=datetime.timezone.utc)
def background_alias():
# What Finder stores for /.background/background.tiff on the volume, minus anything about the
# machine (dmgbuild writes the same kind of alias from a mounted image). Disk type 5 (ejectable),
# the volume flags and the folder/file ids (25, 26) are what Finder wrote on a test image; the ids
# are only hints, as the volume's creation date.
volume = VolumeInfo(VOLUME, FIXED_DATE, b"H+", 5, 0x0D02, b"\0\0")
volume.posix_path = f"/Volumes/{VOLUME}"
target = TargetInfo(0, "background.tiff", 25, 26, FIXED_DATE, b"\0\0\0\0", b"\0\0\0\0")
target.folder_name = ".background"
target.cnid_path = [25]
target.carbon_path = f"{VOLUME}:.background:\0background.tiff"
target.posix_path = "/.background/background.tiff"
return Alias(volume=volume, target=target).to_bytes()
def write_ds_store(out):
if os.path.exists(out):
os.remove(out)
with DSStore.open(out, "w+") as d:
d["."]["bwsp"] = {
"ShowStatusBar": False,
"ShowToolbar": False,
"ShowTabView": False,
"ContainerShowSidebar": False,
"ShowSidebar": False,
"WindowBounds": f"{{{{200, 528}}, {{{WIDTH}, {HEIGHT + TITLE_BAR}}}}}",
}
d["."]["icvp"] = {
"viewOptionsVersion": 1,
"backgroundType": 2,
"backgroundImageAlias": background_alias(),
"backgroundColorRed": 1.0,
"backgroundColorGreen": 1.0,
"backgroundColorBlue": 1.0,
"gridOffsetX": 0.0,
"gridOffsetY": 0.0,
"gridSpacing": 100.0,
"arrangeBy": "none",
"showIconPreview": True,
"showItemInfo": False,
"labelOnBottom": True,
"textSize": 16.0,
"iconSize": float(ICON_SIZE),
}
d["."]["vSrn"] = ("long", 1)
for name, pos in ICONS.items():
d[name]["Iloc"] = pos
def main():
write_ds_store(os.path.join(HERE, "dmg-layout.DS_Store"))
if __name__ == "__main__":
main()
+11 -1
View File
@@ -129,10 +129,20 @@ STAGE="$WORK/dmg"
mkdir -p "$STAGE"
ditto "$APP" "$STAGE/EffectCraft.app"
ln -s /Applications "$STAGE/Applications"
# Finder window layout: background, icon size and positions (packaging/macos/dmg/README.md).
# The background is rendered from its SVG (1x + 2x in one HiDPI TIFF), so no bitmap is committed.
command -v resvg >/dev/null || { echo "resvg not found (cargo install resvg --locked --version 0.48.1)" >&2; exit 1; }
mkdir -p "$STAGE/.background"
resvg --skip-system-fonts -w 660 "$HERE/dmg/background.svg" "$WORK/background.png"
resvg --skip-system-fonts -w 1320 "$HERE/dmg/background.svg" "$WORK/[email protected]"
sips -s dpiWidth 144 -s dpiHeight 144 "$WORK/[email protected]" >/dev/null
tiffutil -cathidpicheck "$WORK/background.png" "$WORK/[email protected]" -out "$STAGE/.background/background.tiff"
cp "$HERE/dmg/dmg-layout.DS_Store" "$STAGE/.DS_Store"
rm -f "$DMG" "$WORK/raw.dmg"
# makehybrid + convert builds the image without attaching a device, unlike `create -srcfolder`,
# which is flaky on CI runners ("Resource busy") and hangs in sandboxed sessions.
hdiutil makehybrid -hfs -hfs-volume-name "EffectCraft $VERSION" -hfs-openfolder "$STAGE" -o "$WORK/raw.dmg" "$STAGE"
# The volume name has no version: .DS_Store finds the background through an alias that includes it.
hdiutil makehybrid -hfs -hfs-volume-name "EffectCraft" -hfs-openfolder "$STAGE" -o "$WORK/raw.dmg" "$STAGE"
hdiutil convert "$WORK/raw.dmg" -format UDZO -imagekey zlib-level=9 -o "$DMG"
rm -f "$WORK/raw.dmg"
sign "$DMG"