Posted on 15 Dec 2021.
This is the followup on this post about making SDL2 execuables work as macOS app bundles. In this post the process of making file opening with open-with and such work with an SDL2 app is explained.
Essentially all ways of opening a file with an app in macOS
(the open-with menu, double-clicking it (if the app is the default), dragging it on the app icon, dragging it on the dock icon and using open
in terminal)
are handled by SDL2 as if it were a drag-and-drop action.
This means the SDL_DROPFILE
event needs to be implemented to have the app react to it. An example follows (assuming a switch-case on event.type
):
case SDL_DROPFILE: { char* droppedFile = event.drop.file; // droppedFile is the path to the file to open/use // handle opening/using the file SDL_free(droppedFile); break; }
To have the app work nicely, having the app open even when no file is given as argument is also needed, so simply opening the app itself does not lead to it instantly quitting again.
Also note that when the app is opened by macOS when the app was not running yet (due to opening a file), macOS will give it a argument indicating an action, which is not a filepath.
Make sure therefore, that the app handles being given a non-file argument and that it doesn't crash or quit when that happens. I was stuck on this point for quite a while,
as my app would quit when it was given an argument that fopen
could not open.
With this done, the executable itself is set up for being able to open files. However, at this point it will not work yet. The Info.plist requires changes to indicate to macOS that this app is able to open files, and to indictae which files those are.
All that remains is to update the Info.plist to indicate the files (by extension) the app can open.
These are listen in the CFBundleDocumentTypes
array. An example of how to indicate a supported file (from my Chip-8 emulator, for .ch8 files) follows:
<key>CFBundleDocumentTypes</key> <array> <dict> <key>CFBundleTypeExtensions</key> <!-- list of extensions the filetype uses --> <array> <string>ch8</string> <!-- a type can indicate multiple extensions by using multiple <string>'s --> </array> <key>CFBundleTypeName</key> <string>Chip-8 ROM Image</string> <!-- name for the filetype, gets shown by Finder --> <key>CFBundleTypeRole</key> <string>Viewer</string> <!-- role, can be Viewer or Editor --> </dict> <!-- more dicts can be used to support multiple different types --> </array>
If the app is compiled and a bundle made at this point, macOS should recognize this type and allow opening files with the listed extensions. The app should now also be shown in the open-with menu for those files. Additionally, macOS Big Sur and later will show files with the icon used by the app as well.
And with this, an SDL2 executable has been made in a fully working app, with full support for opening files as well.