aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2024-02-07 18:30:44 +0100
committerdec05eba <dec05eba@protonmail.com>2024-02-07 18:30:44 +0100
commita5b86659d972d57d495c5a6fa907a8f7a86deab2 (patch)
tree0ded472aac36bf9e53badb9d5daf6c6d6af9af1b /src
parentb003080265399233aad7de08327e25513ccc9ebc (diff)
Properly read retarded xdg user dirs
Diffstat (limited to 'src')
-rw-r--r--src/Config.cpp61
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);
}