From c2670e9ab90bd657e87a1da2c5322e9007dce01f Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Mon, 17 Nov 2025 18:34:02 +0000 Subject: windowrules: rewrite completely (#12269) Reworks the window rule syntax completely --------- Co-authored-by: Mihai Fufezan --- src/desktop/rule/layerRule/LayerRuleApplicator.cpp | 128 +++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 src/desktop/rule/layerRule/LayerRuleApplicator.cpp (limited to 'src/desktop/rule/layerRule/LayerRuleApplicator.cpp') diff --git a/src/desktop/rule/layerRule/LayerRuleApplicator.cpp b/src/desktop/rule/layerRule/LayerRuleApplicator.cpp new file mode 100644 index 00000000..bb7da97f --- /dev/null +++ b/src/desktop/rule/layerRule/LayerRuleApplicator.cpp @@ -0,0 +1,128 @@ +#include "LayerRuleApplicator.hpp" +#include "LayerRule.hpp" +#include "../Engine.hpp" +#include "../../LayerSurface.hpp" +#include "../../types/OverridableVar.hpp" +#include "../../../helpers/MiscFunctions.hpp" + +using namespace Desktop; +using namespace Desktop::Rule; + +CLayerRuleApplicator::CLayerRuleApplicator(PHLLS ls) : m_ls(ls) { + ; +} + +void CLayerRuleApplicator::resetProps(std::underlying_type_t props, Types::eOverridePriority prio) { + // TODO: fucking kill me, is there a better way to do this? + +#define UNSET(x) \ + if (m_##x.second & props) { \ + if (prio == Types::PRIORITY_WINDOW_RULE) \ + m_##x.second &= ~props; \ + m_##x.first.unset(prio); \ + } + + UNSET(noanim) + UNSET(blur) + UNSET(blurPopups) + UNSET(dimAround) + UNSET(xray) + UNSET(noScreenShare) + UNSET(order) + UNSET(aboveLock) + UNSET(ignoreAlpha) + UNSET(animationStyle) +} + +void CLayerRuleApplicator::applyDynamicRule(const SP& rule) { + for (const auto& [key, effect] : rule->effects()) { + switch (key) { + case LAYER_RULE_EFFECT_NONE: { + Debug::log(ERR, "CLayerRuleApplicator::applyDynamicRule: BUG THIS: LAYER_RULE_EFFECT_NONE??"); + break; + } + case LAYER_RULE_EFFECT_NO_ANIM: { + m_noanim.first.set(truthy(effect), 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.second |= rule->getPropertiesMask(); + break; + } + case LAYER_RULE_EFFECT_BLUR_POPUPS: { + m_blurPopups.first.set(truthy(effect), 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.second |= rule->getPropertiesMask(); + break; + } + case LAYER_RULE_EFFECT_XRAY: { + m_xray.first.set(truthy(effect), 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.second |= rule->getPropertiesMask(); + break; + } + case LAYER_RULE_EFFECT_ORDER: { + try { + m_noScreenShare.first.set(std::stoi(effect), Types::PRIORITY_WINDOW_RULE); + m_noScreenShare.second |= rule->getPropertiesMask(); + } catch (...) { Debug::log(ERR, "CLayerRuleApplicator::applyDynamicRule: invalid order {}", effect); } + 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 (...) { Debug::log(ERR, "CLayerRuleApplicator::applyDynamicRule: invalid order {}", effect); } + 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 (...) { Debug::log(ERR, "CLayerRuleApplicator::applyDynamicRule: invalid order {}", effect); } + break; + } + case LAYER_RULE_EFFECT_ANIMATION: { + m_animationStyle.first.set(effect, Types::PRIORITY_WINDOW_RULE); + m_animationStyle.second |= rule->getPropertiesMask(); + break; + } + } + } +} + +void CLayerRuleApplicator::propertiesChanged(std::underlying_type_t props) { + if (!m_ls) + return; + + resetProps(props); + + // FIXME: this will not update properties correctly if we implement dynamic rules for + // layers, due to effects overlapping on 0 prop intersection. + // See WindowRule.cpp, and ::propertiesChanged there. + + for (const auto& r : ruleEngine()->rules()) { + if (r->type() != RULE_TYPE_LAYER) + continue; + + if (!(r->getPropertiesMask() & props)) + continue; + + auto wr = reinterpretPointerCast(r); + + if (!wr->matches(m_ls.lock())) + continue; + + applyDynamicRule(wr); + } +} -- cgit v1.2.3