This commit is contained in:
arnaud-ma
2025-07-19 04:47:31 +02:00
parent 64ed2cd970
commit a4f200cdb5
2 changed files with 42 additions and 13 deletions

View File

@ -118,7 +118,7 @@ class Workspaces : public AModule, public EventHandler {
void initializeWorkspaces(); void initializeWorkspaces();
void setCurrentMonitorId(); void setCurrentMonitorId();
void loadPersistentWorkspacesFromConfig(Json::Value const& clientsJson); void loadPersistentWorkspacesFromConfig(Json::Value const& clientsJson);
void loadPersistentWorkspacesFromWorkspaceRules(const Json::Value& clientsJson);
bool m_allOutputs = false; bool m_allOutputs = false;
bool m_showSpecial = false; bool m_showSpecial = false;
bool m_activeOnly = false; bool m_activeOnly = false;

View File

@ -69,14 +69,13 @@ void Workspaces::createWorkspace(Json::Value const &workspace_data,
spdlog::debug("Creating workspace {}", workspaceName); spdlog::debug("Creating workspace {}", workspaceName);
// avoid recreating existing workspaces // avoid recreating existing workspaces
auto workspace = auto workspace = std::ranges::find_if(m_workspaces, [&](std::unique_ptr<Workspace> const &w) {
std::ranges::find_if(m_workspaces, [&](std::unique_ptr<Workspace> const &w) { if (workspaceId > 0) {
if (workspaceId > 0) { return w->id() == workspaceId;
return w->id() == workspaceId; }
} return (workspaceName.starts_with("special:") && workspaceName.substr(8) == w->name()) ||
return (workspaceName.starts_with("special:") && workspaceName.substr(8) == w->name()) || workspaceName == w->name();
workspaceName == w->name(); });
});
if (workspace != m_workspaces.end()) { if (workspace != m_workspaces.end()) {
// don't recreate workspace, but update persistency if necessary // don't recreate workspace, but update persistency if necessary
@ -206,9 +205,8 @@ void Workspaces::initializeWorkspaces() {
// a persistent workspace config is defined, so use that instead of workspace rules // a persistent workspace config is defined, so use that instead of workspace rules
loadPersistentWorkspacesFromConfig(clientsJson); loadPersistentWorkspacesFromConfig(clientsJson);
} }
// persistent workspaces configured with hyprland's workspace rules // load Hyprland's workspace rules
// are already listed in 'workspacesJson', so we don't need to loadPersistentWorkspacesFromWorkspaceRules(clientsJson);
// load them again.
} }
bool isDoubleSpecial(std::string const &workspace_name) { bool isDoubleSpecial(std::string const &workspace_name) {
@ -283,6 +281,37 @@ void Workspaces::loadPersistentWorkspacesFromConfig(Json::Value const &clientsJs
} }
} }
void Workspaces::loadPersistentWorkspacesFromWorkspaceRules(const Json::Value &clientsJson) {
spdlog::info("Loading persistent workspaces from Hyprland workspace rules");
auto const workspaceRules = m_ipc.getSocket1JsonReply("workspacerules");
for (Json::Value const &rule : workspaceRules) {
if (!rule["workspaceString"].isString()) {
spdlog::warn("Workspace rules: invalid workspaceString, skipping: {}", rule);
continue;
}
if (!rule["persistent"].asBool()) {
continue;
}
auto const &workspace = rule.isMember("defaultName") ? rule["defaultName"].asString()
: rule["workspaceString"].asString();
auto const &monitor = rule["monitor"].asString();
// create this workspace persistently if:
// 1. the allOutputs config option is enabled
// 2. the rule's monitor is the current monitor
// 3. no monitor is specified in the rule => assume it needs to be persistent on every monitor
if (allOutputs() || m_bar.output->name == monitor || monitor.empty()) {
// => persistent workspace should be shown on this monitor
auto workspaceData = createMonitorWorkspaceData(workspace, m_bar.output->name);
workspaceData["persistent-rule"] = true;
m_workspacesToCreate.emplace_back(workspaceData, clientsJson);
} else {
// This can be any workspace selector.
m_workspacesToRemove.emplace_back(workspace);
}
}
}
void Workspaces::onEvent(const std::string &ev) { void Workspaces::onEvent(const std::string &ev) {
std::lock_guard<std::mutex> lock(m_mutex); std::lock_guard<std::mutex> lock(m_mutex);
std::string eventName(begin(ev), begin(ev) + ev.find_first_of('>')); std::string eventName(begin(ev), begin(ev) + ev.find_first_of('>'));