The user direction after WP0: ENet exists only for Moonlight, so the native
plane must be provably safe and the compat planes a deliberate choice.
Opt-in, everywhere. Windows already was (unchecked installer task). The three
opt-out surfaces are flipped: the shipped systemd user unit (deb/RPM/Arch/
sysext) no longer bakes --gamestream into ExecStart — a new
PUNKTFUNK_GAMESTREAM=1 host.env knob (pf-host-config, OR-ed with the CLI
flag) is the packaged opt-in; the NixOS module default goes true→false, with
a module-check assertion that unset = native-only; the Deck installer takes
--gamestream to opt in (--no-gamestream kept as explicit-off). Docs
(quickstart, running-as-a-service, moonlight, ubuntu/fedora/arch firewall
sections, gnome/sway, how-it-works) rewritten to the opt-in shape; the
CHANGELOG carries the upgrade note.
Enforced-safe. punktfunk-core is #![deny(unsafe_code)] crate-wide — every
module that parses network bytes is safe Rust as a compile error, not a
census result. Carve-outs are exactly two documented classes, neither of
which interprets attacker bytes: the client surface (abi, client) and the
transport syscall-batching shims (udp/{apple,linux,windows}, qos_windows).
In punktfunk-host, the modules a secure-default host exposes — native
(cfg-not-test: its tests exercise the client C ABI on purpose),
native_pairing, mgmt, mgmt_token, discovery, wol — are #[forbid(unsafe_code)].
Gates: Linux amd64 container clippy --all-targets -D warnings clean over
core+host-config+host; core 204 tests green under the deny; mgmt 46/46,
control 6/6. .133 Windows clippy (shipped features, clean-first,
sentinel-checked) clean — covers the qos_windows/udp-windows carve-outs.
macOS + iOS cargo check green (the apple.rs carve-out compiles for real).
5.1 KiB
title, description
| title | description |
|---|---|
| GNOME (Mutter) | Configure a Punktfunk host for GNOME — host.env, the EGL/lock traps, and a headless session. |
Configure a host running GNOME. The host drives GNOME's Mutter compositor to create a per-client
virtual display over D-Bus (RecordVirtual), zero-copy. This page assumes the host is already
installed — see Ubuntu, Fedora, or Arch.
New here? Read Security & Safe Use first — a streaming host is remote control of the machine, so keep it on a trusted LAN or VPN and require pairing.
host.env
The host auto-detects the compositor from your live session on every connect, so the starter
~/.config/punktfunk/host.env is one line:
# ~/.config/punktfunk/host.env (keys are case-sensitive)
PUNKTFUNK_VIDEO_SOURCE=virtual
# GPU zero-copy (dmabuf → CUDA → NVENC) is ON by default; auto-falls back to CPU. Set =0 to force CPU.
Don't set
PUNKTFUNK_COMPOSITOR,WAYLAND_DISPLAY, orXDG_CURRENT_DESKTOPhere. Pinning the compositor turns auto-detection off — per connect and mid-stream — so the host stops following session switches, and stale session values point it at dead sockets. Forcing a backend is a CI / dedicated-appliance posture, not desktop configuration.
You must be on a Wayland session (not X11), and Mutter must be ≥ 48. See the Configuration reference for every option.
The GL/EGL userspace
On NVIDIA, gnome-shell fails to start — or the host logs "GPU … not supported by EGL" — when the
NVIDIA GL/EGL userspace is missing. The base driver package doesn't always pull it in. Install your
distro's NVIDIA GL/EGL userspace package — on Ubuntu it's libnvidia-gl-<version> matching
your driver; on Fedora/Arch it ships with the RPM Fusion / repo driver — then confirm the glvnd
vendor file exists:
ls /usr/share/glvnd/egl_vendor.d/10_nvidia.json # must exist
Installing the driver itself is covered on your distro's install page (Ubuntu, Fedora, Arch).
Do not lock the session
A locked GNOME session blocks screen capture — the host fails with "Session creation inhibited". On an always-on or headless host there's no one to unlock it, so disable the lock:
gsettings set org.gnome.desktop.screensaver lock-enabled false
gsettings set org.gnome.desktop.session idle-delay 0
Start the host
With host.env in place, start the host from inside your GNOME session:
systemctl --user enable --now punktfunk-host
journalctl --user -u punktfunk-host -f # watch it come up and print its identity fingerprint
This unit runs the secure native-only host. To also serve stock Moonlight
clients, GameStream compat is opt-in (PUNKTFUNK_GAMESTREAM=1 in host.env, trusted LANs only) —
see What the unit starts.
A desktop-login host should also follow your session's lifetime, or restarting GNOME Shell leaves the host wired to a compositor that is gone — it keeps answering, and every session after that fails at capture. Add the drop-in from Restart the host with your desktop. Skip it on the headless route below.
Then bring up The Web Console to arm pairing and connect a client. For an always-on box, see the headless session below.
Display scaling you set while streaming sticks per client: the host remembers each device's scale and reapplies it on reconnect — see Persistent scaling.
HDR (GNOME 50+)
The per-client virtual display this page is about always streams SDR — Mutter's RecordVirtual
screencasts are 8-bit upstream, so there is nothing to turn on.
GNOME 50 added HDR screencast for real monitors, and the host can use that route — on the
GameStream/Moonlight plane only, by mirroring a monitor instead of creating one.
HDR → Linux + GNOME has the two settings it needs, which monitor it
checks, and how it degrades when none is in HDR mode; Check it has the
hdr-probe subcommand that names the link that said no.
Headless session
To run with no monitor and no login, keep a GNOME Wayland session up at all times and start the host without a login. Have GDM auto-login your user:
# /etc/gdm3/custom.conf (Ubuntu) · /etc/gdm/custom.conf (Fedora)
[daemon]
AutomaticLoginEnable = true
AutomaticLogin = your-user
Disable the lock (see above), then enable the host user service and let it linger past logout:
systemctl --user enable --now punktfunk-host
sudo loginctl enable-linger "$USER"
Reboot and the host comes up on the auto-login session. Full walkthrough: Running as a Service.
Troubleshooting
More fixes — black screen, discovery, pairing — in Troubleshooting.
Once the host is up, bring the console up and pair — see The Web Console.