Files
enricobuehler 76b6543758
CI / build (push) Failing after 13s
CI / publish (push) Skipped
feat(desktop): add the desktop-entry library source
Games that no store plugin lists still sit in the app menu: distro
packages, Flatpaks, hand-written launchers. This source reads every
`.desktop` file whose Categories say Game, in XDG precedence order, so
a user-level NoDisplay copy hides the system one exactly as the menu
does. Launchers this library already covers, plus the shortcuts they
write for their own games, are skipped so a title is never listed twice.

Entries publish `launch: {kind: "plugin"}` and no command. The host
asks back at launch time; the answer is the Exec line with its field
codes stripped, or `flatpak run <app-id>`, resolved against a fresh
scan so a forged id answers 404. The command is the game, so no detect
hint is needed.

Needs plugin-kit 0.4.5 for the `launch` field. The lockfile is not
committed until that version is published.
2026-09-02 11:04:45 +02:00

3.2 KiB

@punktfunk/plugin-desktop

Adds every Linux desktop entry that calls itself a game — a distro package, a Flatpak, a hand-written .desktop launcher — to a Punktfunk host's library, with its icon as art.

Install it from the host's plugin store (Library → Game sources → Add a source), or:

punktfunk-host plugins add desktop

Nothing to configure. If you keep .desktop files somewhere non-standard, add the directories in Library → Game sources → Desktop entries → Settings.

What is read

The applications/ directory of every XDG data root, in precedence order — $XDG_DATA_HOME (~/.local/share), each $XDG_DATA_DIRS entry (/usr/local/share:/usr/share) — plus the Flatpak exports (~/.local/share/flatpak/exports/share, /var/lib/flatpak/exports/share), one subdirectory deep. The first directory to define a desktop-file id owns it, so a user-level copy with NoDisplay=true hides the system one, exactly as it does in your app menu.

A file becomes a game when it is Type=Application, lists Game in Categories, has an Exec, is not NoDisplay, Hidden or Terminal, and its TryExec (if any) exists. The launchers this library already covers — Steam, Lutris, Heroic, Bottles, RetroArch, itch — are skipped, and so is any shortcut they wrote for one of their games (steam://, lutris:, heroic://, bottles-cli): those titles come from their own plugins, with the ids and art those give them.

Art is the entry's Icon: an absolute .png/.jpg, or a name looked up in the hicolor theme (512 down to 64 px) and /usr/share/pixmaps. SVG is never used; the host refuses it.

How a game starts

Entries carry no command. When you pick one, the host asks this plugin what to run and gets the Exec line with its field codes stripped, run from Path= — or flatpak run <app-id> for a Flatpak. The command is the game, so the session ends when it exits.

Config fields

Field Meaning
extraDirs More directories holding .desktop files, scanned after the standard ones.

Commands

punktfunk-plugin-desktop detect            # is this a Linux desktop with an applications dir?
punktfunk-plugin-desktop scan --preview    # what WOULD be synced, as JSON (works with no host)
punktfunk-plugin-desktop uninstall         # drop the games and release the store claim

The kit's parity verb has no baseline here: the host never had a built-in desktop-entry scanner.

Platform caveat

Linux only. On any other platform detect reports absent and the library stays empty.

Development

bun install
bun run typecheck && bun test && bun run build

This needs @punktfunk/plugin-kit 0.4.5 (the launch field). Until it is published, bun.lock is not committed; the first install after the kit lands regenerates it.

The framework — store claim, sync engine, __config, CLI verbs, and the file helpers — lives in @punktfunk/plugin-kit/library. This package is the desktop-entry part: find the directories, parse the files, map games to entries, answer the launch ask. See design/library-scanner-plugins.md in the main repo.

License

MIT OR Apache-2.0.