oxwm

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

add configurable back-and-forth tag switching

Commit
a96e35b6bc98305b9507ed61e3e29a98bbecddc6
Parent
46596a9
Author
emzywastaken <amiamemetoo@gmail.com>
Date
2025-12-15 10:02:47
Adds the ability to optionally switch back to the previously viewed tag
when trying to view the current tag. Adds `tag_back_and_forth` to
config, configured with `oxwm.tag.set_back_and_forth` in Lua API.

Closes #71.

Diff

diff --git a/src/config/lua.rs b/src/config/lua.rs
index f97797a..57b2ed1 100644
--- a/src/config/lua.rs
+++ b/src/config/lua.rs
@@ -42,6 +42,7 @@ pub fn parse_lua_config(
         tags: builder_data.tags,
         layout_symbols: builder_data.layout_symbols,
         keybindings: builder_data.keybindings,
+        tag_back_and_forth: builder_data.tag_back_and_forth,
         window_rules: builder_data.window_rules,
         status_blocks: builder_data.status_blocks,
         scheme_normal: builder_data.scheme_normal,
diff --git a/src/config/lua_api.rs b/src/config/lua_api.rs
index 91030ae..4025276 100644
--- a/src/config/lua_api.rs
+++ b/src/config/lua_api.rs
@@ -26,6 +26,7 @@ pub struct ConfigBuilder {
     pub tags: Vec<String>,
     pub layout_symbols: Vec<crate::LayoutSymbolOverride>,
     pub keybindings: Vec<KeyBinding>,
+    pub tag_back_and_forth: bool,
     pub window_rules: Vec<crate::WindowRule>,
     pub status_blocks: Vec<BlockConfig>,
     pub scheme_normal: ColorScheme,
@@ -53,6 +54,7 @@ impl Default for ConfigBuilder {
             tags: vec!["1".into(), "2".into(), "3".into()],
             layout_symbols: Vec::new(),
             keybindings: Vec::new(),
+            tag_back_and_forth: false,
             window_rules: Vec::new(),
             status_blocks: Vec::new(),
             scheme_normal: ColorScheme {
@@ -89,7 +91,7 @@ pub fn register_api(lua: &Lua) -> Result<SharedBuilder, ConfigError> {
     register_border_module(&lua, &oxwm_table, builder.clone())?;
     register_client_module(&lua, &oxwm_table)?;
     register_layout_module(&lua, &oxwm_table)?;
-    register_tag_module(&lua, &oxwm_table)?;
+    register_tag_module(&lua, &oxwm_table, builder.clone())?;
     register_monitor_module(&lua, &oxwm_table)?;
     register_rule_module(&lua, &oxwm_table, builder.clone())?;
     register_bar_module(&lua, &oxwm_table, builder.clone())?;
@@ -296,7 +298,12 @@ fn register_layout_module(lua: &Lua, parent: &Table) -> Result<(), ConfigError>
     Ok(())
 }
 
-fn register_tag_module(lua: &Lua, parent: &Table) -> Result<(), ConfigError> {
+fn register_tag_module(
+    lua: &Lua,
+    parent: &Table,
+    builder: SharedBuilder,
+) -> Result<(), ConfigError> {
+    let builder_clone = builder.clone();
     let tag_table = lua.create_table()?;
 
     let view = lua.create_function(|lua, idx: i32| {
@@ -328,6 +335,11 @@ fn register_tag_module(lua: &Lua, parent: &Table) -> Result<(), ConfigError> {
         create_action_table(lua, "ToggleTag", Value::Integer(idx as i64))
     })?;
 
+    let set_back_and_forth = lua.create_function(move |_, enabled: bool| {
+        builder_clone.borrow_mut().tag_back_and_forth = enabled;
+        Ok(())
+    })?;
+
     tag_table.set("view", view)?;
     tag_table.set("view_next", view_next)?;
     tag_table.set("view_previous", view_previous)?;
@@ -336,6 +348,7 @@ fn register_tag_module(lua: &Lua, parent: &Table) -> Result<(), ConfigError> {
     tag_table.set("toggleview", toggleview)?;
     tag_table.set("move_to", move_to)?;
     tag_table.set("toggletag", toggletag)?;
+    tag_table.set("set_back_and_forth", set_back_and_forth)?;
     parent.set("tag", tag_table)?;
     Ok(())
 }
diff --git a/src/lib.rs b/src/lib.rs
index bab7d55..a2c7069 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -87,6 +87,7 @@ pub struct Config {
 
     // Keybindings
     pub keybindings: Vec<crate::keyboard::handlers::Key>,
+    pub tag_back_and_forth: bool,
 
     // Window rules
     pub window_rules: Vec<WindowRule>,
@@ -320,6 +321,7 @@ impl Default for Config {
                     Arg::Int(8),
                 ),
             ],
+            tag_back_and_forth: false,
             window_rules: vec![],
             status_blocks: vec![crate::bar::BlockConfig {
                 format: "{}".to_string(),
diff --git a/src/window_manager.rs b/src/window_manager.rs
index 6ee5bd1..cb94215 100644
--- a/src/window_manager.rs
+++ b/src/window_manager.rs
@@ -1142,12 +1142,15 @@ impl WindowManager {
         let new_tagset = tag_mask(tag_index);
 
         if new_tagset == monitor.tagset[monitor.selected_tags_index] {
-            return Ok(());
+            if !self.config.tag_back_and_forth {
+                return Ok(());
+            }
+            monitor.tagset.swap(0, 1);
+        } else {
+            monitor.selected_tags_index ^= 1;
+            monitor.tagset[monitor.selected_tags_index] = new_tagset;
         }
 
-        monitor.selected_tags_index ^= 1;
-        monitor.tagset[monitor.selected_tags_index] = new_tagset;
-
         self.save_selected_tags()?;
         self.focus(None)?;
         self.apply_layout()?;
diff --git a/templates/oxwm.lua b/templates/oxwm.lua
index 2af84d6..3ec047c 100644
--- a/templates/oxwm.lua
+++ b/templates/oxwm.lua
@@ -236,6 +236,10 @@ function oxwm.tag.toggleview(index) end
 ---@return table Action table for keybinding
 function oxwm.tag.toggletag(index) end
 
+---When enabled an attempt to view the current tag switches back to the previously viewed tag.
+---@param enabled boolean Enable or disable tag_back_and_forth
+function oxwm.tag.set_back_and_forth(enabled) end
+
 ---Status bar configuration module
 ---@class oxwm.bar
 oxwm.bar = {}