oxwm

https://git.tonybtw.com/oxwm.git git://git.tonybtw.com/oxwm.git
4,785 bytes raw
1
use std::path::PathBuf;
2
3
fn main() -> Result<(), Box<dyn std::error::Error>> {
4
    let arguments: Vec<String> = std::env::args().collect();
5
6
    let mut custom_config_path: Option<PathBuf> = None;
7
8
    match arguments.get(1).map(|string| string.as_str()) {
9
        Some("--version") => {
10
            println!("oxwm {}", env!("CARGO_PKG_VERSION"));
11
            return Ok(());
12
        }
13
        Some("--help") => {
14
            print_help();
15
            return Ok(());
16
        }
17
        Some("--init") => {
18
            init_config()?;
19
            return Ok(());
20
        }
21
        Some("--config") => {
22
            if let Some(path) = arguments.get(2) {
23
                custom_config_path = Some(PathBuf::from(path));
24
            } else {
25
                eprintln!("Error: --config requires a path argument");
26
                std::process::exit(1);
27
            }
28
        }
29
        _ => {}
30
    }
31
32
    let (config, had_broken_config) = load_config(custom_config_path)?;
33
34
    let mut window_manager = oxwm::window_manager::WindowManager::new(config)?;
35
36
    if had_broken_config {
37
        window_manager.show_migration_overlay();
38
    }
39
40
    let should_restart = window_manager.run()?;
41
42
    drop(window_manager);
43
44
    if should_restart {
45
        use std::os::unix::process::CommandExt;
46
        let error = std::process::Command::new(&arguments[0]).args(&arguments[1..]).exec();
47
        eprintln!("Failed to restart: {}", error);
48
    }
49
50
    Ok(())
51
}
52
53
fn load_config(custom_path: Option<PathBuf>) -> Result<(oxwm::Config, bool), Box<dyn std::error::Error>> {
54
    let config_path = if let Some(path) = custom_path {
55
        path
56
    } else {
57
        let config_directory = get_config_path();
58
        let lua_path = config_directory.join("config.lua");
59
60
        if !lua_path.exists() {
61
            let ron_path = config_directory.join("config.ron");
62
            let had_ron_config = ron_path.exists();
63
64
            println!("No config found at {:?}", config_directory);
65
            println!("Creating default Lua config...");
66
            init_config()?;
67
68
            if had_ron_config {
69
                println!("\n NOTICE: OXWM has migrated to Lua configuration.");
70
                println!("   Your old config.ron has been preserved, but is no longer used.");
71
                println!("   Your settings have been reset to defaults.");
72
                println!("   Please manually port your configuration to the new Lua format.");
73
                println!("   See the new config.lua template for examples.\n");
74
            }
75
        }
76
77
        lua_path
78
    };
79
80
    let config_string = std::fs::read_to_string(&config_path)
81
        .map_err(|error| format!("Failed to read config file: {}", error))?;
82
83
    let config_directory = config_path.parent();
84
85
    match oxwm::config::parse_lua_config(&config_string, config_directory) {
86
        Ok(config) => Ok((config, false)),
87
        Err(_error) => {
88
            let template = include_str!("../../templates/config.lua");
89
            let config = oxwm::config::parse_lua_config(template, None)
90
                .map_err(|error| format!("Failed to parse default template config: {}", error))?;
91
            Ok((config, true))
92
        }
93
    }
94
}
95
96
fn init_config() -> Result<(), Box<dyn std::error::Error>> {
97
    let config_directory = get_config_path();
98
    std::fs::create_dir_all(&config_directory)?;
99
100
    let config_template = include_str!("../../templates/config.lua");
101
    let config_path = config_directory.join("config.lua");
102
    std::fs::write(&config_path, config_template)?;
103
104
    println!("✓ Config created at {:?}", config_path);
105
    println!("  Edit the file and reload with Mod+Shift+R");
106
    println!("  No compilation needed - changes take effect immediately!");
107
108
    Ok(())
109
}
110
111
fn get_config_path() -> PathBuf {
112
    dirs::config_dir()
113
        .expect("Could not find config directory")
114
        .join("oxwm")
115
}
116
117
fn print_help() {
118
    println!("OXWM - A dynamic window manager written in Rust\n");
119
    println!("USAGE:");
120
    println!("    oxwm [OPTIONS]\n");
121
    println!("OPTIONS:");
122
    println!("    --init              Create default config in ~/.config/oxwm/config.lua");
123
    println!("    --config <PATH>     Use custom config file");
124
    println!("    --version           Print version information");
125
    println!("    --help              Print this help message\n");
126
    println!("CONFIG:");
127
    println!("    Location: ~/.config/oxwm/config.lua");
128
    println!("    Edit the config file and use Mod+Shift+R to reload");
129
    println!("    No compilation needed - instant hot-reload!");
130
    println!("    LSP support included with oxwm.lua type definitions\n");
131
    println!("FIRST RUN:");
132
    println!("    Run 'oxwm --init' to create a config file");
133
    println!("    Or just start oxwm and it will create one automatically\n");
134
}