oxwm

https://git.tonybtw.com/oxwm.git git://git.tonybtw.com/oxwm.git
3,397 bytes raw
1
use anyhow::{Context, Result};
2
use std::path::PathBuf;
3
4
fn main() -> Result<()> {
5
    let args: Vec<String> = std::env::args().collect();
6
7
    let mut custom_config_path: Option<PathBuf> = None;
8
9
    match args.get(1).map(|s| s.as_str()) {
10
        Some("--version") => {
11
            println!("oxwm {}", env!("CARGO_PKG_VERSION"));
12
            return Ok(());
13
        }
14
        Some("--help") => {
15
            print_help();
16
            return Ok(());
17
        }
18
        Some("--init") => {
19
            init_config()?;
20
            return Ok(());
21
        }
22
        Some("--config") => {
23
            if let Some(path) = args.get(2) {
24
                custom_config_path = Some(PathBuf::from(path));
25
            } else {
26
                eprintln!("Error: --config requires a path argument");
27
                std::process::exit(1);
28
            }
29
        }
30
        _ => {}
31
    }
32
33
    let config = load_config(custom_config_path)?;
34
35
    let mut wm = oxwm::window_manager::WindowManager::new(config)?;
36
    let should_restart = wm.run()?;
37
38
    drop(wm);
39
40
    if should_restart {
41
        use std::os::unix::process::CommandExt;
42
        let err = std::process::Command::new(&args[0]).args(&args[1..]).exec();
43
        eprintln!("Failed to restart: {}", err);
44
    }
45
46
    Ok(())
47
}
48
49
fn load_config(custom_path: Option<PathBuf>) -> Result<oxwm::Config> {
50
    let config_path = if let Some(path) = custom_path {
51
        path
52
    } else {
53
        let default_path = get_config_path().join("config.ron");
54
        if !default_path.exists() {
55
            println!("No config found at {:?}", default_path);
56
            println!("Creating default config...");
57
            init_config()?;
58
        }
59
        default_path
60
    };
61
62
    let config_str =
63
        std::fs::read_to_string(&config_path).with_context(|| "Failed to read config file")?;
64
65
    oxwm::config::parse_config(&config_str).with_context(|| "Failed to parse config")
66
}
67
68
fn init_config() -> Result<()> {
69
    let config_dir = get_config_path();
70
    std::fs::create_dir_all(&config_dir)?;
71
72
    let config_template = include_str!("../../templates/config.ron");
73
    let config_path = config_dir.join("config.ron");
74
75
    std::fs::write(&config_path, config_template)?;
76
77
    println!("✓ Config created at {:?}", config_path);
78
    println!("  Edit the file and reload with Mod+Shift+R");
79
    println!("  No compilation needed - changes take effect immediately!");
80
81
    Ok(())
82
}
83
84
fn get_config_path() -> PathBuf {
85
    dirs::config_dir()
86
        .expect("Could not find config directory")
87
        .join("oxwm")
88
}
89
90
fn print_help() {
91
    println!("OXWM - A dynamic window manager written in Rust\n");
92
    println!("USAGE:");
93
    println!("    oxwm [OPTIONS]\n");
94
    println!("OPTIONS:");
95
    println!("    --init              Create default config in ~/.config/oxwm/config.ron");
96
    println!("    --config <PATH>     Use custom config file");
97
    println!("    --version           Print version information");
98
    println!("    --help              Print this help message\n");
99
    println!("CONFIG:");
100
    println!("    Location: ~/.config/oxwm/config.ron");
101
    println!("    Edit the config file and use Mod+Shift+R to reload");
102
    println!("    No compilation needed - instant hot-reload!\n");
103
    println!("FIRST RUN:");
104
    println!("    Run 'oxwm --init' to create a config file");
105
    println!("    Or just start oxwm and it will create one automatically\n");
106
}