2022-07-01 23:05:58 +02:00
|
|
|
#include "ConfigManager.hpp"
|
|
|
|
|
#include "../Hyprpaper.hpp"
|
|
|
|
|
|
|
|
|
|
CConfigManager::CConfigManager() {
|
2022-10-11 19:46:36 +02:00
|
|
|
// Initialize the configuration
|
|
|
|
|
// Read file from default location
|
|
|
|
|
// or from an explicit location given by user
|
2022-07-01 23:05:58 +02:00
|
|
|
|
2022-09-28 12:29:33 +09:00
|
|
|
std::string configPath;
|
2022-09-30 12:18:26 +02:00
|
|
|
if (g_pHyprpaper->m_szExplicitConfigPath.empty()) {
|
2022-10-11 19:46:36 +02:00
|
|
|
const char* const ENVHOME = getenv("HOME");
|
|
|
|
|
configPath = ENVHOME + std::string("/.config/hypr/hyprpaper.conf");
|
|
|
|
|
} else {
|
2022-09-28 12:29:33 +09:00
|
|
|
configPath = g_pHyprpaper->m_szExplicitConfigPath;
|
2022-09-27 09:31:25 +09:00
|
|
|
}
|
2022-07-01 23:05:58 +02:00
|
|
|
|
|
|
|
|
std::ifstream ifs;
|
2022-09-28 12:29:33 +09:00
|
|
|
ifs.open(configPath);
|
2022-07-01 23:05:58 +02:00
|
|
|
|
|
|
|
|
if (!ifs.good()) {
|
2022-10-11 19:46:36 +02:00
|
|
|
if (g_pHyprpaper->m_szExplicitConfigPath.empty()) {
|
2022-10-12 17:11:57 +02:00
|
|
|
Debug::log(CRIT, "No config file provided. Default config file `~/.config/hypr/hyprpaper.conf` couldn't be opened.");
|
2022-10-11 19:46:36 +02:00
|
|
|
} else {
|
|
|
|
|
Debug::log(CRIT, "No config file provided. Specified file `%s` couldn't be opened.", configPath);
|
|
|
|
|
}
|
2022-07-01 23:05:58 +02:00
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string line = "";
|
|
|
|
|
int linenum = 1;
|
|
|
|
|
if (ifs.is_open()) {
|
|
|
|
|
while (std::getline(ifs, line)) {
|
2022-10-11 19:46:36 +02:00
|
|
|
// Read line by line
|
2022-10-12 15:24:29 +02:00
|
|
|
try {
|
|
|
|
|
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) + ": Line parsing error.";
|
|
|
|
|
}
|
2022-07-01 23:05:58 +02:00
|
|
|
|
2022-10-11 19:46:36 +02:00
|
|
|
if (!parseError.empty()) {
|
2022-07-01 23:05:58 +02:00
|
|
|
parseError = "Config error at line " + std::to_string(linenum) + ": " + parseError;
|
2022-10-11 19:46:36 +02:00
|
|
|
break;
|
2022-07-01 23:05:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
++linenum;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ifs.close();
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-30 12:18:26 +02:00
|
|
|
if (!parseError.empty()) {
|
2022-07-01 23:05:58 +02:00
|
|
|
Debug::log(CRIT, "Exiting because of config parse errors!\n%s", parseError.c_str());
|
|
|
|
|
exit(1);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string CConfigManager::removeBeginEndSpacesTabs(std::string str) {
|
|
|
|
|
while (str[0] == ' ' || str[0] == '\t') {
|
|
|
|
|
str = str.substr(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (str.length() != 0 && (str[str.length() - 1] == ' ' || str[str.length() - 1] == '\t')) {
|
|
|
|
|
str = str.substr(0, str.length() - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CConfigManager::parseLine(std::string& line) {
|
2022-10-12 15:24:29 +02:00
|
|
|
// first check if its not a comment
|
2022-07-01 23:05:58 +02:00
|
|
|
const auto COMMENTSTART = line.find_first_of('#');
|
|
|
|
|
if (COMMENTSTART == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
2022-10-12 15:24:29 +02:00
|
|
|
// now, cut the comment off
|
2022-07-01 23:05:58 +02:00
|
|
|
if (COMMENTSTART != std::string::npos)
|
|
|
|
|
line = line.substr(0, COMMENTSTART);
|
|
|
|
|
|
2022-10-11 19:46:36 +02:00
|
|
|
// Strip line
|
2022-07-01 23:05:58 +02:00
|
|
|
while (line[0] == ' ' || line[0] == '\t') {
|
|
|
|
|
line = line.substr(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// And parse
|
|
|
|
|
// check if command
|
|
|
|
|
const auto EQUALSPLACE = line.find_first_of('=');
|
|
|
|
|
|
|
|
|
|
if (EQUALSPLACE == std::string::npos)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
const auto COMMAND = removeBeginEndSpacesTabs(line.substr(0, EQUALSPLACE));
|
|
|
|
|
const auto VALUE = removeBeginEndSpacesTabs(line.substr(EQUALSPLACE + 1));
|
|
|
|
|
|
|
|
|
|
parseKeyword(COMMAND, VALUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CConfigManager::parseKeyword(const std::string& COMMAND, const std::string& VALUE) {
|
|
|
|
|
if (COMMAND == "wallpaper")
|
|
|
|
|
handleWallpaper(COMMAND, VALUE);
|
|
|
|
|
else if (COMMAND == "preload")
|
|
|
|
|
handlePreload(COMMAND, VALUE);
|
2022-07-17 14:17:54 +02:00
|
|
|
else if (COMMAND == "unload")
|
|
|
|
|
handleUnload(COMMAND, VALUE);
|
2022-07-31 17:28:37 +02:00
|
|
|
else if (COMMAND == "ipc")
|
|
|
|
|
g_pHyprpaper->m_bIPCEnabled = VALUE == "1" || VALUE == "yes" || VALUE == "on" || VALUE == "true";
|
2022-07-01 23:05:58 +02:00
|
|
|
else
|
|
|
|
|
parseError = "unknown keyword " + COMMAND;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CConfigManager::handleWallpaper(const std::string& COMMAND, const std::string& VALUE) {
|
2022-11-26 18:27:19 +00:00
|
|
|
if (VALUE == "all") {
|
|
|
|
|
handleUnloadAll(COMMAND, VALUE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-01 23:05:58 +02:00
|
|
|
if (VALUE.find_first_of(',') == std::string::npos) {
|
|
|
|
|
parseError = "wallpaper failed (syntax)";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto MONITOR = VALUE.substr(0, VALUE.find_first_of(','));
|
|
|
|
|
auto WALLPAPER = VALUE.substr(VALUE.find_first_of(',') + 1);
|
|
|
|
|
|
2022-08-03 18:06:33 +02:00
|
|
|
bool contain = false;
|
|
|
|
|
|
|
|
|
|
if (WALLPAPER.find("contain:") == 0) {
|
|
|
|
|
WALLPAPER = WALLPAPER.substr(8);
|
|
|
|
|
contain = true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-01 15:40:50 -04:00
|
|
|
if (WALLPAPER[0] == '~') {
|
|
|
|
|
static const char* const ENVHOME = getenv("HOME");
|
|
|
|
|
WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1);
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-01 23:05:58 +02:00
|
|
|
if (!std::filesystem::exists(WALLPAPER)) {
|
|
|
|
|
parseError = "wallpaper failed (no such file)";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-02 18:26:59 +02:00
|
|
|
if (std::find(m_dRequestedPreloads.begin(), m_dRequestedPreloads.end(), WALLPAPER) == m_dRequestedPreloads.end() && !g_pHyprpaper->isPreloaded(WALLPAPER)) {
|
2022-07-01 23:05:58 +02:00
|
|
|
parseError = "wallpaper failed (not preloaded)";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-02 18:26:59 +02:00
|
|
|
g_pHyprpaper->clearWallpaperFromMonitor(MONITOR);
|
2022-07-01 23:05:58 +02:00
|
|
|
g_pHyprpaper->m_mMonitorActiveWallpapers[MONITOR] = WALLPAPER;
|
2022-08-03 18:06:33 +02:00
|
|
|
g_pHyprpaper->m_mMonitorWallpaperRenderData[MONITOR].contain = contain;
|
2022-07-01 23:05:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CConfigManager::handlePreload(const std::string& COMMAND, const std::string& VALUE) {
|
|
|
|
|
auto WALLPAPER = VALUE;
|
|
|
|
|
|
|
|
|
|
if (WALLPAPER[0] == '~') {
|
|
|
|
|
static const char* const ENVHOME = getenv("HOME");
|
|
|
|
|
WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!std::filesystem::exists(WALLPAPER)) {
|
|
|
|
|
parseError = "preload failed (no such file)";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_dRequestedPreloads.emplace_back(WALLPAPER);
|
|
|
|
|
}
|
2022-07-17 14:17:54 +02:00
|
|
|
|
|
|
|
|
void CConfigManager::handleUnload(const std::string& COMMAND, const std::string& VALUE) {
|
|
|
|
|
auto WALLPAPER = VALUE;
|
|
|
|
|
|
|
|
|
|
if (WALLPAPER[0] == '~') {
|
|
|
|
|
static const char* const ENVHOME = getenv("HOME");
|
|
|
|
|
WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_pHyprpaper->unloadWallpaper(WALLPAPER);
|
|
|
|
|
}
|
2022-11-26 18:27:19 +00:00
|
|
|
|
|
|
|
|
void CConfigManager::handleUnloadAll(const std::string& COMMAND, const std::string& VALUE) {
|
|
|
|
|
for (auto&[name, target] : g_pHyprpaper->m_mWallpaperTargets) {
|
|
|
|
|
|
|
|
|
|
bool exists = false;
|
|
|
|
|
for (auto&[mon, target2] : g_pHyprpaper->m_mMonitorActiveWallpaperTargets) {
|
|
|
|
|
if (&target == target2) {
|
|
|
|
|
exists = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (exists)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
g_pHyprpaper->unloadWallpaper(name);
|
|
|
|
|
}
|
|
|
|
|
}
|