oxwm

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

Removed old fullscreen logic and used i3 logic for fullscreen windows.

Commit
1d0ba77488db957f46f80c650b1c58060596c639
Parent
fa421d2
Author
tonybtw <tonybtw@tonybtw.com>
Date
2025-12-20 08:45:25

Diff

diff --git a/src/window_manager.rs b/src/window_manager.rs
index 6e29e90..873a763 100644
--- a/src/window_manager.rs
+++ b/src/window_manager.rs
@@ -127,11 +127,9 @@ pub struct WindowManager {
     gaps_enabled: bool,
     floating_windows: HashSet<Window>,
     fullscreen_windows: HashSet<Window>,
-    floating_geometry_before_fullscreen: HashMap<Window, (i16, i16, u16, u16, u16)>,
     bars: Vec<Bar>,
     tab_bars: Vec<crate::tab_bar::TabBar>,
     show_bar: bool,
-    last_layout: Option<&'static str>,
     monitors: Vec<Monitor>,
     selected_monitor: usize,
     atoms: AtomCache,
@@ -286,11 +284,9 @@ impl WindowManager {
             gaps_enabled,
             floating_windows: HashSet::new(),
             fullscreen_windows: HashSet::new(),
-            floating_geometry_before_fullscreen: HashMap::new(),
             bars,
             tab_bars,
             show_bar: true,
-            last_layout: None,
             monitors,
             selected_monitor: 0,
             atoms,
@@ -749,13 +745,6 @@ impl WindowManager {
                 }
             }
             KeyAction::ToggleFullScreen => {
-                // Disable gaps and save previous state in config if not already in fullscreen
-                if self.fullscreen_windows.is_empty() {
-                    self.config.gaps_enabled = std::mem::take(&mut self.gaps_enabled);
-                } else {
-                    self.gaps_enabled = self.config.gaps_enabled;
-                }
-
                 self.fullscreen()?;
                 self.restack()?;
             }
@@ -1464,155 +1453,16 @@ impl WindowManager {
     }
 
     fn fullscreen(&mut self) -> WmResult<()> {
-        if self.show_bar {
-            let Some(focused_window) = self
-                .monitors
-                .get(self.selected_monitor)
-                .and_then(|m| m.selected_client)
-            else {
-                return Ok(());
-            };
-
-            self.fullscreen_windows.insert(focused_window);
-
-            let windows: Vec<Window> = self
-                .windows
-                .iter()
-                .filter(|&&w| self.is_window_visible(w))
-                .copied()
-                .collect();
-
-            for window in &windows {
-                if let Ok(geom) = self.connection.get_geometry(*window)?.reply() {
-                    self.floating_geometry_before_fullscreen.insert(
-                        *window,
-                        (geom.x, geom.y, geom.width, geom.height, geom.border_width),
-                    );
-                }
-            }
-
-            self.last_layout = Some(self.layout.name());
-            if let Ok(layout) = layout_from_str("monocle") {
-                self.layout = layout;
-            }
-            self.toggle_bar()?;
-            self.apply_layout()?;
-
-            for window in &windows {
-                self.connection.configure_window(
-                    *window,
-                    &x11rb::protocol::xproto::ConfigureWindowAux::new().border_width(0),
-                )?;
-            }
-
-            let border_width = self.config.border_width;
-            let floating_windows: Vec<Window> = windows
-                .iter()
-                .filter(|&&w| self.floating_windows.contains(&w))
-                .copied()
-                .collect();
-
-            for window in floating_windows {
-                let monitor_idx = self
-                    .clients
-                    .get(&window)
-                    .map(|c| c.monitor_index)
-                    .unwrap_or(self.selected_monitor);
-                let monitor = &self.monitors[monitor_idx];
-
-                let (outer_gap_h, outer_gap_v) = if self.gaps_enabled {
-                    (
-                        self.config.gap_outer_horizontal,
-                        self.config.gap_outer_vertical,
-                    )
-                } else {
-                    (0, 0)
-                };
-
-                let window_x = monitor.screen_x + outer_gap_h as i32;
-                let window_y = monitor.screen_y + outer_gap_v as i32;
-                let window_width = monitor
-                    .screen_width
-                    .saturating_sub(2 * outer_gap_h as i32)
-                    .saturating_sub(2 * border_width as i32);
-                let window_height = monitor
-                    .screen_height
-                    .saturating_sub(2 * outer_gap_v as i32)
-                    .saturating_sub(2 * border_width as i32);
-
-                self.connection.configure_window(
-                    window,
-                    &x11rb::protocol::xproto::ConfigureWindowAux::new()
-                        .x(window_x)
-                        .y(window_y)
-                        .width(window_width as u32)
-                        .height(window_height as u32),
-                )?;
-            }
-            self.connection.flush()?;
-        } else {
-            let Some(focused_window) = self
-                .monitors
-                .get(self.selected_monitor)
-                .and_then(|m| m.selected_client)
-            else {
-                return Ok(());
-            };
-
-            self.fullscreen_windows.remove(&focused_window);
-
-            if let Some(last) = self.last_layout
-                && let Ok(layout) = layout_from_str(last)
-            {
-                self.layout = layout;
-            }
-
-            let windows_to_restore: Vec<Window> = self
-                .floating_geometry_before_fullscreen
-                .keys()
-                .copied()
-                .collect();
-
-            for window in windows_to_restore {
-                if let Some(&(x, y, width, height, border_width)) =
-                    self.floating_geometry_before_fullscreen.get(&window)
-                {
-                    self.connection.configure_window(
-                        window,
-                        &ConfigureWindowAux::new()
-                            .x(x as i32)
-                            .y(y as i32)
-                            .width(width as u32)
-                            .height(height as u32)
-                            .border_width(border_width as u32),
-                    )?;
-
-                    if let Some(c) = self.clients.get_mut(&window) {
-                        c.x_position = x;
-                        c.y_position = y;
-                        c.width = width;
-                        c.height = height;
-                        c.border_width = border_width;
-                    }
-
-                    self.floating_geometry_before_fullscreen.remove(&window);
-                }
-            }
-            self.connection.flush()?;
-
-            self.toggle_bar()?;
+        let Some(focused_window) = self
+            .monitors
+            .get(self.selected_monitor)
+            .and_then(|m| m.selected_client)
+        else {
+            return Ok(());
+        };
 
-            if self.layout.name() != "normie" {
-                self.apply_layout()?;
-            } else if let Some(bar) = self.bars.get(self.selected_monitor) {
-                self.connection.configure_window(
-                    bar.window(),
-                    &x11rb::protocol::xproto::ConfigureWindowAux::new()
-                        .stack_mode(x11rb::protocol::xproto::StackMode::ABOVE),
-                )?;
-                self.connection.flush()?;
-            }
-        }
+        let is_fullscreen = self.fullscreen_windows.contains(&focused_window);
+        self.set_window_fullscreen(focused_window, !is_fullscreen)?;
         Ok(())
     }
 
@@ -1640,11 +1490,15 @@ impl WindowManager {
                 client.is_fullscreen = true;
                 client.old_state = client.is_floating;
                 client.old_border_width = client.border_width;
+                client.old_x_position = client.x_position;
+                client.old_y_position = client.y_position;
+                client.old_width = client.width;
+                client.old_height = client.height;
                 client.border_width = 0;
-                client.is_floating = true;
             }
 
             self.fullscreen_windows.insert(window);
+            self.floating_windows.insert(window);
 
             self.connection.configure_window(
                 window,
@@ -1671,26 +1525,20 @@ impl WindowManager {
 
             self.fullscreen_windows.remove(&window);
 
+            let was_floating = self
+                .clients
+                .get(&window)
+                .map(|c| c.old_state)
+                .unwrap_or(false);
+
+            if !was_floating {
+                self.floating_windows.remove(&window);
+            }
+
             if let Some(client) = self.clients.get_mut(&window) {
                 client.is_fullscreen = false;
                 client.is_floating = client.old_state;
                 client.border_width = client.old_border_width;
-
-                let x = client.old_x_position;
-                let y = client.old_y_position;
-                let w = client.old_width;
-                let h = client.old_height;
-                let bw = client.border_width;
-
-                self.connection.configure_window(
-                    window,
-                    &x11rb::protocol::xproto::ConfigureWindowAux::new()
-                        .x(x as i32)
-                        .y(y as i32)
-                        .width(w as u32)
-                        .height(h as u32)
-                        .border_width(bw as u32),
-                )?;
             }
 
             self.apply_layout()?;
@@ -1699,20 +1547,6 @@ impl WindowManager {
         Ok(())
     }
 
-    fn toggle_bar(&mut self) -> WmResult<()> {
-        self.show_bar = !self.show_bar;
-        if let Some(bar) = self.bars.get(self.selected_monitor) {
-            if self.show_bar {
-                self.connection.map_window(bar.window())?;
-            } else {
-                self.connection.unmap_window(bar.window())?;
-            }
-            self.connection.flush()?;
-        }
-        self.apply_layout()?;
-        Ok(())
-    }
-
     fn get_transient_parent(&self, window: Window) -> Option<Window> {
         self.connection
             .get_property(
@@ -3523,6 +3357,44 @@ impl WindowManager {
             self.showhide(stack_head)?;
         }
 
+        for monitor_index in 0..self.monitors.len() {
+            let monitor = &self.monitors[monitor_index];
+            let tags = monitor.tagset[monitor.selected_tags_index];
+
+            let has_visible_fullscreen = self.fullscreen_windows.iter().any(|&w| {
+                self.clients.get(&w).map_or(false, |c| {
+                    c.monitor_index == monitor_index && (c.tags & tags) != 0
+                })
+            });
+
+            if has_visible_fullscreen {
+                if let Some(bar) = self.bars.get(monitor_index) {
+                    self.connection.unmap_window(bar.window())?;
+                }
+
+                for &window in &self.fullscreen_windows {
+                    if let Some(client) = self.clients.get(&window) {
+                        if client.monitor_index == monitor_index && (client.tags & tags) != 0 {
+                            self.connection.configure_window(
+                                window,
+                                &ConfigureWindowAux::new()
+                                    .border_width(0)
+                                    .x(monitor.screen_x)
+                                    .y(monitor.screen_y)
+                                    .width(monitor.screen_width as u32)
+                                    .height(monitor.screen_height as u32)
+                                    .stack_mode(StackMode::ABOVE),
+                            )?;
+                        }
+                    }
+                }
+            } else if self.show_bar {
+                if let Some(bar) = self.bars.get(monitor_index) {
+                    self.connection.map_window(bar.window())?;
+                }
+            }
+        }
+
         self.connection.flush()?;
 
         let is_tabbed = self.layout.name() == LayoutType::Tabbed.as_str();