oxwm

https://git.tonybtw.com/oxwm.git git://git.tonybtw.com/oxwm.git

Added hide_vacant_tags() feature from dwm patch into oxwm as optional flag.

Commit
f8f0c96eac32d76234e9a0a5a9fb84d4233b8c87
Parent
d47da56
Author
tonybtw <tonybtw@tonybtw.com>
Date
2025-12-29 07:44:10

Diff

diff --git a/resources/test-config.lua b/resources/test-config.lua
index 322d4da..2b754fb 100644
--- a/resources/test-config.lua
+++ b/resources/test-config.lua
@@ -35,6 +35,7 @@ oxwm.set_terminal("st")
 oxwm.set_modkey(modkey)
 oxwm.set_tags({ "1", "2", "3", "4", "5", "6", "7", "8", "9" })
 oxwm.auto_tile(true);
+oxwm.bar.set_hide_vacant_tags(true);
 
 oxwm.set_layout_symbol("tiling", "[T]")
 oxwm.set_layout_symbol("normie", "[F]")
diff --git a/src/bar/bar.rs b/src/bar/bar.rs
index 31ec156..68bfebe 100644
--- a/src/bar/bar.rs
+++ b/src/bar/bar.rs
@@ -28,6 +28,9 @@ pub struct Bar {
     scheme_occupied: crate::ColorScheme,
     scheme_selected: crate::ColorScheme,
     scheme_urgent: crate::ColorScheme,
+    hide_vacant_tags: bool,
+    last_occupied_tags: u32,
+    last_current_tags: u32,
 }
 
 impl Bar {
@@ -129,6 +132,9 @@ impl Bar {
             scheme_occupied: config.scheme_occupied,
             scheme_selected: config.scheme_selected,
             scheme_urgent: config.scheme_urgent,
+            hide_vacant_tags: config.hide_vacant_tags,
+            last_occupied_tags: 0,
+            last_current_tags: 0,
         })
     }
 
@@ -206,6 +212,9 @@ impl Bar {
             x11::xlib::XFreeGC(display, gc);
         }
 
+        self.last_occupied_tags = occupied_tags;
+        self.last_current_tags = current_tags;
+
         let mut x_position: i16 = 0;
 
         for (tag_index, tag) in self.tags.iter().enumerate() {
@@ -214,6 +223,10 @@ impl Bar {
             let is_occupied = (occupied_tags & tag_mask) != 0;
             let is_urgent = (urgent_tags & tag_mask) != 0;
 
+            if self.hide_vacant_tags && !is_occupied && !is_selected {
+                continue;
+            }
+
             let tag_width = self.tag_widths[tag_index];
 
             let scheme = if is_selected {
@@ -374,6 +387,14 @@ impl Bar {
         let mut current_x_position = 0;
 
         for (tag_index, &tag_width) in self.tag_widths.iter().enumerate() {
+            let tag_mask = 1 << tag_index;
+            let is_selected = (self.last_current_tags & tag_mask) != 0;
+            let is_occupied = (self.last_occupied_tags & tag_mask) != 0;
+
+            if self.hide_vacant_tags && !is_occupied && !is_selected {
+                continue;
+            }
+
             if click_x >= current_x_position && click_x < current_x_position + tag_width as i16 {
                 return Some(tag_index);
             }
@@ -406,6 +427,7 @@ impl Bar {
         self.scheme_occupied = config.scheme_occupied;
         self.scheme_selected = config.scheme_selected;
         self.scheme_urgent = config.scheme_urgent;
+        self.hide_vacant_tags = config.hide_vacant_tags;
 
         self.status_text.clear();
         self.needs_redraw = true;
diff --git a/src/config/lua.rs b/src/config/lua.rs
index 952c49e..69d4286 100644
--- a/src/config/lua.rs
+++ b/src/config/lua.rs
@@ -51,6 +51,7 @@ pub fn parse_lua_config(
         scheme_urgent: builder_data.scheme_urgent,
         autostart: builder_data.autostart,
         auto_tile: builder_data.auto_tile,
+        hide_vacant_tags: builder_data.hide_vacant_tags,
         path: None,
     })
 }
diff --git a/src/config/lua_api.rs b/src/config/lua_api.rs
index 52d815f..3471462 100644
--- a/src/config/lua_api.rs
+++ b/src/config/lua_api.rs
@@ -35,6 +35,7 @@ pub struct ConfigBuilder {
     pub scheme_urgent: ColorScheme,
     pub autostart: Vec<String>,
     pub auto_tile: bool,
+    pub hide_vacant_tags: bool,
 }
 
 impl Default for ConfigBuilder {
@@ -80,6 +81,7 @@ impl Default for ConfigBuilder {
             },
             autostart: Vec::new(),
             auto_tile: false,
+            hide_vacant_tags: false,
         }
     }
 }
@@ -726,6 +728,12 @@ fn register_bar_module(
             Ok(())
         })?;
 
+    let builder_clone = builder.clone();
+    let set_hide_vacant_tags = lua.create_function(move |_, hide: bool| {
+        builder_clone.borrow_mut().hide_vacant_tags = hide;
+        Ok(())
+    })?;
+
     bar_table.set("set_font", set_font)?;
     bar_table.set("block", block_table)?;
     bar_table.set("add_block", add_block)?; // Deprecated, for backwards compatibility
@@ -734,6 +742,7 @@ fn register_bar_module(
     bar_table.set("set_scheme_occupied", set_scheme_occupied)?;
     bar_table.set("set_scheme_selected", set_scheme_selected)?;
     bar_table.set("set_scheme_urgent", set_scheme_urgent)?;
+    bar_table.set("set_hide_vacant_tags", set_hide_vacant_tags)?;
     parent.set("bar", bar_table)?;
     Ok(())
 }
diff --git a/src/lib.rs b/src/lib.rs
index b52b23c..87aab35 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -103,6 +103,7 @@ pub struct Config {
 
     pub autostart: Vec<String>,
     pub auto_tile: bool,
+    pub hide_vacant_tags: bool,
 }
 
 #[derive(Debug, Clone, Copy)]
@@ -353,6 +354,7 @@ impl Default for Config {
             },
             autostart: vec![],
             auto_tile: false,
+            hide_vacant_tags: false,
         }
     }
 }
diff --git a/templates/config.lua b/templates/config.lua
index 0679970..b0f09c8 100644
--- a/templates/config.lua
+++ b/templates/config.lua
@@ -172,6 +172,9 @@ oxwm.bar.set_scheme_selected(colors.cyan, colors.bg, colors.purple)
 -- Urgent tags (windows requesting attention)
 oxwm.bar.set_scheme_urgent(colors.red, colors.bg, colors.red)
 
+-- Hide tags that have no windows and are not selected
+-- oxwm.bar.set_hide_vacant_tags(true)
+
 -------------------------------------------------------------------------------
 -- Keybindings
 -------------------------------------------------------------------------------
diff --git a/templates/oxwm.lua b/templates/oxwm.lua
index 3dc0d81..77a2d47 100644
--- a/templates/oxwm.lua
+++ b/templates/oxwm.lua
@@ -315,6 +315,10 @@ function oxwm.bar.set_scheme_selected(foreground, background, underline) end
 ---@param underline string|integer Underline color
 function oxwm.bar.set_scheme_urgent(foreground, background, underline) end
 
+---Hide tags that have no windows and are not currently selected
+---@param hide boolean Whether to hide vacant tags
+function oxwm.bar.set_hide_vacant_tags(hide) end
+
 ---Add an autostart command
 ---@param cmd string Command to run at startup
 function oxwm.autostart(cmd) end