From fb46d16fc2bedea96b6b2a4d005ec66d701431aa Mon Sep 17 00:00:00 2001 From: Pppp1116 Date: Wed, 8 Apr 2026 12:06:58 +0100 Subject: [PATCH] rules: make rule prop reset less cursed (#14003) --- .../rule/layerRule/LayerRuleApplicator.cpp | 40 ++++---- .../rule/windowRule/WindowRuleApplicator.cpp | 94 +++++++++---------- 2 files changed, 62 insertions(+), 72 deletions(-) diff --git a/src/desktop/rule/layerRule/LayerRuleApplicator.cpp b/src/desktop/rule/layerRule/LayerRuleApplicator.cpp index fec3a5b29..8c157dae8 100644 --- a/src/desktop/rule/layerRule/LayerRuleApplicator.cpp +++ b/src/desktop/rule/layerRule/LayerRuleApplicator.cpp @@ -5,36 +5,34 @@ #include "../../types/OverridableVar.hpp" #include "../../../helpers/MiscFunctions.hpp" #include "../../../event/EventBus.hpp" +#include using namespace Desktop; using namespace Desktop::Rule; +namespace { + template + void resetRuleProp(std::pair, std::underlying_type_t>& prop, + std::underlying_type_t props, Desktop::Types::eOverridePriority prio) { + auto& [value, propMask] = prop; + + if (!(propMask & props)) + return; + + if (prio == Desktop::Types::PRIORITY_WINDOW_RULE) + propMask &= ~props; + + value.unset(prio); + } +} + 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) - -#undef UNSET + std::apply([&](auto&... prop) { (resetRuleProp(prop, props, prio), ...); }, + std::forward_as_tuple(m_noanim, m_blur, m_blurPopups, m_dimAround, m_xray, m_noScreenShare, m_order, m_aboveLock, m_ignoreAlpha, m_animationStyle)); if (prio == Types::PRIORITY_WINDOW_RULE) std::erase_if(m_otherProps.props, [props](const auto& el) { return !el.second || el.second->propMask & props; }); diff --git a/src/desktop/rule/windowRule/WindowRuleApplicator.cpp b/src/desktop/rule/windowRule/WindowRuleApplicator.cpp index a9e82ef54..4af0d2ba1 100644 --- a/src/desktop/rule/windowRule/WindowRuleApplicator.cpp +++ b/src/desktop/rule/windowRule/WindowRuleApplicator.cpp @@ -9,70 +9,62 @@ #include #include #include +#include using namespace Hyprutils::String; using namespace Desktop; using namespace Desktop::Rule; +namespace { + template + void resetRuleProp(std::pair, std::underlying_type_t>& prop, + std::underlying_type_t props, Desktop::Types::eOverridePriority prio, + std::unordered_set& effectsNuked, TEffect&& effect) { + auto& [value, propMask] = prop; + + if (!(propMask & props)) + return; + + if (prio == Desktop::Types::PRIORITY_WINDOW_RULE) { + effectsNuked.emplace(effect()); + propMask &= ~props; + } + + value.unset(prio); + } +} + CWindowRuleApplicator::CWindowRuleApplicator(PHLWINDOW w) : m_window(w) { ; } std::unordered_set CWindowRuleApplicator::resetProps(std::underlying_type_t props, Types::eOverridePriority prio) { - // TODO: fucking kill me, is there a better way to do this? - std::unordered_set effectsNuked; -#define UNSET(x) \ - if (m_##x.second & props) { \ - if (prio == Types::PRIORITY_WINDOW_RULE) { \ - effectsNuked.emplace(x##Effect()); \ - m_##x.second &= ~props; \ - } \ - m_##x.first.unset(prio); \ - } - - UNSET(alpha) - UNSET(alphaInactive) - UNSET(alphaFullscreen) - UNSET(allowsInput) - UNSET(decorate) - UNSET(focusOnActivate) - UNSET(keepAspectRatio) - UNSET(nearestNeighbor) - UNSET(noAnim) - UNSET(noBlur) - UNSET(noDim) - UNSET(noFocus) - UNSET(noMaxSize) - UNSET(noShadow) - UNSET(noShortcutsInhibit) - UNSET(opaque) - UNSET(dimAround) - UNSET(RGBX) - UNSET(syncFullscreen) - UNSET(tearing) - UNSET(xray) - UNSET(renderUnfocused) - UNSET(noFollowMouse) - UNSET(noScreenShare) - UNSET(noVRR) - UNSET(persistentSize) - UNSET(stayFocused) - UNSET(idleInhibitMode) - UNSET(borderSize) - UNSET(rounding) - UNSET(roundingPower) - UNSET(scrollMouse) - UNSET(scrollTouchpad) - UNSET(animationStyle) - UNSET(maxSize) - UNSET(minSize) - UNSET(activeBorderColor) - UNSET(inactiveBorderColor) - -#undef UNSET + std::apply([&](auto&&... prop) { (resetRuleProp(prop.first.get(), props, prio, effectsNuked, prop.second), ...); }, + std::make_tuple( + std::pair{std::ref(m_alpha), [this] { return alphaEffect(); }}, std::pair{std::ref(m_alphaInactive), [this] { return alphaInactiveEffect(); }}, + std::pair{std::ref(m_alphaFullscreen), [this] { return alphaFullscreenEffect(); }}, std::pair{std::ref(m_allowsInput), [this] { return allowsInputEffect(); }}, + std::pair{std::ref(m_decorate), [this] { return decorateEffect(); }}, std::pair{std::ref(m_focusOnActivate), [this] { return focusOnActivateEffect(); }}, + std::pair{std::ref(m_keepAspectRatio), [this] { return keepAspectRatioEffect(); }}, + std::pair{std::ref(m_nearestNeighbor), [this] { return nearestNeighborEffect(); }}, std::pair{std::ref(m_noAnim), [this] { return noAnimEffect(); }}, + std::pair{std::ref(m_noBlur), [this] { return noBlurEffect(); }}, std::pair{std::ref(m_noDim), [this] { return noDimEffect(); }}, + std::pair{std::ref(m_noFocus), [this] { return noFocusEffect(); }}, std::pair{std::ref(m_noMaxSize), [this] { return noMaxSizeEffect(); }}, + std::pair{std::ref(m_noShadow), [this] { return noShadowEffect(); }}, std::pair{std::ref(m_noShortcutsInhibit), [this] { return noShortcutsInhibitEffect(); }}, + std::pair{std::ref(m_opaque), [this] { return opaqueEffect(); }}, std::pair{std::ref(m_dimAround), [this] { return dimAroundEffect(); }}, + std::pair{std::ref(m_RGBX), [this] { return RGBXEffect(); }}, std::pair{std::ref(m_syncFullscreen), [this] { return syncFullscreenEffect(); }}, + std::pair{std::ref(m_tearing), [this] { return tearingEffect(); }}, std::pair{std::ref(m_xray), [this] { return xrayEffect(); }}, + std::pair{std::ref(m_renderUnfocused), [this] { return renderUnfocusedEffect(); }}, + std::pair{std::ref(m_noFollowMouse), [this] { return noFollowMouseEffect(); }}, std::pair{std::ref(m_noScreenShare), [this] { return noScreenShareEffect(); }}, + std::pair{std::ref(m_noVRR), [this] { return noVRREffect(); }}, std::pair{std::ref(m_persistentSize), [this] { return persistentSizeEffect(); }}, + std::pair{std::ref(m_stayFocused), [this] { return stayFocusedEffect(); }}, std::pair{std::ref(m_idleInhibitMode), [this] { return idleInhibitModeEffect(); }}, + std::pair{std::ref(m_borderSize), [this] { return borderSizeEffect(); }}, std::pair{std::ref(m_rounding), [this] { return roundingEffect(); }}, + std::pair{std::ref(m_roundingPower), [this] { return roundingPowerEffect(); }}, std::pair{std::ref(m_scrollMouse), [this] { return scrollMouseEffect(); }}, + std::pair{std::ref(m_scrollTouchpad), [this] { return scrollTouchpadEffect(); }}, + std::pair{std::ref(m_animationStyle), [this] { return animationStyleEffect(); }}, std::pair{std::ref(m_maxSize), [this] { return maxSizeEffect(); }}, + std::pair{std::ref(m_minSize), [this] { return minSizeEffect(); }}, std::pair{std::ref(m_activeBorderColor), [this] { return activeBorderColorEffect(); }}, + std::pair{std::ref(m_inactiveBorderColor), [this] { return inactiveBorderColorEffect(); }})); if (prio == Types::PRIORITY_WINDOW_RULE) { std::erase_if(m_dynamicTags, [props, this](const auto& el) {