summaryrefslogtreecommitdiff
path: root/src/debug/HyprCtl.cpp
diff options
context:
space:
mode:
authorVaxry <43317083+vaxerski@users.noreply.github.com>2026-04-26 15:16:36 +0100
committerGitHub <noreply@github.com>2026-04-26 15:16:36 +0100
commit5ba33f846129f3e6c0505b19f94634b24505e828 (patch)
treeaaacabe678006040c342935481a86607c66607fd /src/debug/HyprCtl.cpp
parent329b2b356dd92ac07f4e2aa69cbce82ee9ba9d19 (diff)
config/lua: init lua config manager, use lua if available (#13817)
Adds a new lua config manager, which will automatically be used if there is a lua config present.
Diffstat (limited to 'src/debug/HyprCtl.cpp')
-rw-r--r--src/debug/HyprCtl.cpp126
1 files changed, 95 insertions, 31 deletions
diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp
index fd9cad75..bb575ce5 100644
--- a/src/debug/HyprCtl.cpp
+++ b/src/debug/HyprCtl.cpp
@@ -34,13 +34,14 @@ using namespace Hyprutils::OS;
#include "../config/shared/complex/ComplexDataTypes.hpp"
#include "../config/legacy/ConfigManager.hpp"
+#include "../config/lua/ConfigManager.hpp"
#include "../config/ConfigValue.hpp"
#include "../config/shared/complex/ComplexDataTypes.hpp"
#include "../config/shared/inotify/ConfigWatcher.hpp"
#include "../config/shared/workspace/WorkspaceRuleManager.hpp"
#include "../config/shared/monitor/MonitorRuleManager.hpp"
#include "../config/shared/animation/AnimationTree.hpp"
-#include "../config/supplementary/ConfigDescriptions.hpp"
+#include "../config/values/ConfigValues.hpp"
#include "../managers/CursorManager.hpp"
#include "../errorOverlay/Overlay.hpp"
#include "../devices/IPointer.hpp"
@@ -1013,7 +1014,7 @@ static std::string bindsRequest(eHyprCtlOutputFormat format, std::string request
ret += "d";
ret += std::format("\n\tmodmask: {}\n\tsubmap: {}\n\tkey: {}\n\tkeycode: {}\n\tcatchall: {}\n\tdescription: {}\n\tdispatcher: {}\n\targ: {}\n\n", kb->modmask,
- kb->submap.name, kb->key, kb->keycode, kb->catchAll, kb->description, kb->handler, kb->arg);
+ kb->submap.name, kb->key.empty() ? kb->displayKey : kb->key, kb->keycode, kb->catchAll, kb->description, kb->handler, kb->arg);
}
} else {
// json
@@ -1246,10 +1247,39 @@ std::string systemInfoRequest(eHyprCtlOutputFormat format, std::string request)
return result;
}
+static std::string evalRequest(eHyprCtlOutputFormat format, std::string request) {
+ if (Config::mgr()->type() != Config::CONFIG_LUA)
+ return "eval is only supported with the lua config manager";
+
+ auto luaMgr = dynamicPointerCast<Config::Lua::CConfigManager>(WP<Config::IConfigManager>(Config::mgr()));
+
+ // strip the command name ("eval ") from the request
+ auto code = request.substr(request.find_first_of(' ') + 1);
+
+ auto err = luaMgr->eval(code);
+ if (err)
+ return std::format("error: {}", *err);
+
+ return "ok";
+}
+
static std::string dispatchRequest(eHyprCtlOutputFormat format, std::string in) {
// get rid of the dispatch keyword
in = in.substr(in.find_first_of(' ') + 1);
+ if (Config::mgr()->type() == Config::CONFIG_LUA) {
+ // For lua, this is just a wrapper for `eval("hl.dispatch(in)")
+ std::string evalStr = std::format("hl.dispatch({})", in);
+ auto luaMgr = dynamicPointerCast<Config::Lua::CConfigManager>(WP<Config::IConfigManager>(Config::mgr()));
+ auto ret = luaMgr->eval(evalStr).value_or("ok");
+
+ if (ret.starts_with("ok") || in.contains("(") /* this likely means the user is passing a valid lua dispatch string */)
+ return ret;
+
+ // the user likely is trying to dispatch old hyprlang stuff via lua, let them know
+ return ret + "\n\n → Note: dispatch in lua is a shorthand for hl.dispatch(...), your syntax might need to be updated.";
+ }
+
const auto DISPATCHSTR = in.substr(0, in.find_first_of(' '));
auto DISPATCHARG = std::string();
@@ -1335,7 +1365,7 @@ static std::string dispatchKeyword(eHyprCtlOutputFormat format, std::string in)
// decorations will probably need a repaint
if (COMMAND.contains("decoration:") || COMMAND.contains("border") || COMMAND == "workspace" || COMMAND.contains("zoom_factor") || COMMAND == "source") {
- static auto PZOOMFACTOR = CConfigValue<Hyprlang::FLOAT>("cursor:zoom_factor");
+ static auto PZOOMFACTOR = CConfigValue<Config::FLOAT>("cursor:zoom_factor");
for (auto const& m : g_pCompositor->m_monitors) {
*(m->m_cursorZoom) = *PZOOMFACTOR;
g_pHyprRenderer->damageMonitor(m);
@@ -1599,22 +1629,22 @@ static std::string dispatchGetProp(eHyprCtlOutputFormat format, std::string requ
};
auto borderColorToString = [&](bool active) -> std::string {
- static auto PACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("general:col.active_border");
- static auto PINACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("general:col.inactive_border");
- static auto PNOGROUPACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("general:col.nogroup_border_active");
- static auto PNOGROUPINACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("general:col.nogroup_border");
- static auto PGROUPACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("group:col.border_active");
- static auto PGROUPINACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("group:col.border_inactive");
- static auto PGROUPACTIVELOCKEDCOL = CConfigValue<Hyprlang::CUSTOMTYPE>("group:col.border_locked_active");
- static auto PGROUPINACTIVELOCKEDCOL = CConfigValue<Hyprlang::CUSTOMTYPE>("group:col.border_locked_inactive");
+ static auto PACTIVECOL = CConfigValue<Config::IComplexConfigValue>("general:col.active_border");
+ static auto PINACTIVECOL = CConfigValue<Config::IComplexConfigValue>("general:col.inactive_border");
+ static auto PNOGROUPACTIVECOL = CConfigValue<Config::IComplexConfigValue>("general:col.nogroup_border_active");
+ static auto PNOGROUPINACTIVECOL = CConfigValue<Config::IComplexConfigValue>("general:col.nogroup_border");
+ static auto PGROUPACTIVECOL = CConfigValue<Config::IComplexConfigValue>("group:col.border_active");
+ static auto PGROUPINACTIVECOL = CConfigValue<Config::IComplexConfigValue>("group:col.border_inactive");
+ static auto PGROUPACTIVELOCKEDCOL = CConfigValue<Config::IComplexConfigValue>("group:col.border_locked_active");
+ static auto PGROUPINACTIVELOCKEDCOL = CConfigValue<Config::IComplexConfigValue>("group:col.border_locked_inactive");
const bool GROUPLOCKED = PWINDOW->m_group ? PWINDOW->m_group->locked() : false;
if (active) {
- auto* const ACTIVECOL = (Config::CGradientValueData*)(PACTIVECOL.ptr())->getData();
- auto* const NOGROUPACTIVECOL = (Config::CGradientValueData*)(PNOGROUPACTIVECOL.ptr())->getData();
- auto* const GROUPACTIVECOL = (Config::CGradientValueData*)(PGROUPACTIVECOL.ptr())->getData();
- auto* const GROUPACTIVELOCKEDCOL = (Config::CGradientValueData*)(PGROUPACTIVELOCKEDCOL.ptr())->getData();
+ auto* const ACTIVECOL = (Config::CGradientValueData*)(PACTIVECOL.ptr());
+ auto* const NOGROUPACTIVECOL = (Config::CGradientValueData*)(PNOGROUPACTIVECOL.ptr());
+ auto* const GROUPACTIVECOL = (Config::CGradientValueData*)(PGROUPACTIVECOL.ptr());
+ auto* const GROUPACTIVELOCKEDCOL = (Config::CGradientValueData*)(PGROUPACTIVELOCKEDCOL.ptr());
const auto* const ACTIVECOLOR =
!PWINDOW->m_group ? (!(PWINDOW->m_groupRules & Desktop::View::GROUP_DENY) ? ACTIVECOL : NOGROUPACTIVECOL) : (GROUPLOCKED ? GROUPACTIVELOCKEDCOL : GROUPACTIVECOL);
@@ -1624,10 +1654,10 @@ static std::string dispatchGetProp(eHyprCtlOutputFormat format, std::string requ
else
return std::format(R"({{"{}": "{}"}})", PROP, borderColorString);
} else {
- auto* const INACTIVECOL = (Config::CGradientValueData*)(PINACTIVECOL.ptr())->getData();
- auto* const NOGROUPINACTIVECOL = (Config::CGradientValueData*)(PNOGROUPINACTIVECOL.ptr())->getData();
- auto* const GROUPINACTIVECOL = (Config::CGradientValueData*)(PGROUPINACTIVECOL.ptr())->getData();
- auto* const GROUPINACTIVELOCKEDCOL = (Config::CGradientValueData*)(PGROUPINACTIVELOCKEDCOL.ptr())->getData();
+ auto* const INACTIVECOL = (Config::CGradientValueData*)(PINACTIVECOL.ptr());
+ auto* const NOGROUPINACTIVECOL = (Config::CGradientValueData*)(PNOGROUPINACTIVECOL.ptr());
+ auto* const GROUPINACTIVECOL = (Config::CGradientValueData*)(PGROUPINACTIVECOL.ptr());
+ auto* const GROUPINACTIVELOCKEDCOL = (Config::CGradientValueData*)(PGROUPINACTIVELOCKEDCOL.ptr());
const auto* const INACTIVECOLOR = !PWINDOW->m_group ? (!(PWINDOW->m_groupRules & Desktop::View::GROUP_DENY) ? INACTIVECOL : NOGROUPINACTIVECOL) :
(GROUPLOCKED ? GROUPINACTIVELOCKEDCOL : GROUPINACTIVECOL);
@@ -1771,6 +1801,8 @@ static std::string dispatchGetOption(eHyprCtlOutputFormat format, std::string re
return std::format("float: {:2f}\nset: {}", **rc<Config::FLOAT* const*>(VAL), VAR.setByUser);
else if (TYPE == typeid(Config::VEC2))
return std::format("vec2: [{}, {}]\nset: {}", (*rc<Config::VEC2* const*>(VAL))->x, (*rc<Config::VEC2* const*>(VAL))->y, VAR.setByUser);
+ else if (TYPE == typeid(Hyprlang::VEC2))
+ return std::format("vec2: [{}, {}]\nset: {}", (*rc<Config::VEC2* const*>(VAL))->x, (*rc<Config::VEC2* const*>(VAL))->y, VAR.setByUser);
else if (TYPE == typeid(Hyprlang::STRING))
return std::format("str: {}\nset: {}", *rc<Hyprlang::STRING const*>(VAL), VAR.setByUser);
else if (TYPE == typeid(Config::STRING))
@@ -1785,6 +1817,9 @@ static std::string dispatchGetOption(eHyprCtlOutputFormat format, std::string re
else if (TYPE == typeid(Config::VEC2))
return std::format(R"({{"option": "{}", "vec2": [{},{}], "set": {} }})", curitem, (*rc<Config::VEC2* const*>(VAL))->x, (*rc<Config::VEC2* const*>(VAL))->y,
VAR.setByUser);
+ else if (TYPE == typeid(Hyprlang::VEC2))
+ return std::format(R"({{"option": "{}", "vec2": [{},{}], "set": {} }})", curitem, (*rc<Config::VEC2* const*>(VAL))->x, (*rc<Config::VEC2* const*>(VAL))->y,
+ VAR.setByUser);
else if (TYPE == typeid(Hyprlang::STRING))
return std::format(R"({{"option": "{}", "str": "{}", "set": {} }})", curitem, escapeJSONStrings(*rc<Hyprlang::STRING const*>(VAL)), VAR.setByUser);
else if (TYPE == typeid(Config::STRING))
@@ -2043,18 +2078,7 @@ static std::string getIsLocked(eHyprCtlOutputFormat format, std::string request)
}
static std::string getDescriptions(eHyprCtlOutputFormat format, std::string request) {
- std::string json = "[";
- const auto& DESCS = Config::Supplementary::CONFIG_OPTIONS;
-
- for (const auto& d : DESCS) {
- json += d.jsonify() + ",\n";
- }
-
- json.pop_back();
- json.pop_back();
-
- json += "]\n";
- return json;
+ return Config::Values::getAsJson();
}
static std::string submapRequest(eHyprCtlOutputFormat format, std::string request) {
@@ -2065,6 +2089,43 @@ static std::string submapRequest(eHyprCtlOutputFormat format, std::string reques
return format == FORMAT_JSON ? std::format("\"{}\"\n", escapeJSONStrings(submap)) : (submap + "\n");
}
+static std::string statusRequest(eHyprCtlOutputFormat format, std::string request) {
+ Aquamarine::eBackendType backendType = Aquamarine::eBackendType::AQ_BACKEND_NULL;
+
+ for (const auto& i : g_pCompositor->m_aqBackend->getImplementations()) {
+ if (i->type() == Aquamarine::eBackendType::AQ_BACKEND_NULL || i->type() == Aquamarine::eBackendType::AQ_BACKEND_HEADLESS)
+ continue;
+
+ backendType = i->type();
+ break;
+ }
+
+ std::string backendStr;
+
+ switch (backendType) {
+ case Aquamarine::AQ_BACKEND_DRM: backendStr = "drm"; break;
+ case Aquamarine::AQ_BACKEND_WAYLAND: backendStr = "wayland"; break;
+ default: backendStr = "error"; break;
+ }
+
+ if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
+
+ return std::format(R"#(
+{{
+ "configProvider": "{}",
+ "backend": "{}"
+}}
+)#",
+ Config::typeToString(Config::mgr()->type()), backendStr);
+ }
+
+ return std::format(R"#(
+configProvider: {}
+backend: {}
+)#",
+ Config::typeToString(Config::mgr()->type()), backendStr);
+}
+
static std::string reloadShaders(eHyprCtlOutputFormat format, std::string request) {
CVarList vars(request, 0, ' ');
@@ -2098,6 +2159,7 @@ CHyprCtl::CHyprCtl() {
registerCommand(SHyprCtlCommand{"locked", true, getIsLocked});
registerCommand(SHyprCtlCommand{"descriptions", true, getDescriptions});
registerCommand(SHyprCtlCommand{"submap", true, submapRequest});
+ registerCommand(SHyprCtlCommand{"status", true, statusRequest});
registerCommand(SHyprCtlCommand{.name = "reloadshaders", .exact = false, .fn = reloadShaders});
registerCommand(SHyprCtlCommand{"monitors", false, monitorsRequest});
@@ -2115,6 +2177,7 @@ CHyprCtl::CHyprCtl() {
registerCommand(SHyprCtlCommand{"getoption", false, dispatchGetOption});
registerCommand(SHyprCtlCommand{"decorations", false, decorationRequest});
registerCommand(SHyprCtlCommand{"[[BATCH]]", false, dispatchBatch});
+ registerCommand(SHyprCtlCommand{"eval", false, evalRequest});
startHyprCtlSocket();
}
@@ -2200,6 +2263,7 @@ std::string CHyprCtl::getReply(std::string request) {
if (reloadAll) {
Config::monitorRuleMgr()->scheduleReload();
+ Layout::Supplementary::algoMatcher()->updateWorkspaceLayouts();
g_pInputManager->setKeyboardLayout(); // update kb layout
g_pInputManager->setPointerConfigs(); // update mouse cfgs