2022-07-01 23:05:58 +02:00
|
|
|
#include "ConfigManager.hpp"
|
|
|
|
|
#include "../Hyprpaper.hpp"
|
2024-07-17 17:21:50 +03:00
|
|
|
#include <hyprutils/path/Path.hpp>
|
2024-07-17 16:25:07 +02:00
|
|
|
#include <filesystem>
|
2022-07-01 23:05:58 +02:00
|
|
|
|
2023-12-31 01:37:50 +01: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) {
|
2023-12-31 01:37:50 +01:00
|
|
|
result.setError("wallpaper failed (syntax)");
|
|
|
|
|
return result;
|
2022-07-01 23:05:58 +02:00
|
|
|
}
|
|
|
|
|
|
2024-07-17 16:25:07 +02:00
|
|
|
auto MONITOR = VALUE.substr(0, VALUE.find_first_of(','));
|
2023-12-31 01:37:50 +01:00
|
|
|
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);
|
2024-07-17 16:25:07 +02:00
|
|
|
contain = true;
|
2022-08-03 18:06:33 +02:00
|
|
|
}
|
|
|
|
|
|
2022-11-01 15:40:50 -04:00
|
|
|
if (WALLPAPER[0] == '~') {
|
|
|
|
|
static const char* const ENVHOME = getenv("HOME");
|
2024-07-17 16:25:07 +02:00
|
|
|
WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1);
|
2022-11-01 15:40:50 -04:00
|
|
|
}
|
|
|
|
|
|
2024-06-09 10:50:27 +03:00
|
|
|
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());
|
2023-12-31 01:37:50 +01:00
|
|
|
return result;
|
2022-07-01 23:05:58 +02:00
|
|
|
}
|
|
|
|
|
|
2024-07-17 16:25:07 +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)) {
|
2023-12-31 01:37:50 +01:00
|
|
|
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);
|
2024-07-17 16:25:07 +02:00
|
|
|
g_pHyprpaper->m_mMonitorActiveWallpapers[MONITOR] = WALLPAPER;
|
2024-02-27 21:45:28 +00:00
|
|
|
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);
|
2024-07-17 16:25:07 +02:00
|
|
|
g_pHyprpaper->m_mMonitorActiveWallpapers[m->name] = WALLPAPER;
|
2024-01-03 13:47:49 +01:00
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2023-12-31 01:37:50 +01:00
|
|
|
return result;
|
2022-07-01 23:05:58 +02:00
|
|
|
}
|
|
|
|
|
|
2023-12-31 01:37:50 +01:00
|
|
|
static Hyprlang::CParseResult handlePreload(const char* C, const char* V) {
|
2024-07-17 16:25:07 +02:00
|
|
|
const std::string COMMAND = C;
|
|
|
|
|
const std::string VALUE = V;
|
|
|
|
|
auto WALLPAPER = VALUE;
|
2022-07-01 23:05:58 +02:00
|
|
|
|
|
|
|
|
if (WALLPAPER[0] == '~') {
|
|
|
|
|
static const char* const ENVHOME = getenv("HOME");
|
2024-07-17 16:25:07 +02:00
|
|
|
WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1);
|
2022-07-01 23:05:58 +02:00
|
|
|
}
|
|
|
|
|
|
2024-06-09 10:50:27 +03:00
|
|
|
std::error_code ec;
|
|
|
|
|
|
|
|
|
|
if (!std::filesystem::exists(WALLPAPER, ec)) {
|
2023-12-31 01:37:50 +01:00
|
|
|
Hyprlang::CParseResult result;
|
2024-06-09 10:50:27 +03:00
|
|
|
result.setError(((ec ? ec.message() : std::string{"no such file"}) + std::string{": "} + WALLPAPER).c_str());
|
2023-12-31 01:37:50 +01:00
|
|
|
return result;
|
2022-07-01 23:05:58 +02:00
|
|
|
}
|
|
|
|
|
|
2023-12-31 01:37:50 +01:00
|
|
|
g_pConfigManager->m_dRequestedPreloads.emplace_back(WALLPAPER);
|
2022-07-17 14:17:54 +02:00
|
|
|
|
2023-12-31 01:37:50 +01:00
|
|
|
return Hyprlang::CParseResult{};
|
2022-07-17 14:17:54 +02:00
|
|
|
}
|
2022-11-26 18:27:19 +00:00
|
|
|
|
2023-12-31 01:37:50 +01:00
|
|
|
static Hyprlang::CParseResult handleUnloadAll(const char* C, const char* V) {
|
2024-07-17 16:25:07 +02:00
|
|
|
const std::string COMMAND = C;
|
|
|
|
|
const std::string VALUE = V;
|
2022-11-28 11:43:08 +00:00
|
|
|
std::vector<std::string> toUnload;
|
|
|
|
|
|
2023-07-16 18:44:16 -04:00
|
|
|
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);
|
2023-12-31 01:37:50 +01:00
|
|
|
|
|
|
|
|
return Hyprlang::CParseResult{};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Hyprlang::CParseResult handleUnload(const char* C, const char* V) {
|
2024-07-17 16:25:07 +02:00
|
|
|
const std::string COMMAND = C;
|
|
|
|
|
const std::string VALUE = V;
|
|
|
|
|
auto WALLPAPER = VALUE;
|
2023-12-31 01:37:50 +01:00
|
|
|
|
2024-02-27 21:45:28 +00:00
|
|
|
if (VALUE == "all" || VALUE == "unused")
|
2023-12-31 01:37:50 +01:00
|
|
|
return handleUnloadAll(C, V);
|
|
|
|
|
|
|
|
|
|
if (WALLPAPER[0] == '~') {
|
|
|
|
|
static const char* const ENVHOME = getenv("HOME");
|
2024-07-17 16:25:07 +02:00
|
|
|
WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1);
|
2023-12-31 01:37:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_pHyprpaper->unloadWallpaper(WALLPAPER);
|
|
|
|
|
|
|
|
|
|
return Hyprlang::CParseResult{};
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-26 03:40:11 +10:00
|
|
|
static Hyprlang::CParseResult handleReload(const char* C, const char* V) {
|
|
|
|
|
const std::string COMMAND = C;
|
2024-07-17 16:25:07 +02:00
|
|
|
const std::string VALUE = V;
|
2024-05-26 03:40:11 +10:00
|
|
|
|
2024-07-17 16:25:07 +02:00
|
|
|
auto WALLPAPER = g_pConfigManager->trimPath(VALUE.substr(VALUE.find_first_of(',') + 1));
|
2024-05-26 03:40:11 +10:00
|
|
|
|
|
|
|
|
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{};
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-31 01:37:50 +01:00
|
|
|
CConfigManager::CConfigManager() {
|
|
|
|
|
// Initialize the configuration
|
|
|
|
|
// Read file from default location
|
|
|
|
|
// or from an explicit location given by user
|
|
|
|
|
|
|
|
|
|
std::string configPath = getMainConfigPath();
|
|
|
|
|
|
2024-01-01 13:34:50 +01:00
|
|
|
config = std::make_unique<Hyprlang::CConfig>(configPath.c_str(), Hyprlang::SConfigOptions{.allowMissingConfig = true});
|
2023-12-31 01:37:50 +01:00
|
|
|
|
2024-02-21 16:28:39 +00:00
|
|
|
config->addConfigValue("ipc", Hyprlang::INT{1L});
|
|
|
|
|
config->addConfigValue("splash", Hyprlang::INT{0L});
|
|
|
|
|
config->addConfigValue("splash_offset", Hyprlang::FLOAT{2.F});
|
2024-04-04 21:52:48 +02:00
|
|
|
config->addConfigValue("splash_color", Hyprlang::INT{0x55ffffff});
|
2023-12-31 01:37:50 +01:00
|
|
|
|
|
|
|
|
config->registerHandler(&handleWallpaper, "wallpaper", {.allowFlags = false});
|
|
|
|
|
config->registerHandler(&handleUnload, "unload", {.allowFlags = false});
|
|
|
|
|
config->registerHandler(&handlePreload, "preload", {.allowFlags = false});
|
|
|
|
|
config->registerHandler(&handleUnloadAll, "unloadAll", {.allowFlags = false});
|
2024-05-26 03:40:11 +10:00
|
|
|
config->registerHandler(&handleReload, "reload", {.allowFlags = false});
|
2023-12-31 01:37:50 +01:00
|
|
|
|
|
|
|
|
config->commence();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CConfigManager::parse() {
|
|
|
|
|
const auto ERROR = config->parse();
|
|
|
|
|
|
|
|
|
|
if (ERROR.error)
|
2024-07-17 16:25:07 +02:00
|
|
|
std::cout << "Error in config: \n" << ERROR.getError() << "\n";
|
2023-12-31 01:37:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string CConfigManager::getMainConfigPath() {
|
|
|
|
|
if (!g_pHyprpaper->m_szExplicitConfigPath.empty())
|
|
|
|
|
return g_pHyprpaper->m_szExplicitConfigPath;
|
|
|
|
|
|
2024-07-17 17:21:50 +03:00
|
|
|
static const auto paths = Hyprutils::Path::findConfig("hyprpaper");
|
|
|
|
|
if (paths.first.has_value())
|
|
|
|
|
return paths.first.value();
|
2023-12-31 01:37:50 +01:00
|
|
|
else
|
2024-07-17 17:21:50 +03:00
|
|
|
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
|
|
|
}
|
2023-01-03 15:09:20 +03:00
|
|
|
|
|
|
|
|
// trim from both ends
|
|
|
|
|
std::string CConfigManager::trimPath(std::string path) {
|
2023-12-24 01:12:34 +08:00
|
|
|
if (path.empty())
|
|
|
|
|
return "";
|
|
|
|
|
|
2023-07-16 18:44:16 -04:00
|
|
|
// trims whitespaces, tabs and new line feeds
|
2023-01-03 15:09:20 +03:00
|
|
|
size_t pathStartIndex = path.find_first_not_of(" \t\r\n");
|
2024-07-17 16:25:07 +02:00
|
|
|
size_t pathEndIndex = path.find_last_not_of(" \t\r\n");
|
2023-01-03 15:09:20 +03:00
|
|
|
return path.substr(pathStartIndex, pathEndIndex - pathStartIndex + 1);
|
2023-01-05 00:50:01 +03:00
|
|
|
}
|