Diff
diff --git a/src/bar/bar.rs b/src/bar/bar.rs
index 9857406..f45e59c 100644
--- a/src/bar/bar.rs
+++ b/src/bar/bar.rs
@@ -171,6 +171,7 @@ impl Bar {
current_tags: u32,
occupied_tags: u32,
draw_blocks: bool,
+ layout_symbol: &str,
) -> Result<(), X11Error> {
if !self.needs_redraw {
return Ok(());
@@ -246,6 +247,20 @@ impl Bar {
x_position += tag_width as i16;
}
+ x_position += 10;
+
+ let text_x = x_position;
+ let top_padding = 4;
+ let text_y = top_padding + font.ascent();
+
+ self.font_draw.draw_text(
+ font,
+ self.scheme_normal.foreground,
+ text_x,
+ text_y,
+ layout_symbol
+ );
+
if draw_blocks && !self.status_text.is_empty() {
let padding = 10;
let mut x_position = self.width as i16 - padding;
diff --git a/src/config/mod.rs b/src/config/mod.rs
index 070eec0..2fc4649 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -161,6 +161,12 @@ pub fn parse_config(input: &str) -> Result<crate::Config, ConfigError> {
config_data_to_config(config_data)
}
+#[derive(Debug, Deserialize)]
+struct LayoutSymbolOverrideData {
+ name: String,
+ symbol: String,
+}
+
#[derive(Debug, Deserialize)]
struct ConfigData {
border_width: u32,
@@ -178,6 +184,8 @@ struct ConfigData {
modkey: ModKey,
tags: Vec<String>,
+ #[serde(default)]
+ layout_symbols: Vec<LayoutSymbolOverrideData>,
keybindings: Vec<KeybindingData>,
status_blocks: Vec<StatusBlockData>,
@@ -307,6 +315,15 @@ fn config_data_to_config(data: ConfigData) -> Result<crate::Config, ConfigError>
});
}
+ let layout_symbols = data
+ .layout_symbols
+ .into_iter()
+ .map(|l| crate::LayoutSymbolOverride {
+ name: l.name,
+ symbol: l.symbol,
+ })
+ .collect();
+
Ok(crate::Config {
border_width: data.border_width,
border_focused: data.border_focused,
@@ -320,6 +337,7 @@ fn config_data_to_config(data: ConfigData) -> Result<crate::Config, ConfigError>
terminal: data.terminal,
modkey,
tags: data.tags,
+ layout_symbols,
keybindings,
status_blocks,
scheme_normal: crate::ColorScheme {
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index cf96dd2..90b9ff6 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -41,6 +41,7 @@ pub trait Layout {
gaps: &GapConfig,
) -> Vec<WindowGeometry>;
fn name(&self) -> &'static str;
+ fn symbol(&self) -> &'static str;
}
pub struct WindowGeometry {
diff --git a/src/layout/normie.rs b/src/layout/normie.rs
index 1dc3205..e189c10 100644
--- a/src/layout/normie.rs
+++ b/src/layout/normie.rs
@@ -9,6 +9,10 @@ impl Layout for NormieLayout {
super::NORMIE
}
+ fn symbol(&self) -> &'static str {
+ "><>"
+ }
+
fn arrange(
&self,
windows: &[Window],
diff --git a/src/layout/tiling.rs b/src/layout/tiling.rs
index a31589e..f0e1464 100644
--- a/src/layout/tiling.rs
+++ b/src/layout/tiling.rs
@@ -8,6 +8,10 @@ impl Layout for TilingLayout {
super::TILING
}
+ fn symbol(&self) -> &'static str {
+ "[]="
+ }
+
fn arrange(
&self,
windows: &[Window],
diff --git a/src/lib.rs b/src/lib.rs
index 293e3ce..147cdb6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -8,11 +8,18 @@ pub mod window_manager;
pub mod prelude {
pub use crate::ColorScheme;
+ pub use crate::LayoutSymbolOverride;
pub use crate::bar::{BlockCommand, BlockConfig};
pub use crate::keyboard::{Arg, KeyAction, handlers::Key, keycodes};
pub use x11rb::protocol::xproto::KeyButMask;
}
+#[derive(Clone)]
+pub struct LayoutSymbolOverride {
+ pub name: String,
+ pub symbol: String,
+}
+
#[derive(Clone)]
pub struct Config {
// Appearance
@@ -35,6 +42,9 @@ pub struct Config {
// Tags
pub tags: Vec<String>,
+ // Layout symbol overrides
+ pub layout_symbols: Vec<LayoutSymbolOverride>,
+
// Keybindings
pub keybindings: Vec<crate::keyboard::handlers::Key>,
@@ -81,6 +91,7 @@ impl Default for Config {
.into_iter()
.map(String::from)
.collect(),
+ layout_symbols: vec![],
keybindings: vec![
Key::new(
vec![MODKEY],
diff --git a/src/window_manager.rs b/src/window_manager.rs
index 03066dd..5ef536e 100644
--- a/src/window_manager.rs
+++ b/src/window_manager.rs
@@ -789,7 +789,19 @@ impl WindowManager {
Ok(())
}
+ fn get_layout_symbol(&self) -> String {
+ let layout_name = self.layout.name();
+ self.config
+ .layout_symbols
+ .iter()
+ .find(|l| l.name == layout_name)
+ .map(|l| l.symbol.clone())
+ .unwrap_or_else(|| self.layout.symbol().to_string())
+ }
+
fn update_bar(&mut self) -> WmResult<()> {
+ let layout_symbol = self.get_layout_symbol();
+
for (monitor_index, monitor) in self.monitors.iter().enumerate() {
if let Some(bar) = self.bars.get_mut(monitor_index) {
let mut occupied_tags: TagMask = 0;
@@ -808,6 +820,7 @@ impl WindowManager {
monitor.selected_tags,
occupied_tags,
draw_blocks,
+ &layout_symbol,
)?;
}
}
@@ -842,6 +855,7 @@ impl WindowManager {
Ok(layout) => {
self.layout = layout;
self.apply_layout()?;
+ self.update_bar()?;
}
Err(e) => eprintln!("Failed to change layout: {}", e),
}
@@ -854,6 +868,7 @@ impl WindowManager {
Ok(layout) => {
self.layout = layout;
self.apply_layout()?;
+ self.update_bar()?;
}
Err(e) => eprintln!("Failed to cycle layout: {}", e),
}
diff --git a/templates/config.ron b/templates/config.ron
index 18dcd89..69af9f1 100644
--- a/templates/config.ron
+++ b/templates/config.ron
@@ -18,6 +18,10 @@
modkey: Mod4,
tags: ["1", "2", "3", "4", "5", "6", "7", "8", "9"],
+ layout_symbols: [
+ (name: "tiling", symbol: "[T]"),
+ (name: "normie", symbol: "[F]"),
+ ],
keybindings: [
(modifiers: [Mod4], key: Return, action: Spawn, arg: "st"),
@@ -28,6 +32,7 @@
(modifiers: [Mod4, Shift], key: Space, action: ToggleFloating),
(modifiers: [Mod4], key: F, action: ChangeLayout, arg: "normie"),
(modifiers: [Mod4], key: C, action: ChangeLayout, arg: "tiling"),
+ (modifiers: [Mod1], key: N, action: CycleLayout),
(modifiers: [Mod4], key: A, action: ToggleGaps),
(modifiers: [Mod4, Shift], key: Q, action: Quit),
(modifiers: [Mod4, Shift], key: R, action: Restart),
@@ -53,6 +58,18 @@
(modifiers: [Mod4, Shift], key: Key7, action: MoveToTag, arg: 6),
(modifiers: [Mod4, Shift], key: Key8, action: MoveToTag, arg: 7),
(modifiers: [Mod4, Shift], key: Key9, action: MoveToTag, arg: 8),
+
+ // Moving Windows
+ (modifiers: [Mod4, Control], key: K, action: SmartMoveWin, arg: 0), // UP
+ (modifiers: [Mod4, Control], key: J, action: SmartMoveWin, arg: 1), // DOWN
+ (modifiers: [Mod4, Control], key: H, action: SmartMoveWin, arg: 2), // LEFT
+ (modifiers: [Mod4, Control], key: L, action: SmartMoveWin, arg: 3), // RIGHT
+
+ // Exchanging Clients
+ (modifiers: [Mod4, Shift], key: K, action: ExchangeClient, arg: 0), // UP
+ (modifiers: [Mod4, Shift], key: J, action: ExchangeClient, arg: 1), // DOWN
+ (modifiers: [Mod4, Shift], key: H, action: ExchangeClient, arg: 2), // LEFT
+ (modifiers: [Mod4, Shift], key: L, action: ExchangeClient, arg: 3), // RIGHT
],
status_blocks: [
diff --git a/test-config.ron b/test-config.ron
index b38fe05..ac3303a 100644
--- a/test-config.ron
+++ b/test-config.ron
@@ -16,7 +16,6 @@
terminal: "st",
modkey: Mod1,
-
tags: ["1", "2", "3", "4", "5", "6", "7", "8", "9"],
// Alternative icon tags (uncomment to use):
@@ -25,6 +24,11 @@
// Alternative text tags (uncomment to use):
// tags: ["DEV", "WWW", "SYS", "DOC", "VBOX", "CHAT", "MUS", "VID", "MISC"],
+ layout_symbols: [
+ (name: "tiling", symbol: "[T]"),
+ (name: "normie", symbol: "[F]"),
+ ],
+
keybindings: [
(modifiers: [Mod1], key: Return, action: Spawn, arg: "st"),
(modifiers: [Mod1], key: D, action: Spawn, arg: ["sh", "-c", "dmenu_run -l 10"]),
@@ -41,6 +45,10 @@
(modifiers: [Mod1], key: J, action: FocusStack, arg: -1),
(modifiers: [Mod1], key: K, action: FocusStack, arg: 1),
// Exchange client (vim-style with Mod+Shift)
+ (modifiers: [Mod1, Control], key: K, action: SmartMoveWin, arg: 0), // UP
+ (modifiers: [Mod1, Control], key: J, action: SmartMoveWin, arg: 1), // DOWN
+ (modifiers: [Mod1, Control], key: H, action: SmartMoveWin, arg: 2), // LEFT
+ (modifiers: [Mod1, Control], key: L, action: SmartMoveWin, arg: 3), // RIGHT
(modifiers: [Mod1, Shift], key: K, action: ExchangeClient, arg: 0), // UP
(modifiers: [Mod1, Shift], key: J, action: ExchangeClient, arg: 1), // DOWN
(modifiers: [Mod1, Shift], key: H, action: ExchangeClient, arg: 2), // LEFT