oxwm

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

added sane defaults

Commit
4001329983a7b31d87a0a8c950f56fcea65f5f05
Parent
ac5ee9e
Author
tonybtw <tonybtw@tonybtw.com>
Date
2025-10-11 04:05:04

Diff

diff --git a/src/bin/main.rs b/src/bin/main.rs
index 11b1b83..296f74f 100644
--- a/src/bin/main.rs
+++ b/src/bin/main.rs
@@ -32,10 +32,27 @@ fn main() -> Result<()> {
         let err = Command::new(&cache_binary).args(&args[1..]).exec();
         anyhow::bail!("Failed to exec user binary: {}", err);
     } else {
-        eprintln!("No configuration found.");
-        eprintln!("Run: oxwm --init");
-        eprintln!("Then add 'exec oxwm' to your ~/.xinitrc");
-        std::process::exit(1);
+        // No user config - use built-in defaults
+        eprintln!("╔════════════════════════════════════════╗");
+        eprintln!("║  OXWM: Running with default config    ║");
+        eprintln!("╚════════════════════════════════════════╝");
+        eprintln!();
+        eprintln!("ℹ️  Run 'oxwm --init' to create a custom config");
+        eprintln!();
+
+        let config = oxwm::Config::default();
+        let mut wm = oxwm::window_manager::WindowManager::new(config)?;
+        let should_restart = wm.run()?;
+
+        drop(wm);
+
+        if should_restart {
+            use std::os::unix::process::CommandExt;
+            let err = Command::new(&args[0]).args(&args[1..]).exec();
+            eprintln!("Failed to restart: {}", err);
+        }
+
+        Ok(())
     }
 }
 
@@ -123,7 +140,7 @@ pkgs.mkShell {
     recompile_config()?;
 
     println!("\n✓ Setup complete!");
-    println!("  Add 'exec oxwm' to your ~/.xinitrc");
+    println!("  Your custom config is now active");
     println!("  Reload config anytime with Mod+Shift+R");
 
     Ok(())
@@ -253,14 +270,15 @@ fn print_help() {
     println!("    --recompile    Recompile user configuration");
     println!("    --version      Print version information");
     println!("    --help         Print this help message\n");
-    println!("SETUP:");
-    println!("    1. Run 'oxwm --init' to create your config");
-    println!("    2. Edit ~/.config/oxwm/config.rs");
-    println!("    3. Add 'exec oxwm' to your ~/.xinitrc");
-    println!("    4. Start X with 'startx'\n");
     println!("CONFIGURATION:");
-    println!("    Config location: ~/.config/oxwm/config.rs");
-    println!("    Reload hotkey:   Mod+Shift+R (auto-recompiles if needed)\n");
+    println!("    Without --init: Runs with built-in defaults");
+    println!("    With --init:    Uses custom config from ~/.config/oxwm/config.rs");
+    println!("    Reload hotkey:  Mod+Shift+R (auto-recompiles if needed)\n");
+    println!("SETUP:");
+    println!("    1. Add 'exec oxwm' to your ~/.xinitrc (works immediately with defaults)");
+    println!("    2. Optionally run 'oxwm --init' to create custom config");
+    println!("    3. Edit ~/.config/oxwm/config.rs to customize");
+    println!("    4. Restart with Mod+Shift+R\n");
     println!("ADVANCED:");
     println!("    Create flake.nix or shell.nix in ~/.config/oxwm to use nix builds");
 }
diff --git a/src/lib.rs b/src/lib.rs
index dcd06a7..ebb5195 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -53,6 +53,16 @@ pub struct ColorScheme {
 
 impl Default for Config {
     fn default() -> Self {
+        use crate::keyboard::handlers::Key;
+        use crate::keyboard::{Arg, KeyAction, keycodes};
+        use x11rb::protocol::xproto::KeyButMask;
+
+        const MODKEY: KeyButMask = KeyButMask::MOD4;
+        const SHIFT: KeyButMask = KeyButMask::SHIFT;
+
+        // Detect terminal
+        let terminal = detect_terminal();
+
         Self {
             border_width: 2,
             border_focused: 0x6dade3,
@@ -63,13 +73,101 @@ impl Default for Config {
             gap_inner_vertical: 0,
             gap_outer_horizontal: 0,
             gap_outer_vertical: 0,
-            terminal: "xterm".to_string(),
-            modkey: x11rb::protocol::xproto::KeyButMask::MOD4,
+            terminal,
+            modkey: MODKEY,
             tags: vec!["1", "2", "3", "4", "5", "6", "7", "8", "9"]
                 .into_iter()
                 .map(String::from)
                 .collect(),
-            keybindings: Vec::new(),
+            keybindings: vec![
+                // Launch terminal
+                Key::new(
+                    &[MODKEY],
+                    keycodes::RETURN,
+                    KeyAction::Spawn,
+                    Arg::Str("xterm"),
+                ),
+                // Window management
+                Key::new(&[MODKEY], keycodes::Q, KeyAction::KillClient, Arg::None),
+                Key::new(
+                    &[MODKEY, SHIFT],
+                    keycodes::F,
+                    KeyAction::ToggleFullScreen,
+                    Arg::None,
+                ),
+                Key::new(&[MODKEY], keycodes::A, KeyAction::ToggleGaps, Arg::None),
+                // WM controls
+                Key::new(&[MODKEY, SHIFT], keycodes::Q, KeyAction::Quit, Arg::None),
+                Key::new(&[MODKEY, SHIFT], keycodes::R, KeyAction::Restart, Arg::None),
+                // Focus
+                Key::new(&[MODKEY], keycodes::J, KeyAction::FocusStack, Arg::Int(-1)),
+                Key::new(&[MODKEY], keycodes::K, KeyAction::FocusStack, Arg::Int(1)),
+                // View tags
+                Key::new(&[MODKEY], keycodes::KEY_1, KeyAction::ViewTag, Arg::Int(0)),
+                Key::new(&[MODKEY], keycodes::KEY_2, KeyAction::ViewTag, Arg::Int(1)),
+                Key::new(&[MODKEY], keycodes::KEY_3, KeyAction::ViewTag, Arg::Int(2)),
+                Key::new(&[MODKEY], keycodes::KEY_4, KeyAction::ViewTag, Arg::Int(3)),
+                Key::new(&[MODKEY], keycodes::KEY_5, KeyAction::ViewTag, Arg::Int(4)),
+                Key::new(&[MODKEY], keycodes::KEY_6, KeyAction::ViewTag, Arg::Int(5)),
+                Key::new(&[MODKEY], keycodes::KEY_7, KeyAction::ViewTag, Arg::Int(6)),
+                Key::new(&[MODKEY], keycodes::KEY_8, KeyAction::ViewTag, Arg::Int(7)),
+                Key::new(&[MODKEY], keycodes::KEY_9, KeyAction::ViewTag, Arg::Int(8)),
+                // Move windows to tags
+                Key::new(
+                    &[MODKEY, SHIFT],
+                    keycodes::KEY_1,
+                    KeyAction::MoveToTag,
+                    Arg::Int(0),
+                ),
+                Key::new(
+                    &[MODKEY, SHIFT],
+                    keycodes::KEY_2,
+                    KeyAction::MoveToTag,
+                    Arg::Int(1),
+                ),
+                Key::new(
+                    &[MODKEY, SHIFT],
+                    keycodes::KEY_3,
+                    KeyAction::MoveToTag,
+                    Arg::Int(2),
+                ),
+                Key::new(
+                    &[MODKEY, SHIFT],
+                    keycodes::KEY_4,
+                    KeyAction::MoveToTag,
+                    Arg::Int(3),
+                ),
+                Key::new(
+                    &[MODKEY, SHIFT],
+                    keycodes::KEY_5,
+                    KeyAction::MoveToTag,
+                    Arg::Int(4),
+                ),
+                Key::new(
+                    &[MODKEY, SHIFT],
+                    keycodes::KEY_6,
+                    KeyAction::MoveToTag,
+                    Arg::Int(5),
+                ),
+                Key::new(
+                    &[MODKEY, SHIFT],
+                    keycodes::KEY_7,
+                    KeyAction::MoveToTag,
+                    Arg::Int(6),
+                ),
+                Key::new(
+                    &[MODKEY, SHIFT],
+                    keycodes::KEY_8,
+                    KeyAction::MoveToTag,
+                    Arg::Int(7),
+                ),
+                Key::new(
+                    &[MODKEY, SHIFT],
+                    keycodes::KEY_9,
+                    KeyAction::MoveToTag,
+                    Arg::Int(8),
+                ),
+            ],
             status_blocks: Vec::new(),
             scheme_normal: ColorScheme {
                 foreground: 0xbbbbbb,
@@ -89,3 +187,19 @@ impl Default for Config {
         }
     }
 }
+
+fn detect_terminal() -> String {
+    let terminals = ["alacritty", "kitty", "st", "xterm", "urxvt", "termite"];
+
+    for term in &terminals {
+        if std::process::Command::new("which")
+            .arg(term)
+            .output()
+            .map(|o| o.status.success())
+            .unwrap_or(false)
+        {
+            return term.to_string();
+        }
+    }
+    "xterm".to_string()
+}