Merge pull request #4305 from edeustua/fix_hyprland_window_count
fix: Use workspace ID to handle hyprland/workspace updates
This commit is contained in:
@@ -79,18 +79,13 @@ Json::Value Workspaces::createMonitorWorkspaceData(std::string const& name,
|
|||||||
|
|
||||||
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 workspaceId = workspace_data["id"].asInt();
|
auto workspaceId = workspace_data["id"].asInt();
|
||||||
spdlog::debug("Creating workspace {}", workspaceName);
|
spdlog::debug("Creating workspace {}", workspaceId);
|
||||||
|
|
||||||
// avoid recreating existing workspaces
|
// avoid recreating existing workspaces
|
||||||
auto workspace = std::ranges::find_if(m_workspaces, [&](std::unique_ptr<Workspace> const& w) {
|
auto workspace = std::ranges::find_if(
|
||||||
if (workspaceId > 0) {
|
m_workspaces,
|
||||||
return w->id() == workspaceId;
|
[workspaceId](std::unique_ptr<Workspace> const& w) { return workspaceId == w->id(); });
|
||||||
}
|
|
||||||
return (workspaceName.starts_with("special:") && workspaceName.substr(8) == 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
|
||||||
@@ -98,14 +93,14 @@ void Workspaces::createWorkspace(Json::Value const& workspace_data,
|
|||||||
|
|
||||||
const auto* k = "persistent-rule";
|
const auto* k = "persistent-rule";
|
||||||
if (std::ranges::find(keys, k) != keys.end()) {
|
if (std::ranges::find(keys, k) != keys.end()) {
|
||||||
spdlog::debug("Set dynamic persistency of workspace {} to: {}", workspaceName,
|
spdlog::debug("Set dynamic persistency of workspace {} to: {}", workspaceId,
|
||||||
workspace_data[k].asBool() ? "true" : "false");
|
workspace_data[k].asBool() ? "true" : "false");
|
||||||
(*workspace)->setPersistentRule(workspace_data[k].asBool());
|
(*workspace)->setPersistentRule(workspace_data[k].asBool());
|
||||||
}
|
}
|
||||||
|
|
||||||
k = "persistent-config";
|
k = "persistent-config";
|
||||||
if (std::ranges::find(keys, k) != keys.end()) {
|
if (std::ranges::find(keys, k) != keys.end()) {
|
||||||
spdlog::debug("Set config persistency of workspace {} to: {}", workspaceName,
|
spdlog::debug("Set config persistency of workspace {} to: {}", workspaceId,
|
||||||
workspace_data[k].asBool() ? "true" : "false");
|
workspace_data[k].asBool() ? "true" : "false");
|
||||||
(*workspace)->setPersistentConfig(workspace_data[k].asBool());
|
(*workspace)->setPersistentConfig(workspace_data[k].asBool());
|
||||||
}
|
}
|
||||||
@@ -221,8 +216,6 @@ 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);
|
||||||
}
|
}
|
||||||
// load Hyprland's workspace rules
|
|
||||||
loadPersistentWorkspacesFromWorkspaceRules(clientsJson);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isDoubleSpecial(std::string const& workspace_name) {
|
bool isDoubleSpecial(std::string const& workspace_name) {
|
||||||
@@ -297,51 +290,6 @@ 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 workspace = rule.isMember("defaultName") ? rule["defaultName"].asString()
|
|
||||||
: rule["workspaceString"].asString();
|
|
||||||
|
|
||||||
// There could be persistent special workspaces, only show those when show-special is enabled.
|
|
||||||
if (workspace.starts_with("special:") && !showSpecial()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The prefix "name:" cause mismatches with workspace names taken anywhere else.
|
|
||||||
if (workspace.starts_with("name:")) {
|
|
||||||
workspace = workspace.substr(5);
|
|
||||||
}
|
|
||||||
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()) {
|
|
||||||
// => skip ignore-workspaces even if its a persistent
|
|
||||||
if (isWorkspaceIgnored(workspace)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// => 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);
|
||||||
@@ -1100,10 +1048,8 @@ auto Workspaces::update() -> void {
|
|||||||
void Workspaces::updateWindowCount() {
|
void Workspaces::updateWindowCount() {
|
||||||
const Json::Value workspacesJson = m_ipc.getSocket1JsonReply("workspaces");
|
const Json::Value workspacesJson = m_ipc.getSocket1JsonReply("workspaces");
|
||||||
for (auto const& workspace : m_workspaces) {
|
for (auto const& workspace : m_workspaces) {
|
||||||
auto workspaceJson = std::ranges::find_if(workspacesJson, [&](Json::Value const& x) {
|
auto workspaceJson = std::ranges::find_if(
|
||||||
return x["name"].asString() == workspace->name() ||
|
workspacesJson, [&](Json::Value const& x) { return x["id"].asInt() == workspace->id(); });
|
||||||
(workspace->isSpecial() && x["name"].asString() == "special:" + workspace->name());
|
|
||||||
});
|
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
if (workspaceJson != workspacesJson.end()) {
|
if (workspaceJson != workspacesJson.end()) {
|
||||||
try {
|
try {
|
||||||
@@ -1171,9 +1117,7 @@ void Workspaces::updateWorkspaceStates() {
|
|||||||
workspaceTooltip = workspace->selectString(m_tooltipMap);
|
workspaceTooltip = workspace->selectString(m_tooltipMap);
|
||||||
}
|
}
|
||||||
auto updatedWorkspace = std::ranges::find_if(updatedWorkspaces, [&workspace](const auto& w) {
|
auto updatedWorkspace = std::ranges::find_if(updatedWorkspaces, [&workspace](const auto& w) {
|
||||||
auto wNameRaw = w["name"].asString();
|
return w["id"].asInt() == workspace->id();
|
||||||
auto wName = wNameRaw.starts_with("special:") ? wNameRaw.substr(8) : wNameRaw;
|
|
||||||
return wName == workspace->name();
|
|
||||||
});
|
});
|
||||||
if (updatedWorkspace != updatedWorkspaces.end()) {
|
if (updatedWorkspace != updatedWorkspaces.end()) {
|
||||||
workspace->setOutput((*updatedWorkspace)["monitor"].asString());
|
workspace->setOutput((*updatedWorkspace)["monitor"].asString());
|
||||||
|
|||||||
Reference in New Issue
Block a user