mirror of
https://github.com/hyprwm/Hyprland
synced 2024-12-27 03:29:48 +01:00
workspacerules: Add new optional "default command" for auto-launching apps on new workspaces (#3559)
This commit is contained in:
parent
59f27e7f57
commit
b135bd6cd4
8 changed files with 100 additions and 30 deletions
|
@ -1194,24 +1194,33 @@ void CCompositor::sanityCheckWorkspaces() {
|
|||
continue;
|
||||
}
|
||||
|
||||
const auto WINDOWSONWORKSPACE = getWindowsOnWorkspace((*it)->m_iID);
|
||||
const auto& WORKSPACE = *it;
|
||||
const auto WINDOWSONWORKSPACE = getWindowsOnWorkspace(WORKSPACE->m_iID);
|
||||
|
||||
if ((WINDOWSONWORKSPACE == 0 && !isWorkspaceVisible((*it)->m_iID))) {
|
||||
if (WINDOWSONWORKSPACE == 0) {
|
||||
if (!isWorkspaceVisible(WORKSPACE->m_iID)) {
|
||||
|
||||
if ((*it)->m_bIsSpecialWorkspace) {
|
||||
if ((*it)->m_fAlpha.fl() > 0.f /* don't abruptly end the fadeout */) {
|
||||
++it;
|
||||
continue;
|
||||
if (WORKSPACE->m_bIsSpecialWorkspace) {
|
||||
if (WORKSPACE->m_fAlpha.fl() > 0.f /* don't abruptly end the fadeout */) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto PMONITOR = getMonitorFromID(WORKSPACE->m_iMonitorID);
|
||||
|
||||
if (PMONITOR && PMONITOR->specialWorkspaceID == WORKSPACE->m_iID)
|
||||
PMONITOR->setSpecialWorkspace(nullptr);
|
||||
}
|
||||
|
||||
const auto PMONITOR = getMonitorFromID((*it)->m_iMonitorID);
|
||||
|
||||
if (PMONITOR && PMONITOR->specialWorkspaceID == (*it)->m_iID)
|
||||
PMONITOR->setSpecialWorkspace(nullptr);
|
||||
it = m_vWorkspaces.erase(it);
|
||||
continue;
|
||||
}
|
||||
if (!WORKSPACE->m_bOnCreatedEmptyExecuted) {
|
||||
if (auto cmd = WORKSPACERULE.onCreatedEmptyRunCmd)
|
||||
g_pKeybindManager->spawn(*cmd);
|
||||
|
||||
it = m_vWorkspaces.erase(it);
|
||||
continue;
|
||||
WORKSPACE->m_bOnCreatedEmptyExecuted = true;
|
||||
}
|
||||
}
|
||||
|
||||
++it;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "../managers/KeybindManager.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
@ -1176,7 +1177,10 @@ void CConfigManager::handleWorkspaceRules(const std::string& command, const std:
|
|||
rules = value.substr(WORKSPACE_DELIM + 1);
|
||||
}
|
||||
|
||||
auto assignRule = [&](std::string rule) {
|
||||
const static std::string ruleOnCreatedEmtpy = "on-created-empty:";
|
||||
const static int ruleOnCreatedEmtpyLen = ruleOnCreatedEmtpy.length();
|
||||
|
||||
auto assignRule = [&](std::string rule) {
|
||||
size_t delim = std::string::npos;
|
||||
if ((delim = rule.find("gapsin:")) != std::string::npos)
|
||||
wsRule.gapsIn = std::stoi(rule.substr(delim + 7));
|
||||
|
@ -1198,6 +1202,8 @@ void CConfigManager::handleWorkspaceRules(const std::string& command, const std:
|
|||
wsRule.isDefault = configStringToInt(rule.substr(delim + 8));
|
||||
else if ((delim = rule.find("persistent:")) != std::string::npos)
|
||||
wsRule.isPersistent = configStringToInt(rule.substr(delim + 11));
|
||||
else if ((delim = rule.find(ruleOnCreatedEmtpy)) != std::string::npos)
|
||||
wsRule.onCreatedEmptyRunCmd = cleanCmdForWorkspace(name, rule.substr(delim + ruleOnCreatedEmtpyLen));
|
||||
};
|
||||
|
||||
size_t pos = 0;
|
||||
|
|
|
@ -36,19 +36,20 @@ struct SConfigValue {
|
|||
};
|
||||
|
||||
struct SWorkspaceRule {
|
||||
std::string monitor = "";
|
||||
std::string workspaceString = "";
|
||||
std::string workspaceName = "";
|
||||
int workspaceId = -1;
|
||||
bool isDefault = false;
|
||||
bool isPersistent = false;
|
||||
std::optional<int64_t> gapsIn;
|
||||
std::optional<int64_t> gapsOut;
|
||||
std::optional<int64_t> borderSize;
|
||||
std::optional<int> border;
|
||||
std::optional<int> rounding;
|
||||
std::optional<int> decorate;
|
||||
std::optional<int> shadow;
|
||||
std::string monitor = "";
|
||||
std::string workspaceString = "";
|
||||
std::string workspaceName = "";
|
||||
int workspaceId = -1;
|
||||
bool isDefault = false;
|
||||
bool isPersistent = false;
|
||||
std::optional<int64_t> gapsIn;
|
||||
std::optional<int64_t> gapsOut;
|
||||
std::optional<int64_t> borderSize;
|
||||
std::optional<int> border;
|
||||
std::optional<int> rounding;
|
||||
std::optional<int> decorate;
|
||||
std::optional<int> shadow;
|
||||
std::optional<std::string> onCreatedEmptyRunCmd;
|
||||
};
|
||||
|
||||
struct SMonitorAdditionalReservedArea {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "../defines.hpp"
|
||||
#include <algorithm>
|
||||
#include "../Compositor.hpp"
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <sys/utsname.h>
|
||||
#include <iomanip>
|
||||
|
@ -503,6 +504,43 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
|
|||
return result;
|
||||
}
|
||||
|
||||
std::optional<std::string> cleanCmdForWorkspace(const std::string& inWorkspaceName, std::string dirtyCmd) {
|
||||
|
||||
std::string cmd = removeBeginEndSpacesTabs(dirtyCmd);
|
||||
|
||||
if (!cmd.empty()) {
|
||||
std::string rules;
|
||||
const std::string workspaceRule = "workspace " + inWorkspaceName;
|
||||
|
||||
if (cmd[0] == '[') {
|
||||
const int closingBracketIdx = cmd.find_last_of(']');
|
||||
auto tmpRules = cmd.substr(1, closingBracketIdx - 1);
|
||||
cmd = cmd.substr(closingBracketIdx + 1);
|
||||
|
||||
auto rulesList = CVarList(tmpRules, 0, ';');
|
||||
|
||||
bool hadWorkspaceRule = false;
|
||||
rulesList.map([&](std::string& rule) {
|
||||
if (rule.find("workspace") == 0) {
|
||||
rule = workspaceRule;
|
||||
hadWorkspaceRule = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (!hadWorkspaceRule)
|
||||
rulesList.append(workspaceRule);
|
||||
|
||||
rules = "[" + rulesList.join(";") + "]";
|
||||
} else {
|
||||
rules = "[" + workspaceRule + "]";
|
||||
}
|
||||
|
||||
return std::optional<std::string>(rules + " " + cmd);
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
float vecToRectDistanceSquared(const Vector2D& vec, const Vector2D& p1, const Vector2D& p2) {
|
||||
const float DX = std::max({0.0, p1.x - vec.x, vec.x - p2.x});
|
||||
const float DY = std::max({0.0, p1.y - vec.y, vec.y - p2.y});
|
||||
|
@ -594,8 +632,8 @@ int64_t getPPIDof(int64_t pid) {
|
|||
|
||||
return 0;
|
||||
#else
|
||||
std::string dir = "/proc/" + std::to_string(pid) + "/status";
|
||||
FILE* infile;
|
||||
std::string dir = "/proc/" + std::to_string(pid) + "/status";
|
||||
FILE* infile;
|
||||
|
||||
infile = fopen(dir.c_str(), "r");
|
||||
if (!infile)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <wayland-server.h>
|
||||
#include <wlr/util/box.h>
|
||||
|
@ -20,6 +21,7 @@ std::string removeBeginEndSpacesTabs(std::string);
|
|||
bool isNumber(const std::string&, bool allowfloat = false);
|
||||
bool isDirection(const std::string&);
|
||||
int getWorkspaceIDFromString(const std::string&, std::string&);
|
||||
std::optional<std::string> cleanCmdForWorkspace(const std::string&, std::string);
|
||||
float vecToRectDistanceSquared(const Vector2D& vec, const Vector2D& p1, const Vector2D& p2);
|
||||
void logSystemInfo();
|
||||
std::string execAndGet(const char*);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "../macros.hpp"
|
||||
|
@ -20,6 +21,15 @@ class CVarList {
|
|||
|
||||
std::string join(const std::string& joiner, size_t from = 0, size_t to = 0) const;
|
||||
|
||||
void map(std::function<void(std::string&)> func) {
|
||||
for (auto& s : m_vArgs)
|
||||
func(s);
|
||||
}
|
||||
|
||||
void append(const std::string arg) {
|
||||
m_vArgs.emplace_back(arg);
|
||||
}
|
||||
|
||||
std::string operator[](const size_t& idx) const {
|
||||
if (idx >= m_vArgs.size())
|
||||
return "";
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
#include <string>
|
||||
#include "../defines.hpp"
|
||||
|
||||
enum eFullscreenMode : int8_t
|
||||
{
|
||||
enum eFullscreenMode : int8_t {
|
||||
FULLSCREEN_INVALID = -1,
|
||||
FULLSCREEN_FULL = 0,
|
||||
FULLSCREEN_MAXIMIZED
|
||||
|
@ -53,6 +52,9 @@ class CWorkspace {
|
|||
// last monitor (used on reconnect)
|
||||
std::string m_szLastMonitor = "";
|
||||
|
||||
// Whether the user configured command for on-created-empty has been executed, if any
|
||||
bool m_bOnCreatedEmptyExecuted = false;
|
||||
|
||||
void startAnim(bool in, bool left, bool instant = false);
|
||||
void setActive(bool on);
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "KeybindManager.hpp"
|
||||
#include "../render/decorations/CHyprGroupBarDecoration.hpp"
|
||||
#include "debug/Log.hpp"
|
||||
#include "helpers/VarList.hpp"
|
||||
|
||||
#include <regex>
|
||||
|
||||
|
|
Loading…
Reference in a new issue