feat(host+client): host-driven mouse-model flip — remote-desktop sweep M3
The full Parsec model: launching a game from a desktop session flips the client into captured relative automatically, and back — no chords. - Capture overlay now distinguishes 'hidden' from 'no cursor yet': CursorOverlay grows a visible flag, overlay() returns Some whenever a bitmap is known (the encode loop strips invisible overlays after forwarding so no blend path ever draws one; the CPU composite guarded on visibility already). - Host forwarder maps it onto the reserved wire bit: visible ⇒ VISIBLE, hidden-but-known ⇒ RELATIVE_HINT (an app grabbed/hid the pointer), never any hint before the first bitmap — a cold start can't flip a desktop session into capture. - Presenter: edge-triggered auto-flip on hint changes via the new Capture::set_desktop (chord semantics untouched); a manual ⌃⌥⇧M sets an override latch that holds until the HOST's intent next changes, so the hint never fights the user. Leaving relative warps the local cursor to the host's last pointer position through the new content_to_window inverse-letterbox mapping (unit-tested against finger_to_content) — the hand-back is seamless. Verified on .21: fmt + clippy -D warnings + tests (presenter 20 incl. the inverse-mapping roundtrip, host 245). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -133,6 +133,20 @@ impl Capture {
|
||||
Some(self.desktop)
|
||||
}
|
||||
|
||||
/// Set the mouse model directly (the M3 host-driven flip — `relative_hint` says a host
|
||||
/// app grabbed/hid the pointer, so run relative; hint clear = back to absolute). Same
|
||||
/// gating and motion hygiene as [`toggle_desktop`](Self::toggle_desktop); returns whether
|
||||
/// the model actually changed.
|
||||
pub fn set_desktop(&mut self, on: bool) -> bool {
|
||||
if !self.abs_ok || self.desktop == on {
|
||||
return false;
|
||||
}
|
||||
self.desktop = on;
|
||||
self.pending_rel = (0, 0);
|
||||
self.pending_abs = None;
|
||||
true
|
||||
}
|
||||
|
||||
/// Whether a regained focus should re-engage: yes unless the user released
|
||||
/// deliberately (the chord keeps its meaning across an Alt-Tab).
|
||||
pub fn should_reengage(&self) -> bool {
|
||||
|
||||
Reference in New Issue
Block a user