From 6a7abd00379b4f37b468bc2d0e717d4ba293efe1 Mon Sep 17 00:00:00 2001 From: Lichie <90825386+lichie567@users.noreply.github.com> Date: Sun, 3 May 2026 10:55:47 -0700 Subject: [PATCH] config/lua: add clear tag api (#14273) --- meta/hl.meta.lua | 1 + src/config/lua/bindings/LuaBindingsDispatchers.cpp | 11 +++++++++++ src/config/shared/actions/ConfigActions.cpp | 13 +++++++++++++ src/config/shared/actions/ConfigActions.hpp | 1 + src/helpers/TagKeeper.cpp | 9 +++++++++ src/helpers/TagKeeper.hpp | 1 + 6 files changed, 36 insertions(+) diff --git a/meta/hl.meta.lua b/meta/hl.meta.lua index a13655633..d6a44567d 100644 --- a/meta/hl.meta.lua +++ b/meta/hl.meta.lua @@ -826,6 +826,7 @@ local __HL_DspGroupNamespace = {} ---@field alter_zorder fun(...): HL.Dispatcher ---@field bring_to_top fun(...): HL.Dispatcher ---@field center fun(...): HL.Dispatcher +---@field clear_tags fun(...): HL.Dispatcher ---@field close fun(...): HL.Dispatcher ---@field cycle_next fun(...): HL.Dispatcher ---@field deny_from_group fun(...): HL.Dispatcher diff --git a/src/config/lua/bindings/LuaBindingsDispatchers.cpp b/src/config/lua/bindings/LuaBindingsDispatchers.cpp index 4fd332eb7..32b4e2bf2 100644 --- a/src/config/lua/bindings/LuaBindingsDispatchers.cpp +++ b/src/config/lua/bindings/LuaBindingsDispatchers.cpp @@ -563,6 +563,10 @@ static int dsp_tagWindow(lua_State* L) { return Internal::checkResult(L, CA::tag(lua_tostring(L, lua_upvalueindex(1)), Internal::windowFromUpval(L, 2))); } +static int dsp_clearTags(lua_State* L) { + return Internal::checkResult(L, CA::clearTags(Internal::windowFromUpval(L, 1))); +} + static int dsp_toggleSwallow(lua_State* L) { return Internal::checkResult(L, CA::toggleSwallow()); } @@ -915,6 +919,12 @@ static int hlWindowTag(lua_State* L) { return 1; } +static int hlWindowClearTags(lua_State* L) { + Internal::pushWindowUpval(L, 1); + lua_pushcclosure(L, dsp_clearTags, 1); + return 1; +} + static int hlWindowToggleSwallow(lua_State* L) { lua_pushcclosure(L, dsp_toggleSwallow, 0); return 1; @@ -1248,6 +1258,7 @@ void Internal::registerDispatcherBindings(lua_State* L) { Internal::setFn(L, "center", hlWindowCenter); Internal::setFn(L, "cycle_next", hlWindowCycleNext); Internal::setFn(L, "tag", hlWindowTag); + Internal::setFn(L, "clear_tags", hlWindowClearTags); Internal::setFn(L, "toggle_swallow", hlWindowToggleSwallow); Internal::setFn(L, "pin", hlWindowPin); Internal::setFn(L, "bring_to_top", hlWindowBringToTop); diff --git a/src/config/shared/actions/ConfigActions.cpp b/src/config/shared/actions/ConfigActions.cpp index 5db1aaf1e..7111afd8f 100644 --- a/src/config/shared/actions/ConfigActions.cpp +++ b/src/config/shared/actions/ConfigActions.cpp @@ -605,6 +605,19 @@ ActionResult Actions::tag(const std::string& tagStr, std::optional w) return {}; } +ActionResult Actions::clearTags(std::optional w) { + auto window = xtract(w); + if (!window) + return {}; + + if (window->m_ruleApplicator->m_tagKeeper.clearTags()) { + window->m_ruleApplicator->propertiesChanged(Desktop::Rule::RULE_PROP_TAG); + window->updateDecorationValues(); + } + + return {}; +} + ActionResult Actions::swapNext(const bool next, std::optional w) { auto window = xtract(w); if (!window) diff --git a/src/config/shared/actions/ConfigActions.hpp b/src/config/shared/actions/ConfigActions.hpp index 0f16aff74..6ddf64d9d 100644 --- a/src/config/shared/actions/ConfigActions.hpp +++ b/src/config/shared/actions/ConfigActions.hpp @@ -53,6 +53,7 @@ namespace Config::Actions { ActionResult move(const Vector2D& pos, bool relative = false, std::optional window = std::nullopt /* Active */); ActionResult cycleNext(const bool next, std::optional onlyTiled, std::optional onlyFloating, std::optional window = std::nullopt /* Active */); ActionResult tag(const std::string& tag, std::optional window = std::nullopt /* Active */); + ActionResult clearTags(std::optional w = std::nullopt); ActionResult pass(std::optional window = std::nullopt /* Active */); ActionResult pass(uint32_t modMask, uint32_t key, std::optional window = std::nullopt /* Active */); ActionResult sendKeyState(uint32_t modMask, uint32_t key, uint32_t state, std::optional window = std::nullopt /* Active */); diff --git a/src/helpers/TagKeeper.cpp b/src/helpers/TagKeeper.cpp index 7f377657e..80bf3957d 100644 --- a/src/helpers/TagKeeper.cpp +++ b/src/helpers/TagKeeper.cpp @@ -38,6 +38,15 @@ bool CTagKeeper::applyTag(const std::string& tag, bool dynamic) { return true; } +bool CTagKeeper::clearTags() { + if (!m_tags.empty()) { + m_tags.clear(); + return true; + } + + return false; +} + bool CTagKeeper::removeDynamicTag(const std::string& s) { return std::erase_if(m_tags, [&s](const auto& tag) { return tag == s + "*"; }); } diff --git a/src/helpers/TagKeeper.hpp b/src/helpers/TagKeeper.hpp index d18a0d29a..f90b06295 100644 --- a/src/helpers/TagKeeper.hpp +++ b/src/helpers/TagKeeper.hpp @@ -8,6 +8,7 @@ class CTagKeeper { bool isTagged(const std::string& tag, bool strict = false) const; bool applyTag(const std::string& tag, bool dynamic = false); bool removeDynamicTag(const std::string& tag); + bool clearTags(); const auto& getTags() const { return m_tags;