mirror of
https://github.com/hyprwm/Hyprland.git
synced 2026-08-24 10:04:19 -05:00
hyprctl: add config full-reload for performing a ground-up reload (#14748)
allows to switch to/from lua at runtime
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
#include "ConfigValue.hpp"
|
||||
#include "ConfigManager.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
void local__configValuePopulate(void* const** p, void* const** hlangp, std::type_index* ti, const std::string& val) {
|
||||
const auto BIGP = Config::mgr()->getConfigValue(val);
|
||||
|
||||
@@ -18,4 +20,37 @@ void local__configValuePopulate(void* const** p, void* const** hlangp, std::type
|
||||
std::type_index local__configValueTypeIdx(const std::string& val) {
|
||||
const auto BIGP = Config::mgr()->getConfigValue(val);
|
||||
return std::type_index(*BIGP.type);
|
||||
}
|
||||
}
|
||||
|
||||
CConfigValueBase::CConfigValueBase() {
|
||||
registry().emplace_back(this);
|
||||
}
|
||||
|
||||
CConfigValueBase::~CConfigValueBase() {
|
||||
std::erase(registry(), this);
|
||||
}
|
||||
|
||||
void CConfigValueBase::populateFromName() {
|
||||
m_p = nullptr;
|
||||
m_hlangp = nullptr;
|
||||
m_typeIndex = typeid(void);
|
||||
if (!m_valueName.empty())
|
||||
local__configValuePopulate(&m_p, &m_hlangp, &m_typeIndex, m_valueName);
|
||||
}
|
||||
|
||||
void CConfigValueBase::bindInternal(const std::string& val) {
|
||||
m_valueName = val;
|
||||
registry().push_back(this);
|
||||
populateFromName();
|
||||
}
|
||||
|
||||
std::vector<CConfigValueBase*>& CConfigValueBase::registry() {
|
||||
static std::vector<CConfigValueBase*> r;
|
||||
return r;
|
||||
}
|
||||
|
||||
void CConfigValueBase::flushCaches() {
|
||||
for (const auto& v : registry()) {
|
||||
v->bindInternal(v->m_valueName);
|
||||
}
|
||||
}
|
||||
|
||||
+24
-21
@@ -16,27 +16,35 @@
|
||||
void local__configValuePopulate(void* const** p, void* const** hlangp, std::type_index* ti, const std::string& val);
|
||||
std::type_index local__configValueTypeIdx(const std::string& val);
|
||||
|
||||
class CConfigValueBase {
|
||||
protected:
|
||||
std::string m_valueName;
|
||||
void* const* m_p = nullptr;
|
||||
void* const* m_hlangp = nullptr;
|
||||
std::type_index m_typeIndex = typeid(void);
|
||||
|
||||
CConfigValueBase();
|
||||
~CConfigValueBase();
|
||||
|
||||
void populateFromName();
|
||||
void bindInternal(const std::string& val);
|
||||
|
||||
public:
|
||||
static std::vector<CConfigValueBase*>& registry();
|
||||
static void flushCaches();
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class CConfigValue {
|
||||
class CConfigValue : private CConfigValueBase {
|
||||
public:
|
||||
// creates an empty value. Deref'ing this will be a crash
|
||||
CConfigValue() = default;
|
||||
explicit CConfigValue(const std::string& val) {
|
||||
bind(val);
|
||||
}
|
||||
|
||||
CConfigValue(const std::string& val) {
|
||||
#ifdef HYPRLAND_DEBUG
|
||||
// verify type
|
||||
// TODO: fix this or leave it idk I'm tired.
|
||||
// const auto TYPE = local__configValueTypeIdx(val);
|
||||
|
||||
// // exceptions
|
||||
// const bool STRINGEX = (typeid(T) == typeid(std::string) && TYPE == typeid(Hyprlang::STRING));
|
||||
// const bool CUSTOMEX = ((typeid(T) == typeid(Hyprlang::CUSTOMTYPE) || typeid(T) == typeid(Config::IComplexConfigValue)) &&
|
||||
// (TYPE == typeid(Hyprlang::CUSTOMTYPE*) || TYPE == typeid(Config::IComplexConfigValue*) || TYPE == typeid(void*) /* dunno why it does this? */));
|
||||
|
||||
// RASSERT(typeid(T) == TYPE || STRINGEX || CUSTOMEX, "Mismatched type in CConfigValue<T>, got {} but has {}", typeid(T).name(), TYPE.name());
|
||||
#endif
|
||||
|
||||
local__configValuePopulate(&m_p, &m_hlangp, &m_typeIndex, val);
|
||||
void bind(const std::string& val) {
|
||||
bindInternal(val);
|
||||
}
|
||||
|
||||
T* ptr() const {
|
||||
@@ -50,11 +58,6 @@ class CConfigValue {
|
||||
bool good() const {
|
||||
return m_p || m_hlangp;
|
||||
}
|
||||
|
||||
private:
|
||||
void* const* m_p = nullptr;
|
||||
void* const* m_hlangp = nullptr;
|
||||
std::type_index m_typeIndex = typeid(void);
|
||||
};
|
||||
|
||||
template <>
|
||||
|
||||
@@ -183,7 +183,16 @@ CConfigManager::SDeviceConfig::SDeviceConfig() {
|
||||
}
|
||||
|
||||
CConfigManager::CConfigManager() : m_mainConfigPath(Supplementary::Jeremy::getMainConfigPath()->path) {
|
||||
;
|
||||
for (const auto& v : Values::CONFIG_VALUES) {
|
||||
m_configValues.emplace(luaConfigValueName(v->name()), fromGenericValue(v));
|
||||
}
|
||||
|
||||
m_configValues["autogenerated"] = fromGenericValue(makeShared<Values::CIntValue>("autogenerated", "whether the config is autogenerated or not", 0));
|
||||
|
||||
Config::watcher()->setOnChange([this](const CConfigWatcher::SConfigWatchEvent& e) {
|
||||
Log::logger->log(Log::DEBUG, "[lua] file {} modified, reloading", e.file);
|
||||
reload();
|
||||
});
|
||||
}
|
||||
|
||||
CConfigManager* CConfigManager::fromLuaState(lua_State* L) {
|
||||
@@ -330,17 +339,6 @@ void CConfigManager::reinitLuaState() {
|
||||
void CConfigManager::init() {
|
||||
reinitLuaState();
|
||||
|
||||
for (const auto& v : Values::CONFIG_VALUES) {
|
||||
m_configValues.emplace(luaConfigValueName(v->name()), fromGenericValue(v));
|
||||
}
|
||||
|
||||
m_configValues["autogenerated"] = fromGenericValue(makeShared<Values::CIntValue>("autogenerated", "whether the config is autogenerated or not", 0));
|
||||
|
||||
Config::watcher()->setOnChange([this](const CConfigWatcher::SConfigWatchEvent& e) {
|
||||
Log::logger->log(Log::DEBUG, "[lua] file {} modified, reloading", e.file);
|
||||
reload();
|
||||
});
|
||||
|
||||
reload();
|
||||
}
|
||||
|
||||
|
||||
@@ -9,11 +9,19 @@ using namespace Config;
|
||||
using namespace Config::Supplementary;
|
||||
using namespace Config::Supplementary::Jeremy;
|
||||
|
||||
static bool needsPathRecheck = false;
|
||||
|
||||
//
|
||||
void Jeremy::flushCachedCfgPath() {
|
||||
needsPathRecheck = true;
|
||||
}
|
||||
|
||||
std::expected<SConfigStateReply, std::string> Jeremy::getMainConfigPath() {
|
||||
static bool lastSafeMode = g_pCompositor->m_safeMode;
|
||||
|
||||
static auto getCfgPath = []() -> std::expected<SConfigStateReply, std::string> {
|
||||
lastSafeMode = g_pCompositor->m_safeMode;
|
||||
lastSafeMode = g_pCompositor->m_safeMode;
|
||||
needsPathRecheck = false;
|
||||
|
||||
if (g_pCompositor->m_safeMode)
|
||||
return SConfigStateReply{.path = (std::filesystem::path{g_pCompositor->m_instancePath} / "recoverycfg.conf").string(), .type = CONFIG_TYPE_SPECIAL};
|
||||
@@ -39,7 +47,7 @@ std::expected<SConfigStateReply, std::string> Jeremy::getMainConfigPath() {
|
||||
};
|
||||
static auto CONFIG_PATH = getCfgPath();
|
||||
|
||||
if (lastSafeMode != g_pCompositor->m_safeMode)
|
||||
if (lastSafeMode != g_pCompositor->m_safeMode || needsPathRecheck)
|
||||
CONFIG_PATH = getCfgPath();
|
||||
|
||||
return CONFIG_PATH;
|
||||
|
||||
@@ -18,4 +18,5 @@ namespace Config::Supplementary::Jeremy {
|
||||
};
|
||||
|
||||
std::expected<SConfigStateReply, std::string> getMainConfigPath();
|
||||
void flushCachedCfgPath();
|
||||
};
|
||||
@@ -42,6 +42,7 @@ using namespace Hyprutils::OS;
|
||||
#include "../config/shared/workspace/WorkspaceRuleManager.hpp"
|
||||
#include "../config/shared/monitor/MonitorRuleManager.hpp"
|
||||
#include "../config/shared/animation/AnimationTree.hpp"
|
||||
#include "../config/supplementary/jeremy/Jeremy.hpp"
|
||||
#include "../config/values/ConfigValues.hpp"
|
||||
#include "../managers/CursorManager.hpp"
|
||||
#include "../errorOverlay/Overlay.hpp"
|
||||
@@ -1233,6 +1234,21 @@ static std::string dispatchKeyword(eHyprCtlOutputFormat format, std::string in)
|
||||
}
|
||||
|
||||
static std::string reloadRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||
|
||||
if (request.ends_with("full-reset")) {
|
||||
// perform a full config reset. First, reset config manager and load it anew. Then,
|
||||
// flush all config value caches. This will momentarily degrade performance
|
||||
// but a config load will be slow enough for this not to matter probably
|
||||
Config::mgr().reset();
|
||||
Config::Supplementary::Jeremy::flushCachedCfgPath();
|
||||
Config::initConfigManager();
|
||||
CConfigValueBase::flushCaches();
|
||||
Config::mgr()->init();
|
||||
CConfigValueBase::flushCaches();
|
||||
|
||||
return "ok";
|
||||
}
|
||||
|
||||
Config::mgr()->reload();
|
||||
|
||||
return "ok";
|
||||
|
||||
Reference in New Issue
Block a user