diff options
author | dec05eba <dec05eba@protonmail.com> | 2024-02-07 18:30:44 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2024-02-07 18:30:44 +0100 |
commit | a5b86659d972d57d495c5a6fa907a8f7a86deab2 (patch) | |
tree | 0ded472aac36bf9e53badb9d5daf6c6d6af9af1b /src | |
parent | b003080265399233aad7de08327e25513ccc9ebc (diff) |
Properly read retarded xdg user dirs
Diffstat (limited to 'src')
-rw-r--r-- | src/Config.cpp | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/src/Config.cpp b/src/Config.cpp index 2d44ed1..2938338 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -1,5 +1,7 @@ #include "../include/Config.hpp" #include "../include/Storage.hpp" +#include <map> +#include <limits.h> #include <json/value.h> #include <assert.h> #include <X11/Xlib.h> @@ -13,6 +15,60 @@ namespace QuickMedia { static float scale = 1.0f; static bool scale_set = false; + // Whoever designed xdg-user-dirs is retarded. Why are some XDG variables environment variables + // while others are in this pseudo shell config file ~/.config/user-dirs.dirs + static std::map<std::string, std::string> get_xdg_variables() { + std::string user_dirs_filepath; + const char *xdg_config_home = getenv("XDG_CONFIG_HOME"); + if(xdg_config_home) { + user_dirs_filepath = xdg_config_home; + } else { + user_dirs_filepath = get_home_dir().data + "/.config"; + } + + user_dirs_filepath += "/user-dirs.dirs"; + + std::map<std::string, std::string> result; + FILE *f = fopen(user_dirs_filepath.c_str(), "rb"); + if(!f) + return result; + + char line[PATH_MAX]; + while(fgets(line, sizeof(line), f)) { + int len = strlen(line); + if(len < 2) + continue; + + if(line[len - 1] == '\n') { + line[len - 1] = '\0'; + len--; + } + + if(line[len - 1] != '"') + continue; + + line[len - 1] = '\0'; + len--; + + const char *sep = strchr(line, '='); + if(!sep) + continue; + + if(sep[1] != '\"') + continue; + + std::string value(sep + 2); + if(strncmp(value.c_str(), "$HOME/", 6) == 0) + value = get_home_dir().data + value.substr(5); + + std::string key(line, sep - line); + result[std::move(key)] = std::move(value); + } + + fclose(f); + return result; + } + static const int XFT_DPI_DEFAULT = 96; // Returns XFT_DPI_DEFAULT on error static int xrdb_get_dpi() { @@ -269,6 +325,7 @@ namespace QuickMedia { peertube_known_instances_fallback(); const std::string home_dir = get_home_dir().data; + auto xdg_vars = get_xdg_variables(); struct DownloadPaths { const char *json_field; @@ -300,8 +357,8 @@ namespace QuickMedia { for(const DownloadPaths &download_paths : download_paths_list) { if(download_paths.config_var->empty()) { std::string dir = download_paths.fallback_dir; - const char *xdg_var = getenv(download_paths.xdg_var_name); - if(xdg_var) + const std::string &xdg_var = xdg_vars[download_paths.xdg_var_name]; + if(!xdg_var.empty()) dir = xdg_var; *download_paths.config_var = std::move(dir); } |