Xdg config home support (#2047)

* config: Add support for XDG_CONFIG_HOME

Contributes-to: #1040
Co-authored-by: Björn Bidar <bjorn.bidar@thaodan.de>
Signed-off-by: Björn Bidar <bjorn.bidar@thaodan.de>

* config: Log used config file

* config: Add GetConfigDir and minor fixes

* config: fixed minor nitpicks

---------

Signed-off-by: Björn Bidar <bjorn.bidar@thaodan.de>
Co-authored-by: Björn Bidar <bjorn.bidar@thaodan.de>
This commit is contained in:
Ed Younis 2023-07-07 13:19:35 -04:00 committed by GitHub
parent e632bf176b
commit f49af187bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 55 deletions

View file

@ -24,15 +24,7 @@ CConfigManager::CConfigManager() {
setDefaultVars(); setDefaultVars();
setDefaultAnimationVars(); setDefaultAnimationVars();
std::string CONFIGPATH; configPaths.emplace_back(getMainConfigPath());
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);
Debug::disableLogs = &configValues["debug:disable_logs"].intValue; Debug::disableLogs = &configValues["debug:disable_logs"].intValue;
Debug::disableTime = &configValues["debug:disable_time"].intValue; Debug::disableTime = &configValues["debug:disable_time"].intValue;
@ -40,6 +32,23 @@ CConfigManager::CConfigManager() {
populateEnvironment(); 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() { void CConfigManager::populateEnvironment() {
environmentVariables.clear(); environmentVariables.clear();
for (char** env = environ; *env; ++env) { for (char** env = environ; *env; ++env) {
@ -300,9 +309,7 @@ void CConfigManager::init() {
loadConfigLoadVars(); loadConfigLoadVars();
const char* const ENVHOME = getenv("HOME"); const std::string CONFIGPATH = getMainConfigPath();
const std::string CONFIGPATH = ENVHOME + (ISDEBUG ? (std::string) "/.config/hypr/hyprlandd.conf" : (std::string) "/.config/hypr/hyprland.conf");
struct stat fileStat; struct stat fileStat;
int err = stat(CONFIGPATH.c_str(), &fileStat); int err = stat(CONFIGPATH.c_str(), &fileStat);
@ -1454,49 +1461,49 @@ void CConfigManager::loadConfigLoadVars() {
// paths // paths
configPaths.clear(); 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; if (!std::filesystem::is_directory(configPath)) {
Debug::log(WARN, "Creating config home directory");
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;
}
configPaths.push_back(CONFIGPATH);
std::ifstream ifs;
ifs.open(CONFIGPATH);
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 { try {
std::filesystem::rename(CONFIGPATH, CONFIGPATH + ".backup"); std::filesystem::create_directories(configPath);
} catch (...) { /* Probably doesn't exist */
}
try {
if (!std::filesystem::is_directory(CONFIGPARENTPATH))
std::filesystem::create_directories(CONFIGPARENTPATH);
} catch (...) { } catch (...) {
parseError = "Broken config file! (Could not create directory)"; parseError = "Broken config file! (Could not create config directory)";
return; return;
} }
} }
if (!std::filesystem::exists(mainConfigPath)) {
Debug::log(WARN, "No config file found; attempting to generate.");
std::ofstream ofs; std::ofstream ofs;
ofs.open(CONFIGPATH, std::ios::trunc); ofs.open(mainConfigPath, std::ios::trunc);
ofs << AUTOCONFIG; ofs << AUTOCONFIG;
ofs.close();
}
std::ifstream ifs;
ifs.open(mainConfigPath);
if (!ifs.good()) {
Debug::log(WARN, "Config reading error. Attempting to generate, backing up old one if exists");
ifs.close();
if (std::filesystem::exists(mainConfigPath))
std::filesystem::rename(mainConfigPath, mainConfigPath + ".backup");
// Create default config
std::ofstream ofs;
ofs.open(mainConfigPath, std::ios::trunc);
ofs << AUTOCONFIG;
ofs.close(); ofs.close();
ifs.open(CONFIGPATH); // Try to re-open
ifs.open(mainConfigPath);
if (!ifs.good()) { if (!ifs.good()) {
parseError = "Broken config file! (Could not open)"; parseError = "Broken config file! (Could not open)";
return; return;
@ -1509,17 +1516,16 @@ void CConfigManager::loadConfigLoadVars() {
while (std::getline(ifs, line)) { while (std::getline(ifs, line)) {
// Read line by line. // Read line by line.
try { try {
configCurrentPath = "~/.config/hypr/hyprland.conf";
parseLine(line); parseLine(line);
} catch (...) { } catch (...) {
Debug::log(ERR, "Error reading line from config. Line:"); Debug::log(ERR, "Error reading line from config. Line:");
Debug::log(NONE, "%s", line.c_str()); 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) { 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; ++linenum;
@ -1546,7 +1552,7 @@ void CConfigManager::loadConfigLoadVars() {
if (parseError != "") if (parseError != "")
g_pHyprError->queueCreate(parseError + "\nHyprland may not work correctly.", CColor(1.0, 50.0 / 255.0, 50.0 / 255.0, 1.0)); 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) 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)); CColor(1.0, 1.0, 70.0 / 255.0, 1.0));
else else
g_pHyprError->destroy(); g_pHyprError->destroy();
@ -1608,14 +1614,7 @@ void CConfigManager::loadConfigLoadVars() {
} }
void CConfigManager::tick() { void CConfigManager::tick() {
std::string CONFIGPATH; std::string CONFIGPATH = getMainConfigPath();
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;
}
if (!std::filesystem::exists(CONFIGPATH)) { if (!std::filesystem::exists(CONFIGPATH)) {
Debug::log(ERR, "Config doesn't exist??"); Debug::log(ERR, "Config doesn't exist??");
return; return;

View file

@ -175,6 +175,8 @@ class CConfigManager {
SConfigValue* getConfigValuePtr(const std::string&); SConfigValue* getConfigValuePtr(const std::string&);
SConfigValue* getConfigValuePtrSafe(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 = ""); SMonitorRule getMonitorRuleFor(const std::string&, const std::string& displayName = "");
SWorkspaceRule getWorkspaceRuleFor(CWorkspace*); SWorkspaceRule getWorkspaceRuleFor(CWorkspace*);

View file

@ -339,7 +339,7 @@ void CHyprOpenGLImpl::applyScreenShader(const std::string& path) {
if (path == "" || path == STRVAL_EMPTY) if (path == "" || path == STRVAL_EMPTY)
return; return;
std::ifstream infile(absolutePath(path, std::string(getenv("HOME")) + "/.config/hypr")); std::ifstream infile(absolutePath(path, g_pConfigManager->getConfigDir()));
if (!infile.good()) { if (!infile.good()) {
g_pConfigManager->addParseError("Screen shader parser: Screen shader path not found"); g_pConfigManager->addParseError("Screen shader parser: Screen shader path not found");