hyprpaper/src/config/ConfigManager.cpp

217 lines
7.1 KiB
C++
Raw Normal View History

2022-07-01 23:05:58 +02:00
#include "ConfigManager.hpp"
#include "../Hyprpaper.hpp"
#include <hyprutils/path/Path.hpp>
2022-07-01 23:05:58 +02:00
static Hyprlang::CParseResult handleWallpaper(const char* C, const char* V) {
const std::string COMMAND = C;
const std::string VALUE = V;
Hyprlang::CParseResult result;
2022-07-01 23:05:58 +02:00
if (VALUE.find_first_of(',') == std::string::npos) {
result.setError("wallpaper failed (syntax)");
return result;
2022-07-01 23:05:58 +02:00
}
auto MONITOR = VALUE.substr(0, VALUE.find_first_of(','));
auto WALLPAPER = g_pConfigManager->trimPath(VALUE.substr(VALUE.find_first_of(',') + 1));
2022-07-01 23:05:58 +02:00
2022-08-03 18:06:33 +02:00
bool contain = false;
if (WALLPAPER.find("contain:") == 0) {
WALLPAPER = WALLPAPER.substr(8);
contain = true;
}
if (WALLPAPER[0] == '~') {
static const char* const ENVHOME = getenv("HOME");
WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1);
}
std::error_code ec;
if (!std::filesystem::exists(WALLPAPER, ec)) {
result.setError((std::string{"wallpaper failed ("} + (ec ? ec.message() : std::string{"no such file"}) + std::string{": "} + WALLPAPER + std::string{")"}).c_str());
return result;
2022-07-01 23:05:58 +02:00
}
if (std::find(g_pConfigManager->m_dRequestedPreloads.begin(), g_pConfigManager->m_dRequestedPreloads.end(), WALLPAPER) == g_pConfigManager->m_dRequestedPreloads.end() && !g_pHyprpaper->isPreloaded(WALLPAPER)) {
result.setError("wallpaper failed (not preloaded)");
return result;
2022-07-01 23:05:58 +02:00
}
2024-02-27 21:45:28 +00:00
g_pHyprpaper->clearWallpaperFromMonitor(MONITOR);
g_pHyprpaper->m_mMonitorActiveWallpapers[MONITOR] = WALLPAPER;
g_pHyprpaper->m_mMonitorWallpaperRenderData[MONITOR].contain = contain;
if (MONITOR.empty()) {
2024-01-03 13:47:49 +01:00
for (auto& m : g_pHyprpaper->m_vMonitors) {
if (!m->hasATarget || m->wildcard) {
g_pHyprpaper->clearWallpaperFromMonitor(m->name);
g_pHyprpaper->m_mMonitorActiveWallpapers[m->name] = WALLPAPER;
g_pHyprpaper->m_mMonitorWallpaperRenderData[m->name].contain = contain;
}
}
2024-02-27 21:45:28 +00:00
} else {
const auto PMON = g_pHyprpaper->getMonitorFromName(MONITOR);
if (PMON)
PMON->wildcard = false;
2024-01-03 13:47:49 +01:00
}
return result;
2022-07-01 23:05:58 +02:00
}
static Hyprlang::CParseResult handlePreload(const char* C, const char* V) {
const std::string COMMAND = C;
const std::string VALUE = V;
2022-07-01 23:05:58 +02:00
auto WALLPAPER = VALUE;
if (WALLPAPER[0] == '~') {
static const char* const ENVHOME = getenv("HOME");
WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1);
}
std::error_code ec;
if (!std::filesystem::exists(WALLPAPER, ec)) {
Hyprlang::CParseResult result;
result.setError(((ec ? ec.message() : std::string{"no such file"}) + std::string{": "} + WALLPAPER).c_str());
return result;
2022-07-01 23:05:58 +02:00
}
g_pConfigManager->m_dRequestedPreloads.emplace_back(WALLPAPER);
2022-07-17 14:17:54 +02:00
return Hyprlang::CParseResult{};
2022-07-17 14:17:54 +02:00
}
2022-11-26 18:27:19 +00:00
static Hyprlang::CParseResult handleUnloadAll(const char* C, const char* V) {
const std::string COMMAND = C;
const std::string VALUE = V;
2022-11-28 11:43:08 +00:00
std::vector<std::string> toUnload;
for (auto& [name, target] : g_pHyprpaper->m_mWallpaperTargets) {
2024-02-27 21:45:28 +00:00
if (VALUE == "unused") {
bool exists = false;
for (auto& [mon, target2] : g_pHyprpaper->m_mMonitorActiveWallpaperTargets) {
if (&target == target2) {
exists = true;
break;
}
}
if (exists)
continue;
}
2022-11-28 11:43:08 +00:00
toUnload.emplace_back(name);
2022-11-26 18:27:19 +00:00
}
2022-11-28 11:43:08 +00:00
for (auto& tu : toUnload)
g_pHyprpaper->unloadWallpaper(tu);
return Hyprlang::CParseResult{};
}
static Hyprlang::CParseResult handleUnload(const char* C, const char* V) {
const std::string COMMAND = C;
const std::string VALUE = V;
auto WALLPAPER = VALUE;
2024-02-27 21:45:28 +00:00
if (VALUE == "all" || VALUE == "unused")
return handleUnloadAll(C, V);
if (WALLPAPER[0] == '~') {
static const char* const ENVHOME = getenv("HOME");
WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1);
}
g_pHyprpaper->unloadWallpaper(WALLPAPER);
return Hyprlang::CParseResult{};
}
static Hyprlang::CParseResult handleReload(const char* C, const char* V) {
const std::string COMMAND = C;
const std::string VALUE = V;
auto WALLPAPER = g_pConfigManager->trimPath(VALUE.substr(VALUE.find_first_of(',') + 1));
if (WALLPAPER.find("contain:") == 0) {
WALLPAPER = WALLPAPER.substr(8);
}
auto preloadResult = handlePreload(C, WALLPAPER.c_str());
if (preloadResult.error)
return preloadResult;
auto MONITOR = VALUE.substr(0, VALUE.find_first_of(','));
if (MONITOR.empty()) {
for (auto& m : g_pHyprpaper->m_vMonitors) {
auto OLD_WALLPAPER = g_pHyprpaper->m_mMonitorActiveWallpapers[m->name];
g_pHyprpaper->unloadWallpaper(OLD_WALLPAPER);
}
} else {
auto OLD_WALLPAPER = g_pHyprpaper->m_mMonitorActiveWallpapers[MONITOR];
g_pHyprpaper->unloadWallpaper(OLD_WALLPAPER);
}
auto wallpaperResult = handleWallpaper(C, V);
if (wallpaperResult.error)
return wallpaperResult;
return Hyprlang::CParseResult{};
}
CConfigManager::CConfigManager() {
// Initialize the configuration
// Read file from default location
// or from an explicit location given by user
std::string configPath = getMainConfigPath();
config = std::make_unique<Hyprlang::CConfig>(configPath.c_str(), Hyprlang::SConfigOptions{.allowMissingConfig = true});
config->addConfigValue("ipc", Hyprlang::INT{1L});
config->addConfigValue("splash", Hyprlang::INT{0L});
config->addConfigValue("splash_offset", Hyprlang::FLOAT{2.F});
config->addConfigValue("splash_color", Hyprlang::INT{0x55ffffff});
config->registerHandler(&handleWallpaper, "wallpaper", {.allowFlags = false});
config->registerHandler(&handleUnload, "unload", {.allowFlags = false});
config->registerHandler(&handlePreload, "preload", {.allowFlags = false});
config->registerHandler(&handleUnloadAll, "unloadAll", {.allowFlags = false});
config->registerHandler(&handleReload, "reload", {.allowFlags = false});
config->commence();
}
void CConfigManager::parse() {
const auto ERROR = config->parse();
if (ERROR.error)
std::cout << "Error in config: \n"
<< ERROR.getError() << "\n";
}
std::string CConfigManager::getMainConfigPath() {
if (!g_pHyprpaper->m_szExplicitConfigPath.empty())
return g_pHyprpaper->m_szExplicitConfigPath;
static const auto paths = Hyprutils::Path::findConfig("hyprpaper");
if (paths.first.has_value())
return paths.first.value();
else
throw std::runtime_error("Could not find config in HOME, XDG_CONFIG_HOME, XDG_CONFIG_DIRS or /etc/hypr.");
2022-11-26 18:27:19 +00:00
}
// trim from both ends
std::string CConfigManager::trimPath(std::string path) {
2023-12-24 01:12:34 +08:00
if (path.empty())
return "";
// trims whitespaces, tabs and new line feeds
size_t pathStartIndex = path.find_first_not_of(" \t\r\n");
size_t pathEndIndex = path.find_last_not_of(" \t\r\n");
return path.substr(pathStartIndex, pathEndIndex - pathStartIndex + 1);
2023-01-05 00:50:01 +03:00
}