diff --git a/crates/gpui_macos/src/platform.rs b/crates/gpui_macos/src/platform.rs index 07b77b8fff..16b5a859ab 100644 --- a/crates/gpui_macos/src/platform.rs +++ b/crates/gpui_macos/src/platform.rs @@ -13,7 +13,8 @@ use cocoa::{ }, base::{BOOL, NO, YES, id, nil, selector}, foundation::{ - NSArray, NSAutoreleasePool, NSBundle, NSInteger, NSProcessInfo, NSString, NSUInteger, NSURL, + NSArray, NSAutoreleasePool, NSBundle, NSInteger, NSMutableArray, NSProcessInfo, NSString, + NSUInteger, NSURL, }, }; use core_foundation::{ @@ -767,6 +768,20 @@ impl Platform for MacPlatform { let _: () = msg_send![panel, setPrompt: ns_string(&prompt)]; } + // Extension filter (the host's allowed_extensions): the + // open panel's allowedFileTypes. Empty = any. + if !options.allowed_extensions.is_empty() { + let ns_array = { + let arr = NSMutableArray::::new(); + for ext in &options.allowed_extensions { + let s = ns_string(ext.as_str()); + arr.addObject(&*s); + } + arr + }; + let _: () = msg_send![panel, setAllowedFileTypes: &*ns_array]; + } + let _: () = msg_send![panel, beginWithCompletionHandler: block]; } }) diff --git a/crates/gpui_windows/src/platform.rs b/crates/gpui_windows/src/platform.rs index f2b93f62b7..b761423215 100644 --- a/crates/gpui_windows/src/platform.rs +++ b/crates/gpui_windows/src/platform.rs @@ -1188,6 +1188,30 @@ fn file_open_dialog( folder_dialog.SetOkButtonLabel(&HSTRING::from(prompt))?; } + // Extension filter (the host's allowed_extensions, e.g. + // .ove/.otio/.fcpxml for the project import): the common + // ComDlg filter spec. + if !options.allowed_extensions.is_empty() { + let filter = options + .allowed_extensions + .iter() + .map(|ext| format!("*.{ext}")) + .collect::>() + .join(";"); + // The HSTRINGs must outlive the call (the filter spec holds + // raw pointers into them). + let name = windows::core::HSTRING::from("Supported files"); + let pattern = windows::core::HSTRING::from(filter); + let spec = Common::COMDLG_FILTERSPEC { + pszName: name.as_ptr(), + pszSpec: pattern.as_ptr(), + }; + folder_dialog.SetFileTypes(1, &spec)?; + folder_dialog.SetDefaultExtension( + &HSTRING::from(options.allowed_extensions[0].as_str()), + )?; + } + if folder_dialog.Show(window).is_err() { // User cancelled return Ok(None);