Merge pull request #2967 from aruhier/pr_hyprland_workspaces

hyprland/workspaces: Improve the workspaces persistency logic
This commit is contained in:
Alexis Rouillard 2024-02-27 16:41:32 +01:00 committed by GitHub
commit e79ea93d7d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 36 additions and 17 deletions

View File

@ -70,14 +70,17 @@ class Workspace {
std::string output() const { return m_output; };
bool isActive() const { return m_isActive; };
bool isSpecial() const { return m_isSpecial; };
bool isPersistent() const { return m_isPersistent; };
bool isPersistent() const { return m_isPersistentRule || m_isPersistentConfig; };
bool isPersistentConfig() const { return m_isPersistentConfig; };
bool isPersistentRule() const { return m_isPersistentRule; };
bool isVisible() const { return m_isVisible; };
bool isEmpty() const { return m_windows == 0; };
bool isUrgent() const { return m_isUrgent; };
bool handleClicked(GdkEventButton* bt) const;
void setActive(bool value = true) { m_isActive = value; };
void setPersistent(bool value = true) { m_isPersistent = value; };
void setPersistentRule(bool value = true) { m_isPersistentRule = value; };
void setPersistentConfig(bool value = true) { m_isPersistentConfig = value; };
void setUrgent(bool value = true) { m_isUrgent = value; };
void setVisible(bool value = true) { m_isVisible = value; };
void setWindows(uint value) { m_windows = value; };
@ -101,7 +104,8 @@ class Workspace {
uint m_windows;
bool m_isActive = false;
bool m_isSpecial = false;
bool m_isPersistent = false;
bool m_isPersistentRule = false; // represents the persistent state in hyprland
bool m_isPersistentConfig = false; // represents the persistent state in the Waybar config
bool m_isUrgent = false;
bool m_isVisible = false;

View File

@ -349,7 +349,7 @@ void Workspaces::onWorkspaceCreated(std::string const &workspaceName,
(showSpecial() || !name.starts_with("special")) && !isDoubleSpecial(workspaceName)) {
for (Json::Value const &rule : workspaceRules) {
if (rule["workspaceString"].asString() == workspaceName) {
workspaceJson["persistent"] = rule["persistent"].asBool();
workspaceJson["persistent-rule"] = rule["persistent"].asBool();
break;
}
}
@ -587,8 +587,7 @@ std::optional<std::string> Workspace::closeWindow(WindowAddress const &addr) {
void Workspaces::createWorkspace(Json::Value const &workspace_data,
Json::Value const &clients_data) {
auto workspaceName = workspace_data["name"].asString();
spdlog::debug("Creating workspace {}, persistent: {}", workspaceName,
workspace_data["persistent"].asBool() ? "true" : "false");
spdlog::debug("Creating workspace {}", workspaceName);
// avoid recreating existing workspaces
auto workspace = std::find_if(
@ -600,7 +599,22 @@ void Workspaces::createWorkspace(Json::Value const &workspace_data,
if (workspace != m_workspaces.end()) {
// don't recreate workspace, but update persistency if necessary
(*workspace)->setPersistent(workspace_data["persistent"].asBool());
const auto keys = workspace_data.getMemberNames();
const auto *k = "persistent-rule";
if (std::find(keys.begin(), keys.end(), k) != keys.end()) {
spdlog::debug("Set dynamic persistency of workspace {} to: {}", workspaceName,
workspace_data[k].asBool() ? "true" : "false");
(*workspace)->setPersistentRule(workspace_data[k].asBool());
}
k = "persistent-config";
if (std::find(keys.begin(), keys.end(), k) != keys.end()) {
spdlog::debug("Set config persistency of workspace {} to: {}", workspaceName,
workspace_data[k].asBool() ? "true" : "false");
(*workspace)->setPersistentConfig(workspace_data[k].asBool());
}
return;
}
@ -624,8 +638,8 @@ void Workspaces::removeWorkspace(std::string const &name) {
return;
}
if ((*workspace)->isPersistent()) {
spdlog::trace("Not removing persistent workspace {}", name);
if ((*workspace)->isPersistentConfig()) {
spdlog::trace("Not removing config persistent workspace {}", name);
return;
}
@ -633,7 +647,7 @@ void Workspaces::removeWorkspace(std::string const &name) {
m_workspaces.erase(workspace);
}
Json::Value createPersistentWorkspaceData(std::string const &name, std::string const &monitor) {
Json::Value createMonitorWorkspaceData(std::string const &name, std::string const &monitor) {
spdlog::trace("Creating persistent workspace: {} on monitor {}", name, monitor);
Json::Value workspaceData;
try {
@ -646,7 +660,6 @@ Json::Value createPersistentWorkspaceData(std::string const &name, std::string c
workspaceData["name"] = name;
workspaceData["monitor"] = monitor;
workspaceData["windows"] = 0;
workspaceData["persistent"] = true;
return workspaceData;
}
@ -699,7 +712,8 @@ void Workspaces::loadPersistentWorkspacesFromConfig(Json::Value const &clientsJs
}
for (auto const &workspace : persistentWorkspacesToCreate) {
auto const workspaceData = createPersistentWorkspaceData(workspace, m_bar.output->name);
auto workspaceData = createMonitorWorkspaceData(workspace, m_bar.output->name);
workspaceData["persistent-config"] = true;
m_workspacesToCreate.emplace_back(workspaceData, clientsJson);
}
}
@ -724,7 +738,8 @@ void Workspaces::loadPersistentWorkspacesFromWorkspaceRules(const Json::Value &c
// 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 = createPersistentWorkspaceData(workspace, m_bar.output->name);
auto workspaceData = createMonitorWorkspaceData(workspace, m_bar.output->name);
workspaceData["persistent-rule"] = true;
m_workspacesToCreate.emplace_back(workspaceData, clientsJson);
} else {
m_workspacesToRemove.emplace_back(workspace);
@ -774,10 +789,9 @@ void Workspaces::initializeWorkspaces() {
if (m_persistentWorkspaceConfig.isObject()) {
// a persistent workspace config is defined, so use that instead of workspace rules
loadPersistentWorkspacesFromConfig(clientsJson);
} else {
// no persistent workspaces config defined, use Hyprland's workspace rules
loadPersistentWorkspacesFromWorkspaceRules(clientsJson);
}
// load Hyprland's workspace rules
loadPersistentWorkspacesFromWorkspaceRules(clientsJson);
}
void Workspaces::extendOrphans(int workspaceId, Json::Value const &clientsJson) {
@ -812,7 +826,8 @@ Workspace::Workspace(const Json::Value &workspace_data, Workspaces &workspace_ma
m_output(workspace_data["monitor"].asString()), // TODO:allow using monitor desc
m_windows(workspace_data["windows"].asInt()),
m_isActive(true),
m_isPersistent(workspace_data["persistent"].asBool()) {
m_isPersistentRule(workspace_data["persistent-rule"].asBool()),
m_isPersistentConfig(workspace_data["persistent-config"].asBool()) {
if (m_name.starts_with("name:")) {
m_name = m_name.substr(5);
} else if (m_name.starts_with("special")) {