From 8ee46f1b0e7b19da0756be42c54de9e0f63dc4c6 Mon Sep 17 00:00:00 2001 From: Alexandre Bouvier Date: Sun, 1 Sep 2024 16:57:48 +0200 Subject: [PATCH] Use standard user paths thanks to SDL --- CMakeLists.txt | 1 + cmake/MacOSXBundleInfo.plist.in | 43 +++++++++++++++ src/common/path_util.cpp | 98 +++++---------------------------- 3 files changed, 57 insertions(+), 85 deletions(-) create mode 100644 cmake/MacOSXBundleInfo.plist.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a41e1ac9..d3cc9ad29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -855,6 +855,7 @@ if (ENABLE_QT_GUI) set_target_properties(shadps4 PROPERTIES # WIN32_EXECUTABLE ON MACOSX_BUNDLE ON + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/cmake/MacOSXBundleInfo.plist.in" MACOSX_BUNDLE_ICON_FILE shadPS4.icns) set_source_files_properties(src/images/shadPS4.icns PROPERTIES diff --git a/cmake/MacOSXBundleInfo.plist.in b/cmake/MacOSXBundleInfo.plist.in new file mode 100644 index 000000000..99738004a --- /dev/null +++ b/cmake/MacOSXBundleInfo.plist.in @@ -0,0 +1,43 @@ + + + + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${MACOSX_BUNDLE_EXECUTABLE_NAME} + CFBundleGetInfoString + ${MACOSX_BUNDLE_INFO_STRING} + CFBundleIconFile + ${MACOSX_BUNDLE_ICON_FILE} + CFBundleIdentifier + ${MACOSX_BUNDLE_GUI_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleLongVersionString + ${MACOSX_BUNDLE_LONG_VERSION_STRING} + CFBundleName + ${MACOSX_BUNDLE_BUNDLE_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + ${MACOSX_BUNDLE_SHORT_VERSION_STRING} + CFBundleSignature + ???? + CFBundleVersion + ${MACOSX_BUNDLE_BUNDLE_VERSION} + CSResourcesFileMapped + + NSHumanReadableCopyright + ${MACOSX_BUNDLE_COPYRIGHT} + SDL_FILESYSTEM_BASE_DIR_TYPE + parent + + diff --git a/src/common/path_util.cpp b/src/common/path_util.cpp index 7551d3b05..d318fd461 100644 --- a/src/common/path_util.cpp +++ b/src/common/path_util.cpp @@ -2,15 +2,10 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include +#include +#include "common/assert.h" #include "common/logging/log.h" #include "common/path_util.h" -#include "common/scope_exit.h" - -#ifdef __APPLE__ -#include -#include -#include -#endif #ifndef MAX_PATH #ifdef _WIN32 @@ -30,86 +25,19 @@ namespace Common::FS { namespace fs = std::filesystem; -#ifdef __APPLE__ -using IsTranslocatedURLFunc = Boolean (*)(CFURLRef path, bool* isTranslocated, - CFErrorRef* __nullable error); -using CreateOriginalPathForURLFunc = CFURLRef __nullable (*)(CFURLRef translocatedPath, - CFErrorRef* __nullable error); - -static CFURLRef UntranslocateBundlePath(const CFURLRef bundle_path) { - if (void* security_handle = - dlopen("/System/Library/Frameworks/Security.framework/Security", RTLD_LAZY)) { - SCOPE_EXIT { - dlclose(security_handle); - }; - - const auto IsTranslocatedURL = reinterpret_cast( - dlsym(security_handle, "SecTranslocateIsTranslocatedURL")); - const auto CreateOriginalPathForURL = reinterpret_cast( - dlsym(security_handle, "SecTranslocateCreateOriginalPathForURL")); - - bool is_translocated = false; - if (IsTranslocatedURL && CreateOriginalPathForURL && - IsTranslocatedURL(bundle_path, &is_translocated, nullptr) && is_translocated) { - return CreateOriginalPathForURL(bundle_path, nullptr); - } - } - return nullptr; -} - -static std::filesystem::path GetBundleParentDirectory() { - if (CFBundleRef bundle_ref = CFBundleGetMainBundle()) { - if (CFURLRef bundle_url_ref = CFBundleCopyBundleURL(bundle_ref)) { - SCOPE_EXIT { - CFRelease(bundle_url_ref); - }; - - CFURLRef untranslocated_url_ref = UntranslocateBundlePath(bundle_url_ref); - SCOPE_EXIT { - if (untranslocated_url_ref) { - CFRelease(untranslocated_url_ref); - } - }; - - char app_bundle_path[MAXPATHLEN]; - if (CFURLGetFileSystemRepresentation( - untranslocated_url_ref ? untranslocated_url_ref : bundle_url_ref, true, - reinterpret_cast(app_bundle_path), sizeof(app_bundle_path))) { - std::filesystem::path bundle_path{app_bundle_path}; - return bundle_path.parent_path(); - } - } - } - return std::filesystem::current_path(); -} -#endif - static auto UserPaths = [] { + const auto base_dir = SDL_GetBasePath(); + ASSERT(base_dir != NULL); #ifdef __APPLE__ - // Start by assuming the base directory is the bundle's parent directory. - std::filesystem::path base_dir = GetBundleParentDirectory(); - std::filesystem::path user_dir = base_dir / PORTABLE_DIR; - // Check if the "user" directory exists in the current path: - if (!std::filesystem::exists(user_dir)) { - // If it doesn't exist, use the new hardcoded path: - user_dir = - std::filesystem::path(getenv("HOME")) / "Library" / "Application Support" / "shadPS4"; - } -#elif defined(__linux__) - auto user_dir = std::filesystem::current_path() / PORTABLE_DIR; - // Check if the "user" directory exists in the current path: - if (!std::filesystem::exists(user_dir)) { - // If it doesn't exist, use XDG_DATA_HOME if it is set, and provide a standard default - const char* xdg_data_home = getenv("XDG_DATA_HOME"); - if (xdg_data_home != nullptr && strlen(xdg_data_home) > 0) { - user_dir = std::filesystem::path(xdg_data_home) / "shadPS4"; - } else { - user_dir = std::filesystem::path(getenv("HOME")) / ".local" / "share" / "shadPS4"; - } - } -#else - const auto user_dir = std::filesystem::current_path() / PORTABLE_DIR; + fs::current_path(base_dir); #endif + fs::path user_dir = fs::path(base_dir) / PORTABLE_DIR; + if (!fs::exists(user_dir)) { + const auto sdl_dir = SDL_GetPrefPath("shadps4-emu", "shadPS4"); + ASSERT(sdl_dir != NULL); + user_dir = sdl_dir; + SDL_free(sdl_dir); + } std::unordered_map paths; @@ -197,4 +125,4 @@ std::filesystem::path PathFromQString(const QString& path) { } #endif -} // namespace Common::FS \ No newline at end of file +} // namespace Common::FS