Skip to content

Commit 691cc5b

Browse files
committed
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.
1 parent 4ef8b6c commit 691cc5b

File tree

2 files changed

+28
-15
lines changed

2 files changed

+28
-15
lines changed

src/dialog/cocoa/SDL_cocoadialog.m

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,26 @@
2727
#import <Cocoa/Cocoa.h>
2828
#import <UniformTypeIdentifiers/UTType.h>
2929

30+
static void AddFileExtensionType(NSMutableArray *types, const char *pattern_ptr)
31+
{
32+
if (!*pattern_ptr) {
33+
return; // in case the string had an extra ';' at the end.
34+
}
35+
36+
// -[UTType typeWithFilenameExtension] will return nil if there's a period in the string. It's better to
37+
// allow too many files than not allow the one the user actually needs, so just take the part after the '.'
38+
const char *dot = SDL_strrchr(pattern_ptr, '.');
39+
NSString *extstr = [NSString stringWithFormat: @"%s", dot ? (dot + 1) : pattern_ptr];
40+
if (@available(macOS 11.0, *)) {
41+
UTType *uttype = [UTType typeWithFilenameExtension:extstr];
42+
if (uttype) { // still failed? Don't add the pattern. This is what the pre-macOS11 path does internally anyhow.
43+
[types addObject:uttype];
44+
}
45+
} else {
46+
[types addObject:extstr];
47+
}
48+
}
49+
3050
void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFileCallback callback, void *userdata, SDL_PropertiesID props)
3151
{
3252
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
87107

88108
if (filters) {
89109
// On macOS 11.0 and up, this is an array of UTType. Prior to that, it's an array of NSString
90-
NSMutableArray *types = [[NSMutableArray alloc] initWithCapacity:nfilters ];
110+
NSMutableArray *types = [[NSMutableArray alloc] initWithCapacity:nfilters];
91111

92112
int has_all_files = 0;
93113
for (int i = 0; i < nfilters; i++) {
@@ -102,21 +122,14 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil
102122
for (char *c = pattern; *c; c++) {
103123
if (*c == ';') {
104124
*c = '\0';
105-
if(@available(macOS 11.0, *)) {
106-
[types addObject: [UTType typeWithFilenameExtension:[NSString stringWithFormat: @"%s", pattern_ptr]]];
107-
} else {
108-
[types addObject: [NSString stringWithFormat: @"%s", pattern_ptr]];
109-
}
125+
AddFileExtensionType(types, pattern_ptr);
110126
pattern_ptr = c + 1;
111127
} else if (*c == '*') {
112128
has_all_files = 1;
113129
}
114130
}
115-
if(@available(macOS 11.0, *)) {
116-
[types addObject: [UTType typeWithFilenameExtension:[NSString stringWithFormat: @"%s", pattern_ptr]]];
117-
} else {
118-
[types addObject: [NSString stringWithFormat: @"%s", pattern_ptr]];
119-
}
131+
132+
AddFileExtensionType(types, pattern_ptr); // get the last piece of the string.
120133

121134
SDL_free(pattern);
122135
}

test/testdialog.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
#include <SDL3/SDL_main.h>
1616
#include <SDL3/SDL_test.h>
1717

18-
const SDL_DialogFileFilter filters[3] = {
18+
const SDL_DialogFileFilter filters[] = {
1919
{ "All files", "*" },
20+
{ "SVI Session Indexes", "index;svi-index;index.pb" },
2021
{ "JPG images", "jpg;jpeg" },
2122
{ "PNG images", "png" }
2223
};
@@ -54,7 +55,6 @@ int main(int argc, char *argv[])
5455
const SDL_FRect open_folder_rect = { 370, 50, 220, 140 };
5556
int i;
5657
const char *initial_path = NULL;
57-
const int nfilters = sizeof(filters) / sizeof(*filters);
5858

5959
/* Initialize test framework */
6060
state = SDLTest_CommonCreateState(argv, 0);
@@ -112,11 +112,11 @@ int main(int argc, char *argv[])
112112
* - Nonzero if the user is allowed to choose multiple entries (not for SDL_ShowSaveFileDialog)
113113
*/
114114
if (SDL_PointInRectFloat(&p, &open_file_rect)) {
115-
SDL_ShowOpenFileDialog(callback, NULL, w, filters, nfilters, initial_path, 1);
115+
SDL_ShowOpenFileDialog(callback, NULL, w, filters, SDL_arraysize(filters), initial_path, 1);
116116
} else if (SDL_PointInRectFloat(&p, &open_folder_rect)) {
117117
SDL_ShowOpenFolderDialog(callback, NULL, w, initial_path, 1);
118118
} else if (SDL_PointInRectFloat(&p, &save_file_rect)) {
119-
SDL_ShowSaveFileDialog(callback, NULL, w, filters, nfilters, initial_path);
119+
SDL_ShowSaveFileDialog(callback, NULL, w, filters, SDL_arraysize(filters), initial_path);
120120
}
121121
}
122122
}

0 commit comments

Comments
 (0)