diff --git a/desktop/build.gradle.kts b/desktop/build.gradle.kts index 7a88b04c..6e4991c2 100644 --- a/desktop/build.gradle.kts +++ b/desktop/build.gradle.kts @@ -65,6 +65,8 @@ dependencies { compose.desktop { application { mainClass = "com.greenart7c3.nostrsigner.desktop.MainKt" + // Lets Main.kt set the X11 WM_CLASS so Linux docks match amber.desktop. + jvmArgs += "--add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED" nativeDistributions { targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Exe, TargetFormat.Deb, TargetFormat.Rpm) @@ -75,7 +77,7 @@ compose.desktop { copyright = "© greenart7c3. Distributed under the MIT license." linux { - iconFile.set(rootProject.file("assets/android-icon-hires.png")) + iconFile.set(project.file("src/main/resources/icon.png")) menuGroup = "Network" } windows { @@ -88,6 +90,7 @@ compose.desktop { } macOS { bundleID = "com.greenart7c3.nostrsigner" + iconFile.set(project.file("icons/amber.icns")) infoPlist { // Claim nostrconnect:// so LaunchServices routes those // links to Amber (delivered via Desktop.setOpenURIHandler). diff --git a/desktop/icons/amber.icns b/desktop/icons/amber.icns new file mode 100644 index 00000000..d6298d95 Binary files /dev/null and b/desktop/icons/amber.icns differ diff --git a/desktop/icons/amber.ico b/desktop/icons/amber.ico index 79beabce..65427844 100644 Binary files a/desktop/icons/amber.ico and b/desktop/icons/amber.ico differ diff --git a/desktop/icons/amber.svg b/desktop/icons/amber.svg new file mode 100644 index 00000000..f3fea40f --- /dev/null +++ b/desktop/icons/amber.svg @@ -0,0 +1 @@ + diff --git a/desktop/src/main/kotlin/com/greenart7c3/nostrsigner/desktop/Main.kt b/desktop/src/main/kotlin/com/greenart7c3/nostrsigner/desktop/Main.kt index a29c40dc..8f0cce8b 100644 --- a/desktop/src/main/kotlin/com/greenart7c3/nostrsigner/desktop/Main.kt +++ b/desktop/src/main/kotlin/com/greenart7c3/nostrsigner/desktop/Main.kt @@ -22,6 +22,7 @@ import androidx.compose.ui.window.rememberTrayState import com.greenart7c3.nostrsigner.desktop.core.AccountManager import com.greenart7c3.nostrsigner.desktop.core.AccountsStore import com.greenart7c3.nostrsigner.desktop.core.AmberDesktop +import com.greenart7c3.nostrsigner.desktop.core.AmberLogger import com.greenart7c3.nostrsigner.desktop.core.AutoStart import com.greenart7c3.nostrsigner.desktop.core.DesktopAccount import com.greenart7c3.nostrsigner.desktop.core.NetworkConnectivity @@ -129,6 +130,23 @@ private object DesktopTray { var instance: NativeTray? = null } +/** + * AWT derives the X11 WM_CLASS from whichever thread first loaded the toolkit + * (e.g. `java-lang-Thread`), so docks (GNOME, KDE) can't match the window to + * `amber.desktop` (StartupWMClass=Amber) and show a generic icon instead of + * Amber's. Must run before the first window is created; needs + * `--add-opens java.desktop/sun.awt.X11=ALL-UNNAMED`. + */ +private fun setX11WindowClass(name: String) { + runCatching { + val toolkit = java.awt.Toolkit.getDefaultToolkit() + toolkit.javaClass.getDeclaredField("awtAppClassName").apply { + isAccessible = true + set(toolkit, name) + } + }.onFailure { AmberLogger.e("Main", "could not set WM_CLASS", it) } +} + fun main(args: Array) { // Packaged handler: the URI arrives as an argument. Dev handler // (gradle): it arrives via the drop file (gradle cannot take it as an @@ -179,6 +197,8 @@ fun main(args: Array) { ) } + if (DesktopTray.isLinux) setX11WindowClass("Amber") + Session.boot() application { diff --git a/desktop/src/main/resources/icon.png b/desktop/src/main/resources/icon.png index 0403d946..9dd1b6ad 100644 Binary files a/desktop/src/main/resources/icon.png and b/desktop/src/main/resources/icon.png differ