dialog: Cocoa shouldn't crash if there's a '.' in the filters.

So something like "index.pb" will now accept any file with a ".pb" extension,
to make macOS happy. This seems like a reasonable tradeoff.

Other minor cleanups.

Fixes #12778.

(cherry picked from commit 691cc5bb5e)
This commit is contained in:
Ryan C. Gordon
2025-05-01 18:11:36 -04:00
committed by Sam Lantinga
parent 4ad6d18203
commit 2f3d242183
2 changed files with 28 additions and 15 deletions

View File

@@ -27,6 +27,26 @@
#import <Cocoa/Cocoa.h>
#import <UniformTypeIdentifiers/UTType.h>
static void AddFileExtensionType(NSMutableArray *types, const char *pattern_ptr)
{
if (!*pattern_ptr) {
return; // in case the string had an extra ';' at the end.
}
// -[UTType typeWithFilenameExtension] will return nil if there's a period in the string. It's better to
// allow too many files than not allow the one the user actually needs, so just take the part after the '.'
const char *dot = SDL_strrchr(pattern_ptr, '.');
NSString *extstr = [NSString stringWithFormat: @"%s", dot ? (dot + 1) : pattern_ptr];
if (@available(macOS 11.0, *)) {
UTType *uttype = [UTType typeWithFilenameExtension:extstr];
if (uttype) { // still failed? Don't add the pattern. This is what the pre-macOS11 path does internally anyhow.
[types addObject:uttype];
}
} else {
[types addObject:extstr];
}
}
void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFileCallback callback, void *userdata, SDL_PropertiesID props)
{
SDL_Window* window = SDL_GetPointerProperty(props, SDL_PROP_FILE_DIALOG_WINDOW_POINTER, NULL);
@@ -87,7 +107,7 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil
if (filters) {
// On macOS 11.0 and up, this is an array of UTType. Prior to that, it's an array of NSString
NSMutableArray *types = [[NSMutableArray alloc] initWithCapacity:nfilters ];
NSMutableArray *types = [[NSMutableArray alloc] initWithCapacity:nfilters];
int has_all_files = 0;
for (int i = 0; i < nfilters; i++) {
@@ -102,21 +122,14 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil
for (char *c = pattern; *c; c++) {
if (*c == ';') {
*c = '\0';
if(@available(macOS 11.0, *)) {
[types addObject: [UTType typeWithFilenameExtension:[NSString stringWithFormat: @"%s", pattern_ptr]]];
} else {
[types addObject: [NSString stringWithFormat: @"%s", pattern_ptr]];
}
AddFileExtensionType(types, pattern_ptr);
pattern_ptr = c + 1;
} else if (*c == '*') {
has_all_files = 1;
}
}
if(@available(macOS 11.0, *)) {
[types addObject: [UTType typeWithFilenameExtension:[NSString stringWithFormat: @"%s", pattern_ptr]]];
} else {
[types addObject: [NSString stringWithFormat: @"%s", pattern_ptr]];
}
AddFileExtensionType(types, pattern_ptr); // get the last piece of the string.
SDL_free(pattern);
}