chore(release): bump workspace version to 0.19.0
audit / bun-audit (push) Successful in 11s
ci / web (push) Successful in 50s
ci / docs-site (push) Successful in 54s
apple / swift (push) Successful in 1m20s
audit / cargo-audit (push) Successful in 2m13s
ci / bench (push) Successful in 6m52s
android-screenshots / screenshots (push) Successful in 3m58s
release / apple (push) Successful in 11m11s
deb / build-publish (push) Failing after 8m56s
decky / build-publish (push) Failing after 24s
deb / build-publish-host (push) Failing after 9m15s
android / android (push) Successful in 13m6s
ci / rust (push) Successful in 25m44s
arch / build-publish (push) Successful in 13m37s
docker / deploy-docs (push) Successful in 11s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 11s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 10s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 9s
docker / build-push (ci, ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 8s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 9s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 9s
windows / build (aarch64-pc-windows-msvc) (push) Successful in 4m31s
apple / screenshots (push) Successful in 6m32s
web-screenshots / screenshots (push) Successful in 3m2s
windows / build (x86_64-pc-windows-msvc) (push) Failing after 2m43s
flatpak / build-publish (push) Failing after 8m20s
linux-client-screenshots / screenshots (push) Successful in 7m46s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 15m45s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 18m4s
windows-host / package (push) Successful in 15m54s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 3m26s
windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 3m49s

Headline: the whole pen/tablet input stack (P0–P5) — a pressure-sensitive stylus plane
across core wire, Linux, GameStream/Moonlight, Windows, iPad Pencil and Android. Plus
touch-injection fixes, cursor-DPI scaling, three Windows-host display/cursor fixes, a
gamepad same-PID conflict fix, and the Android mouse/keyboard (TV) regressions.

Release notes authored in-repo at docs/releases/v0.19.0.md (first release on the new flow;
CI seeds the release body from it). cargo update --workspace syncs the lock (versions only).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-23 18:26:49 +02:00
co-authored by Claude Opus 4.8
parent c3c0115a82
commit 0dce1cd116
3 changed files with 75 additions and 28 deletions
Generated
+27 -27
View File
@@ -2194,7 +2194,7 @@ dependencies = [
[[package]]
name = "latency-probe"
version = "0.18.0"
version = "0.19.0"
[[package]]
name = "lazy_static"
@@ -2299,7 +2299,7 @@ dependencies = [
[[package]]
name = "libvpl-sys"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"bindgen",
"cmake",
@@ -2334,7 +2334,7 @@ checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad"
[[package]]
name = "loss-harness"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"punktfunk-core",
]
@@ -2823,7 +2823,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[package]]
name = "pf-capture"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"anyhow",
"ashpd",
@@ -2844,7 +2844,7 @@ dependencies = [
[[package]]
name = "pf-client-core"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"anyhow",
"ash",
@@ -2868,7 +2868,7 @@ dependencies = [
[[package]]
name = "pf-clipboard"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"anyhow",
"ashpd",
@@ -2886,7 +2886,7 @@ dependencies = [
[[package]]
name = "pf-console-ui"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"anyhow",
"ash",
@@ -2907,7 +2907,7 @@ dependencies = [
[[package]]
name = "pf-encode"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"anyhow",
"ash",
@@ -2931,7 +2931,7 @@ dependencies = [
[[package]]
name = "pf-ffvk"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"ash",
"bindgen",
@@ -2940,7 +2940,7 @@ dependencies = [
[[package]]
name = "pf-frame"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"anyhow",
"libc",
@@ -2952,7 +2952,7 @@ dependencies = [
[[package]]
name = "pf-gpu"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"anyhow",
"pf-host-config",
@@ -2966,11 +2966,11 @@ dependencies = [
[[package]]
name = "pf-host-config"
version = "0.18.0"
version = "0.19.0"
[[package]]
name = "pf-inject"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"anyhow",
"ashpd",
@@ -2998,14 +2998,14 @@ dependencies = [
[[package]]
name = "pf-paths"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"tracing",
]
[[package]]
name = "pf-presenter"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"anyhow",
"ash",
@@ -3020,7 +3020,7 @@ dependencies = [
[[package]]
name = "pf-vdisplay"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"anyhow",
"ashpd",
@@ -3050,7 +3050,7 @@ dependencies = [
[[package]]
name = "pf-win-display"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"anyhow",
"pf-paths",
@@ -3062,7 +3062,7 @@ dependencies = [
[[package]]
name = "pf-zerocopy"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"anyhow",
"ash",
@@ -3269,7 +3269,7 @@ dependencies = [
[[package]]
name = "punktfunk-client-android"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"android_logger",
"jni",
@@ -3285,7 +3285,7 @@ dependencies = [
[[package]]
name = "punktfunk-client-linux"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"anyhow",
"async-channel",
@@ -3301,7 +3301,7 @@ dependencies = [
[[package]]
name = "punktfunk-client-session"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"anyhow",
"pf-client-core",
@@ -3316,7 +3316,7 @@ dependencies = [
[[package]]
name = "punktfunk-client-windows"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"async-channel",
"ffmpeg-next",
@@ -3335,7 +3335,7 @@ dependencies = [
[[package]]
name = "punktfunk-core"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"aes-gcm",
"bytes",
@@ -3367,7 +3367,7 @@ dependencies = [
[[package]]
name = "punktfunk-host"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"aes",
"aes-gcm",
@@ -3451,7 +3451,7 @@ dependencies = [
[[package]]
name = "punktfunk-probe"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"anyhow",
"mdns-sd",
@@ -3465,7 +3465,7 @@ dependencies = [
[[package]]
name = "punktfunk-tray"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"anyhow",
"ksni",
@@ -3488,7 +3488,7 @@ checksum = "d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea"
[[package]]
name = "pyrowave-sys"
version = "0.18.0"
version = "0.19.0"
dependencies = [
"bindgen",
"cmake",
+1 -1
View File
@@ -48,7 +48,7 @@ exclude = [
ndk = { path = "clients/android/native/vendor/ndk" }
[workspace.package]
version = "0.18.0"
version = "0.19.0"
edition = "2021"
rust-version = "1.82"
license = "MIT OR Apache-2.0"
+47
View File
@@ -0,0 +1,47 @@
Wire-compatible with 0.18.x — existing pairings and clients keep working. The new stylus plane is capability-negotiated (`HOST_CAP_PEN`) and rides an additive datagram that older peers never send and never have to parse, so a 0.18 host and a 0.19 client (or the reverse) pair exactly as before and simply fall back to pen-as-touch. WIRE_VERSION stays **2**; the embeddable C ABI moves to **13** for one new entry point (`punktfunk_connection_send_pen`); the Windows display-driver protocol is unchanged at **6** (compat floor **3**).
## Pen, stylus & tablet — a whole new input plane
Punktfunk streams now carry a first-class, pressure-sensitive stylus, end to end and on every platform. It is its own wire plane — not mouse events in disguise — so pressure, tilt, hover and barrel buttons survive the trip from glass to host.
- **The wire (P0).** A state-full `RICH_PEN` datagram carries batches of up to 8 samples — sub-pixel `f32` position, `u16` pressure, hover distance, tilt + azimuth, an eraser tool, and two barrel buttons — ordered by a wrapping sequence number and dropped whole when stale, so a late batch never rewrites the present. A `PenTracker` coalesces the stream and `HOST_CAP_PEN` advertises the plane; toward a host without the bit the client keeps its pen-as-touch fallback.
- **Linux host (P1).** A per-session uinput virtual graphics tablet injects the full stylus — pressure and tilt included — and tears down with the session. `HOST_CAP_PEN` goes live wherever uinput is available.
- **GameStream / Moonlight (P2).** The host ingests Moonlight's `SS_PEN`/`SS_TOUCH` pointer packets and advertises the matching `featureFlags`, so a capable Moonlight client sends real stylus onto the same plane.
- **Windows host (P3).** `PT_PEN` + `PT_TOUCH` synthetic pointer injection drives the Windows pen stack directly — pressure and barrel buttons reach applications as genuine pen input.
- **iPad (P4).** Apple Pencil (including Pencil Pro) capture maps onto the stylus plane — pressure and tilt from the panel, with the cursor-capability fix so the pencil and the pointer coexist.
- **Android (P5).** Active-stylus capture (S Pen and friends) forwards onto the pen plane with pressure and tilt.
## Touch injection, fixed
- **Windows native touch actually injects now.** `PT_TOUCH` pointer ids must be contiguous injector slots, but the host was passing the raw wire touch ids straight through — Windows rejected them **silently** and Moonlight-native multitouch landed nothing. Wire ids are now compacted into slots, and the first rejection is surfaced with a warning instead of vanishing.
- **NaN pressure no longer drops a finger.** VoidLink's finger touches arrive with a NaN `pressureOrDistance`; the GameStream path discarded the whole packet. It now tolerates NaN and injects the touch.
## Cursor & pointer polish
- **The forwarded cursor is scaled to the video fit** on the SDL/Linux and Apple/macOS clients. A high-DPI host pointer was drawn against the client's own backing scale and came out roughly 2× too large; it now renders true-size against the streamed video.
## Windows host fixes
- **No more `0x57` on display-config isolate.** When a supplied CCD path is doomed (a Steam Deck's live-deactivate always is), the isolate escalates to a keep-only supplied config instead of failing the whole apply with `0x57`.
- **Cursor exclusion is reported adapter-wide.** The IddCx declare's cursor exclusion is not a per-target property; the virtual-display driver now reports `cursor_excluded` across the adapter.
- **Secure-desktop cursor stood down.** The IddCx hardware cursor is held down while the Windows secure desktop (UAC / Winlogon) is up, ending the duplicated/stuck pointer there.
## Gamepad
- **A virtual Steam Deck pad no longer degrades to a DualSense because of an unrelated Steam controller.** To stop Steam Input from double-driving two *identical* controllers, the host downgrades a requested virtual Steam pad to a DualSense when a matching physical Valve controller is present — but the gate matched *any* `28DE` (Valve) device. So plugging a physical Steam Controller 2 (`28DE:1302`) into the host dropped a client's virtual Steam Deck (`28DE:1205`) to the wrong pad — the passthrough came up as a DualSense. The gate now keys on the exact VID+PID: distinct Steam controllers coexist (Steam Input drives them side by side fine), and only a genuine same-identity duplicate — a physical Deck alongside a virtual Deck — still degrades.
## Android input — mouse & keyboard regressions
Two regressions from 0.18.0's mouse-&-keyboard overhaul, felt most on Android TV boxes:
- **Mouse back/forward stays in the stream.** A mouse's back/forward buttons were synthesized by the reader as `SOURCE_MOUSE` key events and leaked into Android navigation (yanking you out of the stream on a TV); they're now swallowed while streaming.
- **Hardware typing no longer pops the IME.** The soft keyboard is gated on `imeShown`, so typing on a physical keyboard against a text-input host doesn't summon the on-screen IME.
## Release & CI
- **Release notes now ship with the release.** Notes are authored in-repo at `docs/releases/vX.Y.Z.md` and seeded into the release body at creation, and stable releases announce to the Discord `#releases` channel. This file is the first of them.
- **iOS `.ipa` attached.** The iOS build exports an App Store-signed `.ipa` to the unified release and to the run artifacts (archival/TestFlight, not a direct sideload).
## Versions
WIRE_VERSION **2** (unchanged — 0.18.x hosts and clients interoperate) · C ABI **13** (adds `punktfunk_connection_send_pen`; embedders recompile) · Windows display driver protocol **6**, compat floor **3** (unchanged — pen injects through the Windows pen stack, not the display driver). Windows drivers ship separately, as always.