Diff
diff --git a/Cargo.toml b/Cargo.toml
index 581dd72..2ae4727 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "oxwm"
-version = "0.1.12"
+version = "0.2.0"
edition = "2024"
[lib]
diff --git a/default.nix b/default.nix
index 51bbe18..52305dd 100644
--- a/default.nix
+++ b/default.nix
@@ -9,7 +9,7 @@
}:
rustPlatform.buildRustPackage (finalAttrs: {
pname = "oxwm";
- version = "0.1.12";
+ version = "0.2.0";
src = ./.;
diff --git a/src/config/mod.rs b/src/config/mod.rs
index 612fd7e..70d61c0 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -6,6 +6,155 @@ use crate::keyboard::{Arg, KeyAction};
use serde::Deserialize;
use x11rb::protocol::xproto::{KeyButMask, Keycode};
+#[derive(Debug, Deserialize)]
+pub enum ModKey {
+ Mod1,
+ Mod2,
+ Mod3,
+ Mod4,
+ Mod5,
+ Shift,
+ Control,
+}
+
+impl ModKey {
+ fn to_keybut_mask(&self) -> KeyButMask {
+ match self {
+ ModKey::Mod1 => KeyButMask::MOD1,
+ ModKey::Mod2 => KeyButMask::MOD2,
+ ModKey::Mod3 => KeyButMask::MOD3,
+ ModKey::Mod4 => KeyButMask::MOD4,
+ ModKey::Mod5 => KeyButMask::MOD5,
+ ModKey::Shift => KeyButMask::SHIFT,
+ ModKey::Control => KeyButMask::CONTROL,
+ }
+ }
+}
+
+#[derive(Debug, Deserialize)]
+pub enum KeyData {
+ Return,
+ Q,
+ Escape,
+ Space,
+ Tab,
+ Backspace,
+ Delete,
+ F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
+ A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, R, S, T, U, V, W, X, Y, Z,
+ Key0,
+ Key1,
+ Key2,
+ Key3,
+ Key4,
+ Key5,
+ Key6,
+ Key7,
+ Key8,
+ Key9,
+ Left,
+ Right,
+ Up,
+ Down,
+ Home,
+ End,
+ PageUp,
+ PageDown,
+ Insert,
+ Minus,
+ Equal,
+ BracketLeft,
+ BracketRight,
+ Semicolon,
+ Apostrophe,
+ Grave,
+ Backslash,
+ Comma,
+ Period,
+ Slash,
+}
+
+impl KeyData {
+ fn to_keycode(&self) -> Keycode {
+ match self {
+ KeyData::Return => keycodes::RETURN,
+ KeyData::Q => keycodes::Q,
+ KeyData::Escape => keycodes::ESCAPE,
+ KeyData::Space => keycodes::SPACE,
+ KeyData::Tab => keycodes::TAB,
+ KeyData::Backspace => keycodes::BACKSPACE,
+ KeyData::Delete => keycodes::DELETE,
+ KeyData::F1 => keycodes::F1,
+ KeyData::F2 => keycodes::F2,
+ KeyData::F3 => keycodes::F3,
+ KeyData::F4 => keycodes::F4,
+ KeyData::F5 => keycodes::F5,
+ KeyData::F6 => keycodes::F6,
+ KeyData::F7 => keycodes::F7,
+ KeyData::F8 => keycodes::F8,
+ KeyData::F9 => keycodes::F9,
+ KeyData::F10 => keycodes::F10,
+ KeyData::F11 => keycodes::F11,
+ KeyData::F12 => keycodes::F12,
+ KeyData::A => keycodes::A,
+ KeyData::B => keycodes::B,
+ KeyData::C => keycodes::C,
+ KeyData::D => keycodes::D,
+ KeyData::E => keycodes::E,
+ KeyData::F => keycodes::F,
+ KeyData::G => keycodes::G,
+ KeyData::H => keycodes::H,
+ KeyData::I => keycodes::I,
+ KeyData::J => keycodes::J,
+ KeyData::K => keycodes::K,
+ KeyData::L => keycodes::L,
+ KeyData::M => keycodes::M,
+ KeyData::N => keycodes::N,
+ KeyData::O => keycodes::O,
+ KeyData::P => keycodes::P,
+ KeyData::R => keycodes::R,
+ KeyData::S => keycodes::S,
+ KeyData::T => keycodes::T,
+ KeyData::U => keycodes::U,
+ KeyData::V => keycodes::V,
+ KeyData::W => keycodes::W,
+ KeyData::X => keycodes::X,
+ KeyData::Y => keycodes::Y,
+ KeyData::Z => keycodes::Z,
+ KeyData::Key0 => keycodes::KEY_0,
+ KeyData::Key1 => keycodes::KEY_1,
+ KeyData::Key2 => keycodes::KEY_2,
+ KeyData::Key3 => keycodes::KEY_3,
+ KeyData::Key4 => keycodes::KEY_4,
+ KeyData::Key5 => keycodes::KEY_5,
+ KeyData::Key6 => keycodes::KEY_6,
+ KeyData::Key7 => keycodes::KEY_7,
+ KeyData::Key8 => keycodes::KEY_8,
+ KeyData::Key9 => keycodes::KEY_9,
+ KeyData::Left => keycodes::LEFT,
+ KeyData::Right => keycodes::RIGHT,
+ KeyData::Up => keycodes::UP,
+ KeyData::Down => keycodes::DOWN,
+ KeyData::Home => keycodes::HOME,
+ KeyData::End => keycodes::END,
+ KeyData::PageUp => keycodes::PAGE_UP,
+ KeyData::PageDown => keycodes::PAGE_DOWN,
+ KeyData::Insert => keycodes::INSERT,
+ KeyData::Minus => keycodes::MINUS,
+ KeyData::Equal => keycodes::EQUAL,
+ KeyData::BracketLeft => keycodes::LEFT_BRACKET,
+ KeyData::BracketRight => keycodes::RIGHT_BRACKET,
+ KeyData::Semicolon => keycodes::SEMICOLON,
+ KeyData::Apostrophe => keycodes::APOSTROPHE,
+ KeyData::Grave => keycodes::GRAVE,
+ KeyData::Backslash => keycodes::BACKSLASH,
+ KeyData::Comma => keycodes::COMMA,
+ KeyData::Period => keycodes::PERIOD,
+ KeyData::Slash => keycodes::SLASH,
+ }
+ }
+}
+
pub fn parse_config(input: &str) -> Result<crate::Config, ConfigError> {
let config_data: ConfigData = ron::from_str(input)?;
config_data_to_config(config_data)
@@ -25,7 +174,7 @@ struct ConfigData {
gap_outer_vertical: u32,
terminal: String,
- modkey: String,
+ modkey: ModKey,
tags: Vec<String>,
keybindings: Vec<KeybindingData>,
@@ -38,9 +187,9 @@ struct ConfigData {
#[derive(Debug, Deserialize)]
struct KeybindingData {
- modifiers: Vec<String>,
- key: String,
- action: String,
+ modifiers: Vec<ModKey>,
+ key: KeyData,
+ action: KeyAction,
#[serde(default)]
arg: ArgData,
}
@@ -88,18 +237,18 @@ struct ColorSchemeData {
}
fn config_data_to_config(data: ConfigData) -> Result<crate::Config, ConfigError> {
- let modkey = parse_modkey(&data.modkey)?;
+ let modkey = data.modkey.to_keybut_mask();
let mut keybindings = Vec::new();
for kb_data in data.keybindings {
let modifiers = kb_data
.modifiers
.iter()
- .map(|s| parse_modkey(s))
- .collect::<Result<Vec<_>, _>>()?;
+ .map(|m| m.to_keybut_mask())
+ .collect();
- let key = string_to_keycode(&kb_data.key)?;
- let action = parse_key_action(&kb_data.action)?;
+ let key = kb_data.key.to_keycode();
+ let action = kb_data.action;
let arg = arg_data_to_arg(kb_data.arg)?;
keybindings.push(Key::new(modifiers, key, action, arg));
@@ -190,121 +339,6 @@ fn config_data_to_config(data: ConfigData) -> Result<crate::Config, ConfigError>
})
}
-fn parse_modkey(s: &str) -> Result<KeyButMask, ConfigError> {
- match s {
- "Mod1" => Ok(KeyButMask::MOD1),
- "Mod2" => Ok(KeyButMask::MOD2),
- "Mod3" => Ok(KeyButMask::MOD3),
- "Mod4" => Ok(KeyButMask::MOD4),
- "Mod5" => Ok(KeyButMask::MOD5),
- "Shift" => Ok(KeyButMask::SHIFT),
- "Control" => Ok(KeyButMask::CONTROL),
- _ => Err(ConfigError::InvalidModkey(s.to_string())),
- }
-}
-
-fn string_to_keycode(s: &str) -> Result<Keycode, ConfigError> {
- match s.to_lowercase().as_str() {
- "return" => Ok(keycodes::RETURN),
- "q" => Ok(keycodes::Q),
- "escape" => Ok(keycodes::ESCAPE),
- "space" => Ok(keycodes::SPACE),
- "tab" => Ok(keycodes::TAB),
- "backspace" => Ok(keycodes::BACKSPACE),
- "delete" => Ok(keycodes::DELETE),
-
- "f1" => Ok(keycodes::F1),
- "f2" => Ok(keycodes::F2),
- "f3" => Ok(keycodes::F3),
- "f4" => Ok(keycodes::F4),
- "f5" => Ok(keycodes::F5),
- "f6" => Ok(keycodes::F6),
- "f7" => Ok(keycodes::F7),
- "f8" => Ok(keycodes::F8),
- "f9" => Ok(keycodes::F9),
- "f10" => Ok(keycodes::F10),
- "f11" => Ok(keycodes::F11),
- "f12" => Ok(keycodes::F12),
-
- "a" => Ok(keycodes::A),
- "b" => Ok(keycodes::B),
- "c" => Ok(keycodes::C),
- "d" => Ok(keycodes::D),
- "e" => Ok(keycodes::E),
- "f" => Ok(keycodes::F),
- "g" => Ok(keycodes::G),
- "h" => Ok(keycodes::H),
- "i" => Ok(keycodes::I),
- "j" => Ok(keycodes::J),
- "k" => Ok(keycodes::K),
- "l" => Ok(keycodes::L),
- "m" => Ok(keycodes::M),
- "n" => Ok(keycodes::N),
- "o" => Ok(keycodes::O),
- "p" => Ok(keycodes::P),
- "r" => Ok(keycodes::R),
- "s" => Ok(keycodes::S),
- "t" => Ok(keycodes::T),
- "u" => Ok(keycodes::U),
- "v" => Ok(keycodes::V),
- "w" => Ok(keycodes::W),
- "x" => Ok(keycodes::X),
- "y" => Ok(keycodes::Y),
- "z" => Ok(keycodes::Z),
-
- "0" => Ok(keycodes::KEY_0),
- "1" => Ok(keycodes::KEY_1),
- "2" => Ok(keycodes::KEY_2),
- "3" => Ok(keycodes::KEY_3),
- "4" => Ok(keycodes::KEY_4),
- "5" => Ok(keycodes::KEY_5),
- "6" => Ok(keycodes::KEY_6),
- "7" => Ok(keycodes::KEY_7),
- "8" => Ok(keycodes::KEY_8),
- "9" => Ok(keycodes::KEY_9),
-
- "left" => Ok(keycodes::LEFT),
- "right" => Ok(keycodes::RIGHT),
- "up" => Ok(keycodes::UP),
- "down" => Ok(keycodes::DOWN),
- "home" => Ok(keycodes::HOME),
- "end" => Ok(keycodes::END),
- "pageup" => Ok(keycodes::PAGE_UP),
- "pagedown" => Ok(keycodes::PAGE_DOWN),
- "insert" => Ok(keycodes::INSERT),
-
- "minus" | "-" => Ok(keycodes::MINUS),
- "equal" | "=" => Ok(keycodes::EQUAL),
- "bracketleft" | "[" => Ok(keycodes::LEFT_BRACKET),
- "bracketright" | "]" => Ok(keycodes::RIGHT_BRACKET),
- "semicolon" | ";" => Ok(keycodes::SEMICOLON),
- "apostrophe" | "'" => Ok(keycodes::APOSTROPHE),
- "grave" | "`" => Ok(keycodes::GRAVE),
- "backslash" | "\\" => Ok(keycodes::BACKSLASH),
- "comma" | "," => Ok(keycodes::COMMA),
- "period" | "." => Ok(keycodes::PERIOD),
- "slash" | "/" => Ok(keycodes::SLASH),
-
- _ => Err(ConfigError::UnknownKey(s.to_string())),
- }
-}
-
-fn parse_key_action(s: &str) -> Result<crate::keyboard::KeyAction, ConfigError> {
- match s {
- "Spawn" => Ok(KeyAction::Spawn),
- "KillClient" => Ok(KeyAction::KillClient),
- "FocusStack" => Ok(KeyAction::FocusStack),
- "Quit" => Ok(KeyAction::Quit),
- "Restart" => Ok(KeyAction::Restart),
- "ViewTag" => Ok(KeyAction::ViewTag),
- "MoveToTag" => Ok(KeyAction::MoveToTag),
- "ToggleGaps" => Ok(KeyAction::ToggleGaps),
- "ToggleFullScreen" => Ok(KeyAction::ToggleFullScreen),
- "ToggleFloating" => Ok(KeyAction::ToggleFloating),
- _ => Err(ConfigError::UnknownAction(s.to_string())),
- }
-}
-
fn arg_data_to_arg(data: ArgData) -> Result<Arg, ConfigError> {
match data {
ArgData::None => Ok(Arg::None),
diff --git a/src/keyboard/handlers.rs b/src/keyboard/handlers.rs
index 34c9cd3..3fb40a0 100644
--- a/src/keyboard/handlers.rs
+++ b/src/keyboard/handlers.rs
@@ -1,12 +1,13 @@
use std::io;
use std::process::Command;
+use serde::Deserialize;
use x11rb::connection::Connection;
use x11rb::protocol::xproto::*;
use crate::errors::X11Error;
-#[derive(Debug, Copy, Clone)]
+#[derive(Debug, Copy, Clone, Deserialize)]
pub enum KeyAction {
Spawn,
KillClient,
diff --git a/templates/config.ron b/templates/config.ron
index cc74772..56a9f30 100644
--- a/templates/config.ron
+++ b/templates/config.ron
@@ -15,40 +15,40 @@
gap_outer_vertical: 5,
terminal: "st",
- modkey: "Mod4",
-
+ modkey: Mod4,
+
tags: ["1", "2", "3", "4", "5", "6", "7", "8", "9"],
-
+
keybindings: [
- (modifiers: ["Mod4"], key: "return", action: "Spawn", arg: "st"),
- (modifiers: ["Mod4"], key: "d", action: "Spawn", arg: ["sh", "-c", "dmenu_run -l 10"]),
- (modifiers: ["Mod4"], key: "s", action: "Spawn", arg: ["sh", "-c", "maim -s | xclip -selection clipboard -t image/png"]),
- (modifiers: ["Mod4"], key: "q", action: "KillClient"),
- (modifiers: ["Mod4", "Shift"], key: "f", action: "ToggleFullScreen"),
- (modifiers: ["Mod4", "Shift"], key: "space", action: "ToggleFloating"),
- (modifiers: ["Mod4"], key: "a", action: "ToggleGaps"),
- (modifiers: ["Mod4", "Shift"], key: "q", action: "Quit"),
- (modifiers: ["Mod4", "Shift"], key: "r", action: "Restart"),
- (modifiers: ["Mod4"], key: "j", action: "FocusStack", arg: -1),
- (modifiers: ["Mod4"], key: "k", action: "FocusStack", arg: 1),
- (modifiers: ["Mod4"], key: "1", action: "ViewTag", arg: 0),
- (modifiers: ["Mod4"], key: "2", action: "ViewTag", arg: 1),
- (modifiers: ["Mod4"], key: "3", action: "ViewTag", arg: 2),
- (modifiers: ["Mod4"], key: "4", action: "ViewTag", arg: 3),
- (modifiers: ["Mod4"], key: "5", action: "ViewTag", arg: 4),
- (modifiers: ["Mod4"], key: "6", action: "ViewTag", arg: 5),
- (modifiers: ["Mod4"], key: "7", action: "ViewTag", arg: 6),
- (modifiers: ["Mod4"], key: "8", action: "ViewTag", arg: 7),
- (modifiers: ["Mod4"], key: "9", action: "ViewTag", arg: 8),
- (modifiers: ["Mod4", "Shift"], key: "1", action: "MoveToTag", arg: 0),
- (modifiers: ["Mod4", "Shift"], key: "2", action: "MoveToTag", arg: 1),
- (modifiers: ["Mod4", "Shift"], key: "3", action: "MoveToTag", arg: 2),
- (modifiers: ["Mod4", "Shift"], key: "4", action: "MoveToTag", arg: 3),
- (modifiers: ["Mod4", "Shift"], key: "5", action: "MoveToTag", arg: 4),
- (modifiers: ["Mod4", "Shift"], key: "6", action: "MoveToTag", arg: 5),
- (modifiers: ["Mod4", "Shift"], key: "7", action: "MoveToTag", arg: 6),
- (modifiers: ["Mod4", "Shift"], key: "8", action: "MoveToTag", arg: 7),
- (modifiers: ["Mod4", "Shift"], key: "9", action: "MoveToTag", arg: 8),
+ (modifiers: [Mod4], key: Return, action: Spawn, arg: "st"),
+ (modifiers: [Mod4], key: D, action: Spawn, arg: ["sh", "-c", "dmenu_run -l 10"]),
+ (modifiers: [Mod4], key: S, action: Spawn, arg: ["sh", "-c", "maim -s | xclip -selection clipboard -t image/png"]),
+ (modifiers: [Mod4], key: Q, action: KillClient),
+ (modifiers: [Mod4, Shift], key: F, action: ToggleFullScreen),
+ (modifiers: [Mod4, Shift], key: Space, action: ToggleFloating),
+ (modifiers: [Mod4], key: A, action: ToggleGaps),
+ (modifiers: [Mod4, Shift], key: Q, action: Quit),
+ (modifiers: [Mod4, Shift], key: R, action: Restart),
+ (modifiers: [Mod4], key: J, action: FocusStack, arg: -1),
+ (modifiers: [Mod4], key: K, action: FocusStack, arg: 1),
+ (modifiers: [Mod4], key: Key1, action: ViewTag, arg: 0),
+ (modifiers: [Mod4], key: Key2, action: ViewTag, arg: 1),
+ (modifiers: [Mod4], key: Key3, action: ViewTag, arg: 2),
+ (modifiers: [Mod4], key: Key4, action: ViewTag, arg: 3),
+ (modifiers: [Mod4], key: Key5, action: ViewTag, arg: 4),
+ (modifiers: [Mod4], key: Key6, action: ViewTag, arg: 5),
+ (modifiers: [Mod4], key: Key7, action: ViewTag, arg: 6),
+ (modifiers: [Mod4], key: Key8, action: ViewTag, arg: 7),
+ (modifiers: [Mod4], key: Key9, action: ViewTag, arg: 8),
+ (modifiers: [Mod4, Shift], key: Key1, action: MoveToTag, arg: 0),
+ (modifiers: [Mod4, Shift], key: Key2, action: MoveToTag, arg: 1),
+ (modifiers: [Mod4, Shift], key: Key3, action: MoveToTag, arg: 2),
+ (modifiers: [Mod4, Shift], key: Key4, action: MoveToTag, arg: 3),
+ (modifiers: [Mod4, Shift], key: Key5, action: MoveToTag, arg: 4),
+ (modifiers: [Mod4, Shift], key: Key6, action: MoveToTag, arg: 5),
+ (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),
],
status_blocks: [