Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc3b2d0328 | ||
|
|
1c1fd7d9bc | ||
|
|
1c60e641b3 | ||
|
|
eda4b7ebd2 | ||
|
|
730ac43169 |
+272
@@ -12,6 +12,278 @@ with the version table of the release you are moving to, then read **Breaking ch
|
||||
|
||||
---
|
||||
|
||||
## v0.31.1
|
||||
|
||||
30 commits since v0.31.0 (19 non-merge), counted at the tip this was cut from.
|
||||
|
||||
**No versioned surface moves.** `WIRE_VERSION` stays **2**, the C ABI stays **25**, and so do the
|
||||
driver protocol, the gamepad channel, the plugin index schema and the host event schema. No C
|
||||
function changed its signature, no `#[repr(C)]` struct grew a field, and `include/punktfunk_core.h`
|
||||
gains exactly one line: a `#define` for a new control-message type byte. An embedder rebuilds
|
||||
against the new header and is done; a packager has one thing to notice (the Windows firewall rule
|
||||
below) and one thing to be glad of (the Arch compositor package finally declares the level it
|
||||
builds).
|
||||
|
||||
Two surfaces grow, both by pure addition: the **management API** gains
|
||||
`PUT /library/provider/{provider}/running` and its three schemas, and **`@punktfunk/plugin-kit`
|
||||
goes 0.4.3 → 0.4.4** to export the client call for it. A plugin that adopts neither is unaffected,
|
||||
and an older host answers the route with a 404 that means "this host tracks games by scanning".
|
||||
|
||||
One control message is **added** to the wire — `DeliveryReport`, type byte **`0x0B`** — which is a
|
||||
`#define`, not an ABI step, exactly as `PipelineGap` (`0x0A`) was at v0.30.0. It takes a free byte
|
||||
in its block rather than lengthening an existing message, deliberately: see below.
|
||||
|
||||
Two behaviour changes are worth reading before you package or embed this release: on Windows,
|
||||
`service install` now provisions a **program-scoped inbound UDP rule** for the host executable, and
|
||||
the **GameStream plane's default virtual-Xbox backend flips from the XUSB companion to the UMDF HID
|
||||
pad**, matching what the native plane has done since 2026-08-09.
|
||||
|
||||
### Versions
|
||||
|
||||
| | v0.31.0 | v0.31.1 | Notes |
|
||||
|---|---|---|---|
|
||||
| Wire protocol | 2 | **2** | unchanged. One additive control message, `DeliveryReport` (`0x0B`), which an older peer does not parse and does not need — see **The wire** below |
|
||||
| C ABI | 25 | **25** | unchanged. `include/punktfunk_core.h` differs from the v0.31.0 tag by one `#define` (`PUNKTFUNK_MSG_DELIVERY_REPORT = 11`, under `PUNKTFUNK_FEATURE_QUIC`), which is a constant, not a declaration. Rust-only addition in `punktfunk-core`: `client::NO_VIDEO_RETRY` is now public beside `client::FLUSH_COOLDOWN` |
|
||||
| Rust edition | 2024 | **2024** | unchanged |
|
||||
| MSRV (`rust-version`) | 1.85 | **1.85** | unchanged |
|
||||
| Workspace crate dirs | 27 | **27** | unchanged (39 `[workspace] members`, also unchanged) |
|
||||
| Virtual-display driver protocol | 6 | **6** | unchanged (minimum accepted still 3); `pf-driver-proto` shows no diff against the v0.31.0 tag |
|
||||
| Windows virtual-gamepad channel | 3 | **3** | unchanged. What changed is which *backend* the GameStream plane picks, not the channel — see **Windows: the GameStream plane builds the pad games can see** |
|
||||
| Plugin index schema | 1 | **1** | unchanged |
|
||||
| Host event schema | 1 | **1** | unchanged (`punktfunk-host/src/events.rs`) |
|
||||
| `api/openapi.json` | 0.31.0 | **0.31.1** | one route **added** — `PUT /library/provider/{provider}/running` plus its three schemas — and the stamp moved with the crate (`info.version` is `CARGO_PKG_VERSION`). Regenerated in #361 and re-stamped here; nothing else in the document differs. `api/` and `docs-site/public/` are byte-identical to each other |
|
||||
| gamescope patch level (`+pfhdrN`) | 8 | **8** | unchanged; no new patch files. ⚠ **`packaging/gamescope/PKGBUILD` is fixed here**: it declared `pfhdr7` while patch 0010 stamps `+pfhdr8` into the banner, so pacman saw no upgrade at all — see below |
|
||||
| `@punktfunk/host` (SDK) | 0.1.5 | **0.1.5** | unchanged; nothing under `sdk/` moved |
|
||||
| `@punktfunk/plugin-kit` | 0.4.3 | **0.4.4** | cut, for `ProviderClient.reportRunning` and its two types: they were reachable only through the deep `./reconcile.js` path, because `index.ts` re-exports an explicit list rather than a star, so no plugin could import them from the package root. Tagged `plugin-kit-v0.4.4` and **published** — the registry's `latest` (0.4.2 is still skipped there, as it has been since v0.30.0). The playnite plugin deliberately does *not* depend on it, calling the route through the untyped host seam so it was never gated on this publish |
|
||||
|
||||
### ⚠ Breaking changes
|
||||
|
||||
**None.** No wire change, no ABI change, no driver-protocol change, no plugin-contract change. Every
|
||||
0.31.0 host, client, driver and plugin keeps interoperating in both directions with no re-pairing.
|
||||
|
||||
Two **behaviour** changes that break no build but change what a machine does:
|
||||
|
||||
- **Windows `service install` adds a second firewall rule.** `Punktfunk UDP (data plane)` —
|
||||
`dir=in action=allow protocol=UDP program=<host exe>`, on the same profile set the port rules use.
|
||||
`service uninstall` deletes it by name. If you provision firewall rules yourself instead of
|
||||
letting `service install` do it, you need the equivalent, or your hosts keep the black-picture
|
||||
failure below. Program-scoped rather than port-scoped by design: the data plane binds `0.0.0.0:0`,
|
||||
and a pinned port inside 47998-48010 would collide with Sunshine/Apollo.
|
||||
- **`PUNKTFUNK_XBOX_BACKEND` now governs both planes on Windows, and the GameStream plane's default
|
||||
moves to the HID pad.** `PUNKTFUNK_XBOX_BACKEND=xusb` reverts both planes together; it previously
|
||||
reverted only the native one, because `windows_xbox_hid` was `pub(super)` and unreachable from
|
||||
`gamestream/control.rs`. It is `pub(crate)` now, with one definition and one name.
|
||||
|
||||
### A provider plugin can report which of its titles are running
|
||||
|
||||
The host derives liveness by **scanning**, which needs something recognizable on disk. A
|
||||
Playnite-launched emulated game, a manually added one, or a library plugin that records no install
|
||||
directory has none — and its launch is a `playnite://` hand-off, so the host holds no process
|
||||
either. The lease went `Untracked`: the exit was never noticed, `session_on_game_exit` could not
|
||||
fire, and `POST /game/end` had nothing to aim at.
|
||||
|
||||
**`PUT /library/provider/{provider}/running`** takes a provider's *complete* running set (with the
|
||||
pid where it knows one) — declarative and idempotent like the reconcile beside it, so a missed event
|
||||
or a plugin restart self-corrects rather than drifting. `crate::runstate` holds it and **expires it
|
||||
after 90 s unless restated**, which is what makes it safe for a live provider to hold a session open
|
||||
for a game the host cannot see: a plugin that dies stops counting and the host falls back to
|
||||
scanning. The route is the plugin lane's, like the reconcile, and carries **no new authority** — the
|
||||
host maps `external_id` through the catalog, so a provider can only speak about entries it
|
||||
published. An unknown id is *counted, not refused*, because a report legitimately races its own
|
||||
reconcile and 400-ing the batch would discard the liveness of every other running title.
|
||||
|
||||
**`LeaseKind::Reported`** is the lease that follows. `open` reaches it when the spec is empty and a
|
||||
provider speaks for the id, and — load-bearing on Windows, where every launch is a hand-off by
|
||||
construction — the three shim reclassification paths now fall back to it where they fell to
|
||||
`Untracked`. Phase 1 takes "running" as the game appearing; phase 2 takes "stopped" as the exit.
|
||||
Unlike `procscan::running_hint`, which may only ever *delay* an exit (Steam's registry flag survives
|
||||
an unclean one), a fresh report is decisive in both directions. A reported pid joins the termination
|
||||
ladders on the same terms as a spawned one: re-resolved and start-time-pinned at the moment of use.
|
||||
|
||||
Client side, `ProviderClient.reportRunning` is exported from the plugin-kit root in 0.4.4 (see the
|
||||
table). A **404 from an older host means "this host tracks games by scanning"** — it is not an error
|
||||
a plugin should retry.
|
||||
|
||||
### The wire: `DeliveryReport` (`0x0B`)
|
||||
|
||||
`LossReport` carries `loss_ppm`, which is a ratio over the packets that **arrived** — so a flawless
|
||||
link and a link delivering nothing both report `0`. A host reading total silence as perfection
|
||||
decayed adaptive FEC to its floor and logged confident wording about the client's network.
|
||||
|
||||
Clients now also send `DeliveryReport`, carrying the session's received-packet count. It is a **new
|
||||
type byte, not a field appended to `LossReport`**: that message is length-checked exactly, so
|
||||
lengthening it would make every shipped host reject the loss reports its FEC runs on. Send policy is
|
||||
deliberately sparse — every window while the count is zero, once when the first packets land, then
|
||||
never — because an older host warns per unknown message type and must not be flooded across a good
|
||||
session.
|
||||
|
||||
`client::NO_VIDEO_RETRY` (the client got nothing) and `client::FLUSH_COOLDOWN` (the client is
|
||||
drowning) were both 2000 ms, so the host's cadence classifier could not tell two opposite faults
|
||||
apart and named the wrong one out loud. `NO_VIDEO_RETRY` moves into `punktfunk-core` beside
|
||||
`FLUSH_COOLDOWN` at **2600 ms**, and both sides now compare against the shared constant rather than
|
||||
against a local copy.
|
||||
|
||||
### Windows: the data plane was never open, on any host
|
||||
|
||||
The firewall rules `service install` writes are `localport=`-scoped (47998-48010, 9777, 5353), and
|
||||
the media data plane binds an **ephemeral** port per session. No such rule can cover it, so Windows
|
||||
Firewall dropped the client's hole-punch on **every session on every Windows host** — `punched=false`
|
||||
on the "data plane bound" line, in all six sessions across two field logs, including sessions that
|
||||
appeared to work. Video then fell back to blind-sending at the address the client *reported*; where
|
||||
the path needed the flow opened client-first, the control plane stayed healthy and the picture never
|
||||
arrived. One field host sent 1,919 frames into a black screen while blaming the client.
|
||||
|
||||
Diagnosis changed with it: it now leads with the delivery count (zero is an **error** naming the data
|
||||
plane; a confirmed count keeps the old confident wording; a client that cannot answer gets a warning
|
||||
that says so), and a punch that never arrives is its own warning rather than a debug field on an info
|
||||
line.
|
||||
|
||||
### Windows: the GameStream plane builds the pad games can see
|
||||
|
||||
There are two virtual Xbox backends on Windows and they are not interchangeable to a game. The XUSB
|
||||
companion registers only `GUID_DEVINTERFACE_XUSB` and exposes no HID collection (`pf_xusb.inx`:
|
||||
"a non-HID UMDF2 driver", `Class = System`), so Steam's hidapi enumeration, SDL, RawInput,
|
||||
DirectInput, `joy.cpl` and WGI/GameInput cannot see it at all — only classic `XInputGetState` can.
|
||||
The native plane moved to the real HID pad as its default in `bd5735b8` for exactly that reason.
|
||||
|
||||
`gamestream/control.rs` had bound `crate::inject::gamepad` since the first gamepad commit, when that
|
||||
name meant uinput and Windows had no second backend; Windows later gave the same name the XUSB
|
||||
companion, so this plane inherited it by module-name coincidence rather than by decision. Every
|
||||
Moonlight-compatible session since has presented a pad most games cannot enumerate. A `SessionPads`
|
||||
enum is now the one place this plane picks a backend, reading the same knob the native plane reads.
|
||||
The HID pad's rich-feedback plane is dropped rather than plumbed: an Xbox pad has no lightbar or
|
||||
adaptive triggers, and GameStream's rumble message (`0x010B`) carries the two handle motors only.
|
||||
|
||||
### Android: buttons resolved from the scancode
|
||||
|
||||
Android names a pad's buttons through a **key layout file** matched on VID/PID; a pad with no
|
||||
matching file falls back to AOSP's `Generic.kl`, which assigns keycodes by **scancode position**
|
||||
(`0x130`→`BUTTON_A`, `0x131`→`BUTTON_B`, …). A HID gamepad with no kernel driver numbers its buttons
|
||||
`1..n` in its own report order, so every keycode past the first divergence is somebody else's button.
|
||||
AOSP ships no layout for the Elite Series 2 over Bluetooth (`045e:0b05`) on any version, and the
|
||||
DualSense's (`054c:0ce6`) postdates Fire OS and requires `CONFIG_HID_PLAYSTATION`, which a Fire TV
|
||||
kernel has not.
|
||||
|
||||
`Gamepad.padKeyCode(event)` is a drop-in for `event.keyCode` and **every** pad reader now goes
|
||||
through it — the streaming branch, the Skia console shell's probe, the older Compose navigation, and
|
||||
the Controllers tester. Two guards keep it off pads that already work: the correction applies only
|
||||
where the delivered keycode is what `Generic.kl` would have said, and which report order to read is
|
||||
decided from what the device *declares* (a pad numbering straight through claims `BUTTON_C` and
|
||||
`BUTTON_Z`, keycodes no real controller has a button for) rather than from a model table. Axes get
|
||||
the same treatment, with trigger rest position measured from the device's own range instead of
|
||||
assumed. The Xbox Bluetooth product ids (One S, Elite Series 2 and its Core) join the identity table.
|
||||
|
||||
Also here: `pads()` filters on `looksLikeController` (the source claim **and** hardware behind it)
|
||||
rather than on `isPad`, which kept the console UI pinned on for any device merely claiming the
|
||||
gamepad source class; and the `ASurfaceControl` layer's destination rect is now read per-present from
|
||||
a packed atomic on the session handle (new JNI symbol `nativeVideoSurfaceSize`, fed from every
|
||||
`surfaceChanged`) rather than captured once at `surfaceCreated`, which is why the picture sat at the
|
||||
origin once the bars and cutout grew the view.
|
||||
|
||||
### gamescope and the takeover
|
||||
|
||||
- **`packaging/gamescope/PKGBUILD` moves `pfhdr7` → `pfhdr8`.** The banner has said `+pfhdr8` since
|
||||
patch 0010 (the seat's stub keyboard carrying the compiled `XKB_DEFAULT_*` keymap), and the host
|
||||
probes the banner for `>= 8` on the keymap path — but pacman compares `pkgver-pkgrel`, read
|
||||
`3.16.25.pfhdr7-1` on both v0.30.0 and v0.31.0, and **offered no upgrade at all**. deb and rpm
|
||||
derive their version from the binary banner and moved by themselves; Arch is the only channel that
|
||||
hardcodes it. This is the mismatch the v0.31.0 table flagged as pre-existing.
|
||||
- **The in-stream session-select gate is armed again.** v0.31.0's takeover stopped stopping the
|
||||
display manager and started idling the autologin session (`c2f5e91b`), which also deleted the two
|
||||
lines the old path carried (`record_session_select_baseline()`, `STOPPED_DM = Some(dm)`);
|
||||
`38a0f54b` then removed every remaining writer, leaving `honor_session_select_switch` unreachable.
|
||||
Bazzite/SteamOS never noticed — their `os-session-select` writes no sentinel and
|
||||
`is_steam_htpc_platform()` defaults the mid-stream watcher on. `ID=nobara` matches no HTPC default
|
||||
and its ChimeraOS-layout `os-session-select` **does** write the sentinel, so on Nobara a mid-stream
|
||||
"Switch to Desktop" went entirely unhandled. `takeover_idled()` now reads `IDLE_DROPIN_ARMED`, the
|
||||
idle drop-in re-baselines the sentinel, and `STOPPED_DM` is documented as adoption-only state for a
|
||||
takeover stranded by a pre-0.31.0 host. Both hand-back paths also restore the box's own Game Mode
|
||||
unit, which neither did — a mid-stream switch is not a disconnect, so the disconnect sweep never
|
||||
reached the `ExecStart=/usr/bin/sleep infinity` drop-in.
|
||||
- **Nix shipped a wrapper with no target.** nixpkgs wraps this package: the real ELF is
|
||||
`bin/.gamescope-wrapped` and `bin/gamescope` is a makeWrapper launcher. The prune
|
||||
(`find $out/bin -mindepth 1 ! -name gamescope -delete`) deleted the compositor and kept the
|
||||
launcher — measured at 16 KB. That single line explains the empty `--version` output and the
|
||||
"missing `+pfhdr` marker", both of which had been attributed to the build sandbox and to upstream.
|
||||
The prune keeps the target now and the guard asserts on the **wrapped ELF**. Separately,
|
||||
`packaging/nix/gamescope.nix` now pins `src` to `5fb8dce4` like every other channel — it was the
|
||||
only one patching whatever version nixpkgs happened to carry, which broke `host.gamescopeHdr`
|
||||
(default true) builds outright when nixpkgs shipped 3.16.24.
|
||||
|
||||
### Everything else an integrator might notice
|
||||
|
||||
- **`pf-console-ui`:** `ConsoleOptions.fallback_ui` (new, threaded to `Ctx` beside `deck`) gates the
|
||||
Android-only "Controller-optimized UI" row, written through `extra` under
|
||||
`android.gamepad_ui_enabled`; it is true only for the Android touch shell. Down on the carousel
|
||||
opens Settings (`▼` is a new hint glyph — the `▲` triangle inverted, not a second draw routine),
|
||||
and the host options menu gains a Library row on the same terms `Y` offers it (saved **and**
|
||||
paired), replacing the menu rather than stacking on it. Both exist because a TV remote emits only
|
||||
Move/Confirm/Back.
|
||||
- **`scripts/ci/docs-undocumented-env-baseline.txt`** gains `PUNKTFUNK_MSG_DELIVERY_REPORT`.
|
||||
`check-docs-drift.sh` scans for `PUNKTFUNK_*` identifiers and cannot tell an operator knob from a
|
||||
cbindgen-exported `#define`; every other `PUNKTFUNK_MSG_*` is already baselined beside it.
|
||||
- **`clients/probe`** reads the new delivery counter.
|
||||
- **`trust::Settings::extra` is `#[serde(flatten)]`**, so `android.*` keys are **top-level** keys of
|
||||
the settings document, beside `width` and `codec`. `ConsoleJson` wrote and read them nested under
|
||||
an `"extra"` object, which serde stored under the literal key `"extra"` — so no console row ever
|
||||
found `android.gamepad_ui_enabled`, every Android-only row (low latency, phone rumble/gyro, SC2 and
|
||||
DualSense capture, the console-UI mode picker) read its own default, and the value the console
|
||||
saved came back to Kotlin unchanged, so `applySettings` raised no callback. Fixed in #362, which is
|
||||
what makes the `feat` above work at all. A store written by the nesting build carries the dead
|
||||
wrapper and drops it on the next write. The new test pins the shape from **both sides**: a
|
||||
round-trip alone could not catch this, because both halves agreed on the same wrong nesting.
|
||||
- **`pf-console-ui` focus halo / `panel_highlight` radii.** A rounded rect grown by `d` keeps its
|
||||
corners concentric with the original only if its radius grows by `d` too; both helpers kept the
|
||||
card's own radius, so the halo read as a squared-off outline at the four corners. `drop_shadow`
|
||||
only offsets and was already right; the collections plate uses `RRect::with_outset`, which adjusts
|
||||
radii itself. Every card path goes through the two fixed helpers.
|
||||
|
||||
### Verification status
|
||||
|
||||
Gates run on the release tree (this MacBook, rustc/rustfmt per `rust-toolchain.toml`):
|
||||
`cargo fmt --all --check` clean; `cargo metadata --offline` ok with the `Cargo.lock` diff
|
||||
versions-only (36/36 lines); `cargo test -p punktfunk-core --lib` **273 passed**; the C ABI harness
|
||||
(`tests/c_abi.rs`) **passed**, reporting `abi_version=25` and four frames round-tripped byte-exact
|
||||
through lossy loopback — it did **not** run on the v0.31.0 cut, so this is the first cut since ABI 25
|
||||
where a C compiler has actually built the generated header; `scripts/ci/check-docs-drift.sh` clean;
|
||||
the android.yml Play notes gate run verbatim — 442/500 characters and not byte-identical to any prior
|
||||
release's; both openapi copies `cmp` identical, both stamped 0.31.1; notes voice scan clean.
|
||||
|
||||
⚠ **`api/openapi.json` was re-stamped here, not regenerated.** The document itself was regenerated
|
||||
in #361 (with the new route and its three schemas) on a runner where
|
||||
`openapi_document_is_complete_and_checked_in` actually executes; this commit moves only
|
||||
`info.version`, which utoipa fills from `CARGO_PKG_VERSION`. `punktfunk-host` does not build on
|
||||
macOS, so that test could not be re-run here — but `0.31.0` appears nowhere else in either copy, so
|
||||
regeneration would produce this byte-for-byte. If it ever fails on this commit, regenerate with
|
||||
`cargo run -p punktfunk-host -- openapi > api/openapi.json` and `cp` to `docs-site/public/`.
|
||||
|
||||
⚠ **Verified by reading only** — compiled nowhere available to the cutting host: everything under
|
||||
`crates/punktfunk-host` (Windows and Linux arms alike), `packaging/nix/gamescope.nix`, and the
|
||||
Android/Kotlin half. That includes `crate::runstate` and the new route; its own tests turned up a
|
||||
collision on their first run in an environment that executes them (all three shared the provider id
|
||||
`playnite` and cleared the process-global table between cases, so parallel scheduling flipped their
|
||||
answers) — fixed in #361 by giving each test ids only it uses and retiring the blunt `reset()`. The Windows GameStream pad change was checked on `.133` when it landed
|
||||
(`cargo check` and `cargo clippy -p punktfunk-host -- -D warnings` clean, both compiling arms), and
|
||||
`windows-host.yml` has **no `pull_request` trigger**, so a PR will not re-check that arm.
|
||||
|
||||
⚠ **`audit.yml` is red on main and this release does not fix it.** `cargo audit` reports
|
||||
**RUSTSEC-2026-0258** (`h2` 0.4.15, "unbounded empty DATA frames", published 2026-08-17, fixed in
|
||||
0.4.16); `h2` is transitive through `hyper`. It **predates this cut** — the same job failed on
|
||||
`669a1bc0` and on the v0.31.0 tag commit — so it is not a regression here, and it was deliberately
|
||||
**not** bundled into the release commit: `cargo update -p h2 --precise 0.4.16` bumps h2 in eleven
|
||||
lock lines but also rewrites several `windows-sys` references downward (0.61.2 → 0.59.0/0.52.0) on
|
||||
the pinned 1.96.0 toolchain, and re-resolving the graph for the Windows build is not a change to
|
||||
make inside a version bump that cannot be compiled for Windows on the cutting host. It wants its own
|
||||
commit and its own CI.
|
||||
|
||||
⚠ **Not confirmed on glass:** the Android scancode remap (the reporter's Fire TV Stick 4K Max is the
|
||||
test that settles it), the Windows data-plane firewall rule in a field session, and the
|
||||
Moonlight-compatible HID pad — the log line to look for there is
|
||||
`virtual Xbox pad created (Windows UMDF HID)` where it used to say
|
||||
`virtual Xbox 360 created (Windows XUSB companion)`.
|
||||
|
||||
---
|
||||
|
||||
## v0.31.0
|
||||
|
||||
170 commits since v0.30.0 (113 non-merge), counted at the tip this was cut from.
|
||||
|
||||
Generated
+36
-36
@@ -1090,7 +1090,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cursor-probe"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"pf-capture",
|
||||
@@ -1222,7 +1222,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "display-disturb"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"pf-win-display",
|
||||
"windows 0.62.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2343,7 +2343,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "latency-probe"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
@@ -2446,7 +2446,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libvpl-sys"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"cmake",
|
||||
@@ -2475,7 +2475,7 @@ checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad"
|
||||
|
||||
[[package]]
|
||||
name = "loss-harness"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"punktfunk-core",
|
||||
]
|
||||
@@ -2967,7 +2967,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
||||
|
||||
[[package]]
|
||||
name = "pf-bitstream"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"cros-codecs",
|
||||
"tracing",
|
||||
@@ -2975,7 +2975,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pf-capture"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ashpd",
|
||||
@@ -2996,7 +2996,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pf-client-core"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ash",
|
||||
@@ -3032,7 +3032,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pf-clipboard"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ashpd",
|
||||
@@ -3050,7 +3050,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pf-console-ui"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ash",
|
||||
@@ -3073,7 +3073,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pf-dxvadec"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"cros-codecs",
|
||||
"pf-bitstream",
|
||||
@@ -3083,7 +3083,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pf-encode"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ash",
|
||||
@@ -3109,7 +3109,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pf-frame"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"libc",
|
||||
@@ -3122,7 +3122,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pf-gpu"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"pf-host-config",
|
||||
@@ -3136,11 +3136,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pf-host-config"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
|
||||
[[package]]
|
||||
name = "pf-inject"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ashpd",
|
||||
@@ -3169,14 +3169,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pf-paths"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pf-presenter"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ash",
|
||||
@@ -3191,7 +3191,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pf-update"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -3199,7 +3199,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pf-update-check"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"aws-lc-rs",
|
||||
@@ -3211,7 +3211,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pf-vaadec"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"cros-codecs",
|
||||
"pf-bitstream",
|
||||
@@ -3220,7 +3220,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pf-vdisplay"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ashpd",
|
||||
@@ -3253,7 +3253,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pf-vkdecode"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"ash",
|
||||
"cros-codecs",
|
||||
@@ -3264,7 +3264,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pf-win-display"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"pf-paths",
|
||||
"punktfunk-core",
|
||||
@@ -3275,7 +3275,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pf-zerocopy"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ash",
|
||||
@@ -3487,7 +3487,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "punktfunk-cli"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"pf-client-core",
|
||||
"punktfunk-core",
|
||||
@@ -3497,7 +3497,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "punktfunk-client-android"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"android_logger",
|
||||
"anyhow",
|
||||
@@ -3521,7 +3521,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "punktfunk-client-linux"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-channel",
|
||||
@@ -3538,7 +3538,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "punktfunk-client-session"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"log",
|
||||
"pf-client-core",
|
||||
@@ -3554,7 +3554,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "punktfunk-client-windows"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"mdns-sd",
|
||||
@@ -3572,7 +3572,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "punktfunk-core"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"aes-gcm",
|
||||
"cbindgen",
|
||||
@@ -3605,7 +3605,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "punktfunk-encode-worker"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"pf-encode",
|
||||
"tracing",
|
||||
@@ -3614,7 +3614,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "punktfunk-host"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"aes-gcm",
|
||||
@@ -3684,7 +3684,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "punktfunk-probe"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"mdns-sd",
|
||||
@@ -3698,7 +3698,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "punktfunk-tray"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ksni",
|
||||
@@ -3722,7 +3722,7 @@ checksum = "d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea"
|
||||
|
||||
[[package]]
|
||||
name = "pyrowave-sys"
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"cmake",
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ exclude = [
|
||||
ndk = { path = "clients/android/native/vendor/ndk" }
|
||||
|
||||
[workspace.package]
|
||||
version = "0.31.0"
|
||||
version = "0.31.1"
|
||||
edition = "2024"
|
||||
rust-version = "1.85"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@
|
||||
"name": "MIT OR Apache-2.0",
|
||||
"identifier": "MIT OR Apache-2.0"
|
||||
},
|
||||
"version": "0.31.0"
|
||||
"version": "0.31.1"
|
||||
},
|
||||
"paths": {
|
||||
"/api/v1/client-logs": {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"name": "MIT OR Apache-2.0",
|
||||
"identifier": "MIT OR Apache-2.0"
|
||||
},
|
||||
"version": "0.31.0"
|
||||
"version": "0.31.1"
|
||||
},
|
||||
"paths": {
|
||||
"/api/v1/client-logs": {
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
Wire-compatible with 0.31.x — everything you have already paired keeps working, and you can update one side at a time. Nothing here changes how a host and a client agree on what to send each other, so an old client on a new host, or the other way round, streams exactly as it does today.
|
||||
|
||||
This is a fix release, and the largest thing in it has been wrong on every Windows host since there have been Windows hosts: the port your video actually travels on was never opened in the firewall, so on any network that needs your client to knock first, the connection succeeded, every health signal stayed green, and the picture never arrived. Two more are about controllers that were connected, correctly identified, and doing the wrong thing anyway — Moonlight-compatible sessions on Windows were building the one kind of virtual controller Steam and most games cannot see, and on a Fire TV a DualSense's L2 was arriving as L1. The rest is Android: a console that could not be dismissed, a picture that sat in the top-left corner, and a television remote that could not reach Settings or your library. There is one new thing too — a library add-on can now tell your host which of its games are running, which is how a game your host cannot find on disk finally ends its own session.
|
||||
|
||||
## TL;DR
|
||||
|
||||
- **Windows: streams that connected and then stayed black.** The per-session video port was never covered by any firewall rule, on any Windows host, ever. Update with the installer and the rule is added for you — see *Before you update*.
|
||||
- **Windows: controllers did nothing in Moonlight-compatible sessions.** Every client, every device, same result. Those sessions built a virtual controller most games cannot enumerate; they now build the same one ordinary Punktfunk sessions do.
|
||||
- **Android: controllers Android has no layout for pressed the wrong buttons.** A DualSense or an Xbox Elite Series 2 over Bluetooth on a Fire TV had L2 arriving as L1, with Circle and R1 doing nothing at all.
|
||||
- **Android: the controller console would not go away, and the picture sat in the corner.** Both fixed — and the console now carries its own switch for turning itself off.
|
||||
- **A television remote can reach Settings and your library again.** Both were on controller face buttons a remote does not have.
|
||||
- **Android: every setting that only exists in the controller console did nothing when you changed it.** Low latency, the phone's own rumble and motion, controller capture — all saved to somewhere nothing read back.
|
||||
- **Nobara hosts: "Switch to Desktop" during a stream threw you straight back into the stream.** And on Steam Deck-style hosts, a mid-stream switch could leave Gaming Mode unable to start afterwards.
|
||||
- **NixOS: the host installed a compositor that was not there.** The package shipped the small launcher and deleted the program it launches.
|
||||
- **Games your host cannot see on disk can now end their own session.** A library add-on can tell the host which of its titles are running, which is the missing half for anything launched by handing off to another program — emulated titles, manually added ones.
|
||||
|
||||
## Before you update
|
||||
|
||||
- **Windows hosts: run the installer rather than replacing the program by hand.** The black-picture fix is a new firewall rule, and it is added by the host's own service-install step, which the installer runs for you on every update. If you run the host some other way, run `punktfunk-host service install` once as an administrator — or add an inbound rule for `punktfunk-host.exe` yourself. Uninstalling Punktfunk removes the rule again. Nothing on the client side needs doing.
|
||||
- **NixOS hosts: expect a rebuild.** The compositor is now pinned to the exact version every other packaging channel ships, rather than to whatever the packages you happened to have carried, so its build inputs change. The binary cache added in 0.31.0 covers it if you have it configured.
|
||||
- **Add-on authors: `@punktfunk/plugin-kit` 0.4.4 is what you depend on for the running-report above.** The call and its types were reachable only through a deep import path before, so nothing could reach them from the package root. Nothing else in the add-on contract moved.
|
||||
- **Arch and SteamOS hosts: this release finally offers you a compositor upgrade you have been owed since 0.30.0.** The package's declared version had been left behind while the program inside it moved on, so your package manager saw nothing to do — which is why non-US keyboard layouts kept typing US characters on those machines even after the fix shipped.
|
||||
|
||||
## New
|
||||
|
||||
- **A library add-on can tell your host which of its games are running.** Your host normally works out whether a game is still going by looking for it on the machine — which needs something recognisable there to look for. A title that Playnite launches by handing off to another program has none: an emulated game, a manually added one, anything whose add-on records no folder. So the host never noticed those ending, your session stayed open on a game that had already exited, and anything set to happen when a game ends did not. The add-on knew the whole time, and can now say so. It is deliberately hard to get stuck on: a report expires unless it is repeated, so an add-on that crashes or is uninstalled stops speaking for your games within a minute and your host goes back to looking for itself. **This is the host's half.** It does something for you once an add-on sends those reports — the Playnite one is the first and updates separately, on its own schedule.
|
||||
- **The controller console can switch itself off.** On an Android phone or tablet the console's own Settings now carries a Controller-optimized UI switch, so you can leave the console from inside it and land back on the touch interface immediately. Until now that switch existed only in the touch settings — which someone stuck inside the console had no way to reach, and since 0.31.0 the console is the only interface Android shows when a controller is attached. It appears only where switching off has somewhere to land: not on a television, and not on the desktop console, where turning it off would leave you with nothing.
|
||||
|
||||
## Improved
|
||||
|
||||
- **A host can tell a silent connection from a perfect one.** Packet loss is a proportion of what arrived, so a link delivering nothing and a flawless link both reported zero loss — and the host read the silence as perfection, complete with confident wording about the client's network in the log. Clients now also report how much they have actually received, so a host that is sending into a void says so, and names the video path rather than blaming the client. A client too old to answer gets a warning that says as much instead of a guess.
|
||||
- **The Connected controllers page can be trusted again.** It read your button presses the same wrong way the stream did, so it agreed with the bug and confirmed a mistranslated pad as correct. It now shows what the controller actually reported alongside what Android made of it, and names the layout it resolved — which is also what makes an unrecognised pad fixable from a bug report, without the hardware in hand.
|
||||
|
||||
## Fixed
|
||||
|
||||
- **A Windows host could stream into a black screen with nothing anywhere saying why.** One field host sent 1,919 frames of video that were never seen while its own log blamed the client's network. The cause: the firewall rules Punktfunk installs cover fixed port numbers, but the video itself travels on a port chosen fresh for each session — a port no such rule can ever cover. So Windows dropped the client's opening knock on **every session on every Windows host**, including ones that worked; those worked only because nothing on the path needed the client to open the way first. When something did — many home routers, most mobile networks, anything doing address translation in front of the host — the control connection stayed perfectly healthy and the video went nowhere. The host now installs a rule that follows the program instead of the port number, so whichever port a session picks is covered. It is scoped to the program deliberately: pinning a port would have collided with Sunshine and Apollo on machines running both.
|
||||
- **Controllers did nothing at all in Moonlight-compatible sessions on Windows**, reported across every client and every device someone tried, which is what showed it was not a client problem. Windows has two ways to present a virtual Xbox controller, and only one of them is visible to Steam, to games using the common input libraries, and to the Windows Game Controllers panel. Ordinary Punktfunk sessions moved to that one over a year of reports; Moonlight-compatible sessions kept the invisible one purely because both were reached by the same internal name. They now make the same choice, and switching them both back is still one setting if you need it.
|
||||
- **Controllers pressed the wrong buttons on devices Android has no layout for.** Reported from a Fire TV Stick 4K Max with a DualSense and an Xbox Elite Series 2, both over Bluetooth, both identified by name and both wrong under the fingers: L2 arrived as L1, and Circle and R1 were dropped entirely. Android names a controller's buttons from a file matched to that exact model, and when there is no such file it falls back to guessing by the order the buttons appear in the controller's own report — which is only right if that order happens to match. Neither pad has a file on a Fire TV. Punktfunk now reads the button's position in the controller's report directly, which is what the controller means rather than what the guess made of it, and does so only where the guess was in play, so a device that already worked is untouched. Triggers get the same treatment: on a pad Android never mapped they sit on raw axes, which is why pulling a trigger could swing the right stick instead. Whether a trigger rests at zero or at the bottom of its range is now measured from the device rather than assumed. **Not yet confirmed on the reporter's own hardware** — the fix is proven against what those two controllers report, but a Fire TV is the test that settles it, so please say if yours still misbehaves. One thing stays broken and cannot be fixed here: the Xbox pad's Guide button is delivered by Android as the Home key, which it never passes to an app.
|
||||
- **The controller console could not be dismissed on some Android phones.** Turning it off is a matter of no controller being attached, and the app decided that by asking whether a device claimed to be a gamepad — which is the right question for routing a button press and the wrong one for knowing a pad is in the room. Manufacturer game-mode overlays and gaming-phone shoulder triggers make that claim without being controllers, and one of them was enough to pin the console on forever, because a pad that was never there can never be unplugged. The app now also asks whether the hardware is there behind the claim — a stick, a directional pad or real face buttons — and the new switch above is the guaranteed way out either way.
|
||||
- **Changing an Android-only setting inside the controller console did nothing.** Low latency, the phone's own rumble and motion controls, the controller capture switches and the console's own display mode could each be changed in the console, and each quietly went nowhere: the console filed those settings one level deeper than the settings file keeps them, so nothing ever read one back. The row showed its own default, your change came back as the value it had just been handed, and nothing downstream ever heard that anything had moved — which is also why the new off switch above needed this fixed before it could work at all. Settings written by the previous build carry a dead wrapper; it is discarded the next time anything is saved rather than followed around for the life of the install.
|
||||
- **The glow behind a focused card was squarer than the card.** The halo grows the card by a few units on every side but kept the card's own corner radius, and a shape grown outward only stays parallel if its corners grow with it — so the two arcs stopped sharing a centre and the corners read as a badly drawn outline instead of light spilling out from behind. Every card in the console goes through that path: the home tiles, the library grid, the coverflow and the collections deck.
|
||||
- **The picture sat in the top-left corner of an Android screen.** The video layer took the size of the view once, at the moment it was created — and the stream screen hides the system bars and expands into the display cutout a frame or two later, each of which grows the view underneath a layer that never hears about it. The size is now read fresh for every frame, which also means rotating the phone and multi-window both simply work.
|
||||
- **Settings and your game library could not be reached with a television remote.** A remote has a directional pad, OK and Back, and the console had put Settings and the library shelf on controller face buttons it does not have — so on an Android TV neither could be opened at all. Pressing down on the home row now opens Settings, and the library has joined each machine's own options menu, which is where the documentation had been telling you to find it all along. The on-screen hints name whichever route the device in your hand actually has.
|
||||
- **On Nobara, "Switch to Desktop" during a stream threw you straight back into the stream.** The switch takes the picture away, Punktfunk reads that as a problem and rebuilds the session, and the rebuild put Gaming Mode back over the desktop that was trying to start. 0.31.0 changed how the host takes Gaming Mode over and left nothing watching for the switch, which Steam Deck and Bazzite machines never noticed because they follow it another way — Nobara has neither. Also fixed on both: a mid-stream switch used to leave Gaming Mode replaced by a placeholder, so the machine's own "Return to Gaming Mode" afterwards started something that did nothing. Both routes now hand the machine back intact.
|
||||
- **On NixOS the host installed a compositor consisting only of its launcher.** The packaging trims the installed programs down to the one that is needed and had been matching it by name — but the program with that name is a small launcher that sets things up and then runs the real compositor, which the trim deleted. What shipped was a launcher pointing at nothing. That is the true cause of the version banner printing nothing, the marker "missing from the binary", and every HDR-related NixOS failure chased alongside them. Separately, NixOS was the only channel not pinning which compositor version it patches, so a package update could and did break the build outright — and since HDR is on by default, that failure landed on anyone enabling the host at all.
|
||||
|
||||
## Thanks
|
||||
|
||||
Every fix above came from someone describing precisely what did not happen. The Windows black screen was found in two field logs from a host that looked healthy in every respect; the dead controllers in Moonlight-compatible sessions were reported with the detail that made them findable, that it reproduced on every client and device tried; the Fire TV report named which button arrived as which; and one Android user sent two reports in a day that turned out to be the same mistake made twice. Thank you — that is what makes a fault findable rather than merely believable.
|
||||
|
||||
## For developers
|
||||
|
||||
Protocol, ABI, driver and embedder detail — including the version table — is in [CHANGELOG.md](https://git.unom.io/unom/punktfunk/src/tag/v0.31.1/CHANGELOG.md).
|
||||
|
||||
The short version: the streaming protocol, the embedding interface, the driver protocol and the gamepad channel are all exactly where 0.31.0 left them, so nothing needs rebuilding, re-pairing or re-packaging in any direction. The management API and the add-on toolkit each gain one thing by pure addition — the running-report route above, and the toolkit call for it in 0.4.4 — and an add-on that ignores both keeps working unchanged. One control message is added to the wire — clients reporting how much they have received, which is what lets a host tell a dead video path from a clean one — but it takes a spare message number rather than changing an existing message, and an older host on the other end ignores it after one note in its log.
|
||||
@@ -0,0 +1,4 @@
|
||||
• Fixes every console-only setting doing nothing when you changed it — low latency, rumble, motion and controller capture all went nowhere.
|
||||
• Fixes controllers pressing the wrong buttons on boxes Android has no layout for — on a Fire TV a DualSense's L2 arrived as L1.
|
||||
• The controller console can now be switched off from inside it, and a TV remote can reach Settings and your library.
|
||||
• The picture no longer sits in the top-left corner.
|
||||
@@ -19,7 +19,7 @@ pkgname=punktfunk-gamescope
|
||||
# bump it with the marker so pacman sees a new version when only our patches moved.
|
||||
_gsver=3.16.25
|
||||
_gsrev=5fb8dce4a09d0a68d097b9faf9513782106bc843
|
||||
pkgver="${_gsver}.pfhdr7"
|
||||
pkgver="${_gsver}.pfhdr8"
|
||||
# 2: patch 0006 (never destroy the Vulkan device/output at exit). No capability moved, so the
|
||||
# `.pfhdrN` level deliberately stays put — see README.md.
|
||||
# 3: pin moved 8c676c39 -> 5fb8dce4 (3.16.25-1 -> 3.16.25-11), which brings upstream's own
|
||||
@@ -45,6 +45,11 @@ pkgver="${_gsver}.pfhdr7"
|
||||
# racing steamcompmgr's vulkan_screenshot on the same device — a SIGSEGV precisely in the linger
|
||||
# window, so a kept display was dead and reconnect lost the game session. No capability the host
|
||||
# probes for, but "reconnect lost my game" triage has to read the difference off the banner.
|
||||
#
|
||||
# pfhdr8 / rel 1: patch 0010 gives the seat's stub keyboard the compiled `XKB_DEFAULT_*` keymap, so
|
||||
# a session follows the box's configured layout instead of typing US characters. The host PROBES the
|
||||
# banner for this one (`>= 8`), so the level HAS to move here too — leaving it at pfhdr7 made pacman
|
||||
# see no upgrade at all, and every Arch/SteamOS host kept a compositor the probe rejects.
|
||||
pkgrel=1
|
||||
pkgdesc="gamescope with 10-bit BT.2020/PQ PipeWire capture, for punktfunk HDR streaming"
|
||||
arch=('x86_64' 'aarch64')
|
||||
|
||||
Reference in New Issue
Block a user