oxwm

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

Add view next/previous tag actions

Commit
ddba5cee5e5ba7cd59d00e771eafc808616abc44
Parent
cba2953
Author
emzywastaken <amiamemetoo@gmail.com>
Date
2025-12-13 16:42:05

Diff

diff --git a/src/config/lua_api.rs b/src/config/lua_api.rs
index cae6189..cb71369 100644
--- a/src/config/lua_api.rs
+++ b/src/config/lua_api.rs
@@ -303,6 +303,12 @@ fn register_tag_module(lua: &Lua, parent: &Table) -> Result<(), ConfigError> {
         create_action_table(lua, "ViewTag", Value::Integer(idx as i64))
     })?;
 
+    let view_next =
+        lua.create_function(|lua, ()| create_action_table(lua, "ViewNextTag", Value::Nil))?;
+
+    let view_previous =
+        lua.create_function(|lua, ()| create_action_table(lua, "ViewPreviousTag", Value::Nil))?;
+
     let toggleview = lua.create_function(|lua, idx: i32| {
         create_action_table(lua, "ToggleView", Value::Integer(idx as i64))
     })?;
@@ -316,6 +322,8 @@ fn register_tag_module(lua: &Lua, parent: &Table) -> Result<(), ConfigError> {
     })?;
 
     tag_table.set("view", view)?;
+    tag_table.set("view_next", view_next)?;
+    tag_table.set("view_previous", view_previous)?;
     tag_table.set("toggleview", toggleview)?;
     tag_table.set("move_to", move_to)?;
     tag_table.set("toggletag", toggletag)?;
@@ -845,6 +853,8 @@ fn string_to_action(s: &str) -> mlua::Result<KeyAction> {
         "Quit" => Ok(KeyAction::Quit),
         "Restart" => Ok(KeyAction::Restart),
         "ViewTag" => Ok(KeyAction::ViewTag),
+        "ViewNextTag" => Ok(KeyAction::ViewNextTag),
+        "ViewPreviousTag" => Ok(KeyAction::ViewPreviousTag),
         "ToggleView" => Ok(KeyAction::ToggleView),
         "MoveToTag" => Ok(KeyAction::MoveToTag),
         "ToggleTag" => Ok(KeyAction::ToggleTag),
diff --git a/src/keyboard/handlers.rs b/src/keyboard/handlers.rs
index 52a4a4f..87e7bf3 100644
--- a/src/keyboard/handlers.rs
+++ b/src/keyboard/handlers.rs
@@ -17,6 +17,8 @@ pub enum KeyAction {
     Quit,
     Restart,
     ViewTag,
+    ViewNextTag,
+    ViewPreviousTag,
     ToggleView,
     MoveToTag,
     ToggleTag,
diff --git a/src/monitor.rs b/src/monitor.rs
index f73c06e..e7cac16 100644
--- a/src/monitor.rs
+++ b/src/monitor.rs
@@ -1,3 +1,4 @@
+use crate::client::TagMask;
 use crate::errors::WmError;
 use x11rb::protocol::xinerama::ConnectionExt as _;
 use x11rb::protocol::xproto::{Screen, Window};
@@ -75,6 +76,10 @@ impl Monitor {
             && y >= self.screen_y
             && y < self.screen_y + self.screen_height
     }
+
+    pub fn get_selected_tag(&self) -> TagMask {
+        self.tagset[self.selected_tags_index]
+    }
 }
 
 pub fn detect_monitors(
diff --git a/src/overlay/keybind.rs b/src/overlay/keybind.rs
index 7114db3..2a02df0 100644
--- a/src/overlay/keybind.rs
+++ b/src/overlay/keybind.rs
@@ -220,6 +220,8 @@ impl KeybindOverlay {
                 Arg::Int(n) => format!("View Workspace {}", n),
                 _ => "View Workspace".to_string(),
             },
+            KeyAction::ViewNextTag => "View Next Workspace".to_string(),
+            KeyAction::ViewPreviousTag => "View Previous Workspace".to_string(),
             KeyAction::ToggleView => match &binding.arg {
                 Arg::Int(n) => format!("Toggle View Workspace {}", n),
                 _ => "Toggle View Workspace".to_string(),
diff --git a/src/window_manager.rs b/src/window_manager.rs
index 294deda..4a7ca3a 100644
--- a/src/window_manager.rs
+++ b/src/window_manager.rs
@@ -20,6 +20,12 @@ pub fn tag_mask(tag: usize) -> TagMask {
     1 << tag
 }
 
+/// Get back a tag index from a [`TagMask`]
+pub fn unmask_tag(mask: TagMask) -> usize {
+    // mask only has one bit set, so this works.
+    mask.trailing_zeros() as usize
+}
+
 struct AtomCache {
     net_current_desktop: Atom,
     net_client_info: Atom,
@@ -805,6 +811,20 @@ impl WindowManager {
                     self.view_tag(*tag_index as usize)?;
                 }
             }
+            KeyAction::ViewNextTag => {
+                let monitor = self.get_selected_monitor();
+                let current_tag_mask = monitor.get_selected_tag();
+
+                let current_tag_index = unmask_tag(current_tag_mask);
+                self.view_tag(current_tag_index.saturating_add(1))?;
+            }
+            KeyAction::ViewPreviousTag => {
+                let monitor = self.get_selected_monitor();
+                let current_tag_mask = monitor.get_selected_tag();
+
+                let current_tag_index = unmask_tag(current_tag_mask);
+                self.view_tag(current_tag_index.saturating_sub(1))?;
+            }
             KeyAction::ToggleView => {
                 if let Arg::Int(tag_index) = arg {
                     self.toggleview(*tag_index as usize)?;
@@ -1455,8 +1475,7 @@ impl WindowManager {
             for window in &windows {
                 self.connection.configure_window(
                     *window,
-                    &x11rb::protocol::xproto::ConfigureWindowAux::new()
-                        .border_width(0),
+                    &x11rb::protocol::xproto::ConfigureWindowAux::new().border_width(0),
                 )?;
             }
 
@@ -4175,6 +4194,10 @@ impl WindowManager {
         Ok(())
     }
 
+    fn get_selected_monitor(&self) -> &Monitor {
+        &self.monitors[self.selected_monitor]
+    }
+
     fn run_autostart_commands(&self) {
         for command in &self.config.autostart {
             crate::signal::spawn_detached(command);
diff --git a/templates/oxwm.lua b/templates/oxwm.lua
index e2e724a..26fd328 100644
--- a/templates/oxwm.lua
+++ b/templates/oxwm.lua
@@ -205,6 +205,14 @@ oxwm.tag = {}
 ---@return table Action table for keybinding
 function oxwm.tag.view(index) end
 
+---View/switch to next tag
+---@return table Action table for keybinding
+function oxwm.tag.view_next() end
+
+---View/switch to previous tag
+---@return table Action table for keybinding
+function oxwm.tag.view_previous() end
+
 ---Move focused window to tag
 ---@param index integer Tag index (0-based)
 ---@return table Action table for keybinding