diff options
| author | Vaxry <vaxry@vaxry.net> | 2026-04-28 15:45:14 +0100 |
|---|---|---|
| committer | Vaxry <43317083+vaxerski@users.noreply.github.com> | 2026-04-28 16:52:41 +0100 |
| commit | 50b555d86c76987069b68cc4865f955c93161a3a (patch) | |
| tree | b17299f11c66807f6e5072f428ff7c9569f02e89 /src | |
| parent | cbefb357a57ce5f6dd161a400a5867609022ee66 (diff) | |
desktop/layerRule: use variants for storage internally
Improves storage: less dynamic parsing, immediate config errors, faster.
Diffstat (limited to 'src')
| -rw-r--r-- | src/config/legacy/ConfigManager.cpp | 11 | ||||
| -rw-r--r-- | src/config/lua/bindings/LuaBindingsConfigRules.cpp | 11 | ||||
| -rw-r--r-- | src/desktop/rule/layerRule/LayerRule.cpp | 74 | ||||
| -rw-r--r-- | src/desktop/rule/layerRule/LayerRule.hpp | 27 | ||||
| -rw-r--r-- | src/desktop/rule/layerRule/LayerRuleApplicator.cpp | 39 |
5 files changed, 124 insertions, 38 deletions
diff --git a/src/config/legacy/ConfigManager.cpp b/src/config/legacy/ConfigManager.cpp index 5d74528d..3e6fe6e9 100644 --- a/src/config/legacy/ConfigManager.cpp +++ b/src/config/legacy/ConfigManager.cpp @@ -922,8 +922,11 @@ std::optional<std::string> CConfigManager::addLayerRuleFromConfigKey(const std:: for (const auto& e : Desktop::Rule::layerEffects()->allEffectStrings()) { auto VAL = m_config->getSpecialConfigValuePtr("layerrule", e.c_str(), name.c_str()); - if (VAL && VAL->m_bSetByUser) - rule->addEffect(Desktop::Rule::layerEffects()->get(e).value_or(Desktop::Rule::LAYER_RULE_EFFECT_NONE), std::any_cast<Hyprlang::STRING>(VAL->getValue())); + if (VAL && VAL->m_bSetByUser) { + auto res = rule->addEffect(Desktop::Rule::layerEffects()->get(e).value_or(Desktop::Rule::LAYER_RULE_EFFECT_NONE), std::any_cast<Hyprlang::STRING>(VAL->getValue())); + if (!res) + return res.error(); + } } Desktop::Rule::ruleEngine()->registerRule(std::move(rule)); @@ -2025,7 +2028,9 @@ std::optional<std::string> CConfigManager::handleLayerrule(const std::string& co const auto EFFECT = Desktop::Rule::layerEffects()->get(FIRST); if (!EFFECT.has_value()) return std::format("invalid effect {}", el); - rule->addEffect(*EFFECT, std::string{el.substr(spacePos + 1)}); + auto res = rule->addEffect(*EFFECT, std::string{el.substr(spacePos + 1)}); + if (!res) + return res.error(); } else return std::format("invalid field type {}", FIRST); } diff --git a/src/config/lua/bindings/LuaBindingsConfigRules.cpp b/src/config/lua/bindings/LuaBindingsConfigRules.cpp index 4f9fc861..88761f05 100644 --- a/src/config/lua/bindings/LuaBindingsConfigRules.cpp +++ b/src/config/lua/bindings/LuaBindingsConfigRules.cpp @@ -1186,8 +1186,11 @@ static int hlLayerRule(lua_State* L) { auto val = Internal::ruleValueToString(L); if (!val) self->addError(std::format("{}: hl.layer_rule: field '{}': {}", sourceInfo, key, val.error())); - else - rule->addEffect(*dynamicEffect, *val); + else { + auto res = rule->addEffect(*dynamicEffect, *val); + if (!res) + self->addError(std::format("{}: hl.layer_rule: field '{}': {}", sourceInfo, key, res.error())); + } lua_pop(L, 1); continue; @@ -1199,7 +1202,9 @@ static int hlLayerRule(lua_State* L) { self->addError(std::format("{}: hl.layer_rule: field '{}': {}", sourceInfo, key, err.message)); else { auto str = val->toString(); - rule->addEffect(desc->effect, str); + auto res = rule->addEffect(desc->effect, str); + if (!res) + self->addError(std::format("{}: hl.layer_rule: field '{}': {}", sourceInfo, key, res.error())); } lua_pop(L, 1); diff --git a/src/desktop/rule/layerRule/LayerRule.cpp b/src/desktop/rule/layerRule/LayerRule.cpp index d1c472b0..10120d7f 100644 --- a/src/desktop/rule/layerRule/LayerRule.cpp +++ b/src/desktop/rule/layerRule/LayerRule.cpp @@ -1,10 +1,72 @@ #include "LayerRule.hpp" #include "../../../debug/log/Logger.hpp" +#include "../../../helpers/MiscFunctions.hpp" #include "../../view/LayerSurface.hpp" +#include <algorithm> +#include <format> + using namespace Desktop; using namespace Desktop::Rule; +static std::expected<int64_t, std::string> parseInt(std::string_view effectName, const std::string& raw) { + try { + return std::stoll(raw); + } catch (std::exception& e) { return std::unexpected(std::format("{} rule \"{}\" failed with: {}", effectName, raw, e.what())); } +} + +static std::expected<float, std::string> parseFloat(std::string_view effectName, const std::string& raw) { + try { + return std::stof(raw); + } catch (std::exception& e) { return std::unexpected(std::format("{} rule \"{}\" failed with: {}", effectName, raw, e.what())); } +} + +static std::expected<int64_t, std::string> parseAboveLock(const std::string& raw) { + try { + return sc<int64_t>(std::clamp(std::stoull(raw), 0ULL, 2ULL)); + } catch (std::exception& e) { return std::unexpected(std::format("above_lock rule \"{}\" failed with: {}", raw, e.what())); } +} + +static std::expected<LayerRuleEffectValue, std::string> parseLayerRuleEffect(CLayerRuleEffectContainer::storageType e, const std::string& raw) { + if (layerEffects()->isEffectDynamic(e)) + return std::string{raw}; + + const auto EFFECT_NAME = layerEffects()->get(e); + + switch (e) { + default: return std::unexpected(std::format("unknown layer rule effect {}", e)); + + case LAYER_RULE_EFFECT_NONE: return std::monostate{}; + + case LAYER_RULE_EFFECT_NO_ANIM: + case LAYER_RULE_EFFECT_BLUR: + case LAYER_RULE_EFFECT_BLUR_POPUPS: + case LAYER_RULE_EFFECT_DIM_AROUND: + case LAYER_RULE_EFFECT_XRAY: + case LAYER_RULE_EFFECT_NO_SCREEN_SHARE: return truthy(raw); + + case LAYER_RULE_EFFECT_ORDER: { + auto parsed = parseInt(EFFECT_NAME, raw); + if (!parsed) + return std::unexpected(parsed.error()); + return *parsed; + } + case LAYER_RULE_EFFECT_ABOVE_LOCK: { + auto parsed = parseAboveLock(raw); + if (!parsed) + return std::unexpected(parsed.error()); + return *parsed; + } + case LAYER_RULE_EFFECT_IGNORE_ALPHA: { + auto parsed = parseFloat(EFFECT_NAME, raw); + if (!parsed) + return std::unexpected(parsed.error()); + return std::clamp(*parsed, 0.F, 1.F); + } + case LAYER_RULE_EFFECT_ANIMATION: return std::string{raw}; + } +} + CLayerRule::CLayerRule(const std::string& name) : IRule(name) { ; } @@ -13,11 +75,17 @@ eRuleType CLayerRule::type() { return RULE_TYPE_LAYER; } -void CLayerRule::addEffect(CLayerRule::storageType e, const std::string& result) { - m_effects.emplace_back(std::make_pair<>(e, result)); +std::expected<void, std::string> CLayerRule::addEffect(CLayerRule::storageType e, const std::string& result) { + auto parsed = parseLayerRuleEffect(e, result); + if (!parsed) + return std::unexpected(parsed.error()); + + m_effects.emplace_back(SLayerRuleEffect{.key = e, .raw = result, .value = std::move(*parsed)}); + + return {}; } -const std::vector<std::pair<CLayerRule::storageType, std::string>>& CLayerRule::effects() { +const std::vector<SLayerRuleEffect>& CLayerRule::effects() { return m_effects; } diff --git a/src/desktop/rule/layerRule/LayerRule.hpp b/src/desktop/rule/layerRule/LayerRule.hpp index 7650376c..11280a2d 100644 --- a/src/desktop/rule/layerRule/LayerRule.hpp +++ b/src/desktop/rule/layerRule/LayerRule.hpp @@ -4,7 +4,18 @@ #include "../../DesktopTypes.hpp" #include "LayerRuleEffectContainer.hpp" +#include <expected> +#include <variant> + namespace Desktop::Rule { + using LayerRuleEffectValue = std::variant<std::monostate, bool, int64_t, float, std::string>; + + struct SLayerRuleEffect { + CLayerRuleEffectContainer::storageType key = LAYER_RULE_EFFECT_NONE; + std::string raw; + LayerRuleEffectValue value; + }; + class CLayerRule : public IRule { public: using storageType = CLayerRuleEffectContainer::storageType; @@ -12,18 +23,18 @@ namespace Desktop::Rule { CLayerRule(const std::string& name = ""); virtual ~CLayerRule() = default; - virtual eRuleType type(); + virtual eRuleType type(); - void addEffect(storageType e, const std::string& result); - const std::vector<std::pair<storageType, std::string>>& effects(); + std::expected<void, std::string> addEffect(storageType e, const std::string& result); + const std::vector<SLayerRuleEffect>& effects(); - void setEnabled(bool enable); - bool isEnabled() const; + void setEnabled(bool enable); + bool isEnabled() const; - bool matches(PHLLS w); + bool matches(PHLLS w); private: - std::vector<std::pair<storageType, std::string>> m_effects; - bool m_enabled = true; + std::vector<SLayerRuleEffect> m_effects; + bool m_enabled = true; }; }; diff --git a/src/desktop/rule/layerRule/LayerRuleApplicator.cpp b/src/desktop/rule/layerRule/LayerRuleApplicator.cpp index 8c157dae..79ee80ae 100644 --- a/src/desktop/rule/layerRule/LayerRuleApplicator.cpp +++ b/src/desktop/rule/layerRule/LayerRuleApplicator.cpp @@ -3,7 +3,6 @@ #include "../Engine.hpp" #include "../../view/LayerSurface.hpp" #include "../../types/OverridableVar.hpp" -#include "../../../helpers/MiscFunctions.hpp" #include "../../../event/EventBus.hpp" #include <tuple> @@ -39,7 +38,11 @@ void CLayerRuleApplicator::resetProps(std::underlying_type_t<eRuleProperty> prop } void CLayerRuleApplicator::applyDynamicRule(const SP<CLayerRule>& rule) { - for (const auto& [key, effect] : rule->effects()) { + for (const auto& effectData : rule->effects()) { + const auto key = effectData.key; + const auto& effect = effectData.raw; + const auto& value = effectData.value; + switch (key) { default: { if (key <= LAYER_RULE_EFFECT_LAST_STATIC) { @@ -68,58 +71,52 @@ void CLayerRuleApplicator::applyDynamicRule(const SP<CLayerRule>& rule) { break; } case LAYER_RULE_EFFECT_NO_ANIM: { - m_noanim.first.set(truthy(effect), Types::PRIORITY_WINDOW_RULE); + m_noanim.first.set(std::get<bool>(value), Types::PRIORITY_WINDOW_RULE); m_noanim.second |= rule->getPropertiesMask(); break; } case LAYER_RULE_EFFECT_BLUR: { - m_blur.first.set(truthy(effect), Types::PRIORITY_WINDOW_RULE); + m_blur.first.set(std::get<bool>(value), Types::PRIORITY_WINDOW_RULE); m_blur.second |= rule->getPropertiesMask(); break; } case LAYER_RULE_EFFECT_BLUR_POPUPS: { - m_blurPopups.first.set(truthy(effect), Types::PRIORITY_WINDOW_RULE); + m_blurPopups.first.set(std::get<bool>(value), Types::PRIORITY_WINDOW_RULE); m_blurPopups.second |= rule->getPropertiesMask(); break; } case LAYER_RULE_EFFECT_DIM_AROUND: { - m_dimAround.first.set(truthy(effect), Types::PRIORITY_WINDOW_RULE); + m_dimAround.first.set(std::get<bool>(value), Types::PRIORITY_WINDOW_RULE); m_dimAround.second |= rule->getPropertiesMask(); break; } case LAYER_RULE_EFFECT_XRAY: { - m_xray.first.set(truthy(effect), Types::PRIORITY_WINDOW_RULE); + m_xray.first.set(std::get<bool>(value), Types::PRIORITY_WINDOW_RULE); m_xray.second |= rule->getPropertiesMask(); break; } case LAYER_RULE_EFFECT_NO_SCREEN_SHARE: { - m_noScreenShare.first.set(truthy(effect), Types::PRIORITY_WINDOW_RULE); + m_noScreenShare.first.set(std::get<bool>(value), Types::PRIORITY_WINDOW_RULE); m_noScreenShare.second |= rule->getPropertiesMask(); break; } case LAYER_RULE_EFFECT_ORDER: { - try { - m_order.first.set(std::stoi(effect), Types::PRIORITY_WINDOW_RULE); - m_order.second |= rule->getPropertiesMask(); - } catch (...) { Log::logger->log(Log::ERR, "CLayerRuleApplicator::applyDynamicRule: invalid order {}", effect); } + m_order.first.set(std::get<int64_t>(value), Types::PRIORITY_WINDOW_RULE); + m_order.second |= rule->getPropertiesMask(); break; } case LAYER_RULE_EFFECT_ABOVE_LOCK: { - try { - m_aboveLock.first.set(std::clamp(std::stoull(effect), 0ULL, 2ULL), Types::PRIORITY_WINDOW_RULE); - m_aboveLock.second |= rule->getPropertiesMask(); - } catch (...) { Log::logger->log(Log::ERR, "CLayerRuleApplicator::applyDynamicRule: invalid order {}", effect); } + m_aboveLock.first.set(std::get<int64_t>(value), Types::PRIORITY_WINDOW_RULE); + m_aboveLock.second |= rule->getPropertiesMask(); break; } case LAYER_RULE_EFFECT_IGNORE_ALPHA: { - try { - m_ignoreAlpha.first.set(std::clamp(std::stof(effect), 0.F, 1.F), Types::PRIORITY_WINDOW_RULE); - m_ignoreAlpha.second |= rule->getPropertiesMask(); - } catch (...) { Log::logger->log(Log::ERR, "CLayerRuleApplicator::applyDynamicRule: invalid order {}", effect); } + m_ignoreAlpha.first.set(std::get<float>(value), Types::PRIORITY_WINDOW_RULE); + m_ignoreAlpha.second |= rule->getPropertiesMask(); break; } case LAYER_RULE_EFFECT_ANIMATION: { - m_animationStyle.first.set(effect, Types::PRIORITY_WINDOW_RULE); + m_animationStyle.first.set(std::get<std::string>(value), Types::PRIORITY_WINDOW_RULE); m_animationStyle.second |= rule->getPropertiesMask(); break; } |
