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