From 8071b49f9d6fbf1beb41e087377b082428059a43 Mon Sep 17 00:00:00 2001 From: Eric Warmenhoven Date: Sun, 18 Feb 2024 11:23:40 -0500 Subject: [PATCH] macos: add portable.txt as flag for portable install (#16244) --- file_path_special.c | 61 ++++++++++++++++-------------- frontend/drivers/platform_darwin.m | 33 ++++++++-------- 2 files changed, 49 insertions(+), 45 deletions(-) diff --git a/file_path_special.c b/file_path_special.c index ed64e62f14..91516971d2 100644 --- a/file_path_special.c +++ b/file_path_special.c @@ -103,48 +103,53 @@ bool fill_pathname_application_data(char *s, size_t len) #elif defined(OSX) CFBundleRef bundle = CFBundleGetMainBundle(); - bool portable = false; if (!bundle) return false; + + /* get the directory containing the app */ + CFStringRef parent_path; + CFURLRef bundle_url, parent_url; + bundle_url = CFBundleCopyBundleURL(bundle); + parent_url = CFURLCreateCopyDeletingLastPathComponent(NULL, bundle_url); + parent_path = CFURLCopyFileSystemPath(parent_url, kCFURLPOSIXPathStyle); + CFStringGetCString(parent_path, s, len, kCFStringEncodingUTF8); + CFRelease(parent_path); + CFRelease(parent_url); + CFRelease(bundle_url); + #if HAVE_STEAM - portable = true; + return true; #else + /* if portable.txt exists next to the app then we use that directory */ + char portable_buf[PATH_MAX_LENGTH] = {0}; + fill_pathname_join(portable_buf, s, "portable.txt", sizeof(portable_buf)); + if (path_is_valid(portable_buf)) + return true; + + /* if the app itself says it's portable we obey that as well */ CFStringRef key = CFStringCreateWithCString(NULL, "RAPortableInstall", kCFStringEncodingUTF8); if (key) { CFBooleanRef val = CFBundleGetValueForInfoDictionaryKey(bundle, key); + CFRelease(key); if (val) { - portable = CFBooleanGetValue(val); + bool portable = CFBooleanGetValue(val); CFRelease(val); + if (portable) + return true; } - CFRelease(key); + } + + /* otherwise we use ~/Library/Application Support/RetroArch */ + const char *appdata = getenv("HOME"); + if (appdata) + { + fill_pathname_join(s, appdata, + "Library/Application Support/RetroArch", len); + return true; } #endif - if (portable) - { - CFStringRef parent_path; - CFURLRef bundle_url, parent_url; - bundle_url = CFBundleCopyBundleURL(bundle); - parent_url = CFURLCreateCopyDeletingLastPathComponent(NULL, bundle_url); - parent_path = CFURLCopyFileSystemPath(parent_url, kCFURLPOSIXPathStyle); - CFStringGetCString(parent_path, s, len, kCFStringEncodingUTF8); - CFRelease(parent_path); - CFRelease(parent_url); - CFRelease(bundle_url); - return true; - } - else - { - const char *appdata = getenv("HOME"); - - if (appdata) - { - fill_pathname_join(s, appdata, - "Library/Application Support/RetroArch", len); - return true; - } - } #elif defined(RARCH_UNIX_CWD_ENV) getcwd(s, len); return true; diff --git a/frontend/drivers/platform_darwin.m b/frontend/drivers/platform_darwin.m index 1248d25806..5ad83fea76 100644 --- a/frontend/drivers/platform_darwin.m +++ b/frontend/drivers/platform_darwin.m @@ -344,7 +344,6 @@ static void frontend_darwin_get_env(int *argc, char *argv[], char documents_dir_buf[PATH_MAX_LENGTH] = {0}; char application_data[PATH_MAX_LENGTH] = {0}; CFBundleRef bundle = CFBundleGetMainBundle(); - BOOL portable; if (!bundle) return; @@ -354,36 +353,36 @@ static void frontend_darwin_get_env(int *argc, char *argv[], CFStringGetCString(bundle_path, bundle_path_buf, sizeof(bundle_path_buf), kCFStringEncodingUTF8); CFRelease(bundle_path); CFRelease(bundle_url); + path_resolve_realpath(bundle_path_buf, sizeof(bundle_path_buf), true); +#if defined(OSX) + fill_pathname_application_data(application_data, sizeof(application_data)); + + BOOL portable; /* steam || RAPortableInstall || portable.txt */ #if HAVE_STEAM /* For Steam, we're going to put everything next to the .app */ portable = YES; #else portable = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"RAPortableInstall"] boolValue]; + if (!portable) + { + char portable_buf[PATH_MAX_LENGTH] = {0}; + fill_pathname_join(portable_buf, application_data, "portable.txt", sizeof(portable_buf)); + portable = path_is_valid(portable_buf); + } #endif if (portable) - fill_pathname_application_data(documents_dir_buf, sizeof(documents_dir_buf)); + strncpy(documents_dir_buf, application_data, sizeof(documents_dir_buf)); else { CFSearchPathForDirectoriesInDomains(documents_dir_buf, sizeof(documents_dir_buf)); -#if TARGET_OS_IPHONE - char resolved_documents_dir_buf[PATH_MAX_LENGTH] = {0}; - char resolved_bundle_dir_buf[PATH_MAX_LENGTH] = {0}; - if (realpath(documents_dir_buf, resolved_documents_dir_buf)) - strlcpy(documents_dir_buf, - resolved_documents_dir_buf, - sizeof(documents_dir_buf)); - if (realpath(bundle_path_buf, resolved_bundle_dir_buf)) - strlcpy(bundle_path_buf, - resolved_bundle_dir_buf, - sizeof(bundle_path_buf)); -#endif + path_resolve_realpath(documents_dir_buf, sizeof(documents_dir_buf), true); strlcat(documents_dir_buf, "/RetroArch", sizeof(documents_dir_buf)); } - -#if defined(OSX) - fill_pathname_application_data(application_data, sizeof(application_data)); #else + CFSearchPathForDirectoriesInDomains(documents_dir_buf, sizeof(documents_dir_buf)); + path_resolve_realpath(documents_dir_buf, sizeof(documents_dir_buf), true); + strlcat(documents_dir_buf, "/RetroArch", sizeof(documents_dir_buf)); /* iOS and tvOS are going to put everything in the documents dir */ strncpy(application_data, documents_dir_buf, sizeof(application_data)); #endif