From 0f31d33ffea7895197a881ac275d0ebcdde00ff9 Mon Sep 17 00:00:00 2001 From: Sebastian Ratz Date: Tue, 14 Oct 2025 17:47:38 +0200 Subject: [PATCH] [macOS] Only use Decorations#setImage() in Dock if no app bundle set Currently, there are three possible sources for the Dock icon on macOS in the order of precedence: 1) An explicitly set icon via -Xdock:icon=/path/to/icon.icns which calls NSApp setApplicationIconImage 2) An implicitly set icon via org.eclipse.swt.widgets.Decorations.setImage(Image) org.eclipse.swt.widgets.Decorations.setImages(Image[]) which in passed down to the Dock also via NSApp setApplicationIconImage 3) An implicitly set icon in a Bundled.app distrubution via CFBundleIconName / CFBundleIconFile in the Info.plist file 1) and 2) use legacy API NSApp setApplicationIconImage which only supports a single fixed NSImage, i.e. there is no support for dark/light mode and or modern look & feel such as Liquid Glass. Only 3) (app bundle) supports dynamic icons. The problem is that 2) currently overwrites whatever 3) has set. On top of that, the Decorations are typically cross-platform, so in fact this will prevents using a macOS-specific icon at all. We want to prefer 3) over 2), i.e. only pass down the decorations whenever we are *not* an app bundle with a declared image. Similar coding also exists in the JVM, where the dock icon is only set if we are *not* in an app bundle that specifies an icon: https://github.com/openjdk/jdk21u/blob/8c322f5953ae161d793213f92d13a1f53d995883/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m#L280-L290 --- .../cocoa/org/eclipse/swt/widgets/Decorations.java | 4 ++-- .../cocoa/org/eclipse/swt/widgets/Display.java | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Decorations.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Decorations.java index b96e68f8593..e68d86157cf 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Decorations.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Decorations.java @@ -515,7 +515,7 @@ public void setImage (Image image) { if (image != null && image.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT); this.image = image; if (parent != null) return; - if (display.dockImage == null) { + if (display.dockImage == null && !display.isBundledIconSet()) { display.application.setApplicationIconImage (image != null ? image.handle : null); } } @@ -552,7 +552,7 @@ public void setImages (Image [] images) { } this.images = images; if (parent != null) return; - if (display.dockImage == null) { + if (display.dockImage == null && !display.isBundledIconSet()) { if (images != null && images.length > 1) { Image [] bestImages = new Image [images.length]; System.arraycopy (images, 0, bestImages, 0, images.length); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java index abd8b2446dc..dc2caec0293 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java @@ -3441,6 +3441,17 @@ boolean isBundled () { return false; } +boolean isBundledIconSet () { + NSBundle mainBundle = NSBundle.mainBundle(); + if (mainBundle != null) { + NSDictionary info = mainBundle.infoDictionary(); + if (info != null) { + return info.objectForKey(NSString.stringWith("CFBundleIconName")) != null || info.objectForKey(NSString.stringWith("CFBundleIconFile")) != null ; + } + } + return false; +} + static boolean isValidClass (Class clazz) { String name = clazz.getName (); int index = name.lastIndexOf ('.');