Use standard user paths thanks to SDL

This commit is contained in:
Alexandre Bouvier 2024-09-01 16:57:48 +02:00
parent 0f91661660
commit 8ee46f1b0e
3 changed files with 57 additions and 85 deletions

View File

@ -855,6 +855,7 @@ if (ENABLE_QT_GUI)
set_target_properties(shadps4 PROPERTIES set_target_properties(shadps4 PROPERTIES
# WIN32_EXECUTABLE ON # WIN32_EXECUTABLE ON
MACOSX_BUNDLE ON MACOSX_BUNDLE ON
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/cmake/MacOSXBundleInfo.plist.in"
MACOSX_BUNDLE_ICON_FILE shadPS4.icns) MACOSX_BUNDLE_ICON_FILE shadPS4.icns)
set_source_files_properties(src/images/shadPS4.icns PROPERTIES set_source_files_properties(src/images/shadPS4.icns PROPERTIES

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
SPDX-FileCopyrightText: 2024 shadPS4 Emulator Project
SPDX-License-Identifier: GPL-2.0-or-later
-->
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
<key>CFBundleIconFile</key>
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
<key>CFBundleIdentifier</key>
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
<key>CFBundleName</key>
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>SDL_FILESYSTEM_BASE_DIR_TYPE</key>
<string>parent</string>
</dict>
</plist>

View File

@ -2,15 +2,10 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <unordered_map> #include <unordered_map>
#include <SDL3/SDL_filesystem.h>
#include "common/assert.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/path_util.h" #include "common/path_util.h"
#include "common/scope_exit.h"
#ifdef __APPLE__
#include <CoreFoundation/CFBundle.h>
#include <dlfcn.h>
#include <sys/param.h>
#endif
#ifndef MAX_PATH #ifndef MAX_PATH
#ifdef _WIN32 #ifdef _WIN32
@ -30,86 +25,19 @@ namespace Common::FS {
namespace fs = std::filesystem; 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<IsTranslocatedURLFunc>(
dlsym(security_handle, "SecTranslocateIsTranslocatedURL"));
const auto CreateOriginalPathForURL = reinterpret_cast<CreateOriginalPathForURLFunc>(
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<u8*>(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 = [] { static auto UserPaths = [] {
const auto base_dir = SDL_GetBasePath();
ASSERT(base_dir != NULL);
#ifdef __APPLE__ #ifdef __APPLE__
// Start by assuming the base directory is the bundle's parent directory. fs::current_path(base_dir);
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;
#endif #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<PathType, fs::path> paths; std::unordered_map<PathType, fs::path> paths;