From e15659f6d2ab53cbebb81117ed7ed24c51f1ece5 Mon Sep 17 00:00:00 2001 From: Simon Gellis Date: Wed, 12 Aug 2026 19:45:59 -0400 Subject: [PATCH] Use sync API on macos --- src/filepicker.rs | 48 ++++++++++++++++++++++++++++++++++--------- src/window/game.rs | 12 +++++------ src/window/profile.rs | 4 ++-- 3 files changed, 46 insertions(+), 18 deletions(-) diff --git a/src/filepicker.rs b/src/filepicker.rs index 3c5d97a..1ece0b5 100644 --- a/src/filepicker.rs +++ b/src/filepicker.rs @@ -18,39 +18,67 @@ impl FilePicker { self.window = Some(Arc::downgrade(window)); } - pub fn new_dialog(&self) -> FileDialogBuilder { - #[allow(unused_mut)] + pub fn pick_file_dialog(&self) -> FileDialogBuilder { + self.new_dialog(FileDialogAction::PickFile, false) + } + + pub fn save_file_dialog(&self) -> FileDialogBuilder { + self.new_dialog(FileDialogAction::SaveFile, true) + } + + fn new_dialog(&self, action: FileDialogAction, attach_window: bool) -> FileDialogBuilder { + #[cfg(not(target_os = "macos"))] let mut dialog = rfd::AsyncFileDialog::new(); #[cfg(target_os = "macos")] - if let Some(window) = self.window.as_ref().and_then(|w| w.upgrade()) { + let mut dialog = rfd::FileDialog::new(); + + if attach_window && let Some(window) = self.window.as_ref().and_then(|w| w.upgrade()) { dialog = dialog.set_parent(&window); } - FileDialogBuilder { dialog } + FileDialogBuilder { dialog, action } } } pub struct FileDialogBuilder { + #[cfg(not(target_os = "macos"))] dialog: rfd::AsyncFileDialog, + #[cfg(target_os = "macos")] + dialog: rfd::FileDialog, + action: FileDialogAction } impl FileDialogBuilder { pub fn add_filter(self, name: impl Into, extensions: &[impl ToString]) -> Self { Self { dialog: self.dialog.add_filter(name, extensions), + ..self } } pub fn set_file_name(self, file_name: impl Into) -> Self { Self { dialog: self.dialog.set_file_name(file_name), + ..self } } - pub fn pick_file(self) -> Option { - pollster::block_on(self.dialog.pick_file()).map(Into::into) - } - - pub fn save_file(self) -> Option { - pollster::block_on(self.dialog.save_file()).map(Into::into) + pub fn open(self) -> Option { + #[cfg(not(target_os = "macos"))] + fn resolve(action: impl Future>) -> Option { + pollster::block_on(action).map(Into::into) + } + #[cfg(target_os = "macos")] + fn resolve(action: Option) -> Option { + action + } + match self.action { + FileDialogAction::PickFile => resolve(self.dialog.pick_file()), + FileDialogAction::SaveFile => resolve(self.dialog.save_file()), + } } } + +enum FileDialogAction { + PickFile, + SaveFile, +} \ No newline at end of file diff --git a/src/window/game.rs b/src/window/game.rs index 9c9af63..e849459 100644 --- a/src/window/game.rs +++ b/src/window/game.rs @@ -252,9 +252,9 @@ impl GameWindow { Command::OpenRom => { let rom = self .file_picker - .new_dialog() + .pick_file_dialog() .add_filter("Virtual Boy ROMs", &["vb", "vbrom", "elf", "isx"]) - .pick_file(); + .open(); if let Some(path) = rom { self.client .send_command(EmulatorCommand::LoadGame(self.sim_id, path)); @@ -310,9 +310,9 @@ impl GameWindow { { let rom = self .file_picker - .new_dialog() + .pick_file_dialog() .add_filter("Virtual Boy ROMs", &["vb", "vbrom", "elf", "isx"]) - .pick_file(); + .open(); if let Some(path) = rom { self.client .send_command(EmulatorCommand::LoadGame(self.sim_id, path)); @@ -466,10 +466,10 @@ impl GameWindow { let bytes = rx.await.context("Could not take screenshot")?; let file = self .file_picker - .new_dialog() + .save_file_dialog() .add_filter("PNG images", &["png"]) .set_file_name("screenshot.png") - .save_file(); + .open(); let Some(path) = file else { return Ok(None); }; diff --git a/src/window/profile.rs b/src/window/profile.rs index c57b480..a7f1593 100644 --- a/src/window/profile.rs +++ b/src/window/profile.rs @@ -64,10 +64,10 @@ impl ProfileWindow { let bytes_receiver = self.profiler.finish_recording(); let file = self .file_picker - .new_dialog() + .save_file_dialog() .add_filter("Profiler files", &["json"]) .set_file_name("profile.json") - .save_file(); + .open(); if let Some(path) = file { let bytes = pollster::block_on(bytes_receiver)?; let _ = fs::remove_file(&path);