From b9778944ba27e1deeec1be2bdc286790e6274470 Mon Sep 17 00:00:00 2001 From: tcmal Date: Thu, 4 Jul 2024 22:22:46 +0100 Subject: support floating windows --- src/clients/client.rs | 13 +++++++++++++ src/clients/mod.rs | 18 ++++++++++++++++++ src/clients/monitors.rs | 4 ++-- src/config.rs | 3 ++- src/helpers.rs | 7 +++++++ 5 files changed, 42 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/clients/client.rs b/src/clients/client.rs index 394c319..17cfd4f 100644 --- a/src/clients/client.rs +++ b/src/clients/client.rs @@ -12,6 +12,7 @@ use super::hints; /// Information about a single client / window #[derive(Debug)] +#[allow(clippy::struct_excessive_bools)] pub struct Client { /// The corresponding X11 window window: Window, @@ -25,6 +26,7 @@ pub struct Client { urgent: bool, never_focus: bool, + floating: bool, } impl Client { @@ -39,6 +41,7 @@ impl Client { mapped: false, urgent: false, never_focus: false, + floating: false, } } @@ -104,6 +107,16 @@ impl Client { }); } + /// Whether the client is floating - outside of current tiling rules and displaying over any tiled windows + pub const fn floating(&self) -> bool { + self.floating + } + + /// Set the floating status. + pub fn set_floating(&mut self, floating: bool) { + self.floating = floating; + } + /// Ensure this client is currently mapped / visible pub fn ensure_mapped(&mut self, conn: &Connection<'_>) { if !self.mapped { diff --git a/src/clients/mod.rs b/src/clients/mod.rs index fe0a4d3..445c24c 100644 --- a/src/clients/mod.rs +++ b/src/clients/mod.rs @@ -322,6 +322,14 @@ impl ClientState { ); } + /// Toggle whether the client with the given position is floating + pub fn toggle_floating(&mut self, conn: &Connection<'_>, (mon, pos): (usize, usize)) { + let c = &mut self.mons[mon].clients[pos]; + c.set_floating(!c.floating()); + + self.rearrange_monitor(conn, mon); + } + /// Get the amount of monitors this state is currently aware of pub fn monitor_count(&self) -> usize { self.mons.len() @@ -371,6 +379,16 @@ impl ClientState { self.client(self.focused.0, self.focused.1) } + /// Get the position of the currently focused client, if it exists + pub fn focused_pos(&self) -> Option<(usize, usize)> { + let (mon, pos) = self.focused; + if mon < self.mons.len() && pos < self.mons[mon].clients.len() { + Some((mon, pos)) + } else { + None + } + } + /// Get a mutable reference to the currently focused client, if it exists. pub fn focused_mut(&mut self) -> Option<&mut Client> { self.client_mut(self.focused.0, self.focused.1) diff --git a/src/clients/monitors.rs b/src/clients/monitors.rs index 0a9bcde..6ca6fdf 100644 --- a/src/clients/monitors.rs +++ b/src/clients/monitors.rs @@ -15,8 +15,8 @@ pub struct MonitorInfo { impl MonitorInfo { /// Iterate over all tiled clients, returning a mutable reference to each. pub fn clients_tiled_mut(&mut self) -> impl Iterator { - // TODO: tag filtering, floating - self.clients.iter_mut() + // TODO: tag filtering + self.clients.iter_mut().filter(|c| !c.floating()) } } diff --git a/src/config.rs b/src/config.rs index 0fc7144..aac47ae 100644 --- a/src/config.rs +++ b/src/config.rs @@ -7,7 +7,7 @@ use xkeysym::Keysym; use crate::{ bind, conn_info::Colour, - helpers::{focus_next, focus_prev, spawn}, + helpers::{focus_next, focus_prev, spawn, toggle_floating}, keys::{Keybind, Keybinds}, }; @@ -32,6 +32,7 @@ pub const KEYBINDS: Keybinds = Keybinds(&[ bind!(MAIN_MODIFIER , p -> &|_| spawn::<_, &str>(MENU_COMMAND, [])), bind!(MAIN_MODIFIER , j -> &focus_next), bind!(MAIN_MODIFIER , k -> &focus_prev), + bind!(MAIN_MODIFIER.union(ModMask::SHIFT) , space -> &toggle_floating), // { MODKEY, XK_j, focusstack, {.i = +1 } }, // { MODKEY, XK_k, focusstack, {.i = -1 } }, // { MODKEY, XK_i, incnmaster, {.i = +1 } }, diff --git a/src/helpers.rs b/src/helpers.rs index 51ebae8..b7488dd 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -40,3 +40,10 @@ pub fn focus_next(wm: &mut WM<'_>) { pub fn focus_prev(wm: &mut WM<'_>) { wm.clients.change_focus(&wm.conn, false); } + +/// Toggle floating status for the currently focused window +pub fn toggle_floating(wm: &mut WM<'_>) { + if let Some(pos) = wm.clients.focused_pos() { + wm.clients.toggle_floating(&wm.conn, pos); + } +} -- cgit v1.2.3