From 9769bec472bd8014eecfdfe99bf1f0c18fdca94c Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 24 Apr 2026 13:47:30 +0000 Subject: [PATCH] fix(desktop): set macOS dock / Cmd+Tab icon via Taskbar API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Window(icon = ...) only sets the in-title-bar proxy icon — it does NOT drive the Cmd+Tab app switcher on macOS. That reads java.awt.Taskbar's iconImage, which was never set, so gradle-run sessions showed the generic Java coffee-cup square. Load the PNG via ImageIO (preserves alpha), then set Taskbar.iconImage before the application{} block starts. Guarded by isTaskbarSupported + Feature.ICON_IMAGE so the call is a no-op on platforms without it. Applies on all OSes that support the Taskbar API — macOS gets the dock icon, GNOME/KDE get the task-switcher thumbnail, Windows gets the taskbar icon. https://claude.ai/code/session_01NufduPfZvYQVYwLkbCjCUo --- .../vitorpamplona/amethyst/desktop/Main.kt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/Main.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/Main.kt index 56176a09f8..c63db689fe 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/Main.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/Main.kt @@ -196,6 +196,26 @@ fun main() { System.setProperty("apple.awt.application.appearance", "system") } + // Set the dock / taskbar icon image before any window is shown. + // + // On macOS the Cmd+Tab app switcher and the dock use the Taskbar API's + // iconImage, NOT the Window(icon=) composable parameter (which only sets + // the in-title-bar proxy icon). Without this, a JVM launched via gradle + // shows the generic Java coffee-cup square in Cmd+Tab. ImageIO preserves + // the PNG alpha channel so the dock renders the logo with transparency. + try { + val bytes = Unit::class.java.getResourceAsStream("/icon.png")!!.readBytes() + val awtImage = javax.imageio.ImageIO.read(java.io.ByteArrayInputStream(bytes)) + if (awtImage != null && java.awt.Taskbar.isTaskbarSupported()) { + val taskbar = java.awt.Taskbar.getTaskbar() + if (taskbar.isSupported(java.awt.Taskbar.Feature.ICON_IMAGE)) { + taskbar.iconImage = awtImage + } + } + } catch (e: Exception) { + Log.w("Main") { "Failed to set dock icon: ${e.message}" } + } + Log.minLevel = LogLevel.DEBUG DesktopImageLoaderSetup.setup() Runtime.getRuntime().addShutdownHook(