diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 4bb7b7d8..12a11268 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -1490,6 +1490,19 @@ std::vector CConfigManager::getMatchingRules(CWindow* pWindow) { returns.push_back(rule); } + const auto PID = pWindow->getPID(); + bool anyExecFound = false; + + for (auto& er : execRequestedRules) { + if (er.iPid == PID) { + returns.push_back({er.szRule, "execRule"}); + anyExecFound = true; + } + } + + if (anyExecFound) // remove exec rules to unclog searches in the future, why have the garbage here. + execRequestedRules.erase(std::remove_if(execRequestedRules.begin(), execRequestedRules.end(), [&](const SExecRequestedRule& other) { return other.iPid == PID; })); + return returns; } @@ -1646,3 +1659,7 @@ CMonitor* CConfigManager::getBoundMonitorForWS(std::string wsname) { return nullptr; } + +void CConfigManager::addExecRule(SExecRequestedRule rule) { + execRequestedRules.push_back(rule); +} diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp index e390a93b..b78cb273 100644 --- a/src/config/ConfigManager.hpp +++ b/src/config/ConfigManager.hpp @@ -71,14 +71,19 @@ struct SAnimationPropertyConfig { SAnimationPropertyConfig* pParentAnimation = nullptr; }; +struct SExecRequestedRule { + std::string szRule = ""; + uint64_t iPid = 0; +}; + class CVarList { public: - CVarList(const std::string& in, long unsigned int lastArgNo = 0) { + CVarList(const std::string& in, long unsigned int lastArgNo = 0, const char separator = ',') { std::string curitem = ""; std::string argZ = in; auto nextItem = [&]() { - auto idx = lastArgNo != 0 && m_vArgs.size() >= lastArgNo - 1 ? std::string::npos : argZ.find_first_of(','); + auto idx = lastArgNo != 0 && m_vArgs.size() >= lastArgNo - 1 ? std::string::npos : argZ.find_first_of(separator); if (idx != std::string::npos) { curitem = argZ.substr(0, idx); @@ -109,7 +114,13 @@ public: return m_vArgs[idx]; } -private: + // for range-based loops + std::vector::iterator begin() { return m_vArgs.begin(); } + std::vector::const_iterator begin() const { return m_vArgs.begin(); } + std::vector::iterator end() { return m_vArgs.end(); } + std::vector::const_iterator end() const { return m_vArgs.end(); } + + private: std::vector m_vArgs; }; @@ -160,6 +171,8 @@ public: SAnimationPropertyConfig* getAnimationPropertyConfig(const std::string&); + void addExecRule(SExecRequestedRule); + std::string configCurrentPath; private: @@ -179,6 +192,8 @@ private: std::vector> boundWorkspaces; + std::vector execRequestedRules; // rules requested with exec, e.g. [workspace 2] kitty + bool isFirstLaunch = true; // For exec-once std::deque m_dMonitorRules; diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 7eb556b5..a529da97 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -483,6 +483,17 @@ bool CKeybindManager::handleInternalKeybinds(xkb_keysym_t keysym) { // Dispatchers void CKeybindManager::spawn(std::string args) { + + args = removeBeginEndSpacesTabs(args); + + std::string RULES = ""; + + if (args[0] == '[') { + // we have exec rules + RULES = args.substr(1, args.substr(1).find_first_of(']')); + args = args.substr(args.find_first_of(']') + 1); + } + if (g_pXWaylandManager->m_sWLRXWayland) args = "WAYLAND_DISPLAY=" + std::string(g_pCompositor->m_szWLDisplaySocket) + " DISPLAY=" + std::string(g_pXWaylandManager->m_sWLRXWayland->display_name) + " " + args; else @@ -535,7 +546,18 @@ void CKeybindManager::spawn(std::string args) { Debug::log(LOG, "Fail to create the second fork"); return; } + Debug::log(LOG, "Process Created with pid %d", grandchild); + + if (!RULES.empty()) { + const auto RULESLIST = CVarList(RULES, 0, ';'); + + for (auto& r : RULESLIST) { + g_pConfigManager->addExecRule({r, (unsigned long)grandchild}); + } + + Debug::log(LOG, "Applied %i rule arguments for exec.", RULESLIST.size()); + } } void CKeybindManager::killActive(std::string args) {