@@ -113,6 +113,14 @@ one line from the build script and the flag is gone from the run's JVM arguments
113113icon is back. So ` java.awt.Taskbar ` has nothing to add here. ` Window(icon = …) ` does, but only for the
114114Windows and Linux title bar — macOS ignores it.
115115
116+ ** ` -Xdock:icon ` is what puts the icon on the tile, and a bundle around the JVM is not a substitute.**
117+ AWT sets the dock tile from that flag as it starts, and when the flag is absent it sets the tile to
118+ the Java icon — over whatever the bundle asked for. So ` runNamed ` passes the flag too, even though its
119+ generated bundle declares ` CFBundleIconFile ` . ` CFBundleIconFile ` is not ignored, it is just overwritten:
120+ ` NSRunningApplication.icon ` for a ` runNamed ` process without the flag hands back the shark, because
121+ that is the LaunchServices record, while the tile on screen is Duke. ** Which is the trap** — every API
122+ an agent can read says the icon is right, and only a picture of the dock says otherwise.
123+
116124## What macOS calls the run, as against what it calls a window
117125
118126A run is one process and many windows, so the OS gets one name for all of them, and ` main ` sets it from
@@ -195,8 +203,21 @@ what the dock says is to ask the person in front of it. It is granted per respon
195203agent, whichever app launched the session — in System Settings → Privacy & Security → Accessibility.
196204Screen Recording is separate, and without it a screenshot of another process comes back as wallpaper.
197205
198- An icon can be checked without either: ` NSWorkspace.iconForFile ` on a bundle hands back what macOS
199- resolved for it, and writing that to a PNG is a picture an agent can open.
206+ ** A tile's icon, though, only a screenshot of the dock will tell you.** ` NSWorkspace.iconForFile ` on a
207+ bundle and ` NSRunningApplication.icon ` on a pid both hand back a PNG an agent can open, but both read
208+ the LaunchServices record rather than the tile, so both are wrong the moment AWT overwrites it — see
209+ the ` -Xdock:icon ` section. With Screen Recording granted, this is the picture that settles it:
210+
211+ ``` bash
212+ # The dock has no window while it is hidden, so a capture of where AX says the tile is comes back blank.
213+ # Post mouse moves down to the bottom edge — one warp isn't enough, it takes an approach and a dwell —
214+ # then ask AX for the tile again: a y that has moved up by the dock's height means it is on screen.
215+ osascript -e ' tell application "System Events" to tell process "Dock" \
216+ to get {position, size} of (first UI element of list 1 whose name is "<the run>")'
217+ screencapture -x -R < x> ,< y> ,< w> ,< h> tile.png
218+ ```
219+
220+ Put the cursor back where it was afterwards, since it is someone's cursor.
200221
201222## Build and test
202223
0 commit comments