dot

vizie's NixOS desktop: Hyprland, CachyOS kernel and gaming tweaks

116 lines4106 bytesDiff
1diff --color -ruN a/include/modules/sni/item.hpp b/include/modules/sni/item.hpp
2--- a/include/modules/sni/item.hpp 2026-10-04 20:48:34.950686997 +0200
3+++ b/include/modules/sni/item.hpp 2026-10-04 20:48:34.961979805 +0200
4@@ -12,7 +12,9 @@
5 #include <sigc++/trackable.h>
6
7 #include <set>
8+#include <string>
9 #include <string_view>
10+#include <vector>
11
12 #include "bar.hpp"
13
14@@ -63,6 +65,7 @@
15 void setProperty(const Glib::ustring& name, Glib::VariantBase& value);
16 void setStatus(const Glib::ustring& value);
17 void setCustomIcon(const std::string& id);
18+ void applyOrder();
19 void getUpdatedProperties();
20 void processUpdatedProperties(Glib::RefPtr<Gio::AsyncResult>& result);
21 void onSignal(const Glib::ustring& sender_name, const Glib::ustring& signal_name,
22@@ -86,6 +89,8 @@
23 gdouble distance_scrolled_y_ = 0;
24 // visibility of items with Status == Passive
25 bool show_passive_ = false;
26+ // item ids from the "order" config; these are placed first, in this order
27+ std::vector<std::string> order_;
28
29 const Bar& bar_;
30
31diff --color -ruN a/src/modules/sni/item.cpp b/src/modules/sni/item.cpp
32--- a/src/modules/sni/item.cpp 2026-10-04 20:48:34.949687001 +0200
33+++ b/src/modules/sni/item.cpp 2026-10-04 20:48:34.962215355 +0200
34@@ -5,6 +5,8 @@
35 #include <gtkmm/tooltip.h>
36 #include <spdlog/spdlog.h>
37
38+#include <algorithm>
39+#include <climits>
40 #include <filesystem>
41 #include <fstream>
42 #include <map>
43@@ -53,6 +55,13 @@
44 if (config["show-passive-items"].isBool()) {
45 show_passive_ = config["show-passive-items"].asBool();
46 }
47+ if (config["order"].isArray()) {
48+ for (const auto& entry : config["order"]) {
49+ if (entry.isString()) {
50+ order_.push_back(entry.asString());
51+ }
52+ }
53+ }
54
55 auto& window = const_cast<Bar&>(bar).window;
56 window.signal_configure_event().connect_notify(sigc::mem_fun(*this, &Item::onConfigure));
57@@ -115,6 +124,7 @@
58 return;
59 }
60 this->updateImage();
61+ this->applyOrder();
62
63 } catch (const Glib::Error& err) {
64 spdlog::error("Failed to create DBus Proxy for {} {}: {}", bus_name, object_path, err.what());
65@@ -250,6 +260,41 @@
66 }
67 }
68
69+/**
70+ * Sort this item's tray according to the "order" config: items listed there come first,
71+ * in the listed order, and all others keep their relative order after them. Items are
72+ * matched like in the "icons" config, i.e. Electron's "chrome_status_icon_1" by tooltip.
73+ * Runs once an item knows its id, as that is only available after its proxy is ready.
74+ */
75+void Item::applyOrder() {
76+ if (order_.empty()) {
77+ return;
78+ }
79+ static const Glib::Quark rank_key("waybar-tray-order");
80+
81+ const std::string key = id == "chrome_status_icon_1" ? tooltip.text.lowercase().raw() : id;
82+ const auto listed = std::find(order_.begin(), order_.end(), key);
83+ // 0 (no data) means unlisted
84+ event_box.set_data(rank_key, listed == order_.end()
85+ ? nullptr
86+ : GINT_TO_POINTER(std::distance(order_.begin(), listed) + 1));
87+
88+ auto* box = dynamic_cast<Gtk::Box*>(event_box.get_parent());
89+ if (box == nullptr) {
90+ return;
91+ }
92+ const auto rank = [](Gtk::Widget* widget) {
93+ const int value = GPOINTER_TO_INT(widget->get_data(rank_key));
94+ return value == 0 ? INT_MAX : value;
95+ };
96+ auto children = box->get_children();
97+ std::stable_sort(children.begin(), children.end(),
98+ [&rank](Gtk::Widget* a, Gtk::Widget* b) { return rank(a) < rank(b); });
99+ for (std::size_t i = 0; i < children.size(); ++i) {
100+ box->reorder_child(*children[i], static_cast<int>(i));
101+ }
102+}
103+
104 void Item::getUpdatedProperties() {
105 auto params = Glib::VariantContainerBase::create_tuple(
106 {Glib::Variant<Glib::ustring>::create(SNI_INTERFACE_NAME)});
107@@ -279,6 +324,9 @@
108 update_pending_.count("ToolTip")) {
109 setCustomIcon(id == "chrome_status_icon_1" ? tooltip.text.lowercase() : Glib::ustring(id));
110 }
111+ if (update_pending_.count("ToolTip")) {
112+ this->applyOrder();
113+ }
114
115 this->updateImage();
116 } catch (const Glib::Error& err) {