Completing the DMG Layout with Coordinates

In Part 1, we introduced the create-dmg tool and prepared a staging folder holding only the .app along with a background image.

Now for the final piece, the layout. How large to open the DMG window, and where to place the app icon and the Applications shortcut — all of this is decided by the coordinates you pass to create-dmg. In this article, we’ll design those coordinates one by one.

As in Part 1, FocusTimer, the coordinate values, and so on are all examples.

The Full create-dmg Command

First, let’s look at the complete command in full. This is the command that builds the DMG for the example app FocusTimer 1.0:

create-dmg \
  --volname "FocusTimer 1.0" \
  --background build/dmg-background.png \
  --window-pos 200 120 \
  --window-size 600 400 \
  --icon-size 100 \
  --icon "FocusTimer.app" 175 190 \
  --hide-extension "FocusTimer.app" \
  --app-drop-link 425 190 \
  --no-internet-enable \
  "build/FocusTimer-1.0.dmg" \
  "build/dmg-stage/"

The last two lines are the output and the input:

  • build/FocusTimer-1.0.dmg — the path of the DMG file to be created
  • build/dmg-stage/ — the staging folder that held only the .app from Part 1

The lines above them that start with -- are the options that design the window and the icons. Let’s go through them one by one.

Understanding the Coordinate System

Before we look at the options, let’s nail down how the coordinates work.

All of create-dmg’s position coordinates are coordinates within the DMG window. The unit is the point explained in Part 1.

  • The origin (0, 0) is the top-left corner of the window.
  • X increases as you move right, and Y increases as you move down. (Note that, unlike a math graph, Y increases downward.)
  • If you set the window size to 600 400, the coordinates move within the range 0–600 horizontally and 0–400 vertically.

An icon’s position coordinate points to the center of that icon — not its top-left corner, but its dead center.

The Options, One by One

OptionValue (example)Meaning
--volname"FocusTimer 1.0"The volume name shown when the DMG is mounted
--backgroundbuild/dmg-background.pngThe window background image (the one prepared in Part 1)
--window-pos200 120The position where the window opens on the screen (X, Y)
--window-size600 400The size of the window (width, height — in points)
--icon-size100The size of the icons inside the window (in points)
--icon "FocusTimer.app"175 190The position of the app icon (X, Y within the window)
--hide-extension "FocusTimer.app"Hides the .app extension in the icon’s name
--app-drop-link425 190The position of the Applications folder shortcut (X, Y within the window)
--no-internet-enableTurns off the no-longer-used “internet-enable” feature

A few of these are worth calling out separately.

--window-pos vs. --window-size — these two are easy to mix up. --window-pos is where on the screen (the desktop) the window appears when the user opens the DMG, while --window-size is the size of the window itself. The one that matters for coordinate design is --window-size.

--icon-size 100 — the icons inside the window are drawn at a size of 100 points. You need to know this value when designing the background image too, because the 100-point space each icon occupies (= 200 pixels in the background image) must be left empty in the background.

--icon and --app-drop-link — these two are the left and right stars of the window. --icon is the app icon the user has to drag, and --app-drop-link is the Applications folder shortcut that serves as the drop destination. With --app-drop-link, there’s no need to create a symbolic link separately — create-dmg makes and places the Applications shortcut for you.

--hide-extension — without this, the icon shows the full FocusTimer.app with its extension underneath. Hiding it makes it appear cleanly as just FocusTimer.

--no-internet-enable — “internet-enable” is an old feature by which an older Safari automatically processed downloaded DMGs; it’s no longer used today. Passing this option makes create-dmg skip that processing step and the related warning.

Coordinate Design — Placing the Two Icons

Now for the heart of it. We set the window size to 600 400, so within that we decide where to place the app icon and the Applications shortcut.

In the example command, we set them like this:

  • App icon: --icon "FocusTimer.app" 175 190
  • Applications shortcut: --app-drop-link 425 190

Here’s what these numbers mean:

The X axis (horizontal) — 175 and 425

The window width is 600 points, and its center is 300. Placing the two icons at 175 and 425 puts each one 125 to the left and 125 to the right of the center. In other words, the two icons are placed symmetrically about the center. With the app icon on the left and Applications on the right, this creates the natural direction of “drag from left to right.”

The Y axis (vertical) — both at 190

The window height is 400 points, and its center is 200. Placing both icons at the same 190 puts them side by side at the same height, sitting slightly above the dead center (200). Since the icon label is attached below the icon, nudging it slightly up makes it visually centered once the label is included.

There’s no single correct answer for the coordinates. The values above are just one balanced example of placing “two 100-point icons side by side and symmetrically in a 600×400 window.” Feel free to adjust them to fit your own background design.

Aligning the Background Image with the Coordinates

Here, the @2x convention from Part 1 reappears.

The icon coordinates (175,190, 425,190) are the window’s point coordinates. But the background image is twice that size — 1200×800 pixels. When you draw the arrow on the background image, you have to think in terms of pixel coordinates that are the window coordinates multiplied by 2.

Background image pixel coordinates = window point coordinates × 2

Converting the two icons from the example into background image pixel coordinates gives this:

ElementWindow coordinates (points)Background image coordinates (pixels)
App icon center(175, 190)(350, 380)
Applications center(425, 190)(850, 380)

So when you draw the guiding arrow on the background image (1200×800), it must be drawn between pixels (350, 380) and (850, 380) — the spots of the two icons. Since the icon size is 100 points = 200 pixels, leave the 200-pixel area each icon occupies empty and place the arrow in the space between them.

Aligning the background image’s artwork with create-dmg’s icon coordinates against the same reference is the heart of DMG design. If the two are off, the arrow misses the icons or gets drawn overlapping them.

Verification and Fine-Tuning

When you run the command, build/FocusTimer-1.0.dmg is created. Double-click the resulting DMG and open it yourself.

  • Does the background fill the window completely? (If it’s shrunk into a corner → that’s the DPI pitfall from Part 1. Normalize it to 144 with sips.)
  • Are the app icon and Applications placed nicely at the two ends of the background arrow?
  • Are the icon labels not cut off or overlapping?

The coordinates usually don’t line up perfectly on the first try. Just repeat the process a few times: tweak the numbers in --icon and --app-drop-link a little, run the command again, and check with your eyes. Once you’ve finalized the coordinates, you’ll rarely need to change them again.

Reusing for Every Release — Automation

DMG design is effectively a one-time task. Once you’ve finalized the background image and the coordinates, you reuse the exact same settings for every release that follows.

So it’s a good idea to put this create-dmg call in as one step of your release build script. In a script, the flow usually looks like this:

  1. Copy the signed, notarized, and stapled .app into the staging folder (Part 1)
  2. Copy the background image and then normalize its DPI to 144 with sips (preventing the Part 1 pitfall)
  3. Run create-dmg with the coordinates designed above
  4. Clean up temporary files such as the staging folder

Only the version number changes from release to release (the 1.0 in --volname, and FocusTimer-1.0.dmg in the output filename), so if you pull just that part out into a script variable, you won’t need to touch the command each time. Keep the background image path and all the coordinates as fixed values.

We recommend having the script automatically perform the background image’s DPI normalization (sips) every time. That way, even if you forget to normalize the DPI when you re-export the design original and swap it in, the script always corrects it for you.

Series Wrap-Up

The two-part DMG design is complete. You now have:

  • (Part 1) create-dmg + a .app staging folder + a background image with @2x and DPI normalized
  • (Part 2) Window and icon coordinate design + aligning the background pixel coordinates with the window point coordinates + automation

To recap the key points:

  • The DMG window is 600×400 points, and the background image is twice that — 1200×800 pixels (@2x).
  • The background PNG’s DPI must be normalized to 144 — only then does the background fill the window exactly.
  • The icon coordinates are point coordinates within the window, and the background artwork coordinates are pixel coordinates twice that — align the two against the same reference.
  • Put the design you’ve finalized into your build script and reuse it as-is for every release.

A single small arrow, or an icon position off by a few points, can sway a user’s first impression. Since the .dmg window is the very place a user first meets your app, it’s well worth designing carefully, once.

References