From 97886cf0dab39ce4b7887e549b93ccec30156ddc Mon Sep 17 00:00:00 2001 From: Vaxry Date: Tue, 28 Apr 2026 15:55:41 +0100 Subject: [PATCH] desktop/rule: cleanup inheritance, use templates to avoid dup --- src/desktop/rule/Rule.cpp | 12 +++++ src/desktop/rule/Rule.hpp | 8 +++- src/desktop/rule/RuleWithEffects.hpp | 51 ++++++++++++++++++++++ src/desktop/rule/layerRule/LayerRule.cpp | 30 ++----------- src/desktop/rule/layerRule/LayerRule.hpp | 23 ++++------ src/desktop/rule/windowRule/WindowRule.cpp | 35 ++------------- src/desktop/rule/windowRule/WindowRule.hpp | 23 ++++------ 7 files changed, 94 insertions(+), 88 deletions(-) create mode 100644 src/desktop/rule/RuleWithEffects.hpp diff --git a/src/desktop/rule/Rule.cpp b/src/desktop/rule/Rule.cpp index 5e3141cdd..cfc1edf34 100644 --- a/src/desktop/rule/Rule.cpp +++ b/src/desktop/rule/Rule.cpp @@ -104,10 +104,22 @@ std::underlying_type_t IRule::getPropertiesMask() { return m_mask; } +void IRule::setEnabled(bool enable) { + m_enabled = enable; +} + +bool IRule::isEnabled() const { + return m_enabled; +} + bool IRule::has(eRuleProperty p) { return m_matchEngines.contains(p); } +bool IRule::canMatch() const { + return !m_matchEngines.empty() && m_enabled; +} + bool IRule::matches(eRuleProperty p, const std::string& s) { if (!has(p)) return false; diff --git a/src/desktop/rule/Rule.hpp b/src/desktop/rule/Rule.hpp index efd3cb39a..85c9b2c42 100644 --- a/src/desktop/rule/Rule.hpp +++ b/src/desktop/rule/Rule.hpp @@ -52,6 +52,8 @@ namespace Desktop::Rule { virtual std::underlying_type_t getPropertiesMask(); void registerMatch(eRuleProperty, const std::string&); + void setEnabled(bool enable); + bool isEnabled() const; void markAsExecRule(const std::string& token, uint64_t pid, bool persistent = false); bool isExecRule(); bool isExecPersistent(); @@ -66,13 +68,15 @@ namespace Desktop::Rule { bool matches(eRuleProperty, const std::string& s); bool matches(eRuleProperty, bool b); bool has(eRuleProperty); + bool canMatch() const; // std::unordered_map> m_matchEngines; private: - std::underlying_type_t m_mask = 0; - std::string m_name = ""; + std::underlying_type_t m_mask = 0; + std::string m_name = ""; + bool m_enabled = true; struct { bool isExecRule = false; diff --git a/src/desktop/rule/RuleWithEffects.hpp b/src/desktop/rule/RuleWithEffects.hpp new file mode 100644 index 000000000..17d755e8b --- /dev/null +++ b/src/desktop/rule/RuleWithEffects.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include "Rule.hpp" + +#include +#include +#include +#include +#include + +namespace Desktop::Rule { + template + class CRuleWithEffects : public IRule { + public: + using effectType = TEffect; + using storageType = TEffect::storageType; + using valueType = TEffect::valueType; + + eRuleType type() override { + return RULE_TYPE; + } + + std::expected addEffect(storageType e, const std::string& result) { + auto parsed = parseEffect(e, result); + if (!parsed) + return std::unexpected(parsed.error()); + + m_effects.emplace_back(TEffect{.key = e, .raw = result, .value = std::move(*parsed)}); + m_effectSet.emplace(e); + + return {}; + } + + const std::vector& effects() { + return m_effects; + } + + const std::unordered_set& effectsSet() { + return m_effectSet; + } + + protected: + CRuleWithEffects(const std::string& name = "") : IRule(name) {} + + virtual std::expected parseEffect(storageType e, const std::string& result) = 0; + + private: + std::vector m_effects; + std::unordered_set m_effectSet; + }; +} diff --git a/src/desktop/rule/layerRule/LayerRule.cpp b/src/desktop/rule/layerRule/LayerRule.cpp index ccff39605..11cdd7026 100644 --- a/src/desktop/rule/layerRule/LayerRule.cpp +++ b/src/desktop/rule/layerRule/LayerRule.cpp @@ -85,30 +85,16 @@ static std::expected parseLayerRuleEffect(CLa } } -CLayerRule::CLayerRule(const std::string& name) : IRule(name) { +CLayerRule::CLayerRule(const std::string& name) : CRuleWithEffects(name) { ; } -eRuleType CLayerRule::type() { - return RULE_TYPE_LAYER; -} - -std::expected 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& CLayerRule::effects() { - return m_effects; +std::expected CLayerRule::parseEffect(CLayerRule::storageType e, const std::string& result) { + return parseLayerRuleEffect(e, result); } bool CLayerRule::matches(PHLLS ls) { - if (m_matchEngines.empty() || !m_enabled) + if (!canMatch()) return false; for (const auto& [prop, engine] : m_matchEngines) { @@ -127,11 +113,3 @@ bool CLayerRule::matches(PHLLS ls) { return true; } - -void CLayerRule::setEnabled(bool enable) { - m_enabled = enable; -} - -bool CLayerRule::isEnabled() const { - return m_enabled; -} diff --git a/src/desktop/rule/layerRule/LayerRule.hpp b/src/desktop/rule/layerRule/LayerRule.hpp index 11280a2db..8934d1c62 100644 --- a/src/desktop/rule/layerRule/LayerRule.hpp +++ b/src/desktop/rule/layerRule/LayerRule.hpp @@ -1,6 +1,6 @@ #pragma once -#include "../Rule.hpp" +#include "../RuleWithEffects.hpp" #include "../../DesktopTypes.hpp" #include "LayerRuleEffectContainer.hpp" @@ -11,30 +11,25 @@ namespace Desktop::Rule { using LayerRuleEffectValue = std::variant; struct SLayerRuleEffect { + using storageType = CLayerRuleEffectContainer::storageType; + using valueType = LayerRuleEffectValue; + CLayerRuleEffectContainer::storageType key = LAYER_RULE_EFFECT_NONE; std::string raw; LayerRuleEffectValue value; }; - class CLayerRule : public IRule { + class CLayerRule : public CRuleWithEffects { public: - using storageType = CLayerRuleEffectContainer::storageType; + using Base = CRuleWithEffects; + using storageType = Base::storageType; CLayerRule(const std::string& name = ""); virtual ~CLayerRule() = default; - virtual eRuleType type(); - - std::expected addEffect(storageType e, const std::string& result); - const std::vector& effects(); - - void setEnabled(bool enable); - bool isEnabled() const; - - bool matches(PHLLS w); + bool matches(PHLLS w); private: - std::vector m_effects; - bool m_enabled = true; + std::expected parseEffect(storageType e, const std::string& result) override; }; }; diff --git a/src/desktop/rule/windowRule/WindowRule.cpp b/src/desktop/rule/windowRule/WindowRule.cpp index 481e471cf..c2b520c05 100644 --- a/src/desktop/rule/windowRule/WindowRule.cpp +++ b/src/desktop/rule/windowRule/WindowRule.cpp @@ -330,31 +330,16 @@ static std::expected parseWindowRuleEffect(C } } -CWindowRule::CWindowRule(const std::string& name) : IRule(name) { +CWindowRule::CWindowRule(const std::string& name) : CRuleWithEffects(name) { ; } -eRuleType CWindowRule::type() { - return RULE_TYPE_WINDOW; -} - -std::expected CWindowRule::addEffect(CWindowRule::storageType e, const std::string& result) { - auto parsed = parseWindowRuleEffect(e, result); - if (!parsed) - return std::unexpected(parsed.error()); - - m_effects.emplace_back(SWindowRuleEffect{.key = e, .raw = result, .value = std::move(*parsed)}); - m_effectSet.emplace(e); - - return {}; -} - -const std::vector& CWindowRule::effects() { - return m_effects; +std::expected CWindowRule::parseEffect(CWindowRule::storageType e, const std::string& result) { + return parseWindowRuleEffect(e, result); } bool CWindowRule::matches(PHLWINDOW w, bool allowEnvLookup) { - if (m_matchEngines.empty() || !m_enabled) + if (!canMatch()) return false; for (const auto& [prop, engine] : m_matchEngines) { @@ -491,15 +476,3 @@ std::expected, std::string> CWindowRule::buildFromExecString(std return wr; } - -const std::unordered_set& CWindowRule::effectsSet() { - return m_effectSet; -} - -void CWindowRule::setEnabled(bool enable) { - m_enabled = enable; -} - -bool CWindowRule::isEnabled() const { - return m_enabled; -} diff --git a/src/desktop/rule/windowRule/WindowRule.hpp b/src/desktop/rule/windowRule/WindowRule.hpp index 19560c153..61fc15203 100644 --- a/src/desktop/rule/windowRule/WindowRule.hpp +++ b/src/desktop/rule/windowRule/WindowRule.hpp @@ -1,6 +1,6 @@ #pragma once -#include "../Rule.hpp" +#include "../RuleWithEffects.hpp" #include "../../DesktopTypes.hpp" #include "../../types/OverridableVar.hpp" #include "WindowRuleEffectContainer.hpp" @@ -33,14 +33,18 @@ namespace Desktop::Rule { using WindowRuleEffectValue = std::variant, SFullscreenStateRule, SOpacityRule, SBorderColorRule>; struct SWindowRuleEffect { + using storageType = CWindowRuleEffectContainer::storageType; + using valueType = WindowRuleEffectValue; + CWindowRuleEffectContainer::storageType key = WINDOW_RULE_EFFECT_NONE; std::string raw; WindowRuleEffectValue value; }; - class CWindowRule : public IRule { + class CWindowRule : public CRuleWithEffects { private: - using storageType = CWindowRuleEffectContainer::storageType; + using Base = CRuleWithEffects; + using storageType = Base::storageType; public: CWindowRule(const std::string& name = ""); @@ -52,20 +56,9 @@ namespace Desktop::Rule { static std::expected, std::string> buildFromExecString(std::string&&); - virtual eRuleType type(); - - std::expected addEffect(storageType e, const std::string& result); - const std::vector& effects(); - const std::unordered_set& effectsSet(); - - void setEnabled(bool enable); - bool isEnabled() const; - bool matches(PHLWINDOW w, bool allowEnvLookup = false); private: - std::vector m_effects; - std::unordered_set m_effectSet; - bool m_enabled = true; + std::expected parseEffect(storageType e, const std::string& result) override; }; };