From 3d04ce92a1f048f63e3d928b1b169a026bca26a9 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Tue, 16 Jun 2026 11:15:47 +0000 Subject: [PATCH] =?UTF-8?q?feat(host/windows):=20PUNKTFUNK=5FNO=5FWGC=20?= =?UTF-8?q?=E2=80=94=20force=20single-process=20DDA=20everywhere?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A single test flag to bring up / validate DDA on its own and as the base for the secure-desktop work. When set it (1) skips WGC in capture_virtual_output (forces dxgi::DuplCapturer, same as PUNKTFUNK_CAPTURE=dda) and (2) makes should_use_helper return false, so even a SYSTEM host bypasses the two-process WGC relay and captures in-process with one DDA capturer for both the normal AND the secure desktop — Apollo's model. All the WGC / relay code stays compiled; unset the flag to restore. Co-Authored-By: Claude Opus 4.8 --- crates/punktfunk-host/src/capture.rs | 12 +++++++++++- crates/punktfunk-host/src/m3.rs | 6 ++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/crates/punktfunk-host/src/capture.rs b/crates/punktfunk-host/src/capture.rs index a964da8..52accf5 100644 --- a/crates/punktfunk-host/src/capture.rs +++ b/crates/punktfunk-host/src/capture.rs @@ -258,6 +258,16 @@ pub fn capture_virtual_output(vout: crate::vdisplay::VirtualOutput) -> Result) } +/// `PUNKTFUNK_NO_WGC=1` forces the pure single-process DDA (Desktop Duplication) path everywhere: it +/// skips WGC in [`capture_virtual_output`] AND bypasses the two-process secure-desktop relay (so even a +/// SYSTEM host captures in-process via DDA, the way Apollo does — one capturer for the normal AND the +/// secure desktop). For bringing DDA up to parity / validating it on its own; all the WGC code stays +/// compiled and comes back the moment the flag is unset. +#[cfg(target_os = "windows")] +pub(crate) fn wgc_disabled() -> bool { + std::env::var_os("PUNKTFUNK_NO_WGC").is_some() +} + #[cfg(target_os = "windows")] pub fn capture_virtual_output(vout: crate::vdisplay::VirtualOutput) -> Result> { let target = vout.win_capture.clone().ok_or_else(|| { @@ -275,7 +285,7 @@ pub fn capture_virtual_output(vout: crate::vdisplay::VirtualOutput) -> Result); } diff --git a/crates/punktfunk-host/src/m3.rs b/crates/punktfunk-host/src/m3.rs index 35c5139..313d3b7 100644 --- a/crates/punktfunk-host/src/m3.rs +++ b/crates/punktfunk-host/src/m3.rs @@ -2266,10 +2266,12 @@ fn virtual_stream( /// Should this host take the two-process (SYSTEM host + user-session WGC helper) path? Yes when it's /// running as SYSTEM — the only account that can capture the secure desktop + drive SendInput on it, /// and the account under which in-process WGC won't activate. `PUNKTFUNK_FORCE_HELPER` forces it on -/// (for testing the relay as a normal user); `PUNKTFUNK_NO_HELPER` forces it off. +/// (for testing the relay as a normal user); `PUNKTFUNK_NO_HELPER` forces it off. `PUNKTFUNK_NO_WGC` +/// also forces it off — that mode runs pure single-process DDA (one capturer for the normal AND secure +/// desktop, Apollo-style), which has no WGC helper to relay. #[cfg(target_os = "windows")] fn should_use_helper() -> bool { - if std::env::var_os("PUNKTFUNK_NO_HELPER").is_some() { + if std::env::var_os("PUNKTFUNK_NO_HELPER").is_some() || crate::capture::wgc_disabled() { return false; } std::env::var_os("PUNKTFUNK_FORCE_HELPER").is_some()