From b64be1dc330707c91c5fa8fdc310e67294286035 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Tue, 9 Jun 2026 14:24:09 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20m0=20portal=20capture=20=E2=80=94=20acti?= =?UTF-8?q?vate=20the=20capturer=20so=20frames=20are=20delivered?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The M2 teardown work added an `active` gate to the PipeWire capture callback (idle by default so reconnects stay cheap, with the stream path calling set_active(true) on PLAY). The `m0` subcommand was never updated, so its portal capturer stayed inactive and the callback dropped every frame — `m0 --source portal` failed with "no PipeWire frame within 10s" on every compositor. Call set_active(true) before the capture loop. Validated on headless KWin (Plasma 6.4) via the RemoteDesktop-anchored ScreenCast session: real desktop frames flow (shm BGRx 1920x1080) and encode to valid H.265. (Also folds in a rustfmt reflow of the input-test log line.) Co-Authored-By: Claude Opus 4.8 (1M context) --- crates/lumen-host/src/m0.rs | 4 ++++ crates/lumen-host/src/main.rs | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/crates/lumen-host/src/m0.rs b/crates/lumen-host/src/m0.rs index 6f68d14..6e9ae10 100644 --- a/crates/lumen-host/src/m0.rs +++ b/crates/lumen-host/src/m0.rs @@ -59,6 +59,10 @@ pub fn run(opts: Options) -> Result<()> { } }; + // Activate the capturer so the portal/PipeWire process callback actually delivers frames + // (it gates the per-frame de-pad on `active`; idle by default so reconnects are cheap). + capturer.set_active(true); + // The first frame establishes the authoritative dimensions (the portal's negotiated // size, or the synthetic size) used to configure the encoder. let first = capturer.next_frame().context("capture first frame")?; diff --git a/crates/lumen-host/src/main.rs b/crates/lumen-host/src/main.rs index 654225a..5c6d22a 100644 --- a/crates/lumen-host/src/main.rs +++ b/crates/lumen-host/src/main.rs @@ -85,7 +85,9 @@ fn input_test() -> Result<()> { y, flags: 0, }; - tracing::info!("input-test: injecting a mouse square + 'A'/click taps for ~8s (watch wev / focused app)"); + tracing::info!( + "input-test: injecting a mouse square + 'A'/click taps for ~8s (watch wev / focused app)" + ); for i in 0..160u32 { let (dx, dy) = match (i / 10) % 4 { 0 => (12, 0),