mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 08:22:32 +00:00
Use standard user paths thanks to SDL
This commit is contained in:
parent
0f91661660
commit
8ee46f1b0e
@ -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
|
||||||
|
43
cmake/MacOSXBundleInfo.plist.in
Normal file
43
cmake/MacOSXBundleInfo.plist.in
Normal 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>
|
@ -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;
|
||||||
|
|
||||||
@ -197,4 +125,4 @@ std::filesystem::path PathFromQString(const QString& path) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace Common::FS
|
} // namespace Common::FS
|
||||||
|
Loading…
Reference in New Issue
Block a user