desktop/rules: use pid for exec rules (#13374)
This commit is contained in:
parent
cc14dd1baf
commit
70cdd819e4
5 changed files with 39 additions and 28 deletions
|
|
@ -52,6 +52,7 @@ static const std::unordered_map<eRuleProperty, eRuleMatchEngine> RULE_ENGINES =
|
||||||
{RULE_PROP_XDG_TAG, RULE_MATCH_ENGINE_REGEX}, //
|
{RULE_PROP_XDG_TAG, RULE_MATCH_ENGINE_REGEX}, //
|
||||||
{RULE_PROP_NAMESPACE, RULE_MATCH_ENGINE_REGEX}, //
|
{RULE_PROP_NAMESPACE, RULE_MATCH_ENGINE_REGEX}, //
|
||||||
{RULE_PROP_EXEC_TOKEN, RULE_MATCH_ENGINE_REGEX}, //
|
{RULE_PROP_EXEC_TOKEN, RULE_MATCH_ENGINE_REGEX}, //
|
||||||
|
{RULE_PROP_EXEC_PID, RULE_MATCH_ENGINE_INT}, //
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::vector<std::string>& Rule::allMatchPropStrings() {
|
const std::vector<std::string>& Rule::allMatchPropStrings() {
|
||||||
|
|
@ -125,10 +126,11 @@ const std::string& IRule::name() {
|
||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IRule::markAsExecRule(const std::string& token, bool persistent) {
|
void IRule::markAsExecRule(const std::string& token, uint64_t pid, bool persistent) {
|
||||||
m_execData.isExecRule = true;
|
m_execData.isExecRule = true;
|
||||||
m_execData.isExecPersistent = persistent;
|
m_execData.isExecPersistent = persistent;
|
||||||
m_execData.token = token;
|
m_execData.token = token;
|
||||||
|
m_execData.pid = pid;
|
||||||
m_execData.expiresAt = Time::steadyNow() + std::chrono::minutes(1);
|
m_execData.expiresAt = Time::steadyNow() + std::chrono::minutes(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
#include "../../helpers/time/Time.hpp"
|
#include "../../helpers/time/Time.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <cstdint>
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
namespace Desktop::Rule {
|
namespace Desktop::Rule {
|
||||||
|
|
@ -31,6 +30,7 @@ namespace Desktop::Rule {
|
||||||
RULE_PROP_XDG_TAG = (1 << 16),
|
RULE_PROP_XDG_TAG = (1 << 16),
|
||||||
RULE_PROP_NAMESPACE = (1 << 17),
|
RULE_PROP_NAMESPACE = (1 << 17),
|
||||||
RULE_PROP_EXEC_TOKEN = (1 << 18),
|
RULE_PROP_EXEC_TOKEN = (1 << 18),
|
||||||
|
RULE_PROP_EXEC_PID = (1 << 19),
|
||||||
|
|
||||||
RULE_PROP_ALL = std::numeric_limits<std::underlying_type_t<eRuleProperty>>::max(),
|
RULE_PROP_ALL = std::numeric_limits<std::underlying_type_t<eRuleProperty>>::max(),
|
||||||
};
|
};
|
||||||
|
|
@ -52,7 +52,7 @@ namespace Desktop::Rule {
|
||||||
virtual std::underlying_type_t<eRuleProperty> getPropertiesMask();
|
virtual std::underlying_type_t<eRuleProperty> getPropertiesMask();
|
||||||
|
|
||||||
void registerMatch(eRuleProperty, const std::string&);
|
void registerMatch(eRuleProperty, const std::string&);
|
||||||
void markAsExecRule(const std::string& token, bool persistent = false);
|
void markAsExecRule(const std::string& token, uint64_t pid, bool persistent = false);
|
||||||
bool isExecRule();
|
bool isExecRule();
|
||||||
bool isExecPersistent();
|
bool isExecPersistent();
|
||||||
bool execExpired();
|
bool execExpired();
|
||||||
|
|
@ -78,7 +78,8 @@ namespace Desktop::Rule {
|
||||||
bool isExecRule = false;
|
bool isExecRule = false;
|
||||||
bool isExecPersistent = false;
|
bool isExecPersistent = false;
|
||||||
std::string token;
|
std::string token;
|
||||||
|
uint64_t pid = 0;
|
||||||
Time::steady_tp expiresAt;
|
Time::steady_tp expiresAt;
|
||||||
} m_execData;
|
} m_execData;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,20 +104,24 @@ bool CWindowRule::matches(PHLWINDOW w, bool allowEnvLookup) {
|
||||||
if (!w->xdgTag().has_value() || !engine->match(*w->xdgTag()))
|
if (!w->xdgTag().has_value() || !engine->match(*w->xdgTag()))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RULE_PROP_EXEC_TOKEN:
|
case RULE_PROP_EXEC_TOKEN:
|
||||||
// this is only allowed on static rules, we don't need it on dynamic plus it's expensive
|
|
||||||
if (!allowEnvLookup)
|
if (!allowEnvLookup)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
const auto ENV = w->getEnv();
|
const auto ENV = w->getEnv();
|
||||||
if (ENV.contains(EXEC_RULE_ENV_NAME)) {
|
bool match = false;
|
||||||
const auto TKN = ENV.at(EXEC_RULE_ENV_NAME);
|
|
||||||
if (!engine->match(TKN))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
if (ENV.contains(EXEC_RULE_ENV_NAME)) {
|
||||||
|
if (engine->match(ENV.at(EXEC_RULE_ENV_NAME)))
|
||||||
|
match = true;
|
||||||
|
} else if (m_matchEngines.contains(RULE_PROP_EXEC_PID)) {
|
||||||
|
if (m_matchEngines.at(RULE_PROP_EXEC_PID)->match(w->getPID()))
|
||||||
|
match = true;
|
||||||
|
}
|
||||||
|
if (!match)
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -153,11 +157,6 @@ SP<CWindowRule> CWindowRule::buildFromExecString(std::string&& s) {
|
||||||
wr->addEffect(*EFFECT, std::string{"1"});
|
wr->addEffect(*EFFECT, std::string{"1"});
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto TOKEN = g_pTokenManager->registerNewToken(nullptr, std::chrono::seconds(1));
|
|
||||||
|
|
||||||
wr->markAsExecRule(TOKEN, false /* TODO: could be nice. */);
|
|
||||||
wr->registerMatch(RULE_PROP_EXEC_TOKEN, TOKEN);
|
|
||||||
|
|
||||||
return wr;
|
return wr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -915,11 +915,13 @@ bool CKeybindManager::handleInternalKeybinds(xkb_keysym_t keysym) {
|
||||||
|
|
||||||
// Dispatchers
|
// Dispatchers
|
||||||
SDispatchResult CKeybindManager::spawn(std::string args) {
|
SDispatchResult CKeybindManager::spawn(std::string args) {
|
||||||
const uint64_t PROC = spawnWithRules(args, nullptr);
|
const auto PROC = spawnWithRules(args, nullptr);
|
||||||
return {.success = PROC > 0, .error = std::format("Failed to start process {}", args)};
|
if (!PROC.has_value())
|
||||||
|
return {.success = false, .error = std::format("Failed to start process. No closing bracket in exec rule. {}", args)};
|
||||||
|
return {.success = PROC.value() > 0, .error = std::format("Failed to start process {}", args)};
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t CKeybindManager::spawnWithRules(std::string args, PHLWORKSPACE pInitialWorkspace) {
|
std::optional<uint64_t> CKeybindManager::spawnWithRules(std::string args, PHLWORKSPACE pInitialWorkspace) {
|
||||||
|
|
||||||
args = trim(args);
|
args = trim(args);
|
||||||
|
|
||||||
|
|
@ -927,22 +929,29 @@ uint64_t CKeybindManager::spawnWithRules(std::string args, PHLWORKSPACE pInitial
|
||||||
|
|
||||||
if (args[0] == '[') {
|
if (args[0] == '[') {
|
||||||
// we have exec rules
|
// we have exec rules
|
||||||
RULES = args.substr(1, args.substr(1).find_first_of(']'));
|
const auto end = args.find_first_of(']');
|
||||||
args = args.substr(args.find_first_of(']') + 1);
|
if (end == std::string::npos)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
RULES = args.substr(1, end - 1);
|
||||||
|
args = args.substr(end + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string execToken = "";
|
std::string execToken = "";
|
||||||
|
|
||||||
if (!RULES.empty()) {
|
if (!RULES.empty()) {
|
||||||
auto rule = Desktop::Rule::CWindowRule::buildFromExecString(std::move(RULES));
|
auto rule = Desktop::Rule::CWindowRule::buildFromExecString(std::move(RULES));
|
||||||
|
|
||||||
execToken = rule->execToken();
|
const auto TOKEN = g_pTokenManager->registerNewToken(nullptr, std::chrono::seconds(1));
|
||||||
|
|
||||||
|
const uint64_t PROC = spawnRawProc(args, pInitialWorkspace, TOKEN);
|
||||||
|
rule->markAsExecRule(TOKEN, PROC, false /* TODO: could be nice. */);
|
||||||
|
rule->registerMatch(Desktop::Rule::RULE_PROP_EXEC_TOKEN, TOKEN);
|
||||||
|
rule->registerMatch(Desktop::Rule::RULE_PROP_EXEC_PID, std::to_string(PROC));
|
||||||
Desktop::Rule::ruleEngine()->registerRule(std::move(rule));
|
Desktop::Rule::ruleEngine()->registerRule(std::move(rule));
|
||||||
|
|
||||||
Log::logger->log(Log::DEBUG, "Applied rule arguments for exec.");
|
Log::logger->log(Log::DEBUG, "Applied rule arguments for exec.");
|
||||||
|
return PROC;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint64_t PROC = spawnRawProc(args, pInitialWorkspace, execToken);
|
const uint64_t PROC = spawnRawProc(args, pInitialWorkspace, execToken);
|
||||||
|
|
||||||
return PROC;
|
return PROC;
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ class CKeybindManager {
|
||||||
|
|
||||||
static void switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool forceFSCycle = false);
|
static void switchToWindow(PHLWINDOW PWINDOWTOCHANGETO, bool forceFSCycle = false);
|
||||||
static uint64_t spawnRawProc(std::string, PHLWORKSPACE pInitialWorkspace, const std::string& execRuleToken = "");
|
static uint64_t spawnRawProc(std::string, PHLWORKSPACE pInitialWorkspace, const std::string& execRuleToken = "");
|
||||||
static uint64_t spawnWithRules(std::string, PHLWORKSPACE pInitialWorkspace);
|
static std::optional<uint64_t> spawnWithRules(std::string, PHLWORKSPACE pInitialWorkspace);
|
||||||
|
|
||||||
// -------------- Dispatchers -------------- //
|
// -------------- Dispatchers -------------- //
|
||||||
static SDispatchResult closeActive(std::string);
|
static SDispatchResult closeActive(std::string);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue