@@ -19,7 +19,10 @@ namespace waybar::modules::dwl {
1919/* dwl stuff */
2020wl_array tags, layouts;
2121
22- static uint num_tags = 0 ;
22+ static uint32_t num_tags = 0 ;
23+ static uint32_t num_counts = 0 ;
24+ std::vector<std::string> tag_labels;
25+
2326
2427static void toggle_visibility (void *data, zdwl_ipc_output_v2 *zdwl_output_v2) {
2528 // Intentionally empty
@@ -87,14 +90,59 @@ static void handle_global_remove(void *data, struct wl_registry *registry, uint3
8790
8891static const wl_registry_listener registry_listener_impl = {.global = handle_global,
8992 .global_remove = handle_global_remove};
93+ uint32_t Tags::get_label_position (std::string label) {
94+ uint32_t i;
95+ for (i=0 ;i< num_counts;i++) {
96+ if (label == tag_labels[i]) {
97+ return i;
98+ }
99+ }
100+ return UINT32_MAX;
101+ }
102+
103+ void Tags::add_button (uint32_t tag) {
104+ uint32_t inser_pos = 0 ;
105+ std::string label = tag_labels[tag];
106+ std::string added_label;
107+ uint32_t position = UINT32_MAX;
108+
109+ for (auto &added_button : buttons_) {
110+ added_label = added_button.get_label ();
111+ position = get_label_position (added_label);
112+ if (position != UINT32_MAX && position < (tag + 1 )) {
113+ inser_pos++;
114+ }
115+ }
116+
117+ buttons_.emplace (buttons_.begin () + (inser_pos), label);
118+
119+ auto &button = buttons_[inser_pos];
120+
121+ button.set_relief (Gtk::RELIEF_NONE);
122+ box_.pack_start (button, false , false , 0 );
123+ for (size_t i = 0 ; i < buttons_.size (); ++i) {
124+ box_.reorder_child (buttons_[i], i);
125+ }
126+
127+ if (!config_[" disable-click" ].asBool ()) {
128+ button.signal_clicked ().connect (
129+ sigc::bind (sigc::mem_fun (*this , &Tags::handle_primary_clicked), 1 <<tag));
130+ button.signal_button_press_event ().connect (
131+ sigc::bind (sigc::mem_fun (*this , &Tags::handle_button_press), 1 <<tag));
132+ }
133+ }
90134
91135Tags::Tags (const std::string &id, const waybar::Bar &bar, const Json::Value &config)
92136 : waybar::AModule(config, " tags" , id, false , false ),
93137 status_manager_{nullptr },
94138 seat_{nullptr },
95139 bar_ (bar),
96140 box_{bar.orientation , 0 },
141+ hide_vacant_ (false ),
97142 output_status_{nullptr } {
143+ if (config_[" hide-vacant" ].asBool ()) {
144+ hide_vacant_ = config_[" hide-vacant" ].asBool ();
145+ }
98146 struct wl_display *display = Client::inst ()->wl_display ;
99147 struct wl_registry *registry = wl_display_get_registry (display);
100148
@@ -118,33 +166,27 @@ Tags::Tags(const std::string &id, const waybar::Bar &bar, const Json::Value &con
118166 event_box_.add (box_);
119167
120168 // Default to 9 tags, cap at 32
121- const uint32_t num_tags =
169+ num_counts =
122170 config[" num-tags" ].isUInt () ? std::min<uint32_t >(32 , config_[" num-tags" ].asUInt ()) : 9 ;
171+
172+ tag_labels.resize (num_counts);
123173
124- std::vector<std::string> tag_labels (num_tags);
125- for (uint32_t tag = 0 ; tag < num_tags; ++tag) {
174+ for (uint32_t tag = 0 ; tag < num_counts; ++tag) {
126175 tag_labels[tag] = std::to_string (tag + 1 );
127176 }
128177 const Json::Value custom_labels = config[" tag-labels" ];
129178 if (custom_labels.isArray () && !custom_labels.empty ()) {
130- for (uint32_t tag = 0 ; tag < std::min (num_tags , custom_labels.size ()); ++tag) {
179+ for (uint32_t tag = 0 ; tag < std::min (num_counts , custom_labels.size ()); ++tag) {
131180 tag_labels[tag] = custom_labels[tag].asString ();
132181 }
133182 }
134183
135- uint32_t i = 1 ;
136- for (const auto &tag_label : tag_labels) {
137- Gtk::Button &button = buttons_.emplace_back (tag_label);
138- button.set_relief (Gtk::RELIEF_NONE);
139- box_.pack_start (button, false , false , 0 );
140- if (!config_[" disable-click" ].asBool ()) {
141- button.signal_clicked ().connect (
142- sigc::bind (sigc::mem_fun (*this , &Tags::handle_primary_clicked), i));
143- button.signal_button_press_event ().connect (
144- sigc::bind (sigc::mem_fun (*this , &Tags::handle_button_press), i));
184+ if (!hide_vacant_) {
185+ uint32_t i = 1 ;
186+ while (i <= num_counts) {
187+ add_button (num_counts-i);
188+ i++;
145189 }
146- button.show ();
147- i <<= 1 ;
148190 }
149191
150192 struct wl_output *output = gdk_wayland_monitor_get_wl_output (bar_.output ->monitor ->gobj ());
@@ -179,24 +221,56 @@ bool Tags::handle_button_press(GdkEventButton *event_button, uint32_t tag) {
179221}
180222
181223void Tags::handle_view_tags (uint32_t tag, uint32_t state, uint32_t clients, uint32_t focused) {
182- // First clear all occupied state
183- auto &button = buttons_[tag];
184- if (clients) {
185- button.get_style_context ()->add_class (" occupied" );
186- } else {
187- button.get_style_context ()->remove_class (" occupied" );
224+
225+ bool is_new_button = true ;
226+ std::string added_label,label;
227+ uint32_t position = UINT32_MAX;
228+
229+ for (auto &added_button : buttons_) {
230+ added_label = added_button.get_label ();
231+ position = get_label_position (added_label);
232+ if (position != UINT32_MAX && position == tag) {
233+ is_new_button = false ;
234+ }
188235 }
189236
190- if (state & TAG_ACTIVE) {
191- button.get_style_context ()->add_class (" focused" );
192- } else {
193- button.get_style_context ()->remove_class (" focused" );
237+ if (is_new_button && ((state & TAG_ACTIVE) || (state & TAG_URGENT) || clients)) {
238+ add_button (tag);
194239 }
195240
196- if (state & TAG_URGENT) {
197- button.get_style_context ()->add_class (" urgent" );
198- } else {
199- button.get_style_context ()->remove_class (" urgent" );
241+ for (auto &button : buttons_) {
242+
243+ label = button.get_label ();
244+ position = get_label_position (label);
245+ if (position == UINT32_MAX || position != tag)
246+ continue ;
247+
248+ if (clients) {
249+ button.get_style_context ()->add_class (" occupied" );
250+ button.set_visible (true );
251+ } else {
252+ button.get_style_context ()->remove_class (" occupied" );
253+ }
254+
255+ if (state & TAG_ACTIVE) {
256+ button.get_style_context ()->add_class (" focused" );
257+ button.set_visible (true );
258+ } else {
259+ button.get_style_context ()->remove_class (" focused" );
260+ }
261+
262+ if (state & TAG_URGENT) {
263+ button.get_style_context ()->add_class (" urgent" );
264+ button.set_visible (true );
265+ } else {
266+ button.get_style_context ()->remove_class (" urgent" );
267+ }
268+
269+ if (hide_vacant_ && !(state & TAG_ACTIVE) && !(state & TAG_URGENT) && !clients) {
270+ button.set_visible (false );
271+ } else {
272+ button.set_visible (true );
273+ }
200274 }
201275}
202276
0 commit comments