diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-09-02 13:10:45 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-09-02 13:10:45 +0300 |
| commit | 4b7c16b04a7c80f5f9b6fcbc4a1d8c9448dffbdb (patch) | |
| tree | c19a52b12720a83a6a06501d5295e35da43065be | |
| parent | aafd5ab70ff7031e8fa448d13a217ab66b6a4483 (diff) | |
| download | niri-4b7c16b04a7c80f5f9b6fcbc4a1d8c9448dffbdb.tar.gz niri-4b7c16b04a7c80f5f9b6fcbc4a1d8c9448dffbdb.tar.bz2 niri-4b7c16b04a7c80f5f9b6fcbc4a1d8c9448dffbdb.zip | |
Read config from /etc/niri/config.kdl too
| -rw-r--r-- | src/main.rs | 122 | ||||
| -rw-r--r-- | src/ui/config_error_notification.rs | 3 | ||||
| -rw-r--r-- | wiki/Configuration:-Overview.md | 4 |
3 files changed, 73 insertions, 56 deletions
diff --git a/src/main.rs b/src/main.rs index ad201b2d..bb22e071 100644 --- a/src/main.rs +++ b/src/main.rs @@ -90,10 +90,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { Sub::Validate { config } => { tracy_client::Client::start(); - let path = config - .or_else(env_config_path) - .or_else(default_config_path) - .expect("error getting config path"); + let (path, _, _) = config_path(config); Config::load(&path)?; info!("config is valid"); return Ok(()); @@ -114,56 +111,50 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { // Load the config. let mut config_created = false; - let path = cli.config.or_else(env_config_path); + let (path, watch_path, create_default) = config_path(cli.config); env::remove_var("NIRI_CONFIG"); - let path = path.or_else(|| { - let default_path = default_config_path()?; - let default_parent = default_path.parent().unwrap(); - - if let Err(err) = fs::create_dir_all(default_parent) { - warn!( - "error creating config directories {:?}: {err:?}", - default_parent - ); - return Some(default_path); - } - - // Create the config and fill it with the default config if it doesn't exist. - let new_file = File::options() - .read(true) - .write(true) - .create_new(true) - .open(&default_path); - match new_file { - Ok(mut new_file) => { - let default = include_bytes!("../resources/default-config.kdl"); - match new_file.write_all(default) { - Ok(()) => { - config_created = true; - info!("wrote default config to {:?}", &default_path); - } - Err(err) => { - warn!("error writing config file at {:?}: {err:?}", &default_path) + if create_default { + let default_parent = path.parent().unwrap(); + + match fs::create_dir_all(default_parent) { + Ok(()) => { + // Create the config and fill it with the default config if it doesn't exist. + let new_file = File::options() + .read(true) + .write(true) + .create_new(true) + .open(&path); + match new_file { + Ok(mut new_file) => { + let default = include_bytes!("../resources/default-config.kdl"); + match new_file.write_all(default) { + Ok(()) => { + config_created = true; + info!("wrote default config to {:?}", &path); + } + Err(err) => { + warn!("error writing config file at {:?}: {err:?}", &path) + } + } } + Err(err) if err.kind() == io::ErrorKind::AlreadyExists => {} + Err(err) => warn!("error creating config file at {:?}: {err:?}", &path), } } - Err(err) if err.kind() == io::ErrorKind::AlreadyExists => {} - Err(err) => warn!("error creating config file at {:?}: {err:?}", &default_path), + Err(err) => { + warn!( + "error creating config directories {:?}: {err:?}", + default_parent + ); + } } - - Some(default_path) - }); + } let mut config_errored = false; - let mut config = path - .as_deref() - .and_then(|path| match Config::load(path) { - Ok(config) => Some(config), - Err(err) => { - warn!("{err:?}"); - config_errored = true; - None - } + let mut config = Config::load(&path) + .map_err(|err| { + warn!("{err:?}"); + config_errored = true; }) .unwrap_or_default(); @@ -231,19 +222,17 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { } // Set up config file watcher. - let _watcher = if let Some(path) = path.clone() { + let _watcher = { let (tx, rx) = calloop::channel::sync_channel(1); - let watcher = Watcher::new(path.clone(), tx); + let watcher = Watcher::new(watch_path.clone(), tx); event_loop .handle() .insert_source(rx, move |event, _, state| match event { - calloop::channel::Event::Msg(()) => state.reload_config(path.clone()), + calloop::channel::Event::Msg(()) => state.reload_config(watch_path.clone()), calloop::channel::Event::Closed => (), }) .unwrap(); - Some(watcher) - } else { - None + watcher }; // Spawn commands from cli and auto-start. @@ -335,6 +324,33 @@ fn default_config_path() -> Option<PathBuf> { Some(path) } +fn system_config_path() -> PathBuf { + PathBuf::from("/etc/niri/config.kdl") +} + +/// Resolves and returns the config path to load, the config path to watch, and whether to create +/// the default config at the path to load. +fn config_path(cli_path: Option<PathBuf>) -> (PathBuf, PathBuf, bool) { + if let Some(explicit) = cli_path.or_else(env_config_path) { + return (explicit.clone(), explicit, false); + } + + let system_path = system_config_path(); + if let Some(path) = default_config_path() { + if path.exists() { + return (path.clone(), path, true); + } + + if system_path.exists() { + (system_path, path, false) + } else { + (path.clone(), path, true) + } + } else { + (system_path.clone(), system_path, false) + } +} + fn notify_fd() -> anyhow::Result<()> { let fd = match env::var("NOTIFY_FD") { Ok(notify_fd) => notify_fd.parse()?, diff --git a/src/ui/config_error_notification.rs b/src/ui/config_error_notification.rs index aa218c91..c4ca3b69 100644 --- a/src/ui/config_error_notification.rs +++ b/src/ui/config_error_notification.rs @@ -60,7 +60,8 @@ impl ConfigErrorNotification { Animation::new(from, to, 0., c.animations.config_notification_open_close.0) } - pub fn show_created(&mut self, created_path: Option<PathBuf>) { + pub fn show_created(&mut self, created_path: PathBuf) { + let created_path = Some(created_path); if self.created_path != created_path { self.created_path = created_path; self.buffers.borrow_mut().clear(); diff --git a/wiki/Configuration:-Overview.md b/wiki/Configuration:-Overview.md index eedcc560..5988ac7c 100644 --- a/wiki/Configuration:-Overview.md +++ b/wiki/Configuration:-Overview.md @@ -13,8 +13,8 @@ You can find documentation for various sections of the config on these wiki page ### Loading -Niri will load configuration from `$XDG_CONFIG_HOME/niri/config.kdl` or `~/.config/niri/config.kdl`. -If that file is missing, niri will create it with the contents of [the default configuration file](https://github.com/YaLTeR/niri/blob/main/resources/default-config.kdl). +Niri will load configuration from `$XDG_CONFIG_HOME/niri/config.kdl` or `~/.config/niri/config.kdl`, falling back to `/etc/niri/config.kdl`. +If both of these files are missing, niri will create `$XDG_CONFIG_HOME/niri/config.kdl` with the contents of [the default configuration file](https://github.com/YaLTeR/niri/blob/main/resources/default-config.kdl), which are embedded into the niri binary at build time. Please use the default configuration file as the starting point for your custom configuration. The configuration is live-reloaded. |
