From b92277ac580408c2d4e3f46ea3c2e74921d497d4 Mon Sep 17 00:00:00 2001 From: vkedwardli Date: Tue, 7 Nov 2023 23:29:08 +0800 Subject: [PATCH] macOS: Register file extensions for `openFile` (Drag ROM to App Icon), update `setupWorkingDirectory`, rename `SDLMain` to `SDLApplicationDelegate` to avoid confusion with the function `SDL_main()` (#1287) Register file extensions for openFile, and supports the following actions Drag ROM to Application icon to launch the app Drag ROM to the running app's dock icon Drag ROM to the running app's window (applicable to all SDL platform by SDL_DROPFILE) Update setupWorkingDirectory macOS default cwd is a nonsense "/" for non-terminal application Rename SDLMain to SDLApplicationDelegate to avoid confusion with the function SDL_main() some code cleanup --- CMakeLists.txt | 4 +- core/sdl/sdl.cpp | 4 + .../emulator-osx/MacOSXBundleInfo.plist.in | 16 ++++ .../{SDLMain.h => SDLApplicationDelegate.h} | 2 +- .../{SDLMain.mm => SDLApplicationDelegate.mm} | 86 ++++--------------- 5 files changed, 39 insertions(+), 73 deletions(-) rename shell/apple/emulator-osx/emulator-osx/{SDLMain.h => SDLApplicationDelegate.h} (83%) rename shell/apple/emulator-osx/emulator-osx/{SDLMain.mm => SDLApplicationDelegate.mm} (85%) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae348ba887..a3a53b0e65 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1645,8 +1645,8 @@ if(NOT LIBRETRO) target_sources(${PROJECT_NAME} PRIVATE shell/apple/common/http_client.mm - shell/apple/emulator-osx/emulator-osx/SDLMain.h - shell/apple/emulator-osx/emulator-osx/SDLMain.mm + shell/apple/emulator-osx/emulator-osx/SDLApplicationDelegate.h + shell/apple/emulator-osx/emulator-osx/SDLApplicationDelegate.mm shell/apple/emulator-osx/emulator-osx/osx-main.mm) set(ASSETS shell/apple/emulator-osx/emulator-osx/Images.xcassets) target_sources(${PROJECT_NAME} PRIVATE ${ASSETS}) diff --git a/core/sdl/sdl.cpp b/core/sdl/sdl.cpp index 6b1a3c0209..1422ce4c2e 100644 --- a/core/sdl/sdl.cpp +++ b/core/sdl/sdl.cpp @@ -467,6 +467,10 @@ void input_sdl_handle() case SDL_JOYDEVICEREMOVED: sdl_close_joystick((SDL_JoystickID)event.jdevice.which); break; + + case SDL_DROPFILE: + gui_start_game(event.drop.file); + break; } } } diff --git a/shell/apple/emulator-osx/MacOSXBundleInfo.plist.in b/shell/apple/emulator-osx/MacOSXBundleInfo.plist.in index d6c384b053..2b700acc6d 100644 --- a/shell/apple/emulator-osx/MacOSXBundleInfo.plist.in +++ b/shell/apple/emulator-osx/MacOSXBundleInfo.plist.in @@ -2,6 +2,22 @@ + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + chd + gdi + cdi + cue + zip + 7z + + CFBundleTypeRole + Viewer + + CFBundleDevelopmentRegion English CFBundleExecutable diff --git a/shell/apple/emulator-osx/emulator-osx/SDLMain.h b/shell/apple/emulator-osx/emulator-osx/SDLApplicationDelegate.h similarity index 83% rename from shell/apple/emulator-osx/emulator-osx/SDLMain.h rename to shell/apple/emulator-osx/emulator-osx/SDLApplicationDelegate.h index c908cafa4b..634c96b7e8 100644 --- a/shell/apple/emulator-osx/emulator-osx/SDLMain.h +++ b/shell/apple/emulator-osx/emulator-osx/SDLApplicationDelegate.h @@ -9,7 +9,7 @@ #import -@interface SDLMain : NSObject +@interface SDLApplicationDelegate : NSObject @end #endif /* _SDLMain_h_ */ diff --git a/shell/apple/emulator-osx/emulator-osx/SDLMain.mm b/shell/apple/emulator-osx/emulator-osx/SDLApplicationDelegate.mm similarity index 85% rename from shell/apple/emulator-osx/emulator-osx/SDLMain.mm rename to shell/apple/emulator-osx/emulator-osx/SDLApplicationDelegate.mm index 3b8912229b..1ebbe7e9d8 100644 --- a/shell/apple/emulator-osx/emulator-osx/SDLMain.mm +++ b/shell/apple/emulator-osx/emulator-osx/SDLApplicationDelegate.mm @@ -5,7 +5,8 @@ Feel free to customize this file to suit your needs */ #include -#include "SDLMain.h" +#include "SDLApplicationDelegate.h" +#include "emulator.h" #include /* for MAXPATHLEN */ #include #include "rend/gui.h" @@ -39,11 +40,6 @@ - (void)setAppleMenu:(NSMenu *)menu; } #endif /* SDL_USE_CPS */ -static int gArgc; -static char **gArgv; -static BOOL gFinderLaunch; -static BOOL gCalledAppMainline = FALSE; - static NSString *getApplicationName(void) { const NSDictionary *dict; @@ -127,21 +123,14 @@ - (void)selectAllAction:(id)sender @end /* The main class of the application, the application's delegate */ -@implementation SDLMain +@implementation SDLApplicationDelegate /* Set the working directory to the .app's parent directory */ -- (void) setupWorkingDirectory:(BOOL)shouldChdir +- (void) setupWorkingDirectory { - if (shouldChdir) + if([[NSProcessInfo processInfo] environment][@"PWD"] == NULL && [[[NSFileManager defaultManager] currentDirectoryPath] isEqualToString:@"/"]) { - char parentdir[MAXPATHLEN]; - CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); - if (CFURLGetFileSystemRepresentation(url2, 1, (UInt8 *)parentdir, MAXPATHLEN)) { - chdir(parentdir); /* chdir to the binary app's parent */ - } - CFRelease(url); - CFRelease(url2); + chdir([[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] cStringUsingEncoding:NSUTF8StringEncoding]); } } @@ -274,7 +263,7 @@ static void setupHelpMenu(void) static void CustomApplicationMain (int argc, char **argv) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - SDLMain *sdlMain; + SDLApplicationDelegate *appDelegate; /* Ensure the application object is initialised */ [NSApplication sharedApplication]; @@ -297,13 +286,13 @@ static void CustomApplicationMain (int argc, char **argv) setupHelpMenu(); /* needed for help menu */ /* Create SDLMain and make it the app delegate */ - sdlMain = [[SDLMain alloc] init]; - [NSApp setDelegate:sdlMain]; + appDelegate = [[SDLApplicationDelegate alloc] init]; + [NSApp setDelegate:appDelegate]; /* Start the main event loop */ [NSApp run]; - [sdlMain release]; + [appDelegate release]; [pool release]; } @@ -338,34 +327,10 @@ static bool dumpCallback(const char *dump_dir, const char *minidump_id, void *co */ - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename { - const char *temparg; - size_t arglen; - char *arg; - char **newargv; - - if (!gFinderLaunch) /* MacOS is passing command line args. */ - return FALSE; - - if (gCalledAppMainline) /* app has started, ignore this document. */ - return FALSE; - - temparg = [filename UTF8String]; - arglen = SDL_strlen(temparg) + 1; - arg = (char *) SDL_malloc(arglen); - if (arg == NULL) - return FALSE; - - newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2)); - if (newargv == NULL) - { - SDL_free(arg); - return FALSE; - } - gArgv = newargv; - - SDL_strlcpy(arg, temparg, arglen); - gArgv[gArgc++] = arg; - gArgv[gArgc] = NULL; + dispatch_async(dispatch_get_main_queue(), ^(){ + gui_start_game([filename cStringUsingEncoding:NSUTF8StringEncoding]); + }); + return TRUE; } @@ -381,11 +346,9 @@ - (void) applicationDidFinishLaunching: (NSNotification *) note int status; /* Set the working directory to the .app's parent directory */ - [self setupWorkingDirectory:gFinderLaunch]; + [self setupWorkingDirectory]; - /* Hand off to main application code */ - gCalledAppMainline = TRUE; - status = SDL_main (gArgc, gArgv); + status = SDL_main(NULL, NULL); /* We're done, thank you for playing */ exit(status); @@ -456,23 +419,6 @@ - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString /* Main entry point to executable - should *not* be SDL_main! */ int main (int argc, char **argv) { - /* Copy the arguments into a global variable */ - /* This is passed if we are launched by double-clicking */ - if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { - gArgv = (char **) SDL_malloc(sizeof (char *) * 2); - gArgv[0] = argv[0]; - gArgv[1] = NULL; - gArgc = 1; - gFinderLaunch = YES; - } else { - int i; - gArgc = argc; - gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1)); - for (i = 0; i <= argc; i++) - gArgv[i] = argv[i]; - gFinderLaunch = NO; - } - if (getppid() != 1) { /* Make LLDB ignore EXC_BAD_ACCESS for debugging */ task_set_exception_ports(mach_task_self(), EXC_MASK_BAD_ACCESS, MACH_PORT_NULL, EXCEPTION_DEFAULT, 0);