oxwm

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

Fixed merge conflicts. Updated config parser to include keychord implementation.

Commit
aa4066d117fe65161fa232050aa9c771fecfae04
Parents
c07ef11 334f1e8
Author
tonybtw <tonybtw@tonybtw.com>
Date
2025-10-31 04:02:56

Diff

diff --cc src/errors.rs
index 9555d90,0a43192..3481d37
--- a/src/errors.rs
+++ b/src/errors.rs
@@@ -25,7 -25,9 +25,10 @@@ pub enum ConfigError 
      UnknownAction(String),
      UnknownBlockCommand(String),
      MissingCommandArg { command: String, field: String },
 +    ValidationError(String),
+     InvalidVariableName(String),
+     InvalidDefine(String),
+     UndefinedVariable(String),
  }
  
  impl std::fmt::Display for WmError {
@@@ -68,7 -70,15 +71,24 @@@ impl std::fmt::Display for ConfigError 
              Self::MissingCommandArg { command, field } => {
                  write!(f, "{} command requires {}", command, field)
              }
 +            Self::ValidationError(msg) => write!(f, "Config validation error: {}", msg),
+             Self::InvalidVariableName(name) => {
+                 write!(f, "Invalid variable name '{}': must start with $", name)
+             }
+             Self::InvalidDefine(line) => {
 -                write!(f, "Invalid #DEFINE syntax: '{}'. Expected: #DEFINE $var_name = value", line)
++                write!(
++                    f,
++                    "Invalid #DEFINE syntax: '{}'. Expected: #DEFINE $var_name = value",
++                    line
++                )
+             }
+             Self::UndefinedVariable(var) => {
 -                write!(f, "Undefined variable '{}': define it with #DEFINE before use", var)
++                write!(
++                    f,
++                    "Undefined variable '{}': define it with #DEFINE before use",
++                    var
++                )
+             }
          }
      }
  }
diff --cc templates/config.ron
index 8cdbb9a,2f5f18b..a770fa7
--- a/templates/config.ron
+++ b/templates/config.ron
@@@ -23,81 -38,53 +38,73 @@@
          (name: "normie", symbol: "[F]"),
      ],
  
 +    // Keybinding Format:
 +    //
 +    // New format (supports keychords - multi-key sequences):
 +    //   (keys: [(modifiers: [...], key: X), (modifiers: [...], key: Y)], action: ..., arg: ...)
 +    //
 +    // Old format (single key, backwards compatible):
 +    //   (modifiers: [...], key: X, action: ..., arg: ...)
 +    //
 +    // Examples:
 +    //   Single key:  (keys: [(modifiers: [Mod4], key: Return)], action: Spawn, arg: "st")
 +    //   Keychord:    (keys: [(modifiers: [Mod4], key: Space), (modifiers: [], key: F)], action: Spawn, arg: "firefox")
 +    //
 +    // You can cancel any in-progress keychord by pressing Escape.
 +
      keybindings: [
 +        // Basic keybindings (old format for backwards compatibility)
-         (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: 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),
-         (modifiers: [Mod4], key: J, action: FocusStack, arg: -1),
-         (modifiers: [Mod4], key: K, action: FocusStack, arg: 1),
-         (modifiers: [Mod4], key: Comma, action: FocusMonitor, arg: -1),
-         (modifiers: [Mod4], key: Period, action: FocusMonitor, 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),
+         (modifiers: [$modkey], key: Return, action: Spawn, arg: $terminal),
+         (modifiers: [$modkey], key: D, action: Spawn, arg: ["sh", "-c", "dmenu_run -l 10"]),
+         (modifiers: [$modkey], key: S, action: Spawn, arg: ["sh", "-c", "maim -s | xclip -selection clipboard -t image/png"]),
+         (modifiers: [$modkey], key: Q, action: KillClient),
+         (modifiers: [$modkey, Shift], key: F, action: ToggleFullScreen),
+         (modifiers: [$modkey, Shift], key: Space, action: ToggleFloating),
+         (modifiers: [$modkey], key: F, action: ChangeLayout, arg: "normie"),
+         (modifiers: [$modkey], key: C, action: ChangeLayout, arg: "tiling"),
+         (modifiers: [$secondary_modkey], key: N, action: CycleLayout),
+         (modifiers: [$modkey], key: A, action: ToggleGaps),
+         (modifiers: [$modkey, Shift], key: Q, action: Quit),
+         (modifiers: [$modkey, Shift], key: R, action: Restart),
+         (modifiers: [$modkey], key: J, action: FocusStack, arg: -1),
+         (modifiers: [$modkey], key: K, action: FocusStack, arg: 1),
+         (modifiers: [$modkey], key: Comma, action: FocusMonitor, arg: -1),
+         (modifiers: [$modkey], key: Period, action: FocusMonitor, arg: 1),
+         (modifiers: [$modkey], key: Key1, action: ViewTag, arg: 0),
+         (modifiers: [$modkey], key: Key2, action: ViewTag, arg: 1),
+         (modifiers: [$modkey], key: Key3, action: ViewTag, arg: 2),
+         (modifiers: [$modkey], key: Key4, action: ViewTag, arg: 3),
+         (modifiers: [$modkey], key: Key5, action: ViewTag, arg: 4),
+         (modifiers: [$modkey], key: Key6, action: ViewTag, arg: 5),
+         (modifiers: [$modkey], key: Key7, action: ViewTag, arg: 6),
+         (modifiers: [$modkey], key: Key8, action: ViewTag, arg: 7),
+         (modifiers: [$modkey], key: Key9, action: ViewTag, arg: 8),
+         (modifiers: [$modkey, Shift], key: Key1, action: MoveToTag, arg: 0),
+         (modifiers: [$modkey, Shift], key: Key2, action: MoveToTag, arg: 1),
+         (modifiers: [$modkey, Shift], key: Key3, action: MoveToTag, arg: 2),
+         (modifiers: [$modkey, Shift], key: Key4, action: MoveToTag, arg: 3),
+         (modifiers: [$modkey, Shift], key: Key5, action: MoveToTag, arg: 4),
+         (modifiers: [$modkey, Shift], key: Key6, action: MoveToTag, arg: 5),
+         (modifiers: [$modkey, Shift], key: Key7, action: MoveToTag, arg: 6),
+         (modifiers: [$modkey, Shift], key: Key8, action: MoveToTag, arg: 7),
+         (modifiers: [$modkey, 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
+         (modifiers: [$modkey, Control], key: K, action: SmartMoveWin, arg: 0), // UP
+         (modifiers: [$modkey, Control], key: J, action: SmartMoveWin, arg: 1), // DOWN
+         (modifiers: [$modkey, Control], key: H, action: SmartMoveWin, arg: 2), // LEFT
+         (modifiers: [$modkey, 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
+         (modifiers: [$modkey, Shift], key: K, action: ExchangeClient, arg: 0), // UP
+         (modifiers: [$modkey, Shift], key: J, action: ExchangeClient, arg: 1), // DOWN
+         (modifiers: [$modkey, Shift], key: H, action: ExchangeClient, arg: 2), // LEFT
+         (modifiers: [$modkey, Shift], key: L, action: ExchangeClient, arg: 3), // RIGHT
 +
 +        // Example keychord bindings (uncomment to use):
-         // Press Mod4+Space, then f to spawn firefox
-         // (keys: [(modifiers: [Mod4], key: Space), (modifiers: [], key: F)], action: Spawn, arg: "firefox"),
- 
++        // KEYCHORDS
 +        // Press Mod4+Space, then t to spawn terminal
-         // (keys: [(modifiers: [Mod4], key: Space), (modifiers: [], key: T)], action: Spawn, arg: "st"),
- 
-         // Press Mod4+e, then e to spawn a text editor (same key twice)
-         // (keys: [(modifiers: [Mod4], key: E), (modifiers: [], key: E)], action: Spawn, arg: "nvim"),
- 
-         // Press Mod4+x, then Shift+c to kill client (modifier on second key)
-         // (keys: [(modifiers: [Mod4], key: X), (modifiers: [Shift], key: C)], action: KillClient),
++        (keys: [(modifiers: [Mod4], key: Space), (modifiers: [], key: T)], action: Spawn, arg: $terminal),
      ],
      
      status_blocks: [
diff --cc test-config.ron
index eb258fc,1553106..4ea92da
--- a/test-config.ron
+++ b/test-config.ron
@@@ -30,8 -42,7 +42,8 @@@
      ],
  
      keybindings: [
-         (modifiers: [Mod1], key: Return, action: Spawn, arg: "st"),
 +        (keys: [(modifiers: [Mod1], key: Space), (modifiers: [], key: T)], action: Spawn, arg: "st"),
+         (modifiers: [Mod1], key: Return, action: Spawn, arg: $terminal),
          (modifiers: [Mod1], key: D, action: Spawn, arg: ["sh", "-c", "dmenu_run -l 10"]),
          (modifiers: [Mod1], key: S, action: Spawn, arg: ["sh", "-c", "maim -s | xclip -selection clipboard -t image/png"]),
          (modifiers: [Mod1], key: Q, action: KillClient),