From f49af187bc0755f9b5be9376bfd52c0cf12c1e11 Mon Sep 17 00:00:00 2001 From: Ed Younis Date: Fri, 7 Jul 2023 13:19:35 -0400 Subject: [PATCH] Xdg config home support (#2047) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * config: Add support for XDG_CONFIG_HOME Contributes-to: #1040 Co-authored-by: Björn Bidar Signed-off-by: Björn Bidar * config: Log used config file * config: Add GetConfigDir and minor fixes * config: fixed minor nitpicks --------- Signed-off-by: Björn Bidar Co-authored-by: Björn Bidar --- src/config/ConfigManager.cpp | 107 +++++++++++++++++------------------ src/config/ConfigManager.hpp | 2 + src/render/OpenGL.cpp | 2 +- 3 files changed, 56 insertions(+), 55 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index a4250293..2cf6a5c4 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -24,15 +24,7 @@ CConfigManager::CConfigManager() { setDefaultVars(); setDefaultAnimationVars(); - std::string CONFIGPATH; - if (g_pCompositor->explicitConfigPath == "") { - static const char* const ENVHOME = getenv("HOME"); - CONFIGPATH = ENVHOME + (ISDEBUG ? (std::string) "/.config/hypr/hyprlandd.conf" : (std::string) "/.config/hypr/hyprland.conf"); - } else { - CONFIGPATH = g_pCompositor->explicitConfigPath; - } - - configPaths.emplace_back(CONFIGPATH); + configPaths.emplace_back(getMainConfigPath()); Debug::disableLogs = &configValues["debug:disable_logs"].intValue; Debug::disableTime = &configValues["debug:disable_time"].intValue; @@ -40,6 +32,23 @@ CConfigManager::CConfigManager() { populateEnvironment(); } +std::string CConfigManager::getConfigDir() { + static const char* xdgConfigHome = getenv("XDG_CONFIG_HOME"); + std::string configPath; + if (!xdgConfigHome) + configPath = getenv("HOME") + std::string("/.config"); + else + configPath = xdgConfigHome; + return configPath; +} + +std::string CConfigManager::getMainConfigPath() { + if (!g_pCompositor->explicitConfigPath.empty()) + return g_pCompositor->explicitConfigPath; + + return getConfigDir() + "/hypr/" + (ISDEBUG ? "hyprlandd.conf" : "hyprland.conf"); +} + void CConfigManager::populateEnvironment() { environmentVariables.clear(); for (char** env = environ; *env; ++env) { @@ -300,9 +309,7 @@ void CConfigManager::init() { loadConfigLoadVars(); - const char* const ENVHOME = getenv("HOME"); - - const std::string CONFIGPATH = ENVHOME + (ISDEBUG ? (std::string) "/.config/hypr/hyprlandd.conf" : (std::string) "/.config/hypr/hyprland.conf"); + const std::string CONFIGPATH = getMainConfigPath(); struct stat fileStat; int err = stat(CONFIGPATH.c_str(), &fileStat); @@ -1454,49 +1461,49 @@ void CConfigManager::loadConfigLoadVars() { // paths configPaths.clear(); + std::string mainConfigPath = getMainConfigPath(); + Debug::log(LOG, "Using config: %s", mainConfigPath.c_str()); + configPaths.push_back(mainConfigPath); + std::string configPath = mainConfigPath.substr(0, mainConfigPath.find_last_of('/')); + // find_last_of never returns npos since main_config at least has /hypr/ - std::string CONFIGPATH; - - static const char* const ENVHOME = getenv("HOME"); - const std::string CONFIGPARENTPATH = ENVHOME + (std::string) "/.config/hypr/"; - - if (g_pCompositor->explicitConfigPath == "") { - CONFIGPATH = CONFIGPARENTPATH + (ISDEBUG ? "hyprlandd.conf" : "hyprland.conf"); - } else { - CONFIGPATH = g_pCompositor->explicitConfigPath; + if (!std::filesystem::is_directory(configPath)) { + Debug::log(WARN, "Creating config home directory"); + try { + std::filesystem::create_directories(configPath); + } catch (...) { + parseError = "Broken config file! (Could not create config directory)"; + return; + } } - configPaths.push_back(CONFIGPATH); + if (!std::filesystem::exists(mainConfigPath)) { + Debug::log(WARN, "No config file found; attempting to generate."); + std::ofstream ofs; + ofs.open(mainConfigPath, std::ios::trunc); + ofs << AUTOCONFIG; + ofs.close(); + } std::ifstream ifs; - ifs.open(CONFIGPATH); + ifs.open(mainConfigPath); if (!ifs.good()) { - if (g_pCompositor->explicitConfigPath == "") { - Debug::log(WARN, "Config reading error. (No file? Attempting to generate, backing up old one if exists)"); - try { - std::filesystem::rename(CONFIGPATH, CONFIGPATH + ".backup"); - } catch (...) { /* Probably doesn't exist */ - } + Debug::log(WARN, "Config reading error. Attempting to generate, backing up old one if exists"); - try { - if (!std::filesystem::is_directory(CONFIGPARENTPATH)) - std::filesystem::create_directories(CONFIGPARENTPATH); - } catch (...) { - parseError = "Broken config file! (Could not create directory)"; - return; - } - } + ifs.close(); + if (std::filesystem::exists(mainConfigPath)) + std::filesystem::rename(mainConfigPath, mainConfigPath + ".backup"); + + // Create default config std::ofstream ofs; - ofs.open(CONFIGPATH, std::ios::trunc); - + ofs.open(mainConfigPath, std::ios::trunc); ofs << AUTOCONFIG; - ofs.close(); - ifs.open(CONFIGPATH); - + // Try to re-open + ifs.open(mainConfigPath); if (!ifs.good()) { parseError = "Broken config file! (Could not open)"; return; @@ -1509,17 +1516,16 @@ void CConfigManager::loadConfigLoadVars() { while (std::getline(ifs, line)) { // Read line by line. try { - configCurrentPath = "~/.config/hypr/hyprland.conf"; parseLine(line); } catch (...) { Debug::log(ERR, "Error reading line from config. Line:"); Debug::log(NONE, "%s", line.c_str()); - parseError += "Config error at line " + std::to_string(linenum) + " (" + configCurrentPath + "): Line parsing error."; + parseError += "Config error at line " + std::to_string(linenum) + " (" + mainConfigPath + "): Line parsing error."; } if (parseError != "" && parseError.find("Config error at line") != 0) { - parseError = "Config error at line " + std::to_string(linenum) + " (" + configCurrentPath + "): " + parseError; + parseError = "Config error at line " + std::to_string(linenum) + " (" + mainConfigPath + "): " + parseError; } ++linenum; @@ -1546,7 +1552,7 @@ void CConfigManager::loadConfigLoadVars() { if (parseError != "") g_pHyprError->queueCreate(parseError + "\nHyprland may not work correctly.", CColor(1.0, 50.0 / 255.0, 50.0 / 255.0, 1.0)); else if (configValues["autogenerated"].intValue == 1) - g_pHyprError->queueCreate("Warning: You're using an autogenerated config! (config file: " + CONFIGPATH + " )\nSUPER+Q -> kitty\nSUPER+M -> exit Hyprland", + g_pHyprError->queueCreate("Warning: You're using an autogenerated config! (config file: " + mainConfigPath + " )\nSUPER+Q -> kitty\nSUPER+M -> exit Hyprland", CColor(1.0, 1.0, 70.0 / 255.0, 1.0)); else g_pHyprError->destroy(); @@ -1608,14 +1614,7 @@ void CConfigManager::loadConfigLoadVars() { } void CConfigManager::tick() { - std::string CONFIGPATH; - if (g_pCompositor->explicitConfigPath.empty()) { - static const char* const ENVHOME = getenv("HOME"); - CONFIGPATH = ENVHOME + (ISDEBUG ? (std::string) "/.config/hypr/hyprlandd.conf" : (std::string) "/.config/hypr/hyprland.conf"); - } else { - CONFIGPATH = g_pCompositor->explicitConfigPath; - } - + std::string CONFIGPATH = getMainConfigPath(); if (!std::filesystem::exists(CONFIGPATH)) { Debug::log(ERR, "Config doesn't exist??"); return; diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index cd297ed3..6556945c 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -175,6 +175,8 @@ class CConfigManager { SConfigValue* getConfigValuePtr(const std::string&); SConfigValue* getConfigValuePtrSafe(const std::string&); + static std::string getConfigDir(); + static std::string getMainConfigPath(); SMonitorRule getMonitorRuleFor(const std::string&, const std::string& displayName = ""); SWorkspaceRule getWorkspaceRuleFor(CWorkspace*); diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 9e12610f..6091aacf 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -339,7 +339,7 @@ void CHyprOpenGLImpl::applyScreenShader(const std::string& path) { if (path == "" || path == STRVAL_EMPTY) return; - std::ifstream infile(absolutePath(path, std::string(getenv("HOME")) + "/.config/hypr")); + std::ifstream infile(absolutePath(path, g_pConfigManager->getConfigDir())); if (!infile.good()) { g_pConfigManager->addParseError("Screen shader parser: Screen shader path not found");