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; };
|
std::string output() const { return m_output; };
|
||||||
bool isActive() const { return m_isActive; };
|
bool isActive() const { return m_isActive; };
|
||||||
bool isSpecial() const { return m_isSpecial; };
|
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 isVisible() const { return m_isVisible; };
|
||||||
bool isEmpty() const { return m_windows == 0; };
|
bool isEmpty() const { return m_windows == 0; };
|
||||||
bool isUrgent() const { return m_isUrgent; };
|
bool isUrgent() const { return m_isUrgent; };
|
||||||
|
|
||||||
bool handleClicked(GdkEventButton* bt) const;
|
bool handleClicked(GdkEventButton* bt) const;
|
||||||
void setActive(bool value = true) { m_isActive = value; };
|
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 setUrgent(bool value = true) { m_isUrgent = value; };
|
||||||
void setVisible(bool value = true) { m_isVisible = value; };
|
void setVisible(bool value = true) { m_isVisible = value; };
|
||||||
void setWindows(uint value) { m_windows = value; };
|
void setWindows(uint value) { m_windows = value; };
|
||||||
|
@ -101,7 +104,10 @@ class Workspace {
|
||||||
uint m_windows;
|
uint m_windows;
|
||||||
bool m_isActive = false;
|
bool m_isActive = false;
|
||||||
bool m_isSpecial = 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_isUrgent = false;
|
||||||
bool m_isVisible = false;
|
bool m_isVisible = false;
|
||||||
|
|
||||||
|
|
|
@ -349,7 +349,7 @@ void Workspaces::onWorkspaceCreated(std::string const &workspaceName,
|
||||||
(showSpecial() || !name.starts_with("special")) && !isDoubleSpecial(workspaceName)) {
|
(showSpecial() || !name.starts_with("special")) && !isDoubleSpecial(workspaceName)) {
|
||||||
for (Json::Value const &rule : workspaceRules) {
|
for (Json::Value const &rule : workspaceRules) {
|
||||||
if (rule["workspaceString"].asString() == workspaceName) {
|
if (rule["workspaceString"].asString() == workspaceName) {
|
||||||
workspaceJson["persistent"] = rule["persistent"].asBool();
|
workspaceJson["persistent-rule"] = rule["persistent"].asBool();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -587,8 +587,7 @@ std::optional<std::string> Workspace::closeWindow(WindowAddress const &addr) {
|
||||||
void Workspaces::createWorkspace(Json::Value const &workspace_data,
|
void Workspaces::createWorkspace(Json::Value const &workspace_data,
|
||||||
Json::Value const &clients_data) {
|
Json::Value const &clients_data) {
|
||||||
auto workspaceName = workspace_data["name"].asString();
|
auto workspaceName = workspace_data["name"].asString();
|
||||||
spdlog::debug("Creating workspace {}, persistent: {}", workspaceName,
|
spdlog::debug("Creating workspace {}", workspaceName);
|
||||||
workspace_data["persistent"].asBool() ? "true" : "false");
|
|
||||||
|
|
||||||
// avoid recreating existing workspaces
|
// avoid recreating existing workspaces
|
||||||
auto workspace = std::find_if(
|
auto workspace = std::find_if(
|
||||||
|
@ -600,7 +599,22 @@ void Workspaces::createWorkspace(Json::Value const &workspace_data,
|
||||||
|
|
||||||
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
|
||||||
(*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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -624,8 +638,8 @@ void Workspaces::removeWorkspace(std::string const &name) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*workspace)->isPersistent()) {
|
if ((*workspace)->isPersistentConfig()) {
|
||||||
spdlog::trace("Not removing persistent workspace {}", name);
|
spdlog::trace("Not removing config persistent workspace {}", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -633,7 +647,7 @@ void Workspaces::removeWorkspace(std::string const &name) {
|
||||||
m_workspaces.erase(workspace);
|
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);
|
spdlog::trace("Creating persistent workspace: {} on monitor {}", name, monitor);
|
||||||
Json::Value workspaceData;
|
Json::Value workspaceData;
|
||||||
try {
|
try {
|
||||||
|
@ -646,7 +660,6 @@ Json::Value createPersistentWorkspaceData(std::string const &name, std::string c
|
||||||
workspaceData["name"] = name;
|
workspaceData["name"] = name;
|
||||||
workspaceData["monitor"] = monitor;
|
workspaceData["monitor"] = monitor;
|
||||||
workspaceData["windows"] = 0;
|
workspaceData["windows"] = 0;
|
||||||
workspaceData["persistent"] = true;
|
|
||||||
return workspaceData;
|
return workspaceData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -699,7 +712,8 @@ void Workspaces::loadPersistentWorkspacesFromConfig(Json::Value const &clientsJs
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto const &workspace : persistentWorkspacesToCreate) {
|
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);
|
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
|
// 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()) {
|
if (allOutputs() || m_bar.output->name == monitor || monitor.empty()) {
|
||||||
// => persistent workspace should be shown on this monitor
|
// => 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);
|
m_workspacesToCreate.emplace_back(workspaceData, clientsJson);
|
||||||
} else {
|
} else {
|
||||||
m_workspacesToRemove.emplace_back(workspace);
|
m_workspacesToRemove.emplace_back(workspace);
|
||||||
|
@ -774,10 +789,9 @@ void Workspaces::initializeWorkspaces() {
|
||||||
if (m_persistentWorkspaceConfig.isObject()) {
|
if (m_persistentWorkspaceConfig.isObject()) {
|
||||||
// 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);
|
||||||
} 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) {
|
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_output(workspace_data["monitor"].asString()), // TODO:allow using monitor desc
|
||||||
m_windows(workspace_data["windows"].asInt()),
|
m_windows(workspace_data["windows"].asInt()),
|
||||||
m_isActive(true),
|
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:")) {
|
if (m_name.starts_with("name:")) {
|
||||||
m_name = m_name.substr(5);
|
m_name = m_name.substr(5);
|
||||||
} else if (m_name.starts_with("special")) {
|
} else if (m_name.starts_with("special")) {
|
||||||
|
|
Loading…
Reference in New Issue