Added window rules

This commit is contained in:
vaxerski 2022-03-24 18:22:01 +01:00
parent 8cec07c39d
commit ccbc0e4a2e
8 changed files with 178 additions and 11 deletions

View file

@ -163,6 +163,30 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v
g_pKeybindManager->addKeybind(SKeybind{KEY, MOD, HANDLER, COMMAND});
}
void CConfigManager::handleWindowRule(const std::string& command, const std::string& value) {
const auto RULE = value.substr(0, value.find_first_of(","));
const auto VALUE = value.substr(value.find_first_of(",") + 1);
// check rule and value
if (RULE == "" || VALUE == "") {
return;
}
// verify we support a rule
if (RULE != "float"
&& RULE != "tile"
&& RULE.find("move") != 0
&& RULE.find("size") != 0
&& RULE.find("monitor") != 0) {
Debug::log(ERR, "Invalid rule found: %s", RULE.c_str());
parseError = "Invalid rule found: " + RULE;
return;
}
m_dWindowRules.push_back({RULE, VALUE});
}
void CConfigManager::handleDefaultWorkspace(const std::string& command, const std::string& value) {
const auto DISPLAY = value.substr(0, value.find_first_of(','));
@ -230,6 +254,9 @@ void CConfigManager::parseLine(std::string& line) {
} else if (COMMAND == "workspace") {
handleDefaultWorkspace(COMMAND, VALUE);
return;
} else if (COMMAND == "windowrule") {
handleWindowRule(COMMAND, VALUE);
return;
}
configSetValueSafe(currentCategory + (currentCategory == "" ? "" : ":") + COMMAND, VALUE);
@ -241,6 +268,7 @@ void CConfigManager::loadConfigLoadVars() {
currentCategory = ""; // reset the category
m_dMonitorRules.clear();
m_dWindowRules.clear();
g_pKeybindManager->clearKeybinds();
const char* const ENVHOME = getenv("HOME");
@ -357,4 +385,33 @@ SMonitorRule CConfigManager::getMonitorRuleFor(std::string name) {
Debug::log(WARN, "No rules configured. Using the default hardcoded one.");
return SMonitorRule{.name = "", .resolution = Vector2D(1280, 720), .offset = Vector2D(0, 0), .mfact = 0.5f, .scale = 1};
}
std::vector<SWindowRule> CConfigManager::getMatchingRules(CWindow* pWindow) {
if (!g_pCompositor->windowValidMapped(pWindow))
return std::vector<SWindowRule>();
std::vector<SWindowRule> returns;
std::string title = g_pXWaylandManager->getTitle(pWindow);
std::string appidclass = g_pXWaylandManager->getAppIDClass(pWindow);
for (auto& rule : m_dWindowRules) {
// check if we have a matching rule
try {
std::regex classCheck(rule.szValue);
if (!std::regex_search(title, classCheck) && !std::regex_search(appidclass, classCheck))
continue;
} catch (...) {
Debug::log(ERR, "Regex error at %s", rule.szValue.c_str());
}
// applies. Read the rule and behave accordingly
Debug::log(LOG, "Window rule %s -> %s matched %x [%s]", rule.szRule.c_str(), rule.szValue.c_str(), pWindow, pWindow->m_szTitle.c_str());
returns.push_back(rule);
}
return returns;
}

View file

@ -6,6 +6,9 @@
#include "../defines.hpp"
#include <vector>
#include <deque>
#include <algorithm>
#include <regex>
#include "../Window.hpp"
struct SConfigValue {
int64_t intValue = -1;
@ -23,6 +26,11 @@ struct SMonitorRule {
int defaultWorkspaceID = -1;
};
struct SWindowRule {
std::string szRule;
std::string szValue;
};
class CConfigManager {
public:
CConfigManager();
@ -36,6 +44,8 @@ public:
SMonitorRule getMonitorRuleFor(std::string);
std::vector<SWindowRule> getMatchingRules(CWindow*);
private:
std::unordered_map<std::string, SConfigValue> configValues;
time_t lastModifyTime = 0; // for reloading the config if changed
@ -47,6 +57,7 @@ private:
bool isFirstLaunch = true; // For exec-once
std::deque<SMonitorRule> m_dMonitorRules;
std::deque<SWindowRule> m_dWindowRules;
// internal methods
void loadConfigLoadVars();
@ -56,6 +67,7 @@ private:
void handleRawExec(const std::string&, const std::string&);
void handleMonitor(const std::string&, const std::string&);
void handleBind(const std::string&, const std::string&);
void handleWindowRule(const std::string&, const std::string&);
void handleDefaultWorkspace(const std::string&, const std::string&);
};