Use sync API on macos

This commit is contained in:
Simon Gellis 2026-08-12 19:45:59 -04:00
parent a926f19f79
commit e15659f6d2
No known key found for this signature in database
GPG Key ID: DA576912FED9577B
3 changed files with 46 additions and 18 deletions

View File

@ -18,39 +18,67 @@ impl FilePicker {
self.window = Some(Arc::downgrade(window)); self.window = Some(Arc::downgrade(window));
} }
pub fn new_dialog(&self) -> FileDialogBuilder { pub fn pick_file_dialog(&self) -> FileDialogBuilder {
#[allow(unused_mut)] 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(); let mut dialog = rfd::AsyncFileDialog::new();
#[cfg(target_os = "macos")] #[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); dialog = dialog.set_parent(&window);
} }
FileDialogBuilder { dialog } FileDialogBuilder { dialog, action }
} }
} }
pub struct FileDialogBuilder { pub struct FileDialogBuilder {
#[cfg(not(target_os = "macos"))]
dialog: rfd::AsyncFileDialog, dialog: rfd::AsyncFileDialog,
#[cfg(target_os = "macos")]
dialog: rfd::FileDialog,
action: FileDialogAction
} }
impl FileDialogBuilder { impl FileDialogBuilder {
pub fn add_filter(self, name: impl Into<String>, extensions: &[impl ToString]) -> Self { pub fn add_filter(self, name: impl Into<String>, extensions: &[impl ToString]) -> Self {
Self { Self {
dialog: self.dialog.add_filter(name, extensions), dialog: self.dialog.add_filter(name, extensions),
..self
} }
} }
pub fn set_file_name(self, file_name: impl Into<String>) -> Self { pub fn set_file_name(self, file_name: impl Into<String>) -> Self {
Self { Self {
dialog: self.dialog.set_file_name(file_name), dialog: self.dialog.set_file_name(file_name),
..self
} }
} }
pub fn pick_file(self) -> Option<PathBuf> { pub fn open(self) -> Option<PathBuf> {
pollster::block_on(self.dialog.pick_file()).map(Into::into) #[cfg(not(target_os = "macos"))]
} fn resolve(action: impl Future<Output = Option<rfd::FileHandle>>) -> Option<PathBuf> {
pollster::block_on(action).map(Into::into)
pub fn save_file(self) -> Option<PathBuf> { }
pollster::block_on(self.dialog.save_file()).map(Into::into) #[cfg(target_os = "macos")]
fn resolve(action: Option<PathBuf>) -> Option<PathBuf> {
action
}
match self.action {
FileDialogAction::PickFile => resolve(self.dialog.pick_file()),
FileDialogAction::SaveFile => resolve(self.dialog.save_file()),
}
} }
} }
enum FileDialogAction {
PickFile,
SaveFile,
}

View File

@ -252,9 +252,9 @@ impl GameWindow {
Command::OpenRom => { Command::OpenRom => {
let rom = self let rom = self
.file_picker .file_picker
.new_dialog() .pick_file_dialog()
.add_filter("Virtual Boy ROMs", &["vb", "vbrom", "elf", "isx"]) .add_filter("Virtual Boy ROMs", &["vb", "vbrom", "elf", "isx"])
.pick_file(); .open();
if let Some(path) = rom { if let Some(path) = rom {
self.client self.client
.send_command(EmulatorCommand::LoadGame(self.sim_id, path)); .send_command(EmulatorCommand::LoadGame(self.sim_id, path));
@ -310,9 +310,9 @@ impl GameWindow {
{ {
let rom = self let rom = self
.file_picker .file_picker
.new_dialog() .pick_file_dialog()
.add_filter("Virtual Boy ROMs", &["vb", "vbrom", "elf", "isx"]) .add_filter("Virtual Boy ROMs", &["vb", "vbrom", "elf", "isx"])
.pick_file(); .open();
if let Some(path) = rom { if let Some(path) = rom {
self.client self.client
.send_command(EmulatorCommand::LoadGame(self.sim_id, path)); .send_command(EmulatorCommand::LoadGame(self.sim_id, path));
@ -466,10 +466,10 @@ impl GameWindow {
let bytes = rx.await.context("Could not take screenshot")?; let bytes = rx.await.context("Could not take screenshot")?;
let file = self let file = self
.file_picker .file_picker
.new_dialog() .save_file_dialog()
.add_filter("PNG images", &["png"]) .add_filter("PNG images", &["png"])
.set_file_name("screenshot.png") .set_file_name("screenshot.png")
.save_file(); .open();
let Some(path) = file else { let Some(path) = file else {
return Ok(None); return Ok(None);
}; };

View File

@ -64,10 +64,10 @@ impl ProfileWindow {
let bytes_receiver = self.profiler.finish_recording(); let bytes_receiver = self.profiler.finish_recording();
let file = self let file = self
.file_picker .file_picker
.new_dialog() .save_file_dialog()
.add_filter("Profiler files", &["json"]) .add_filter("Profiler files", &["json"])
.set_file_name("profile.json") .set_file_name("profile.json")
.save_file(); .open();
if let Some(path) = file { if let Some(path) = file {
let bytes = pollster::block_on(bytes_receiver)?; let bytes = pollster::block_on(bytes_receiver)?;
let _ = fs::remove_file(&path); let _ = fs::remove_file(&path);