diff --git a/crates/punktfunk-host/src/vdisplay/linux/mutter.rs b/crates/punktfunk-host/src/vdisplay/linux/mutter.rs index 199761c..cfafdc1 100644 --- a/crates/punktfunk-host/src/vdisplay/linux/mutter.rs +++ b/crates/punktfunk-host/src/vdisplay/linux/mutter.rs @@ -285,15 +285,16 @@ async fn connect(mode: Mode) -> Result { ) .await?; - // 3. The virtual monitor. By DEFAULT we let Mutter derive the refresh from the PipeWire - // framerate (it defaults the virtual monitor to 60 Hz) — universally safe. - // PUNKTFUNK_MUTTER_VIRTUAL_REFRESH=1 pins the client's exact WxH@Hz via RecordVirtual's "modes" - // (explicit size + refresh-rate; Mutter ≥ 47) for true >60 Hz — validated at 5120×1440@240 on - // Mutter 50 + NVIDIA. (A high-refresh virtual CRTC used to SIGSEGV gnome-shell on teardown; the - // stop-screencast-before-any-monitor-reconfig teardown below avoids that.) + // 3. The virtual monitor. For >60 Hz we pin the client's exact WxH@Hz via RecordVirtual's + // "modes" (explicit size + refresh-rate; Mutter ≥ 47) — validated at 5120×1440@240 on Mutter 50 + // + NVIDIA. At ≤60 Hz we let Mutter derive the refresh from the PipeWire framerate (its 60 Hz + // default is already correct), so the custom-mode path only runs when it buys something. + // (A high-refresh virtual CRTC used to SIGSEGV gnome-shell on teardown, which is why this was + // once gated behind PUNKTFUNK_MUTTER_VIRTUAL_REFRESH; the stop-screencast-before-any-monitor- + // reconfig teardown below fixed the crash, so pinning the client's refresh is now the default.) let mut rec: HashMap<&str, Value> = HashMap::new(); rec.insert("cursor-mode", Value::from(CURSOR_EMBEDDED)); - if virtual_refresh_enabled() && mode.refresh_hz > 60 { + if mode.refresh_hz > 60 { let mut vmode: HashMap<&str, Value> = HashMap::new(); vmode.insert("size", Value::from((mode.width, mode.height))); vmode.insert("refresh-rate", Value::from(mode.refresh_hz as f64)); @@ -382,22 +383,6 @@ type CurrentState = ( type ApplyMon = (String, String, HashMap>); // connector, mode_id, props type ApplyLogical = (i32, i32, f64, u32, bool, Vec); -/// Opt-in: pin the virtual output to the client's exact refresh via RecordVirtual "modes" (true -/// above-60 Hz). Off by default — Mutter-derived 60 Hz is safe on every host; high-refresh virtual -/// CRTCs are validated on Mutter 50 + NVIDIA but behaviour can vary, so it stays opt-in. (The -/// teardown SIGSEGV that first motivated this gate is fixed by stopping the screencast before any -/// monitor-config change.) -fn virtual_refresh_enabled() -> bool { - std::env::var("PUNKTFUNK_MUTTER_VIRTUAL_REFRESH") - .map(|v| { - matches!( - v.trim().to_ascii_lowercase().as_str(), - "1" | "true" | "yes" | "on" - ) - }) - .unwrap_or(false) -} - /// A DisplayConfig proxy on its own session-bus connection (owned, so it stays alive for the /// session — independent of the RemoteDesktop/ScreenCast connection). async fn display_config() -> Result> { diff --git a/design/vrr-plan.md b/design/vrr-plan.md index a2bd311..cb8efbe 100644 --- a/design/vrr-plan.md +++ b/design/vrr-plan.md @@ -24,8 +24,8 @@ on the host display stack. This sidesteps two otherwise-hard blockers entirely: displays as VRR-capable. Not fixable by us; the community IDD projects' "can we fake it" issue is open and unanswered. - **KWin/Mutter/wlroots virtual outputs are fixed-mode** (KWin hardcodes 60 Hz + out-of-band - `kscreen-doctor` custom modes, `vdisplay/linux/kwin.rs:101,138`; Mutter defaults 60 with the - `PUNKTFUNK_MUTTER_VIRTUAL_REFRESH` opt-in, `mutter.rs:244-258`; Sway takes one + `kscreen-doctor` custom modes, `vdisplay/linux/kwin.rs:101,138`; Mutter pins the client's exact + WxH@Hz via `RecordVirtual`'s custom modes for >60 Hz, `mutter.rs`; Sway takes one `--custom WxH@Hz`, `wlroots.rs:93`). What a true-VRR virtual display *would* add is confined to the source end, exactly two residuals: diff --git a/docs-site/content/docs/configuration.md b/docs-site/content/docs/configuration.md index b2e4649..c991f6d 100644 --- a/docs-site/content/docs/configuration.md +++ b/docs-site/content/docs/configuration.md @@ -72,7 +72,6 @@ picture. |---|---|---| | `PUNKTFUNK_KWIN_VIRTUAL_PRIMARY` | `1` | Make the streamed per-session output the sole desktop so plasmashell + windows render on it (not on the headless bootstrap output). Set by the KDE appliance `host.env`. Superseded by the console's **Topology** setting. | | `PUNKTFUNK_MUTTER_VIRTUAL_PRIMARY` | `1` | GNOME/Mutter equivalent of the above. | -| `PUNKTFUNK_MUTTER_VIRTUAL_REFRESH` | `1` | Pin the client's exact WxH**@Hz** via `RecordVirtual`'s custom modes (needed for >60 Hz on Mutter). | ## Video quality