@@ -5,7 +5,7 @@ use std::{
55 mem:: swap,
66 pin:: Pin ,
77 task:: { Poll , ready} ,
8- time:: { Duration , Instant } ,
8+ time:: Duration ,
99} ;
1010
1111use async_trait:: async_trait;
@@ -196,16 +196,17 @@ pub struct InputCapture {
196196 /// pushing past the guest's actual far edge doesn't make the
197197 /// model run away. Only the entry-axis dimension is consulted.
198198 peer_bounds : HashMap < Position , ( u32 , u32 ) > ,
199- /// Set when wall_pressure first crosses `release_threshold_px`,
200- /// cleared when the peer's handover Leave arrives (which routes
201- /// through `release_no_host_warp` → `reset_wall_press_state`) or
202- /// when the cursor moves back into the interior. The wall-press
203- /// auto-release fires only after `wall_press_deadline` elapses
204- /// without being cleared — turning the historically race-y
205- /// "wall-press vs peer-Leave" into an explicit fallback that
206- /// only kicks in when the peer can't deliver a Leave (lock
207- /// screen, restricted DE, dead peer).
208- wall_press_pending_at : Option < Instant > ,
199+ /// True when wall_pressure has crossed `release_threshold_px` and
200+ /// `wall_press_timer` has been armed but not yet either elapsed
201+ /// or been cancelled. Cleared when the peer's handover Leave
202+ /// arrives (which routes through `release_no_host_warp` →
203+ /// `reset_wall_press_state`) or when the cursor moves back into
204+ /// the interior. The wall-press auto-release fires only after
205+ /// `wall_press_deadline` elapses without this being cleared —
206+ /// turning the historically race-y "wall-press vs peer-Leave"
207+ /// into an explicit fallback that only kicks in when the peer
208+ /// can't deliver a Leave (lock screen, restricted DE, dead peer).
209+ wall_press_pending : bool ,
209210 /// Window after the threshold is crossed during which a peer
210211 /// Leave can cancel the deferred AutoRelease. Sized so a
211212 /// healthy LAN round-trip beats it comfortably.
@@ -460,7 +461,7 @@ impl InputCapture {
460461 self . pending_motion = ( 0.0 , 0.0 ) ;
461462 // Cancel any deferred AutoRelease — release() / handover have
462463 // taken responsibility for the transition.
463- self . wall_press_pending_at = None ;
464+ self . wall_press_pending = false ;
464465 }
465466
466467 /// Initial guest-space cursor position for a freshly-started
@@ -534,11 +535,10 @@ impl InputCapture {
534535 }
535536
536537 /// Update the wall-press accumulator from one event coming up
537- /// from the backend. Sets `wall_press_pending_at ` (and arms the
538+ /// from the backend. Sets `wall_press_pending ` (and arms the
538539 /// timer) when the threshold is first crossed; the actual
539540 /// `AutoRelease` synthesis happens in `poll_next` once the
540- /// deadline elapses without a peer Leave clearing the pending
541- /// flag.
541+ /// deadline elapses without a peer Leave clearing the flag.
542542 fn track_wall_press ( & mut self , pos : Position , event : & CaptureEvent ) {
543543 match event {
544544 CaptureEvent :: Begin { cursor } => {
@@ -630,23 +630,20 @@ impl InputCapture {
630630 // by motion deeper into the guest doesn't combine
631631 // with a later wall-press to fire spuriously.
632632 self . wall_pressure = 0.0 ;
633- if self . wall_press_pending_at . take ( ) . is_some ( ) {
633+ if std :: mem :: take ( & mut self . wall_press_pending ) {
634634 log:: info!(
635635 "wall-press deferred AutoRelease cancelled (cursor moved away from entry edge)"
636636 ) ;
637637 }
638638 }
639639
640640 if self . wall_pressure >= f64:: from ( self . release_threshold_px )
641- && self . wall_press_pending_at . is_none ( )
641+ && ! self . wall_press_pending
642642 {
643- let now = Instant :: now ( ) ;
644- self . wall_press_pending_at = Some ( now) ;
643+ self . wall_press_pending = true ;
645644 self . wall_press_timer
646645 . as_mut ( )
647- . reset ( tokio:: time:: Instant :: from_std (
648- now + self . wall_press_deadline ,
649- ) ) ;
646+ . reset ( tokio:: time:: Instant :: now ( ) + self . wall_press_deadline ) ;
650647 log:: info!(
651648 "wall-press threshold reached ({:.0}px past entry edge, {}px threshold) — \
652649 deferring AutoRelease for {}ms pending peer Leave",
@@ -699,7 +696,7 @@ impl InputCapture {
699696 pending_begin_cursor : None ,
700697 pending_motion : ( 0.0 , 0.0 ) ,
701698 peer_bounds : HashMap :: new ( ) ,
702- wall_press_pending_at : None ,
699+ wall_press_pending : false ,
703700 wall_press_deadline : Duration :: from_millis ( 150 ) ,
704701 wall_press_timer : Box :: pin ( tokio:: time:: sleep ( Duration :: from_secs ( 0 ) ) ) ,
705702 } )
@@ -734,16 +731,14 @@ impl Stream for InputCapture {
734731
735732 // Deferred wall-press fallback. If the threshold was crossed
736733 // and the deadline elapsed without a peer Leave clearing
737- // `wall_press_pending_at ` (release_no_host_warp →
734+ // `wall_press_pending ` (release_no_host_warp →
738735 // reset_wall_press_state), synthesize AutoRelease for every
739736 // capture handle at the active position. Polled before the
740737 // backend so a fire still happens when the user pinned the
741738 // cursor against the wall and stopped moving (no further
742739 // backend events, but the deadline still has to elapse).
743- if self . wall_press_pending_at . is_some ( )
744- && self . wall_press_timer . as_mut ( ) . poll ( cx) . is_ready ( )
745- {
746- self . wall_press_pending_at = None ;
740+ if self . wall_press_pending && self . wall_press_timer . as_mut ( ) . poll ( cx) . is_ready ( ) {
741+ self . wall_press_pending = false ;
747742 log:: info!(
748743 "wall-press deadline elapsed ({}ms) — firing AutoRelease (no peer Leave; \
749744 assuming peer-side capture is unavailable, e.g. lock screen)",
0 commit comments