windowrules: add negative: prefix for negating a regex

fixes #8799
This commit is contained in:
Vaxry 2024-12-21 23:07:23 +00:00
parent 57921d7dbd
commit 31422ae25d
5 changed files with 61 additions and 34 deletions

View file

@ -1258,10 +1258,10 @@ std::vector<SP<CWindowRule>> CConfigManager::getMatchingRules(PHLWINDOW pWindow,
if (rule->szValue.starts_with("tag:") && !tags.isTagged(rule->szValue.substr(4))) if (rule->szValue.starts_with("tag:") && !tags.isTagged(rule->szValue.substr(4)))
continue; continue;
if (rule->szValue.starts_with("title:") && !RE2::FullMatch(pWindow->m_szTitle, *rule->rV1Regex)) if (rule->szValue.starts_with("title:") && !rule->rV1Regex.passes(pWindow->m_szTitle))
continue; continue;
if (!RE2::FullMatch(pWindow->m_szClass, *rule->rV1Regex)) if (!rule->rV1Regex.passes(pWindow->m_szClass))
continue; continue;
} catch (...) { } catch (...) {
@ -1351,16 +1351,16 @@ std::vector<SP<CWindowRule>> CConfigManager::getMatchingRules(PHLWINDOW pWindow,
if (!rule->szTag.empty() && !tags.isTagged(rule->szTag)) if (!rule->szTag.empty() && !tags.isTagged(rule->szTag))
continue; continue;
if (!rule->szClass.empty() && !RE2::FullMatch(pWindow->m_szClass, *rule->rClass)) if (!rule->szClass.empty() && !rule->rClass.passes(pWindow->m_szClass))
continue; continue;
if (!rule->szTitle.empty() && !RE2::FullMatch(pWindow->m_szTitle, *rule->rTitle)) if (!rule->szTitle.empty() && !rule->rTitle.passes(pWindow->m_szTitle))
continue; continue;
if (!rule->szInitialTitle.empty() && !RE2::FullMatch(pWindow->m_szInitialTitle, *rule->rInitialTitle)) if (!rule->szInitialTitle.empty() && !rule->rInitialTitle.passes(pWindow->m_szInitialTitle))
continue; continue;
if (!rule->szInitialClass.empty() && !RE2::FullMatch(pWindow->m_szInitialClass, *rule->rInitialClass)) if (!rule->szInitialClass.empty() && !rule->rInitialClass.passes(pWindow->m_szInitialClass))
continue; continue;
} catch (std::exception& e) { } catch (std::exception& e) {
@ -1419,7 +1419,7 @@ std::vector<SP<CLayerRule>> CConfigManager::getMatchingRules(PHLLS pLS) {
if (lr->targetNamespace.starts_with("address:0x")) { if (lr->targetNamespace.starts_with("address:0x")) {
if (std::format("address:0x{:x}", (uintptr_t)pLS.get()) != lr->targetNamespace) if (std::format("address:0x{:x}", (uintptr_t)pLS.get()) != lr->targetNamespace)
continue; continue;
} else if (!RE2::FullMatch(pLS->layerSurface->layerNamespace, *lr->rTargetNamespaceRegex)) } else if (!lr->targetNamespaceRegex.passes(pLS->layerSurface->layerNamespace))
continue; continue;
// hit // hit
@ -2281,7 +2281,7 @@ std::optional<std::string> CConfigManager::handleWindowRule(const std::string& c
return "Invalid rule: " + RULE; return "Invalid rule: " + RULE;
} }
newRule->rV1Regex = std::make_unique<RE2>(VALUE.starts_with("title:") ? VALUE.substr(6) : VALUE); newRule->rV1Regex = {VALUE.starts_with("title:") ? VALUE.substr(6) : VALUE};
if (RULE.starts_with("size") || RULE.starts_with("maxsize") || RULE.starts_with("minsize")) if (RULE.starts_with("size") || RULE.starts_with("maxsize") || RULE.starts_with("minsize"))
m_vWindowRules.insert(m_vWindowRules.begin(), newRule); m_vWindowRules.insert(m_vWindowRules.begin(), newRule);
@ -2311,7 +2311,7 @@ std::optional<std::string> CConfigManager::handleLayerRule(const std::string& co
return "Invalid rule found: " + RULE; return "Invalid rule found: " + RULE;
} }
rule->rTargetNamespaceRegex = std::make_unique<RE2>(VALUE); rule->targetNamespaceRegex = {VALUE};
m_vLayerRules.emplace_back(rule); m_vLayerRules.emplace_back(rule);
@ -2413,22 +2413,22 @@ std::optional<std::string> CConfigManager::handleWindowRuleV2(const std::string&
if (CLASSPOS != std::string::npos) { if (CLASSPOS != std::string::npos) {
rule->szClass = extract(CLASSPOS + 6); rule->szClass = extract(CLASSPOS + 6);
rule->rClass = std::make_unique<RE2>(rule->szClass); rule->rClass = {rule->szClass};
} }
if (TITLEPOS != std::string::npos) { if (TITLEPOS != std::string::npos) {
rule->szTitle = extract(TITLEPOS + 6); rule->szTitle = extract(TITLEPOS + 6);
rule->rTitle = std::make_unique<RE2>(rule->szTitle); rule->rTitle = {rule->szTitle};
} }
if (INITIALCLASSPOS != std::string::npos) { if (INITIALCLASSPOS != std::string::npos) {
rule->szInitialClass = extract(INITIALCLASSPOS + 13); rule->szInitialClass = extract(INITIALCLASSPOS + 13);
rule->rInitialClass = std::make_unique<RE2>(rule->szInitialClass); rule->rInitialClass = {rule->szInitialClass};
} }
if (INITIALTITLEPOS != std::string::npos) { if (INITIALTITLEPOS != std::string::npos) {
rule->szInitialTitle = extract(INITIALTITLEPOS + 13); rule->szInitialTitle = extract(INITIALTITLEPOS + 13);
rule->rInitialTitle = std::make_unique<RE2>(rule->szInitialTitle); rule->rInitialTitle = {rule->szInitialTitle};
} }
if (X11POS != std::string::npos) if (X11POS != std::string::npos)

View file

@ -2,12 +2,7 @@
#include <string> #include <string>
#include <cstdint> #include <cstdint>
#include <memory> #include "Rule.hpp"
//NOLINTNEXTLINE
namespace re2 {
class RE2;
};
class CLayerRule { class CLayerRule {
public: public:
@ -27,10 +22,10 @@ class CLayerRule {
RULE_ZUMBA, RULE_ZUMBA,
}; };
eRuleType ruleType = RULE_INVALID; eRuleType ruleType = RULE_INVALID;
const std::string targetNamespace; const std::string targetNamespace;
const std::string rule; const std::string rule;
std::unique_ptr<re2::RE2> rTargetNamespaceRegex; CRuleRegexContainer targetNamespaceRegex;
}; };

16
src/desktop/Rule.cpp Normal file
View file

@ -0,0 +1,16 @@
#include "Rule.hpp"
#include <re2/re2.h>
CRuleRegexContainer::CRuleRegexContainer(const std::string& regex_) {
const bool NEGATIVE = regex_.starts_with("negative:");
negative = NEGATIVE;
regex = std::make_unique<RE2>(NEGATIVE ? regex_.substr(9) : regex_);
}
bool CRuleRegexContainer::passes(const std::string& str) const {
if (!regex)
return false;
return RE2::FullMatch(str, *regex) != negative;
}

21
src/desktop/Rule.hpp Normal file
View file

@ -0,0 +1,21 @@
#pragma once
#include <memory>
//NOLINTNEXTLINE
namespace re2 {
class RE2;
};
class CRuleRegexContainer {
public:
CRuleRegexContainer() = default;
CRuleRegexContainer(const std::string& regex);
bool passes(const std::string& str) const;
private:
std::unique_ptr<re2::RE2> regex;
bool negative = false;
};

View file

@ -2,12 +2,7 @@
#include <string> #include <string>
#include <cstdint> #include <cstdint>
#include <memory> #include "Rule.hpp"
//NOLINTNEXTLINE
namespace re2 {
class RE2;
};
class CWindowRule { class CWindowRule {
public: public:
@ -65,9 +60,9 @@ class CWindowRule {
std::string szWorkspace = ""; // empty means any std::string szWorkspace = ""; // empty means any
// precompiled regexes // precompiled regexes
std::unique_ptr<re2::RE2> rTitle; CRuleRegexContainer rTitle;
std::unique_ptr<re2::RE2> rClass; CRuleRegexContainer rClass;
std::unique_ptr<re2::RE2> rInitialTitle; CRuleRegexContainer rInitialTitle;
std::unique_ptr<re2::RE2> rInitialClass; CRuleRegexContainer rInitialClass;
std::unique_ptr<re2::RE2> rV1Regex; CRuleRegexContainer rV1Regex;
}; };