Improve hyprland/workspaces persistency logic
Fixes #2945 Split the config and rule persistency in 2 attributes, one storing the persistency as set in Waybar's config, the other one storing the persistency as set in Hyprland. It fixes some conflicts between the persistency state of a workspace as set in Waybar's config and its dynamic state in Hyprland. It allows to remove a persistent workspace in Waybar if this workspace is removed from Hyprland and if the workspace is not set as persistent in Waybar's config.pull/2967/head
parent
601af3de81
commit
b3ee94d87a
|
@ -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,10 @@ class Workspace {
|
|||
uint m_windows;
|
||||
bool m_isActive = false;
|
||||
bool m_isSpecial = false;
|
||||
bool m_isPersistent = false;
|
||||
// m_isPersistentRule represents the persistent state in hyprland
|
||||
bool m_isPersistentRule = false;
|
||||
// m_isPersistentConfig represents the persistent state in the Waybar config
|
||||
bool m_isPersistentConfig = false;
|
||||
bool m_isUrgent = false;
|
||||
bool m_isVisible = false;
|
||||
|
||||
|
|
|
@ -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")) {
|
||||
|
|
Loading…
Reference in New Issue