feat(hyprland/workspaces): grouping icons
This commit is contained in:
@@ -61,6 +61,8 @@ class Workspaces : public AModule, public EventHandler {
|
||||
|
||||
std::string getRewrite(std::string window_class, std::string window_title);
|
||||
std::string& getWindowSeparator() { return m_formatWindowSeparator; }
|
||||
auto windowRewriteGroupThreshold() const -> int { return m_windowRewriteGroupThreshold; }
|
||||
auto const& getWindowRewriteGroupFormat() const { return m_windowRewriteGroupFormat; }
|
||||
bool isWorkspaceIgnored(std::string const& workspace_name);
|
||||
|
||||
bool windowRewriteConfigUsesTitle() const { return m_anyWindowRewriteRuleUsesTitle; }
|
||||
@@ -172,6 +174,8 @@ class Workspaces : public AModule, public EventHandler {
|
||||
util::RegexCollection m_windowRewriteRules;
|
||||
bool m_anyWindowRewriteRuleUsesTitle = false;
|
||||
std::string m_formatWindowSeparator;
|
||||
int m_windowRewriteGroupThreshold = 0;
|
||||
std::string m_windowRewriteGroupFormat = "{icon}×{count}";
|
||||
|
||||
bool m_withIcon;
|
||||
uint64_t m_monitorId;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <json/value.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
@@ -245,15 +246,53 @@ void Workspace::update(const std::string& workspace_icon) {
|
||||
// need to compute this if enableTaskbar() is true
|
||||
if (!m_workspaceManager.enableTaskbar()) {
|
||||
auto windowSeparator = m_workspaceManager.getWindowSeparator();
|
||||
auto groupThreshold = m_workspaceManager.windowRewriteGroupThreshold();
|
||||
|
||||
bool isNotFirst = false;
|
||||
if (groupThreshold > 0) {
|
||||
// Build ordered counts of each unique icon (including singular ones when threshold set to 1)
|
||||
std::vector<std::pair<std::string, int>> iconCounts;
|
||||
for (const auto& window_repr : m_windowMap) {
|
||||
auto it = std::ranges::find_if(iconCounts, [&](const auto& p) {
|
||||
return p.first == window_repr.repr_rewrite;
|
||||
});
|
||||
if (it != iconCounts.end()) {
|
||||
it->second++;
|
||||
} else {
|
||||
iconCounts.emplace_back(window_repr.repr_rewrite, 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& window_repr : m_windowMap) {
|
||||
if (isNotFirst) {
|
||||
windows.append(windowSeparator);
|
||||
// Format the group string
|
||||
auto groupFormat = m_workspaceManager.getWindowRewriteGroupFormat();
|
||||
bool isNotFirst = false;
|
||||
for (const auto& [icon, count] : iconCounts) {
|
||||
if (count >= groupThreshold) {
|
||||
if (isNotFirst) windows.append(windowSeparator);
|
||||
isNotFirst = true;
|
||||
try {
|
||||
windows.append(fmt::format(fmt::runtime(groupFormat),
|
||||
fmt::arg("icon", icon),
|
||||
fmt::arg("count", count)));
|
||||
} catch (const fmt::format_error& e) {
|
||||
spdlog::warn("Formatting window-rewrite-group-format error: {}", e.what());
|
||||
windows.append(icon);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (isNotFirst) windows.append(windowSeparator);
|
||||
isNotFirst = true;
|
||||
windows.append(icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Not grouping icons
|
||||
bool isNotFirst = false;
|
||||
for (const auto& window_repr : m_windowMap) {
|
||||
if (isNotFirst) windows.append(windowSeparator);
|
||||
isNotFirst = true;
|
||||
windows.append(window_repr.repr_rewrite);
|
||||
}
|
||||
isNotFirst = true;
|
||||
windows.append(window_repr.repr_rewrite);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -649,6 +649,16 @@ auto Workspaces::parseConfig(const Json::Value& config) -> void {
|
||||
populateSortByConfig(config);
|
||||
populateIgnoreWorkspacesConfig(config);
|
||||
populateFormatWindowSeparatorConfig(config);
|
||||
|
||||
const auto& groupThreshold = config["window-rewrite-group-threshold"];
|
||||
if (groupThreshold.isInt()) {
|
||||
m_windowRewriteGroupThreshold = groupThreshold.asInt();
|
||||
}
|
||||
const auto& groupFormat = config["window-rewrite-group-format"];
|
||||
if (groupFormat.isString()) {
|
||||
m_windowRewriteGroupFormat = groupFormat.asString();
|
||||
}
|
||||
|
||||
populateWindowRewriteConfig(config);
|
||||
|
||||
if (withWindows) {
|
||||
|
||||
Reference in New Issue
Block a user