oxwm

https://git.tonybtw.com/oxwm.git git://git.tonybtw.com/oxwm.git
4,818 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])
47
            .args(&arguments[1..])
48
            .exec();
49
        eprintln!("Failed to restart: {}", error);
50
    }
51
52
    Ok(())
53
}
54
55
fn load_config(
56
    custom_path: Option<PathBuf>,
57
) -> Result<(oxwm::Config, bool), Box<dyn std::error::Error>> {
58
    let config_path = if let Some(path) = custom_path {
59
        path
60
    } else {
61
        let config_directory = get_config_path();
62
        let lua_path = config_directory.join("config.lua");
63
64
        if !lua_path.exists() {
65
            let ron_path = config_directory.join("config.ron");
66
            let had_ron_config = ron_path.exists();
67
68
            println!("No config found at {:?}", config_directory);
69
            println!("Creating default Lua config...");
70
            init_config()?;
71
72
            if had_ron_config {
73
                println!("\n NOTICE: OXWM has migrated to Lua configuration.");
74
                println!("   Your old config.ron has been preserved, but is no longer used.");
75
                println!("   Your settings have been reset to defaults.");
76
                println!("   Please manually port your configuration to the new Lua format.");
77
                println!("   See the new config.lua template for examples.\n");
78
            }
79
        }
80
81
        lua_path
82
    };
83
84
    let config_string = std::fs::read_to_string(&config_path)
85
        .map_err(|error| format!("Failed to read config file: {}", error))?;
86
87
    let config_directory = config_path.parent();
88
89
    match oxwm::config::parse_lua_config(&config_string, config_directory) {
90
        Ok(config) => Ok((config, false)),
91
        Err(_error) => {
92
            let template = include_str!("../../templates/config.lua");
93
            let config = oxwm::config::parse_lua_config(template, None)
94
                .map_err(|error| format!("Failed to parse default template config: {}", error))?;
95
            Ok((config, true))
96
        }
97
    }
98
}
99
100
fn init_config() -> Result<(), Box<dyn std::error::Error>> {
101
    let config_directory = get_config_path();
102
    std::fs::create_dir_all(&config_directory)?;
103
104
    let config_template = include_str!("../../templates/config.lua");
105
    let config_path = config_directory.join("config.lua");
106
    std::fs::write(&config_path, config_template)?;
107
108
    println!("✓ Config created at {:?}", config_path);
109
    println!("  Edit the file and reload with Mod+Shift+R");
110
    println!("  No compilation needed - changes take effect immediately!");
111
112
    Ok(())
113
}
114
115
fn get_config_path() -> PathBuf {
116
    dirs::config_dir()
117
        .expect("Could not find config directory")
118
        .join("oxwm")
119
}
120
121
fn print_help() {
122
    println!("OXWM - A dynamic window manager written in Rust\n");
123
    println!("USAGE:");
124
    println!("    oxwm [OPTIONS]\n");
125
    println!("OPTIONS:");
126
    println!("    --init              Create default config in ~/.config/oxwm/config.lua");
127
    println!("    --config <PATH>     Use custom config file");
128
    println!("    --version           Print version information");
129
    println!("    --help              Print this help message\n");
130
    println!("CONFIG:");
131
    println!("    Location: ~/.config/oxwm/config.lua");
132
    println!("    Edit the config file and use Mod+Shift+R to reload");
133
    println!("    No compilation needed - instant hot-reload!");
134
    println!("    LSP support included with oxwm.lua type definitions\n");
135
    println!("FIRST RUN:");
136
    println!("    Run 'oxwm --init' to create a config file");
137
    println!("    Or just start oxwm and it will create one automatically\n");
138
}