summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVaxry <vaxry@vaxry.net>2026-04-28 15:45:14 +0100
committerVaxry <43317083+vaxerski@users.noreply.github.com>2026-04-28 16:52:41 +0100
commit50b555d86c76987069b68cc4865f955c93161a3a (patch)
treeb17299f11c66807f6e5072f428ff7c9569f02e89 /src
parentcbefb357a57ce5f6dd161a400a5867609022ee66 (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.cpp11
-rw-r--r--src/config/lua/bindings/LuaBindingsConfigRules.cpp11
-rw-r--r--src/desktop/rule/layerRule/LayerRule.cpp74
-rw-r--r--src/desktop/rule/layerRule/LayerRule.hpp27
-rw-r--r--src/desktop/rule/layerRule/LayerRuleApplicator.cpp39
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;
}