From b2451e6aea1d765b7a3082f64a9b1d02d908c645 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Tue, 7 Jul 2026 23:13:01 +0200 Subject: [PATCH] fix(flatpak): ship punktfunk-session so Decky streaming survives the two-binary split MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The re-architected Linux client is now two binaries: the punktfunk-client shell execs its sibling punktfunk-session (ash/Vulkan presenter + Skia console UI) for --connect/--browse. The Decky plugin's stream and browse paths launch the shell with exactly those flags, but the flatpak built and installed only the shell, so streaming and the gamepad library from the Deck failed at exec with "punktfunk-session: No such file" (pair/wake/library still worked — the shell handles them in-process). Build and install both binaries. The session binary pulls in Skia (skia-safe), whose build script downloads a prebuilt libskia — dead in the offline sandbox — so point skia-bindings at a pinned, vendored archive via SKIA_BINARIES_URL=file:// (read directly, no curl); the tarball rides along as a sha256-pinned flatpak source. Widen the flatpak CI path filters to the session binary's crates (linux-session, pf-presenter, pf-console-ui, pf-client-core) and fix the moved library.rs path in the Decky error-classifier comment. All other plugin↔client contracts (flags, pairing/library output, config files, env vars, exit codes, the 47990 mgmt port) already match — no changes needed. Co-Authored-By: Claude Opus 4.8 (1M context) --- .gitea/workflows/flatpak.yml | 6 +++++ clients/decky/main.py | 2 +- packaging/flatpak/README.md | 4 +++- packaging/flatpak/io.unom.Punktfunk.yml | 32 +++++++++++++++++++++---- 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/.gitea/workflows/flatpak.yml b/.gitea/workflows/flatpak.yml index 16f59578..a6a2c5a1 100644 --- a/.gitea/workflows/flatpak.yml +++ b/.gitea/workflows/flatpak.yml @@ -25,9 +25,15 @@ on: branches: [main] # The flatpak is the CLIENT — only rebuild when the client/core/manifest change, not on every # design/host push (this is a heavy flatpak-builder run). Tags (v*, the client release) build too. + # The bundle ships BOTH client binaries (shell + Vulkan session), so every crate in either + # binary's dependency closure must be listed here. paths: - 'clients/linux/**' + - 'clients/linux-session/**' - 'crates/punktfunk-core/**' + - 'crates/pf-client-core/**' + - 'crates/pf-presenter/**' + - 'crates/pf-console-ui/**' - 'packaging/flatpak/**' - 'Cargo.lock' - '.gitea/workflows/flatpak.yml' diff --git a/clients/decky/main.py b/clients/decky/main.py index 2569bf0d..e25f5088 100644 --- a/clients/decky/main.py +++ b/clients/decky/main.py @@ -104,7 +104,7 @@ def _parse_library_tsv(stdout: str) -> list[dict]: def _classify_library_error(stderr: str) -> str: """Map the client's ``library: `` stderr line to a stable error code for the UI. Substring-matched against the Display strings in - ``clients/linux/src/library.rs`` — a wording change degrades to ``client-error`` + ``crates/pf-client-core/src/library.rs`` — a wording change degrades to ``client-error`` (generic copy), never a crash.""" s = stderr.lower() if "didn't recognize this device" in s: diff --git a/packaging/flatpak/README.md b/packaging/flatpak/README.md index d718d62d..13f7799f 100644 --- a/packaging/flatpak/README.md +++ b/packaging/flatpak/README.md @@ -1,6 +1,8 @@ # punktfunk client — Flatpak (Steam Deck / SteamOS, and any flatpak distro) -The native Linux **client** (crate `punktfunk-client-linux`, binary `punktfunk-client`) is +The native Linux **client** — the shell (crate `punktfunk-client-linux`, binary +`punktfunk-client`) plus the Vulkan session binary it execs for streaming (crate +`punktfunk-client-session`, binary `punktfunk-session`) — is published two ways by CI (`.gitea/workflows/flatpak.yml`), on every push to `main` (a rolling `0.0.1-ciN.` build) and on `v*` tags (a clean `X.Y.Z`): diff --git a/packaging/flatpak/io.unom.Punktfunk.yml b/packaging/flatpak/io.unom.Punktfunk.yml index 1ebc0d91..c20d0fd7 100644 --- a/packaging/flatpak/io.unom.Punktfunk.yml +++ b/packaging/flatpak/io.unom.Punktfunk.yml @@ -1,6 +1,11 @@ -# Flatpak manifest for the native punktfunk Linux client (crate punktfunk-client-linux, -# binary `punktfunk-client`). Built into a single-file `.flatpak` bundle and published to -# Gitea's generic package registry (see .gitea/workflows/flatpak.yml + packaging/flatpak/README.md). +# Flatpak manifest for the native punktfunk Linux client: the shell (crate +# punktfunk-client-linux, binary `punktfunk-client`) PLUS the Vulkan session binary (crate +# punktfunk-client-session, binary `punktfunk-session`) that the shell execs for +# `--connect`/`--browse` — both must ship or streaming from the Deck breaks (the Decky +# wrapper launches the shell with those flags and the shell resolves its sibling +# `punktfunk-session`, see clients/linux/src/spawn.rs). Built into a single-file `.flatpak` +# bundle and published to Gitea's generic package registry (see .gitea/workflows/flatpak.yml +# + packaging/flatpak/README.md). # # Why flatpak for the CLIENT (the host stays an RPM/deb — see packaging/README.md "Why not # Flatpak"): on SteamOS the Steam Deck's /usr is read-only and image-based, so a bare @@ -140,6 +145,12 @@ modules: env: CARGO_HOME: /run/build/punktfunk-client/cargo CARGO_NET_OFFLINE: 'true' + # The session binary's Skia (pf-console-ui → skia-safe) fetches prebuilt libskia in + # its build script — dead in the offline sandbox. skia-bindings accepts a file:// + # override (read directly, no curl), so we point it at the archive that + # flatpak-builder pre-downloaded as a pinned source below. No {tag}/{key} + # placeholders needed: a template without them is used verbatim. + SKIA_BINARIES_URL: file:///run/build/punktfunk-client/skia-binaries.tar.gz build-commands: # Drop the Windows client from the workspace before building. It pins windows-rs as a # git dependency (cfg(windows)-gated, but cargo resolves it for the whole workspace @@ -152,8 +163,13 @@ modules: # no longer matches the reduced member set; --offline still pins every crate to the # vendored cargo-sources.json, so the build stays reproducible.) - sed -i '\#"clients/windows",#d' Cargo.toml - - cargo --offline build --release -p punktfunk-client-linux + # One cargo invocation for both binaries: the shell and the Vulkan session binary it + # execs for --connect/--browse. Building them together keeps skia-bindings' feature + # unification identical to a workspace build (the pinned skia-binaries archive's + # `pdf-textlayout-vulkan` key must match the resolved feature set). + - cargo --offline build --release -p punktfunk-client-linux -p punktfunk-client-session - install -Dm0755 target/release/punktfunk-client ${FLATPAK_DEST}/bin/punktfunk-client + - install -Dm0755 target/release/punktfunk-session ${FLATPAK_DEST}/bin/punktfunk-session # Desktop entry (renamed to the app id; Exec is the in-sandbox binary). - install -Dm0644 packaging/flatpak/io.unom.Punktfunk.desktop ${FLATPAK_DEST}/share/applications/io.unom.Punktfunk.desktop @@ -174,3 +190,11 @@ modules: path: ../.. # Generated offline crate cache (see the comment block above). Remove for --share=network. - cargo-sources.json + # Prebuilt Skia for skia-bindings 0.87.0 (SKIA_BINARIES_URL above). The key encodes the + # crate's pinned skia commit + target + resolved features — when bumping skia-safe, build + # the workspace once locally and take the new name from + # target/release/build/skia-bindings-*/out/.cache/, then update url + sha256 together. + - type: file + url: https://github.com/rust-skia/skia-binaries/releases/download/0.87.0/skia-binaries-e551f334ad5cbdf43abf-x86_64-unknown-linux-gnu-pdf-textlayout-vulkan.tar.gz + sha256: b46e7061e6b9df792025acaf9b8b90180224c7cec63f4c3ce09af7ddddb8abfa + dest-filename: skia-binaries.tar.gz