diff --git a/crates/punktfunk-host/src/gamestream/apps.rs b/crates/punktfunk-host/src/gamestream/apps.rs index b477ec2..c36b74f 100644 --- a/crates/punktfunk-host/src/gamestream/apps.rs +++ b/crates/punktfunk-host/src/gamestream/apps.rs @@ -274,7 +274,10 @@ mod tests { ); // No pretty-print newlines anywhere in the element stream, and no whitespace-only text // nodes between any adjacent tags. - assert!(!xml.contains('\n'), "applist must contain no newlines: {xml}"); + assert!( + !xml.contains('\n'), + "applist must contain no newlines: {xml}" + ); assert!( !xml.contains("> <"), "applist must contain no inter-element spaces: {xml}" diff --git a/crates/punktfunk-host/src/gamestream/nvhttp.rs b/crates/punktfunk-host/src/gamestream/nvhttp.rs index be2c2ea..862aa87 100644 --- a/crates/punktfunk-host/src/gamestream/nvhttp.rs +++ b/crates/punktfunk-host/src/gamestream/nvhttp.rs @@ -132,9 +132,9 @@ async fn h_launch( return xml(error_xml()).into_response(); } let req_fp: Option<[u8; 32]> = match &peer { - Some(Extension(PeerCertFingerprint(Some(fp)))) => { - hex::decode(fp).ok().and_then(|v| <[u8; 32]>::try_from(v).ok()) - } + Some(Extension(PeerCertFingerprint(Some(fp)))) => hex::decode(fp) + .ok() + .and_then(|v| <[u8; 32]>::try_from(v).ok()), _ => None, }; @@ -156,7 +156,9 @@ async fn h_launch( GsDecision::Serve => {} GsDecision::Join((w, h, f)) => { forced_mode = Some((w, h, f)); - tracing::info!("GameStream launch JOIN — admitting at the live session's mode {w}x{h}@{f}"); + tracing::info!( + "GameStream launch JOIN — admitting at the live session's mode {w}x{h}@{f}" + ); } GsDecision::Reject => { tracing::warn!( diff --git a/crates/punktfunk-host/src/gamestream/stream.rs b/crates/punktfunk-host/src/gamestream/stream.rs index f786850..aa51259 100644 --- a/crates/punktfunk-host/src/gamestream/stream.rs +++ b/crates/punktfunk-host/src/gamestream/stream.rs @@ -816,7 +816,10 @@ fn stream_body( dropped_batches += 1; recover_after_drop = true; // re-anchor the reference chain on the next frame if dropped_batches.is_power_of_two() { - tracing::warn!(dropped_batches, "video: pipeline queue full — frame dropped"); + tracing::warn!( + dropped_batches, + "video: pipeline queue full — frame dropped" + ); } } Err(std::sync::mpsc::TrySendError::Disconnected(_)) => { @@ -1019,8 +1022,14 @@ mod tests { let (chunk, steps) = pace_layout(n); assert!(steps >= 1, "n={n}: at least one step"); assert!(steps <= 12, "n={n}: step count {steps} exceeded the cap"); - assert!(chunk >= 16, "n={n}: chunk {chunk} below the 16-packet floor"); - assert!(chunk * steps >= n, "n={n}: {chunk}×{steps} must cover all packets"); + assert!( + chunk >= 16, + "n={n}: chunk {chunk} below the 16-packet floor" + ); + assert!( + chunk * steps >= n, + "n={n}: {chunk}×{steps} must cover all packets" + ); } // Small frames stay on the floor: one 16-packet burst. assert_eq!(pace_layout(1), (16, 1)); diff --git a/crates/punktfunk-host/src/main.rs b/crates/punktfunk-host/src/main.rs index 725e26d..cb05a16 100644 --- a/crates/punktfunk-host/src/main.rs +++ b/crates/punktfunk-host/src/main.rs @@ -515,6 +515,7 @@ fn input_test() -> Result<()> { fn parse_serve(args: &[String]) -> Result<(mgmt::Options, punktfunk1::NativeServe, bool)> { let mut opts = mgmt::Options::default(); let mut native_port: u16 = 9777; // the native plane always runs now + // Fixed data-plane UDP port: `Some(p)` binds p and streams direct (no hole-punch, no ~2.5 s // punch-timeout on a firewalled host); `None` (default) = a random port + hole-punch. Env // default, `--data-port` overrides. diff --git a/crates/punktfunk-host/src/punktfunk1.rs b/crates/punktfunk-host/src/punktfunk1.rs index b320cf8..1c5cdaa 100644 --- a/crates/punktfunk-host/src/punktfunk1.rs +++ b/crates/punktfunk-host/src/punktfunk1.rs @@ -995,7 +995,9 @@ async fn serve_session( let start = Start::decode(&io::read_msg(&mut recv).await?) .map_err(|e| anyhow!("Start decode: {e:?}"))?; - Ok::<_, anyhow::Error>((hello, welcome, udp_port, data_sock, direct, start, compositor)) + Ok::<_, anyhow::Error>(( + hello, welcome, udp_port, data_sock, direct, start, compositor, + )) }; let (hello, welcome, udp_port, data_sock, direct, start, compositor) = tokio::time::timeout(HANDSHAKE_TIMEOUT, handshake) @@ -1206,11 +1208,20 @@ async fn serve_session( let _live_guard = { let id = endpoint::peer_fingerprint(&conn); let label = id - .map(|fp| fp.iter().take(4).map(|b| format!("{b:02x}")).collect::()) + .map(|fp| { + fp.iter() + .take(4) + .map(|b| format!("{b:02x}")) + .collect::() + }) .unwrap_or_else(|| "client".to_string()); crate::vdisplay::admission::register( id, - (welcome.mode.width, welcome.mode.height, welcome.mode.refresh_hz), + ( + welcome.mode.width, + welcome.mode.height, + welcome.mode.refresh_hz, + ), stop.clone(), label, ) diff --git a/crates/punktfunk-host/src/vdisplay/linux/kwin.rs b/crates/punktfunk-host/src/vdisplay/linux/kwin.rs index 743a9b7..a8d1349 100644 --- a/crates/punktfunk-host/src/vdisplay/linux/kwin.rs +++ b/crates/punktfunk-host/src/vdisplay/linux/kwin.rs @@ -364,7 +364,10 @@ fn other_enabled_outputs() -> Vec { /// then sets itself primary — the pre-group behavior). Recent kscreen marks the primary with /// `"priority": 1`; older builds used a `"primary": true` bool — accept either. fn a_managed_output_is_primary() -> bool { - let Ok(out) = std::process::Command::new("kscreen-doctor").arg("-j").output() else { + let Ok(out) = std::process::Command::new("kscreen-doctor") + .arg("-j") + .output() + else { return false; }; let Ok(doc) = serde_json::from_slice::(&out.stdout) else { diff --git a/crates/punktfunk-host/src/vdisplay/windows/manager.rs b/crates/punktfunk-host/src/vdisplay/windows/manager.rs index 28dfaac..021a11e 100644 --- a/crates/punktfunk-host/src/vdisplay/windows/manager.rs +++ b/crates/punktfunk-host/src/vdisplay/windows/manager.rs @@ -129,14 +129,22 @@ impl Monitor { enum MgrState { Idle, - Active { mon: Monitor, refs: u32 }, - Lingering { mon: Monitor, until: Instant }, + Active { + mon: Monitor, + refs: u32, + }, + Lingering { + mon: Monitor, + until: Instant, + }, /// `keep_alive = forever` (gaming-rig): the monitor is kept indefinitely after the last session /// leaves — like `Lingering` but the linger timer never tears it down. A reconnect preempts + /// recreates it (same as `Lingering`, since a reused IddCx swap-chain is dead); only the mgmt /// `/display/release` (or host shutdown) frees it. The physical screens stay off (exclusive) for /// the box's life — the §8 release-now escape hatch (`force_release`) is the way back. - Pinned { mon: Monitor }, + Pinned { + mon: Monitor, + }, } /// The manager's control-device cache. Reopenable: a driver upgrade / WUDFHost restart kills the