summaryrefslogtreecommitdiff
path: root/src/desktop/rule/windowRule
diff options
context:
space:
mode:
authorVaxry <43317083+vaxerski@users.noreply.github.com>2026-04-28 18:10:25 +0100
committerGitHub <noreply@github.com>2026-04-28 18:10:25 +0100
commit94b90a2cb0b4a0e13018cd5ebbf09394abf3b96b (patch)
tree484d32baaab1acdaab7a817c86aa89f117a21059 /src/desktop/rule/windowRule
parentab75bbfbecdfb4a0355106f740944c87cb9edd4c (diff)
config/lua: add ExpressionVec2, allow using a table for vec2 rules (#14197)
Diffstat (limited to 'src/desktop/rule/windowRule')
-rw-r--r--src/desktop/rule/windowRule/WindowRule.cpp24
-rw-r--r--src/desktop/rule/windowRule/WindowRule.hpp8
-rw-r--r--src/desktop/rule/windowRule/WindowRuleApplicator.cpp34
-rw-r--r--src/desktop/rule/windowRule/WindowRuleApplicator.hpp31
4 files changed, 69 insertions, 28 deletions
diff --git a/src/desktop/rule/windowRule/WindowRule.cpp b/src/desktop/rule/windowRule/WindowRule.cpp
index c2b520c0..10d39383 100644
--- a/src/desktop/rule/windowRule/WindowRule.cpp
+++ b/src/desktop/rule/windowRule/WindowRule.cpp
@@ -259,13 +259,19 @@ static std::expected<WindowRuleEffectValue, std::string> parseWindowRuleEffect(C
case WINDOW_RULE_EFFECT_MOVE:
case WINDOW_RULE_EFFECT_SIZE:
+ case WINDOW_RULE_EFFECT_MAX_SIZE:
+ case WINDOW_RULE_EFFECT_MIN_SIZE: {
+ auto parsed = Math::parseExpressionVec2(raw);
+ if (!parsed)
+ return std::unexpected(std::format("{} rule \"{}\" failed with: {}", EFFECT_NAME, raw, parsed.error()));
+ return *parsed;
+ }
+
case WINDOW_RULE_EFFECT_MONITOR:
case WINDOW_RULE_EFFECT_WORKSPACE:
case WINDOW_RULE_EFFECT_GROUP:
case WINDOW_RULE_EFFECT_ANIMATION:
- case WINDOW_RULE_EFFECT_TAG:
- case WINDOW_RULE_EFFECT_MAX_SIZE:
- case WINDOW_RULE_EFFECT_MIN_SIZE: return std::string{raw};
+ case WINDOW_RULE_EFFECT_TAG: return std::string{raw};
case WINDOW_RULE_EFFECT_SUPPRESSEVENT: return parseStringList(raw);
@@ -334,6 +340,18 @@ CWindowRule::CWindowRule(const std::string& name) : CRuleWithEffects<SWindowRule
;
}
+std::expected<void, std::string> CWindowRule::addEffect(CWindowRule::storageType e, const Math::SExpressionVec2& expr) {
+ switch (e) {
+ case WINDOW_RULE_EFFECT_MOVE:
+ case WINDOW_RULE_EFFECT_SIZE:
+ case WINDOW_RULE_EFFECT_MAX_SIZE:
+ case WINDOW_RULE_EFFECT_MIN_SIZE: break;
+ default: return std::unexpected(std::format("{} is not an expression vec2 window rule effect", windowEffects()->get(e)));
+ }
+
+ return addParsedEffect(e, expr, expr.toString());
+}
+
std::expected<WindowRuleEffectValue, std::string> CWindowRule::parseEffect(CWindowRule::storageType e, const std::string& result) {
return parseWindowRuleEffect(e, result);
}
diff --git a/src/desktop/rule/windowRule/WindowRule.hpp b/src/desktop/rule/windowRule/WindowRule.hpp
index 61fc1520..3701ae35 100644
--- a/src/desktop/rule/windowRule/WindowRule.hpp
+++ b/src/desktop/rule/windowRule/WindowRule.hpp
@@ -5,6 +5,7 @@
#include "../../types/OverridableVar.hpp"
#include "WindowRuleEffectContainer.hpp"
#include "../../../config/shared/complex/ComplexDataTypes.hpp"
+#include "../../../helpers/math/Expression.hpp"
#include "../../../helpers/math/Math.hpp"
#include <expected>
@@ -30,7 +31,8 @@ namespace Desktop::Rule {
std::optional<Config::CGradientValueData> inactive;
};
- using WindowRuleEffectValue = std::variant<std::monostate, bool, int64_t, float, std::string, std::vector<std::string>, SFullscreenStateRule, SOpacityRule, SBorderColorRule>;
+ using WindowRuleEffectValue =
+ std::variant<std::monostate, bool, int64_t, float, std::string, std::vector<std::string>, SFullscreenStateRule, SOpacityRule, SBorderColorRule, Math::SExpressionVec2>;
struct SWindowRuleEffect {
using storageType = CWindowRuleEffectContainer::storageType;
@@ -50,12 +52,16 @@ namespace Desktop::Rule {
CWindowRule(const std::string& name = "");
virtual ~CWindowRule() = default;
+ using Base::addEffect;
+
CWindowRule(const CWindowRule&) = default;
CWindowRule(CWindowRule&) = default;
CWindowRule(CWindowRule&&) = default;
static std::expected<SP<CWindowRule>, std::string> buildFromExecString(std::string&&);
+ std::expected<void, std::string> addEffect(storageType e, const Math::SExpressionVec2& expr);
+
bool matches(PHLWINDOW w, bool allowEnvLookup = false);
private:
diff --git a/src/desktop/rule/windowRule/WindowRuleApplicator.cpp b/src/desktop/rule/windowRule/WindowRuleApplicator.cpp
index b51049e6..c19c6338 100644
--- a/src/desktop/rule/windowRule/WindowRuleApplicator.cpp
+++ b/src/desktop/rule/windowRule/WindowRuleApplicator.cpp
@@ -168,9 +168,13 @@ CWindowRuleApplicator::SRuleResult CWindowRuleApplicator::applyDynamicRule(const
if (!m_window)
break;
- const auto VEC = m_window->calculateExpression(effect);
+ const auto& expr = std::get<Math::SExpressionVec2>(value);
+ if (expr.empty())
+ break;
+
+ const auto VEC = m_window->calculateExpression(expr);
if (!VEC) {
- Log::logger->log(Log::ERR, "failed to parse {} as an expression", effect);
+ Log::logger->log(Log::ERR, "failed to parse {} as an expression", expr.toString());
break;
}
if (VEC->x < 1 || VEC->y < 1) {
@@ -182,7 +186,7 @@ CWindowRuleApplicator::SRuleResult CWindowRuleApplicator::applyDynamicRule(const
if (*PCLAMP_TILED || m_window->m_isFloating)
m_window->clampWindowSize(std::nullopt, m_maxSize.first.value());
- } catch (std::exception& e) { Log::logger->log(Log::ERR, "maxsize rule \"{}\" failed with: {}", effect, e.what()); }
+ } catch (std::exception& e) { Log::logger->log(Log::ERR, "maxsize rule \"{}\" failed with: {}", std::get<Math::SExpressionVec2>(value).toString(), e.what()); }
m_maxSize.second = rule->getPropertiesMask();
break;
}
@@ -193,9 +197,13 @@ CWindowRuleApplicator::SRuleResult CWindowRuleApplicator::applyDynamicRule(const
if (!m_window)
break;
- const auto VEC = m_window->calculateExpression(effect);
+ const auto& expr = std::get<Math::SExpressionVec2>(value);
+ if (expr.empty())
+ break;
+
+ const auto VEC = m_window->calculateExpression(expr);
if (!VEC) {
- Log::logger->log(Log::ERR, "failed to parse {} as an expression", effect);
+ Log::logger->log(Log::ERR, "failed to parse {} as an expression", expr.toString());
break;
}
@@ -207,7 +215,7 @@ CWindowRuleApplicator::SRuleResult CWindowRuleApplicator::applyDynamicRule(const
m_minSize.first = Types::COverridableVar(*VEC, Types::PRIORITY_WINDOW_RULE);
if (*PCLAMP_TILED || m_window->m_isFloating)
m_window->clampWindowSize(m_minSize.first.value(), std::nullopt);
- } catch (std::exception& e) { Log::logger->log(Log::ERR, "minsize rule \"{}\" failed with: {}", effect, e.what()); }
+ } catch (std::exception& e) { Log::logger->log(Log::ERR, "minsize rule \"{}\" failed with: {}", std::get<Math::SExpressionVec2>(value).toString(), e.what()); }
m_minSize.second = rule->getPropertiesMask();
break;
}
@@ -385,15 +393,23 @@ CWindowRuleApplicator::SRuleResult CWindowRuleApplicator::applyStaticRule(const
}
case WINDOW_RULE_EFFECT_MOVE: {
static_.center = std::nullopt;
- static_.position = std::get<std::string>(value);
+ const auto& expr = std::get<Math::SExpressionVec2>(value);
+ if (expr.empty())
+ static_.position.reset();
+ else
+ static_.position = expr;
break;
}
case WINDOW_RULE_EFFECT_SIZE: {
- static_.size = std::get<std::string>(value);
+ const auto& expr = std::get<Math::SExpressionVec2>(value);
+ if (expr.empty())
+ static_.size.reset();
+ else
+ static_.size = expr;
break;
}
case WINDOW_RULE_EFFECT_CENTER: {
- static_.position.clear();
+ static_.position.reset();
static_.center = std::get<bool>(value);
break;
}
diff --git a/src/desktop/rule/windowRule/WindowRuleApplicator.hpp b/src/desktop/rule/windowRule/WindowRuleApplicator.hpp
index 1e52ed5c..f5e43609 100644
--- a/src/desktop/rule/windowRule/WindowRuleApplicator.hpp
+++ b/src/desktop/rule/windowRule/WindowRuleApplicator.hpp
@@ -8,6 +8,7 @@
#include "../Rule.hpp"
#include "../../types/OverridableVar.hpp"
#include "../../../helpers/math/Math.hpp"
+#include "../../../helpers/math/Expression.hpp"
#include "../../../helpers/TagKeeper.hpp"
#include "../../../config/shared/complex/ComplexDataTypes.hpp"
@@ -38,25 +39,25 @@ namespace Desktop::Rule {
// static props
struct {
- std::string monitor, workspace, group;
+ std::string monitor, workspace, group;
- std::optional<bool> floating;
- std::optional<bool> fullscreen;
- std::optional<bool> maximize;
- std::optional<bool> pseudo;
- std::optional<bool> pin;
- std::optional<bool> noInitialFocus;
- std::optional<bool> center;
+ std::optional<bool> floating;
+ std::optional<bool> fullscreen;
+ std::optional<bool> maximize;
+ std::optional<bool> pseudo;
+ std::optional<bool> pin;
+ std::optional<bool> noInitialFocus;
+ std::optional<bool> center;
- std::optional<int> fullscreenStateClient;
- std::optional<int> fullscreenStateInternal;
- std::optional<int> content;
- std::optional<int> noCloseFor;
+ std::optional<int> fullscreenStateClient;
+ std::optional<int> fullscreenStateInternal;
+ std::optional<int> content;
+ std::optional<int> noCloseFor;
- std::string size, position;
- std::optional<float> scrollingWidth;
+ std::optional<Math::SExpressionVec2> size, position;
+ std::optional<float> scrollingWidth;
- std::vector<std::string> suppressEvent;
+ std::vector<std::string> suppressEvent;
} static_;
struct SCustomPropContainer {