Skip to content
Merged
43 changes: 29 additions & 14 deletions packages/rsnap-overlay/src/overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1111,9 +1111,7 @@ impl OverlaySession {
}

fn frozen_capture_redraw_pending(&self) -> bool {
matches!(self.state.mode, OverlayMode::Frozen)
&& !self.frozen_display_ready()
&& self.frozen_capture_export_pending()
!self.frozen_display_ready() && self.frozen_capture_export_pending()
}

fn frozen_capture_monitor(&self) -> Option<MonitorRect> {
Expand Down Expand Up @@ -1203,6 +1201,24 @@ impl OverlaySession {
FrozenCaptureSessionState::DisplayPending { monitor, worker_state, window_target };
}

fn frozen_display_handoff_pending(&self) -> bool {
matches!(
self.frozen_capture_session_state,
FrozenCaptureSessionState::DisplayPending { .. }
) && !matches!(self.state.mode, OverlayMode::Frozen)
}

fn commit_first_frozen_display_handoff(&mut self, monitor: MonitorRect) {
if matches!(self.state.mode, OverlayMode::Frozen) {
return;
}

self.state.begin_freeze(monitor);

self.state.drag_rect = None;
self.state.hovered_window_rect = None;
}

fn promote_frozen_capture_display_ready(&mut self, monitor: MonitorRect) {
let export = match self.frozen_capture_session_state {
FrozenCaptureSessionState::DisplayPending { worker_state, window_target, .. } => {
Expand Down Expand Up @@ -1307,10 +1323,7 @@ impl OverlaySession {
}

fn pending_freeze_capture_matches(&self, monitor: MonitorRect) -> bool {
self.frozen_capture_monitor() == Some(monitor)
&& matches!(self.state.mode, OverlayMode::Frozen)
&& self.state.monitor == Some(monitor)
&& self.frozen_capture_dispatch_pending()
self.frozen_capture_monitor() == Some(monitor) && self.frozen_capture_dispatch_pending()
}

#[cfg(target_os = "macos")]
Expand Down Expand Up @@ -1660,6 +1673,7 @@ impl OverlaySession {
image: RgbaImage,
cursor: Option<GlobalPoint>,
) {
self.commit_first_frozen_display_handoff(monitor);
self.state.commit_frozen_display_image(monitor, image);
self.promote_frozen_capture_display_ready(monitor);

Expand Down Expand Up @@ -1844,13 +1858,10 @@ impl OverlaySession {

self.set_alt_loupe_window_visible(None, false);
self.state.clear_error();
self.state.begin_freeze(monitor);
self.begin_frozen_transition_timing(monitor, capture_rect, window_target);

Comment thread
yvette-carlisle marked this conversation as resolved.
self.state.frozen_capture_rect = Some(capture_rect);
self.state.frozen_mosaic_preview_rect = None;
self.state.drag_rect = None;
self.state.hovered_window_rect = None;

self.reset_frozen_annotation_state();

Expand Down Expand Up @@ -1903,6 +1914,7 @@ impl OverlaySession {
{
self.state.live_bg_monitor = None;

self.commit_first_frozen_display_handoff(monitor);
self.state.commit_frozen_final_image(monitor, image);
self.note_frozen_transition_preview_committed(monitor, "cached_live_background", None);
self.promote_frozen_capture_display_ready(monitor);
Expand Down Expand Up @@ -2073,10 +2085,7 @@ impl OverlaySession {
window_image: Option<RgbaImage>,
captured_window_id: Option<u32>,
) {
if matches!(self.state.mode, OverlayMode::Frozen)
&& self.state.monitor == Some(monitor)
&& self.frozen_capture_export_pending()
{
if self.frozen_capture_monitor() == Some(monitor) && self.frozen_capture_export_pending() {
let window_capture_target = self.frozen_capture_window_target();
let had_display_image = self.frozen_display_ready();
let frozen_preview_image = image;
Expand Down Expand Up @@ -2104,6 +2113,7 @@ impl OverlaySession {
);

if !had_display_image {
self.commit_first_frozen_display_handoff(monitor);
self.state.commit_frozen_display_image(monitor, frozen_preview_image.clone());
self.promote_frozen_capture_display_ready(monitor);
self.note_frozen_transition_preview_committed(
Expand Down Expand Up @@ -2928,6 +2938,9 @@ impl OverlaySession {
if scroll_capture_active { None } else { self.active_frozen_arrow_preview() };
let visible_frozen_spotlight_preview_rect =
if scroll_capture_active { None } else { self.frozen_spotlight_preview_rect };
let pending_frozen_display_handoff = self.frozen_display_handoff_pending();
let pending_frozen_display_handoff_monitor =
self.frozen_capture_monitor().filter(|_| pending_frozen_display_handoff);
let toolbar_state = if draw_toolbar { Some(&mut self.toolbar_state) } else { None };

{
Expand Down Expand Up @@ -2955,6 +2968,8 @@ impl OverlaySession {
self.config.selection_flow_enabled,
self.config.selection_flow_stroke_width_px,
!scroll_capture_active,
pending_frozen_display_handoff,
pending_frozen_display_handoff_monitor,
scroll_capture_active,
frozen_selection_resize_handles_enabled,
self.frozen_capture_source,
Expand Down
6 changes: 6 additions & 0 deletions packages/rsnap-overlay/src/overlay/cursor_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ impl OverlaySession {
if !self.is_active() || !matches!(self.state.mode, OverlayMode::Live) {
return;
}
if self.frozen_display_handoff_pending() {
return;
}

let interval = self
.repaint_interval_for_monitor(self.active_cursor_monitor())
Expand Down Expand Up @@ -237,6 +240,9 @@ impl OverlaySession {
if !matches!(self.state.mode, OverlayMode::Live) {
return;
}
if self.frozen_display_handoff_pending() {
return;
}
if self.pending_click_hit_test_request_id.is_some() {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ struct FrozenCaptureBackendDispatch {
enum FrozenCaptureBackendSignal {
None,
Wait { reason: &'static str, arm_worker: bool },
EscalateHiddenFallback { reason: &'static str },
Dispatch(FrozenCaptureBackendDispatch),
Abort { message: &'static str },
}

#[cfg(target_os = "macos")]
Expand Down Expand Up @@ -63,6 +63,14 @@ impl OverlaySession {
monitor: MonitorRect,
snapshot: Option<Arc<MonitorImageSnapshot>>,
) -> Option<(Arc<MonitorImageSnapshot>, u128)> {
if self
.live_sample_stream
.as_ref()
.is_some_and(|stream| !stream.self_capture_filter_complete_for_monitor(monitor))
{
return None;
}

let snapshot = snapshot.filter(|snapshot| snapshot.monitor == monitor)?;
let snapshot_age = snapshot.captured_at.elapsed();

Expand Down Expand Up @@ -170,6 +178,17 @@ impl OverlaySession {
self.note_frozen_transition_authoritative_handoff_armed(monitor);
}
},
FrozenCaptureBackendSignal::EscalateHiddenFallback { reason } => {
self.set_frozen_capture_worker_state(FrozenCaptureWorkerState::Armed);
self.note_frozen_transition_preview_deferred(monitor, reason, None);
self.note_frozen_transition_authoritative_handoff_armed(monitor);

if !self.capture_windows_hidden {
self.hide_capture_windows();
}

self.request_redraw_for_monitor(monitor);
},
FrozenCaptureBackendSignal::Dispatch(dispatch) => {
let Some(worker) = &self.worker else {
self.abort_pending_freeze_capture("Capture worker is unavailable.");
Expand All @@ -184,9 +203,6 @@ impl OverlaySession {
Err(err) => self.handle_freeze_capture_request_send_error(monitor, err),
}
},
FrozenCaptureBackendSignal::Abort { message } => {
self.abort_pending_freeze_capture(message);
},
}
}

Expand Down Expand Up @@ -315,8 +331,8 @@ impl OverlaySession {

FrozenCaptureBackendUpdate {
display_candidate: None,
signal: FrozenCaptureBackendSignal::Abort {
message: "Unable to capture a clean preview. Please try again.",
signal: FrozenCaptureBackendSignal::EscalateHiddenFallback {
reason: "timed_out_waiting_for_clean_preview",
},
}
}
Expand Down
24 changes: 17 additions & 7 deletions packages/rsnap-overlay/src/overlay/frozen_selection_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,28 @@ impl OverlaySession {
| LiveCaptureInteraction::PressPending {
monitor, click_target: Some(target), ..
} => target.capture_rect.map(|rect| MonitorRectPoints { monitor_id: monitor.id, rect }),
LiveCaptureInteraction::FrozenFromClick {
monitor,
target: LiveClickCaptureTarget { capture_rect: Some(target), .. },
} => Some(MonitorRectPoints { monitor_id: monitor.id, rect: target }),
_ => None,
}
}

fn live_capture_interaction_drag_rect(
interaction: LiveCaptureInteraction,
) -> Option<MonitorRectPoints> {
let LiveCaptureInteraction::DraggingSelection { monitor, press_global, current_global } =
interaction
else {
return None;
};
let rect = monitor.local_rect_from_points(press_global, current_global)?;
match interaction {
LiveCaptureInteraction::DraggingSelection { monitor, press_global, current_global } => {
let rect = monitor.local_rect_from_points(press_global, current_global)?;

(!rect.is_empty()).then_some(MonitorRectPoints { monitor_id: monitor.id, rect })
(!rect.is_empty()).then_some(MonitorRectPoints { monitor_id: monitor.id, rect })
},
LiveCaptureInteraction::FrozenFromDrag { monitor, capture_rect } => {
Some(MonitorRectPoints { monitor_id: monitor.id, rect: capture_rect })
},
_ => None,
}
}

pub(super) fn sync_live_capture_visual_state(&mut self) {
Expand Down Expand Up @@ -176,6 +183,9 @@ impl OverlaySession {

return;
}
if self.frozen_display_handoff_pending() {
return;
}

match self.live_capture_interaction {
LiveCaptureInteraction::PressPending {
Expand Down
5 changes: 3 additions & 2 deletions packages/rsnap-overlay/src/overlay/hud_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,7 @@ impl OverlaySession {
let Some(gpu) = self.gpu.as_ref() else {
return Err(eyre::eyre!("Missing GPU context"));
};
let monitor =
self.monitor_for_mode().or_else(|| self.windows.values().next().map(|w| w.monitor));
let monitor = self.monitor_for_mode().or(self.windows.values().next().map(|w| w.monitor));
let mut summary = HudRedrawSummary::default();

if let (Some(monitor), Some(hud_window)) = (monitor, self.hud_window.as_mut()) {
Expand Down Expand Up @@ -143,6 +142,8 @@ impl OverlaySession {
self.config.selection_flow_stroke_width_px,
true,
false,
None,
false,
false,
self.frozen_capture_source,
self.frozen_capture_source == FrozenCaptureSource::FullscreenFallback,
Expand Down
10 changes: 10 additions & 0 deletions packages/rsnap-overlay/src/overlay/input_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -875,6 +875,10 @@ impl OverlaySession {
monitor: MonitorRect,
global: GlobalPoint,
) {
if self.frozen_display_handoff_pending() {
return;
}

self.update_cursor_state(monitor, global);
self.update_hud_window_position(monitor, global);

Expand All @@ -899,6 +903,9 @@ impl OverlaySession {
if !matches!(self.state.mode, OverlayMode::Live) {
return;
}
if self.frozen_display_handoff_pending() {
return;
}
if self.pending_click_hit_test_request_id.is_some() {
return;
}
Expand Down Expand Up @@ -949,6 +956,9 @@ impl OverlaySession {
if !matches!(self.state.mode, OverlayMode::Live) {
return OverlayControl::Continue;
}
if self.frozen_display_handoff_pending() {
return OverlayControl::Continue;
}

self.maybe_timeout_pending_click_hit_test(Instant::now());

Expand Down
Loading
Loading