diff --git a/src/config/ConfigDescriptions.hpp b/src/config/ConfigDescriptions.hpp index 483f1f1f13a..8706c415177 100644 --- a/src/config/ConfigDescriptions.hpp +++ b/src/config/ConfigDescriptions.hpp @@ -1040,6 +1040,12 @@ inline static const std::vector CONFIG_OPTIONS = { .type = CONFIG_OPTION_BOOL, .data = SConfigOptionDescription::SBoolData{false}, }, + SConfigOptionDescription{ + .value = "misc:watch_symlinks", + .description = "If true and the config is a symlink, it will be reloaded when the symlink changes, not when the pointed file changes.", + .type = CONFIG_OPTION_BOOL, + .data = SConfigOptionDescription::SBoolData{false}, + }, SConfigOptionDescription{ .value = "misc:enable_swallow", .description = "Enable window swallowing", diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 047c58d94c2..8b849fbf8da 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -411,6 +411,7 @@ CConfigManager::CConfigManager() { m_pConfig->addConfigValue("misc:animate_manual_resizes", Hyprlang::INT{0}); m_pConfig->addConfigValue("misc:animate_mouse_windowdragging", Hyprlang::INT{0}); m_pConfig->addConfigValue("misc:disable_autoreload", Hyprlang::INT{0}); + m_pConfig->addConfigValue("misc:watch_symlinks", Hyprlang::INT{0}); m_pConfig->addConfigValue("misc:enable_swallow", Hyprlang::INT{0}); m_pConfig->addConfigValue("misc:swallow_regex", {STRVAL_EMPTY}); m_pConfig->addConfigValue("misc:swallow_exception_regex", {STRVAL_EMPTY}); @@ -914,7 +915,8 @@ std::optional CConfigManager::resetHLConfig() { void CConfigManager::updateWatcher() { static const auto PDISABLEAUTORELOAD = CConfigValue("misc:disable_autoreload"); - g_pConfigWatcher->setWatchList(*PDISABLEAUTORELOAD ? std::vector{} : m_configPaths); + static const auto WATCHSYMLINKS = CConfigValue("misc:watch_symlinks"); + g_pConfigWatcher->setWatchList(*PDISABLEAUTORELOAD ? std::vector{} : m_configPaths, *WATCHSYMLINKS); } void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { diff --git a/src/config/ConfigWatcher.cpp b/src/config/ConfigWatcher.cpp index c0a9c5917b8..252d79168cb 100644 --- a/src/config/ConfigWatcher.cpp +++ b/src/config/ConfigWatcher.cpp @@ -29,7 +29,7 @@ int CConfigWatcher::getInotifyFD() { return m_inotifyFd; } -void CConfigWatcher::setWatchList(const std::vector& paths) { +void CConfigWatcher::setWatchList(const std::vector& paths, const bool watchSymlinks) { // we clear all watches first, because whichever fired is now invalid // or that is at least what it seems to be. @@ -46,7 +46,7 @@ void CConfigWatcher::setWatchList(const std::vector& paths) { // add new paths for (const auto& path : paths) { m_watches.emplace_back(SInotifyWatch{ - .wd = inotify_add_watch(m_inotifyFd, path.c_str(), IN_MODIFY), + .wd = inotify_add_watch(m_inotifyFd, path.c_str(), IN_MODIFY | (watchSymlinks ? IN_DONT_FOLLOW : 0)), .file = path, }); } diff --git a/src/config/ConfigWatcher.hpp b/src/config/ConfigWatcher.hpp index c36ecd17663..0454b3ec884 100644 --- a/src/config/ConfigWatcher.hpp +++ b/src/config/ConfigWatcher.hpp @@ -14,7 +14,7 @@ class CConfigWatcher { }; int getInotifyFD(); - void setWatchList(const std::vector& paths); + void setWatchList(const std::vector& paths, const bool watchSymlinks); void setOnChange(const std::function& fn); void onInotifyEvent(); @@ -29,4 +29,4 @@ class CConfigWatcher { int m_inotifyFd = -1; }; -inline UP g_pConfigWatcher = makeUnique(); \ No newline at end of file +inline UP g_pConfigWatcher = makeUnique(); diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 359428b1af5..b81f86a8c44 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -1100,7 +1100,7 @@ static std::string dispatchKeyword(eHyprCtlOutputFormat format, std::string in) } } - if (COMMAND.contains("misc:disable_autoreload")) + if (COMMAND.contains("misc:disable_autoreload") || COMMAND.contains("misc:watch_symlinks")) g_pConfigManager->updateWatcher(); // decorations will probably need a repaint