From 7699430d79303929cf8106c29eba3825ebd9378f Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 20 Aug 2026 22:18:27 +0000 Subject: [PATCH 1/2] fix(desktop): cancel rfd nil-panel before moving dialog_callback The async sheet path moved the non-Copy Fn into RcBlock, then called it again when NSOpenPanel/NSSavePanel was nil (E0382). Complete as cancel first, matching stock rfd's single post-move use. Signed-off-by: Cursor Agent Co-authored-by: jmfcamp --- desktop/src-tauri/src/macos_file_panel.rs | 25 +++++++++++++++++++ .../rfd/src/backend/macos/modal_future.rs | 13 ++++++---- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/desktop/src-tauri/src/macos_file_panel.rs b/desktop/src-tauri/src/macos_file_panel.rs index a6f2d2a336a..cc08548d0a0 100644 --- a/desktop/src-tauri/src/macos_file_panel.rs +++ b/desktop/src-tauri/src/macos_file_panel.rs @@ -83,4 +83,29 @@ mod tests { "ModalFuture::new returns Self; a bare `return;` on the sync nil-panel path is E0069" ); } + + #[test] + fn patched_rfd_async_nil_panel_cancels_before_callback_move() { + // dialog_callback is a non-Copy Fn. The async sheet path used to + // move it into RcBlock, then call it again on a nil panel (E0382). + let sheet = RFD_MODAL + .split("if unsafe { app.isRunning() }") + .nth(1) + .and_then(|s| s.split("} else {").next()) + .expect("async sheet path in ModalFuture::new"); + let build = sheet + .find("let Some(modal) = build_modal") + .expect("async nil-panel guard"); + let block = sheet + .find("RcBlock::new") + .expect("sheet completion block"); + assert!( + build < block, + "nil-panel cancel must run before dialog_callback moves into RcBlock (E0382)" + ); + assert!( + sheet.contains("NSModalResponseCancel"), + "nil panel must complete the sheet path as cancelled" + ); + } } diff --git a/desktop/src-tauri/vendor/rfd/src/backend/macos/modal_future.rs b/desktop/src-tauri/vendor/rfd/src/backend/macos/modal_future.rs index 828fa249b7d..16de558ccf7 100644 --- a/desktop/src-tauri/vendor/rfd/src/backend/macos/modal_future.rs +++ b/desktop/src-tauri/vendor/rfd/src/backend/macos/modal_future.rs @@ -87,17 +87,20 @@ impl ModalFuture { run_on_main(move |mtm| { let window = window; + // Stock rfd builds the panel, then moves dialog_callback into + // RcBlock. After Option, the nil-panel cancel must run + // first — the Fn is not Copy (E0382). + let Some(modal) = build_modal(mtm) else { + dialog_callback(state, NSModalResponseCancel); + return; + }; + let completion = { let state = state.clone(); block2::RcBlock::new(move |result| { dialog_callback(state.clone(), result); }) }; - - let Some(modal) = build_modal(mtm) else { - dialog_callback(state, NSModalResponseCancel); - return; - }; let inner = modal.inner_modal().retain(); state.lock().unwrap().modal = Some(modal); From 89e719ea1a0b1fa5f6b3944652fdbd0edd8a8345 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 20 Aug 2026 22:19:29 +0000 Subject: [PATCH 2/2] style(desktop): rustfmt rfd E0382 string-guard test Signed-off-by: Cursor Agent Co-authored-by: jmfcamp --- desktop/src-tauri/src/macos_file_panel.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/desktop/src-tauri/src/macos_file_panel.rs b/desktop/src-tauri/src/macos_file_panel.rs index cc08548d0a0..1d9e12243a1 100644 --- a/desktop/src-tauri/src/macos_file_panel.rs +++ b/desktop/src-tauri/src/macos_file_panel.rs @@ -96,9 +96,7 @@ mod tests { let build = sheet .find("let Some(modal) = build_modal") .expect("async nil-panel guard"); - let block = sheet - .find("RcBlock::new") - .expect("sheet completion block"); + let block = sheet.find("RcBlock::new").expect("sheet completion block"); assert!( build < block, "nil-panel cancel must run before dialog_callback moves into RcBlock (E0382)"