Diff
diff --git a/justfile b/justfile
index e7c5f23..3befb6f 100644
--- a/justfile
+++ b/justfile
@@ -3,13 +3,13 @@ build:
install: build
cp target/release/oxwm /usr/bin/oxwm
- cp resources/oxwm.desktop /usr/share/xsessions/oxwm.desktop
+ cp resources/oxwm.desktop /usr/share/xsessions/oxwm.desktop
chmod +x /usr/bin/oxwm
@echo "✓ oxwm installed to /usr/bin/oxwm"
@echo " Run 'oxwm --init' to create your config"
checkinstall:
- checkinstall --pkgname oxwm --exclude /root -y just install
+ checkinstall --pkgname oxwm --exclude /root -y just install
uninstall:
rm -f /usr/bin/oxwm
diff --git a/src/monitor.rs b/src/monitor.rs
index 8f55a9c..c87299c 100644
--- a/src/monitor.rs
+++ b/src/monitor.rs
@@ -6,6 +6,30 @@ use x11rb::rust_connection::RustConnection;
type WmResult<T> = Result<T, WmError>;
+#[derive(Debug, Clone)]
+pub struct Pertag {
+ pub current_tag: usize,
+ pub previous_tag: usize,
+ pub num_masters: Vec<i32>,
+ pub master_factors: Vec<f32>,
+ pub layouts: Vec<String>,
+ pub show_bars: Vec<bool>,
+}
+
+impl Pertag {
+ pub fn new(num_tags: usize, default_num_master: i32, default_master_factor: f32, default_show_bar: bool, default_layout: &str) -> Self {
+ let len = num_tags + 1;
+ Self {
+ current_tag: 1,
+ previous_tag: 1,
+ num_masters: vec![default_num_master; len],
+ master_factors: vec![default_master_factor; len],
+ layouts: vec![default_layout.to_string(); len],
+ show_bars: vec![default_show_bar; len],
+ }
+ }
+}
+
#[derive(Debug, Clone)]
pub struct Monitor {
pub layout_symbol: String,
@@ -35,6 +59,7 @@ pub struct Monitor {
pub stack_head: Option<Window>,
pub bar_window: Option<Window>,
pub layout_indices: [usize; 2],
+ pub pertag: Option<Pertag>,
}
impl Monitor {
@@ -67,9 +92,20 @@ impl Monitor {
stack_head: None,
bar_window: None,
layout_indices: [0, 1],
+ pertag: None,
}
}
+ pub fn init_pertag(&mut self, num_tags: usize, default_layout: &str) {
+ self.pertag = Some(Pertag::new(
+ num_tags,
+ self.num_master,
+ self.master_factor,
+ self.show_bar,
+ default_layout,
+ ));
+ }
+
pub fn contains_point(&self, x: i32, y: i32) -> bool {
x >= self.screen_x
&& x < self.screen_x + self.screen_width
diff --git a/src/window_manager.rs b/src/window_manager.rs
index 266a3f9..94180b4 100644
--- a/src/window_manager.rs
+++ b/src/window_manager.rs
@@ -243,7 +243,10 @@ impl WindowManager {
)?;
}
- let monitors = detect_monitors(&connection, &screen, root)?;
+ let mut monitors = detect_monitors(&connection, &screen, root)?;
+ for monitor in monitors.iter_mut() {
+ monitor.init_pertag(config.tags.len(), "tiling");
+ }
let display = unsafe { x11::xlib::XOpenDisplay(std::ptr::null()) };
if display.is_null() {
@@ -710,6 +713,9 @@ impl WindowManager {
if let Some(monitor) = self.monitors.get_mut(self.selected_monitor) {
let new_mfact = (monitor.master_factor + delta).clamp(0.05, 0.95);
monitor.master_factor = new_mfact;
+ if let Some(ref mut pertag) = monitor.pertag {
+ pertag.master_factors[pertag.current_tag] = new_mfact;
+ }
self.apply_layout()?;
}
Ok(())
@@ -719,11 +725,27 @@ impl WindowManager {
if let Some(monitor) = self.monitors.get_mut(self.selected_monitor) {
let new_nmaster = (monitor.num_master + delta).max(0);
monitor.num_master = new_nmaster;
+ if let Some(ref mut pertag) = monitor.pertag {
+ pertag.num_masters[pertag.current_tag] = new_nmaster;
+ }
self.apply_layout()?;
}
Ok(())
}
+ fn toggle_bar(&mut self) -> WmResult<()> {
+ if let Some(monitor) = self.monitors.get_mut(self.selected_monitor) {
+ monitor.show_bar = !monitor.show_bar;
+ self.show_bar = monitor.show_bar;
+ if let Some(ref mut pertag) = monitor.pertag {
+ pertag.show_bars[pertag.current_tag] = monitor.show_bar;
+ }
+ }
+ self.apply_layout()?;
+ self.update_bar()?;
+ Ok(())
+ }
+
fn get_layout_symbol(&self) -> String {
let layout_name = self.layout.name();
self.config
@@ -871,6 +893,11 @@ impl WindowManager {
match layout_from_str(layout_name) {
Ok(layout) => {
self.layout = layout;
+ if let Some(monitor) = self.monitors.get_mut(self.selected_monitor) {
+ if let Some(ref mut pertag) = monitor.pertag {
+ pertag.layouts[pertag.current_tag] = layout_name.to_string();
+ }
+ }
if layout_name != "normie" && layout_name != "floating" {
self.floating_windows.clear();
}
@@ -888,6 +915,11 @@ impl WindowManager {
match layout_from_str(next_name) {
Ok(layout) => {
self.layout = layout;
+ if let Some(monitor) = self.monitors.get_mut(self.selected_monitor) {
+ if let Some(ref mut pertag) = monitor.pertag {
+ pertag.layouts[pertag.current_tag] = next_name.to_string();
+ }
+ }
if next_name != "normie" && next_name != "floating" {
self.floating_windows.clear();
}
@@ -1243,21 +1275,48 @@ impl WindowManager {
return Ok(());
}
- let monitor = match self.monitors.get_mut(self.selected_monitor) {
- Some(m) => m,
- None => return Ok(()),
- };
-
let new_tagset = tag_mask(tag_index);
+ let mut layout_name: Option<String> = None;
+ let mut toggle_bar = false;
- if new_tagset == monitor.tagset[monitor.selected_tags_index] {
- if !self.config.tag_back_and_forth {
- return Ok(());
+ if let Some(monitor) = self.monitors.get_mut(self.selected_monitor) {
+ if new_tagset == monitor.tagset[monitor.selected_tags_index] {
+ if !self.config.tag_back_and_forth {
+ return Ok(());
+ }
+ monitor.tagset.swap(0, 1);
+ if let Some(ref mut pertag) = monitor.pertag {
+ let tmp = pertag.previous_tag;
+ pertag.previous_tag = pertag.current_tag;
+ pertag.current_tag = tmp;
+ }
+ } else {
+ monitor.selected_tags_index ^= 1;
+ monitor.tagset[monitor.selected_tags_index] = new_tagset;
+ if let Some(ref mut pertag) = monitor.pertag {
+ pertag.previous_tag = pertag.current_tag;
+ pertag.current_tag = tag_index + 1;
+ }
}
- monitor.tagset.swap(0, 1);
- } else {
- monitor.selected_tags_index ^= 1;
- monitor.tagset[monitor.selected_tags_index] = new_tagset;
+
+ if let Some(ref pertag) = monitor.pertag {
+ monitor.num_master = pertag.num_masters[pertag.current_tag];
+ monitor.master_factor = pertag.master_factors[pertag.current_tag];
+ layout_name = Some(pertag.layouts[pertag.current_tag].clone());
+ if monitor.show_bar != pertag.show_bars[pertag.current_tag] {
+ toggle_bar = true;
+ }
+ }
+ }
+
+ if let Some(name) = layout_name {
+ if let Ok(layout) = layout_from_str(&name) {
+ self.layout = layout;
+ }
+ }
+
+ if toggle_bar {
+ self.toggle_bar()?;
}
self.save_selected_tags()?;
@@ -1273,19 +1332,50 @@ impl WindowManager {
return Ok(());
}
- let monitor = match self.monitors.get_mut(self.selected_monitor) {
- Some(m) => m,
- None => return Ok(()),
- };
+ let num_tags = self.config.tags.len();
+ let all_tags_mask = (1u32 << num_tags) - 1;
+ let mut layout_name: Option<String> = None;
+ let mut toggle_bar = false;
- let mask = tag_mask(tag_index);
- let new_tagset = monitor.tagset[monitor.selected_tags_index] ^ mask;
+ if let Some(monitor) = self.monitors.get_mut(self.selected_monitor) {
+ let mask = tag_mask(tag_index);
+ let new_tagset = monitor.tagset[monitor.selected_tags_index] ^ mask;
- if new_tagset == 0 {
- return Ok(());
+ if new_tagset == 0 {
+ return Ok(());
+ }
+
+ monitor.tagset[monitor.selected_tags_index] = new_tagset;
+
+ if let Some(ref mut pertag) = monitor.pertag {
+ if new_tagset == all_tags_mask {
+ pertag.previous_tag = pertag.current_tag;
+ pertag.current_tag = 0;
+ }
+
+ if pertag.current_tag > 0 && (new_tagset & (1 << (pertag.current_tag - 1))) == 0 {
+ pertag.previous_tag = pertag.current_tag;
+ pertag.current_tag = (new_tagset.trailing_zeros() as usize) + 1;
+ }
+
+ monitor.num_master = pertag.num_masters[pertag.current_tag];
+ monitor.master_factor = pertag.master_factors[pertag.current_tag];
+ layout_name = Some(pertag.layouts[pertag.current_tag].clone());
+ if monitor.show_bar != pertag.show_bars[pertag.current_tag] {
+ toggle_bar = true;
+ }
+ }
}
- monitor.tagset[monitor.selected_tags_index] = new_tagset;
+ if let Some(name) = layout_name {
+ if let Ok(layout) = layout_from_str(&name) {
+ self.layout = layout;
+ }
+ }
+
+ if toggle_bar {
+ self.toggle_bar()?;
+ }
self.save_selected_tags()?;
self.focus(None)?;