Skip to content

Linux: allow setting the Wayland app_id (JVM/dev runs get "java", so the shell can't match the .desktop entry) #577

Description

@rocketraman

⚠️ Is your feature request related to a problem? Please describe

On Linux, a Nucleus app launched any way other than through the packaged launcher binary gets
the Wayland app_id java, so the desktop shell can't match the window to its .desktop
entry and the taskbar falls back to a generic icon.

Launching via the Gradle run task, the app_id is the GTK program name, which is java for
any JVM process. The compositor matches windows to .desktop entries by
app_id/StartupWMClass, so nothing matches. The packaged .deb/.rpm is fine — there the
launcher binary is named after the package, so the app_id matches the generated
StartupWMClass. run, java -jar and IDE run configurations are all affected.

Setting icon = painterResource(...) on the window doesn't help: Wayland has no per-window
icon that the shell uses.

Reported downstream as rocketraman/gitvantage#10 — a contributor
running from source sees a generic taskbar icon, while the packaged build is correct.

Environment: Nucleus 2.4.0, JVM (Temurin 25), Fedora 44, KDE Plasma 6 (Wayland), Tao
decorated-window backend.

Steps to reproduce

  1. Configure nativeDistributions.linux { packageName = "myapp"; startupWMClass = "MyApp" }.
  2. ./gradlew run on a Wayland session.
  3. Inspect the window's app_id (KWin's window-info overlay, or
    qdbus org.kde.KWin /KWin queryWindowInfo) — it reports java.
  4. Install the .rpm/.deb and launch it from the app menu — app_id is MyApp and the
    icon resolves correctly.

💡 Describe the solution you'd like

On Linux, have the Tao backend set the GTK program name before the first window is realized —
e.g. g_set_prgname(), which is what GDK derives the Wayland app_id from — resolved from
the values Nucleus already computes.

Most of this already exists in the framework; it just isn't applied on the JVM/Tao path:

  • The run task already injects -Dnucleus.app.id=<resolved id>
    (configureJvmApplication.kt, JVM args for the run exec).
  • generateAppProperties writes nucleus/nucleus-app.properties (app.id,
    startup.wm.class) into a resources srcDir of the main source set, so both keys are on the
    classpath during a dev run, not only in packaged builds.
  • AppNameResolver (in nucleus.graalvm-runtime) already implements the desired resolution
    order — startup.wm.classapp.idnucleus.app.id → executable name — but it is only
    wired into a GraalVM substitution for AWT's XToolkit, so it never runs for JVM + Tao.
  • macOS dev runs already get equivalent treatment (-Dapple.awt.application.name,
    -Xdock:icon). Linux has no counterpart.

It would also help to expose an explicit override — a nucleus.app.wm-class-style system
property, or a parameter on the window API — for apps that need a value different from the
packaged one.

Two smaller notes:

  • Prefer startup.wm.class over app.id when both are present. They legitimately differ:
    Debian policy wants a lowercase packageName (gitvantage), while the .desktop
    StartupWMClass matches the launcher binary (GitVantage). AppNameResolver already
    prefers the former.
  • Once this is set at runtime, startupWMClass in the Gradle DSL and the actual app_id can
    no longer drift apart, which today is a silent failure that varies by launch method.

🤚 Do you want to develop this feature yourself?

  • Yes
  • No

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions