diff --git a/crates/pf-vdisplay/src/vdisplay/windows/pf_vdisplay.rs b/crates/pf-vdisplay/src/vdisplay/windows/pf_vdisplay.rs index d765be73..fb27471c 100644 --- a/crates/pf-vdisplay/src/vdisplay/windows/pf_vdisplay.rs +++ b/crates/pf-vdisplay/src/vdisplay/windows/pf_vdisplay.rs @@ -894,6 +894,14 @@ impl VdisplayDriver for PfVdisplayDriver { client_hdr: Option, hw_cursor: bool, ) -> Result { + // Give a capture-mode session the LOSSLESS pointer back: if an earlier session declared a + // hardware cursor and this one does not want it, recycle the driver's host process BEFORE + // this monitor is added. The ADD path is the only place guaranteed to see every session + // (the handshake call site this replaced sat in a `match (source, compositor)` arm that is + // not taken on this host, so it never ran). + if !hw_cursor { + clean_cursor_for_next_session(false); + } let session_id = next_session_id(); // The client display's volume rides into the monitor's EDID CTA HDR block; all-zero = // unknown → the driver keeps its built-in defaults (also what an un-upgraded driver, which diff --git a/crates/punktfunk-host/src/native/handshake.rs b/crates/punktfunk-host/src/native/handshake.rs index 601eee6d..18a76d5d 100644 --- a/crates/punktfunk-host/src/native/handshake.rs +++ b/crates/punktfunk-host/src/native/handshake.rs @@ -686,13 +686,6 @@ pub(super) async fn negotiate( // The bit the Welcome just advertised — read back rather than recomputed, so the // prepared display and the session wiring cannot disagree with it. let cursor_fw = welcome.host_caps & punktfunk_core::quic::HOST_CAP_CURSOR != 0; - // Give a capture-mode session back the LOSSLESS pointer: if an earlier session on this - // host declared the hardware cursor (desktop mouse model) and this one did not ask for - // it, clear the sticky declare now — BEFORE this session's display is created, which is - // the only safe moment, and exactly the "desktop session, disconnect, reconnect in - // capture mode" case the start-up clean cannot reach. No-op when nothing declared, when - // this session wants the channel, or when any display is still held. - pf_vdisplay::driver::clean_cursor_for_next_session(cursor_fw); // Same bit the data plane's SessionContext reads — the prepared plan and the // session wiring must agree on the slicing ceiling (an encoder rebuilt from the // prepared plan with a DIFFERENT max_slices would change the wire shape mid-flow).