summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortcmal <me@aria.rip>2024-07-15 15:30:06 +0100
committertcmal <me@aria.rip>2024-07-15 19:18:59 +0100
commit5d2a23a5d618725b75ba77d7185601e5439801c5 (patch)
treec0d37b1e3e3bd796deab0de904b31ef5cd21e048
parent641d4db398357bd50e83dc77464558acf83d9b1d (diff)
support fullscreen mode
-rw-r--r--src/clients/client.rs60
-rw-r--r--src/clients/mod.rs23
-rw-r--r--src/clients/monitors.rs2
-rw-r--r--src/config.rs3
-rw-r--r--src/helpers.rs7
-rw-r--r--todos.org2
6 files changed, 80 insertions, 17 deletions
diff --git a/src/clients/client.rs b/src/clients/client.rs
index 6845e4e..84f787a 100644
--- a/src/clients/client.rs
+++ b/src/clients/client.rs
@@ -8,7 +8,7 @@ use xcb::{
use crate::{config::BORDER_WIDTH, conn_info::Connection};
-use super::hints;
+use super::{hints, MonitorGeometry};
/// Information about a single client / window
#[derive(Debug)]
@@ -26,7 +26,20 @@ pub struct Client {
urgent: bool,
never_focus: bool,
- floating: bool,
+ layout_mode: LayoutMode,
+}
+
+/// How this window's geometry is determined,
+#[derive(Debug)]
+pub enum LayoutMode {
+ /// By the tiling algorithm
+ Tiled,
+
+ /// By the user
+ Floating,
+
+ /// By the monitor its on
+ Fullscreen,
}
impl Client {
@@ -41,7 +54,7 @@ impl Client {
mapped: false,
urgent: false,
never_focus: false,
- floating: false,
+ layout_mode: LayoutMode::Tiled,
}
}
@@ -107,20 +120,45 @@ 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
+ /// Whether the client is tiled
+ pub const fn tiled(&self) -> bool {
+ matches!(self.layout_mode, LayoutMode::Tiled)
+ }
+
+ /// Set the window as tiled
+ pub fn set_tiled(&mut self) {
+ self.layout_mode = LayoutMode::Tiled;
+ }
+
+ /// Set the window as floating
+ pub fn set_floating(&mut self, conn: &Connection<'_>) {
+ if !matches!(self.layout_mode, LayoutMode::Floating) {
+ conn.send_request(&ConfigureWindow {
+ window: self.window,
+ value_list: &[ConfigWindow::StackMode(StackMode::Above)],
+ });
+ }
+ self.layout_mode = LayoutMode::Floating;
}
- /// Set the floating status.
- pub fn set_floating(&mut self, conn: &Connection<'_>, floating: bool) {
- if floating && floating != self.floating {
+ /// Set the window as fullscreen
+ pub fn set_fullscreen(&mut self, conn: &Connection<'_>, mon_geom: &MonitorGeometry) {
+ if !matches!(self.layout_mode, LayoutMode::Fullscreen) {
conn.send_request(&ConfigureWindow {
window: self.window,
value_list: &[ConfigWindow::StackMode(StackMode::Above)],
});
+
+ self.set_geom(
+ conn,
+ mon_geom.x_org,
+ mon_geom.y_org,
+ mon_geom.width,
+ mon_geom.height,
+ self.border_width,
+ );
}
- self.floating = floating;
+ self.layout_mode = LayoutMode::Fullscreen;
}
/// Ensure this client is currently mapped / visible
@@ -180,7 +218,7 @@ impl Client {
pub fn update_window_type(&mut self, conn: &Connection<'_>) {
// TODO: Fullscreen from net_wm_state
if hints::is_dialog(conn, self.window) {
- self.set_floating(conn, true);
+ self.set_floating(conn);
}
}
diff --git a/src/clients/mod.rs b/src/clients/mod.rs
index 8efa5b1..c370e04 100644
--- a/src/clients/mod.rs
+++ b/src/clients/mod.rs
@@ -210,7 +210,9 @@ impl ClientState {
BORDER_WIDTH,
);
c.set_border(conn, conn.colours.border_normal());
- c.set_floating(conn, floating);
+ if floating {
+ c.set_floating(conn);
+ }
c.update_window_type(conn);
c.ensure_mapped(conn);
@@ -327,7 +329,24 @@ 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(conn, !c.floating());
+ if c.tiled() {
+ c.set_floating(conn);
+ } else {
+ c.set_tiled();
+ }
+
+ self.rearrange_monitor(conn, mon);
+ }
+
+ /// Toggle whether the client with the given position is fullscreen
+ pub fn toggle_fullscreen(&mut self, conn: &Connection<'_>, (mon, pos): (usize, usize)) {
+ let mon_info = &mut self.mons[mon];
+ let c = &mut mon_info.clients[pos];
+ if c.tiled() {
+ c.set_fullscreen(conn, &mon_info.screen_info);
+ } else {
+ c.set_tiled();
+ }
self.rearrange_monitor(conn, mon);
}
diff --git a/src/clients/monitors.rs b/src/clients/monitors.rs
index 6ca6fdf..6790632 100644
--- a/src/clients/monitors.rs
+++ b/src/clients/monitors.rs
@@ -16,7 +16,7 @@ impl MonitorInfo {
/// Iterate over all tiled clients, returning a mutable reference to each.
pub fn clients_tiled_mut(&mut self) -> impl Iterator<Item = &mut Client> {
// TODO: tag filtering
- self.clients.iter_mut().filter(|c| !c.floating())
+ self.clients.iter_mut().filter(|c| c.tiled())
}
}
diff --git a/src/config.rs b/src/config.rs
index aac47ae..9cbfc40 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, toggle_floating},
+ helpers::{focus_next, focus_prev, spawn, toggle_floating, toggle_fullscreen},
keys::{Keybind, Keybinds},
};
@@ -33,6 +33,7 @@ pub const KEYBINDS: Keybinds = Keybinds(&[
bind!(MAIN_MODIFIER , j -> &focus_next),
bind!(MAIN_MODIFIER , k -> &focus_prev),
bind!(MAIN_MODIFIER.union(ModMask::SHIFT) , space -> &toggle_floating),
+ bind!(MAIN_MODIFIER.union(ModMask::SHIFT) , f -> &toggle_fullscreen),
// { 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 b7488dd..24c8cf2 100644
--- a/src/helpers.rs
+++ b/src/helpers.rs
@@ -47,3 +47,10 @@ pub fn toggle_floating(wm: &mut WM<'_>) {
wm.clients.toggle_floating(&wm.conn, pos);
}
}
+
+/// Toggle fullscreen status for the currently focused window
+pub fn toggle_fullscreen(wm: &mut WM<'_>) {
+ if let Some(pos) = wm.clients.focused_pos() {
+ wm.clients.toggle_fullscreen(&wm.conn, pos);
+ }
+}
diff --git a/todos.org b/todos.org
index 3b4a9d8..7bb97ab 100644
--- a/todos.org
+++ b/todos.org
@@ -1,5 +1,3 @@
-* Support fullscreen
-
* Set fullscreen based on hint
* Fix focus changing bug