feat: add custom workspace sorting functionality
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include <gtkmm/button.h>
|
||||
#include <gtkmm/label.h>
|
||||
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -44,6 +45,7 @@ class Workspaces : public AModule, public sigc::trackable {
|
||||
std::string getCycleWorkspace(std::vector<Json::Value>::iterator, bool prev) const;
|
||||
uint16_t getWorkspaceIndex(const std::string& name) const;
|
||||
static std::string trimWorkspaceName(const std::string&);
|
||||
std::optional<uint16_t> getCustomSortIndex(const std::string& name) const;
|
||||
bool handleScroll(GdkEventScroll* /*unused*/) override;
|
||||
|
||||
const Bar& bar_;
|
||||
@@ -56,6 +58,7 @@ class Workspaces : public AModule, public sigc::trackable {
|
||||
util::RegexCollection m_windowRewriteRules;
|
||||
util::JsonParser parser_;
|
||||
std::unordered_map<std::string, Gtk::Button> buttons_;
|
||||
std::unordered_map<std::string, uint16_t> custom_sort_priorities_;
|
||||
std::mutex mutex_;
|
||||
Ipc ipc_;
|
||||
};
|
||||
|
||||
@@ -96,6 +96,11 @@ Addressed by *sway/workspaces*
|
||||
typeof: bool ++
|
||||
Whether to sort workspaces alphabetically. Please note this can make "swaymsg workspace prev/next" move to workspaces inconsistent with the ordering shown in Waybar.
|
||||
|
||||
*custom-sort*: ++
|
||||
typeof: array ++
|
||||
default: [] ++
|
||||
Defines an explicit ordering for workspace names. Entries earlier in the array appear first. Both full names and the trimmed portion after ":" are matched. Any workspace not listed here falls back to the default ordering (or alphabetical ordering when *alphabetical_sort* is true).
|
||||
|
||||
warp-on-scroll: ++
|
||||
typeof: bool ++
|
||||
default: true ++
|
||||
|
||||
@@ -50,6 +50,21 @@ Workspaces::Workspaces(const std::string& id, const Bar& bar, const Json::Value&
|
||||
high_priority_named_.push_back(it.asString());
|
||||
}
|
||||
}
|
||||
if (config_["custom-sort"].isArray()) {
|
||||
uint16_t priority = 0;
|
||||
for (const auto& entry : config_["custom-sort"]) {
|
||||
if (!entry.isString()) {
|
||||
continue;
|
||||
}
|
||||
auto const name = entry.asString();
|
||||
custom_sort_priorities_.insert_or_assign(name, priority);
|
||||
auto const trimmed = trimWorkspaceName(name);
|
||||
if (trimmed != name) {
|
||||
custom_sort_priorities_.insert_or_assign(trimmed, priority);
|
||||
}
|
||||
++priority;
|
||||
}
|
||||
}
|
||||
box_.set_name("workspaces");
|
||||
if (!id.empty()) {
|
||||
box_.get_style_context()->add_class(id);
|
||||
@@ -236,6 +251,20 @@ void Workspaces::onCmd(const struct Ipc::ipc_response& res) {
|
||||
int l = lhs["sort"].asInt();
|
||||
int r = rhs["sort"].asInt();
|
||||
|
||||
if (!custom_sort_priorities_.empty()) {
|
||||
auto const lcustom = getCustomSortIndex(lname);
|
||||
auto const rcustom = getCustomSortIndex(rname);
|
||||
if (lcustom && rcustom) {
|
||||
if (*lcustom != *rcustom) {
|
||||
return *lcustom < *rcustom;
|
||||
}
|
||||
} else if (lcustom) {
|
||||
return true;
|
||||
} else if (rcustom) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (l == r || config_["alphabetical_sort"].asBool()) {
|
||||
// In case both integers are the same, lexicographical
|
||||
// sort. The code above already ensure that this will only
|
||||
@@ -572,6 +601,24 @@ std::string Workspaces::trimWorkspaceName(const std::string& name) {
|
||||
return name;
|
||||
}
|
||||
|
||||
std::optional<uint16_t> Workspaces::getCustomSortIndex(const std::string& name) const {
|
||||
if (custom_sort_priorities_.empty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
auto it = custom_sort_priorities_.find(name);
|
||||
if (it != custom_sort_priorities_.end()) {
|
||||
return it->second;
|
||||
}
|
||||
auto trimmed = trimWorkspaceName(name);
|
||||
if (trimmed != name) {
|
||||
auto trimmed_it = custom_sort_priorities_.find(trimmed);
|
||||
if (trimmed_it != custom_sort_priorities_.end()) {
|
||||
return trimmed_it->second;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool is_focused_recursive(const Json::Value& node) {
|
||||
// If a workspace has a focused container then get_tree will say
|
||||
// that the workspace itself isn't focused. Therefore we need to
|
||||
|
||||
Reference in New Issue
Block a user