FYI, a bunch of ways to customize UI stuff on Java...
# compose-desktop
a
FYI, a bunch of ways to customize UI stuff on Java/macOS: https://developer.apple.com/library/archive/technotes/tn2007/tn2196.html
šŸ‘€ 2
šŸŒ¶ļø 1
Only the window-related stuff is probably interesting for us.
c
Sorta on this same wave-length. The current issue I'm having with my mac app is that I want to prevent it from showing in the task switcher (like most "system tray" apps). It seems like that mode is called an "accessory mode" app on macOS. Does anyone know how to turn your app into an "accessory"?
a
There was a flag to do that
-Dapple.awt.UIElement=true
c
I'll check that out. everything that I saw regarding it was to try to do it at runtime, but I'll see how I can apply that flag.
a
Best to pass that as a JVM argument.
c
Seems like I can do this
Copy code
tasks.named<JavaExec>("run") {
    if (org.gradle.internal.os.OperatingSystem.current().isMacOsX) {
        jvmArgs = listOf("-Dapple.awt.UIElement=true")
    }
}
this also maybe seems to work?
Copy code
nativeDistributions {
            targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
            packageName = "test"
            packageVersion = "1.0.0"

            macOS {
                macOS {
                    infoPlist {
                        extraKeysRawXml = """
                          <key>LSUIElement</key>
                          <true/>
                        """.trimIndent()
                    }
                }
            }
        }
r
You don't even need to check if y ou are on macOS to pass that
-D
argument. It only sets a system property so it'll be a no-op everywhere else.
c
good point. I added it here
Copy code
compose.desktop {
    application {
        jvmArgs += listOf("-Dapple.awt.UIElement=true")
It doesn't seem to work since I still see the java icon in the switcher... but ill try to investigate more
r
You may need to add this property to your Info.plist. I've also sometimes had to set the property directly from the main function instead (not for this property, but for others)
It may also be an issue with whatever JDK you are using. OpenJDK for instance doesn't seem to support it: https://bugs.openjdk.org/browse/JDK-8092032
a
Works for me (using the
run
task)
šŸ‘ 1
err, it should be
Copy code
jvmArgs += "-Dapple.awt.UIElement=true"
c
Confirming that plist did not work either
Copy code
macOS {
    infoPlist {
        extraKeysRawXml = """
              <key>LSUIElement</key>
              <true/>
            """.trimIndent()
    }
}
a
Hmm, works with
listOf
too.
I guess there’s another
plusAssign
overload
c
+= doesn't seem to play nice?
a
I have
Copy code
// Prevents the Java icon from being shown in the macOS dock when running tests
tasks.withType<Test>().configureEach {
    systemProperty("apple.awt.UIElement", "true")
}
which also works
c
Task with name 'run' not found in project ':composeApp'.
hm. I feel like im doing something very wrong. lol
does this go into root build.gradle maybe
r
@Colton Idle for the plist it needs to be
<string>true</string>
a
I would start with just putting it in
main
to verify that it works at all.
ā˜ļø 1
before fighting gradle
Make it the first line though.
ā˜ļø 1
r
Yeah it has to be before anything initializes AWT
a
or create a Kotlin Run configuration in IDEA and put the
-D…
there
c
tried in the plist with <string>true</string> and still no dice.
Let me try in main.
r
Could it be your JDK/JRE?
a
But also… It seems to prevent any UI from being shown. So windows don’t actually show up. Not sure if that’s what you want.
c
CleanShot 2025-03-10 at 18.20.27@2x.png
r
Try using the JetBrains' runtime
a
Task with name ā€˜run’ not found in project ā€˜:composeApp’.
c
Invoking from there worked!
a
What I meant there was
Copy code
compose.desktop {
    application {
        jvmArgs += "-Dapple.awt.UIElement=true"
        ...
    }
}
and then use the
run
task.
c
Gotcha. I was just reusing the task/configuration that came from the run button in the gutter
maybe dumb question... but so is there a "best" place to put this? seems like ive got 3 options: 1. plist 2. jvm args 3. somewhere in the main function of the app?
I can also confirm that I can get my "settings" window to show when I click it from the menu bar. So it seems to work as I wanted!
a
and to set it in your distributable
Copy code
compose.desktop {
    application {
        nativeDistributions {
            ...
            macOS {
                jvmArgs += "-Dapple.awt.application.appearance=system"
            }
        }
    }
}
r
@Colton Idle if you put it in
main
, put it as the first thing and it should work just fine
(I always put these properties for macOS in my main function to avoid this kind of issues)
a
I can also confirm that I can get my ā€œsettingsā€ window to show when I click it from the menu bar. So it seems to work as I wanted!
Ah, so it does open a window, it just doesn’t bring it to the front, so it was behind the IDE for me, and I didn’t see it.
c
FWIW. I changed back to my java_home as the jdk and it worked. So it seems like the trick was running the run task specifically. and not run from the gutter.
Ah, so it does open a window, it just doesn’t bring it to the front, so it was behind the IDE for me, and I didn’t see it.
Ah. I do indeed have that "bring to front" code you helped me with a few weeks ago.
r
Right, because your run task was not launching the Gradle run task, so you'd have needed to add the -D to your existing run task. Hence putting it in main instead šŸ˜„
c
Okay. lemme see how to add it to main.
a
Putting it in main is a bit risky because even if you don’t do any AWT initialization before main now, you could accidentally end up doing it later.
c
FWIW.
Copy code
@OptIn(ExperimentalResourceApi::class)
fun main() = application {
    System.setProperty("apple.awt.UIElement", "true")
did not seem to work
r
True but at least you are keeping UI code where you do UI
šŸ‘ 1
a
fun main() = application {
System.setProperty(ā€œapple.awt.UIElementā€, ā€œtrueā€)
That’s waaay after AWT initialization
šŸ‘€ 1
Copy code
fun main() {
    System...
    application {
        ..
    }
}
c
For anyone that stumbles upon this in the future...
Copy code
compose.desktop {
    application {
        jvmArgs += listOf("-Dapple.awt.UIElement=true")
^worked
Copy code
compose.desktop {
    application {
        nativeDistributions {
...
            macOS {
                jvmArgs.add("-Dapple.awt.UIElement=true")
            }
^worked
Copy code
macOS {
    infoPlist {
        extraKeysRawXml = """
              <key>LSUIElement</key>
              <true/> and tried <string>true</true>
            """.trimIndent()
    }
}
^did not work
Copy code
@OptIn(ExperimentalResourceApi::class)
fun main() {
    System.setProperty("apple.awt.UIElement", "true")
    application {
^worked
Copy code
tasks.named<JavaExec>("run") {
        jvmArgs = listOf("-Dapple.awt.UIElement=true")
}
^did not work, but only because it can't find the run task?
THANK YOU!
a
btw, the AI chatbots know these things, and it’s a simple thing to ask. Well, Claude does, anyway.
c
will do. im still not on that ai train. everytime i give it a "straightforward" ask regarding compose for desktop... it doesn't seem to know. lol
m
That's from 2007, did Apple ever update this functionality?
šŸ‘€ 1