diff --git a/CMakeLists.txt b/CMakeLists.txt index eabeb8bba..8d8d69cea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,8 +70,15 @@ if(APPLE) set(CMAKE_MACOSX_RPATH TRUE) set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) list(APPEND CMAKE_INSTALL_RPATH "@loader_path/" "@executable_path/") -elseif(UNIX AND NOT UNIX_STRUCTURE) - list(APPEND CMAKE_INSTALL_RPATH "$ORIGIN") +elseif(UNIX) + option(USE_XDG "Utilize XDG Base Directory Specification" ON) + if(USE_XDG) + add_definitions(-DUSE_XDG) + endif() + + if(NOT UNIX_STRUCTURE) + list(APPEND CMAKE_INSTALL_RPATH "$ORIGIN") + endif() endif() option(BUILD_TESTS "Build test directory (includes test sources and possibly a platform test executable)" FALSE) diff --git a/libobs/util/platform-nix.c b/libobs/util/platform-nix.c index 1cf488bbd..7ebfded94 100644 --- a/libobs/util/platform-nix.c +++ b/libobs/util/platform-nix.c @@ -153,18 +153,58 @@ uint64_t os_gettime_ns(void) return ((uint64_t) ts.tv_sec * 1000000000ULL + (uint64_t) ts.tv_nsec); } -/* should return $HOME/.[name] */ +/* should return $HOME/.[name], or when using XDG, + * should return $HOME/.config/[name] as default */ int os_get_config_path(char *dst, size_t size, const char *name) { +#ifdef USE_XDG + char *xdg_ptr = getenv("XDG_CONFIG_HOME"); + + // If XDG_CONFIG_HOME is unset, + // we use the default $HOME/.config/[name] instead + if (xdg_ptr == NULL) { + char *home_ptr = getenv("HOME"); + if (home_ptr == NULL) + bcrash("Could not get $HOME\n"); + + return snprintf(dst, size, "%s/.config/%s", home_ptr, name); + } else { + return snprintf(dst, size, "%s/%s", xdg_ptr, name); + } +#else char *path_ptr = getenv("HOME"); if (path_ptr == NULL) bcrash("Could not get $HOME\n"); return snprintf(dst, size, "%s/.%s", path_ptr, name); +#endif } +/* should return $HOME/.[name], or when using XDG, + * should return $HOME/.config/[name] as default */ char *os_get_config_path_ptr(const char *name) { +#ifdef USE_XDG + struct dstr path; + char *xdg_ptr = getenv("XDG_CONFIG_HOME"); + + /* If XDG_CONFIG_HOME is unset, + * we use the default $HOME/.config/[name] instead */ + if (xdg_ptr == NULL) { + char *home_ptr = getenv("HOME"); + if (home_ptr == NULL) + bcrash("Could not get $HOME\n"); + + dstr_init_copy(&path, home_ptr); + dstr_cat(&path, "/.config/"); + dstr_cat(&path, name); + } else { + dstr_init_copy(&path, xdg_ptr); + dstr_cat(&path, "/"); + dstr_cat(&path, name); + } + return path.array; +#else char *path_ptr = getenv("HOME"); if (path_ptr == NULL) bcrash("Could not get $HOME\n"); @@ -174,6 +214,7 @@ char *os_get_config_path_ptr(const char *name) dstr_cat(&path, "/."); dstr_cat(&path, name); return path.array; +#endif } #endif diff --git a/obs/obs-app.cpp b/obs/obs-app.cpp index bede5b726..ce80f101d 100644 --- a/obs/obs-app.cpp +++ b/obs/obs-app.cpp @@ -1058,6 +1058,32 @@ static inline bool arg_is(const char *arg, (short_form && strcmp(arg, short_form) == 0); } +#if !defined(_WIN32) && !defined(__APPLE__) +#define IS_UNIX 1 +#endif + +/* if using XDG and was previously using an older build of OBS, move config + * files to XDG directory */ +#if defined(USE_XDG) && defined(IS_UNIX) +static void move_to_xdg(void) +{ + char old_path[512]; + char new_path[512]; + char *home = getenv("HOME"); + if (!home) + return; + + if (snprintf(old_path, 512, "%s/.obs-studio", home) <= 0) + return; + if (GetConfigPath(new_path, 512, "obs-studio") <= 0) + return; + + if (os_file_exists(old_path) && !os_file_exists(new_path)) { + rename(old_path, new_path); + } +} +#endif + int main(int argc, char *argv[]) { #ifndef _WIN32 @@ -1071,6 +1097,10 @@ int main(int argc, char *argv[]) base_get_log_handler(&def_log_handler, nullptr); +#if defined(USE_XDG) && defined(IS_UNIX) + move_to_xdg(); +#endif + for (int i = 1; i < argc; i++) { if (arg_is(argv[i], "--portable", "-p")) { portable_mode = true;