mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-22 02:01:55 +07:00
Add load-config-file --path to load a different config (#3395)
* ipc: allow load-config to relocate the path of the config * doc: add info about alternative configuration paths and relocating Co-authored-by: Ivan Molodetskikh <yalterz@gmail.com> * Update docs/wiki/Integrating-niri.md * Update niri-ipc/src/lib.rs * Update src/ipc/server.rs --------- Co-authored-by: Ivan Molodetskikh <yalterz@gmail.com>
This commit is contained in:
@@ -11,6 +11,9 @@ When this file is present, niri *will not* automatically create a config at `~/.
|
|||||||
|
|
||||||
Keep in mind that we update the default config in new releases, so if you have a custom `/etc/niri/config.kdl`, you likely want to inspect and apply the relevant changes too.
|
Keep in mind that we update the default config in new releases, so if you have a custom `/etc/niri/config.kdl`, you likely want to inspect and apply the relevant changes too.
|
||||||
|
|
||||||
|
The default configuration locations can be overridden with the `NIRI_CONFIG` environment variable.
|
||||||
|
You can also change the configuration path at runtime via the niri IPC or using the command `niri msg action load-config-file --path <path-to-config.kdl>`.
|
||||||
|
|
||||||
You can split the niri config file into multiple files using [`include`](./Configuration:-Include.md).
|
You can split the niri config file into multiple files using [`include`](./Configuration:-Include.md).
|
||||||
|
|
||||||
### Xwayland
|
### Xwayland
|
||||||
|
|||||||
@@ -368,7 +368,7 @@ pub enum Action {
|
|||||||
#[knuffel(skip)]
|
#[knuffel(skip)]
|
||||||
UnsetWindowUrgent(u64),
|
UnsetWindowUrgent(u64),
|
||||||
#[knuffel(skip)]
|
#[knuffel(skip)]
|
||||||
LoadConfigFile,
|
LoadConfigFile(#[knuffel(argument)] Option<String>),
|
||||||
#[knuffel(skip)]
|
#[knuffel(skip)]
|
||||||
MruAdvance {
|
MruAdvance {
|
||||||
direction: MruDirection,
|
direction: MruDirection,
|
||||||
@@ -699,7 +699,7 @@ impl From<niri_ipc::Action> for Action {
|
|||||||
niri_ipc::Action::ToggleWindowUrgent { id } => Self::ToggleWindowUrgent(id),
|
niri_ipc::Action::ToggleWindowUrgent { id } => Self::ToggleWindowUrgent(id),
|
||||||
niri_ipc::Action::SetWindowUrgent { id } => Self::SetWindowUrgent(id),
|
niri_ipc::Action::SetWindowUrgent { id } => Self::SetWindowUrgent(id),
|
||||||
niri_ipc::Action::UnsetWindowUrgent { id } => Self::UnsetWindowUrgent(id),
|
niri_ipc::Action::UnsetWindowUrgent { id } => Self::UnsetWindowUrgent(id),
|
||||||
niri_ipc::Action::LoadConfigFile {} => Self::LoadConfigFile,
|
niri_ipc::Action::LoadConfigFile { path } => Self::LoadConfigFile(path),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-1
@@ -936,7 +936,13 @@ pub enum Action {
|
|||||||
///
|
///
|
||||||
/// Can be useful for scripts changing the config file, to avoid waiting the small duration for
|
/// Can be useful for scripts changing the config file, to avoid waiting the small duration for
|
||||||
/// niri's config file watcher to notice the changes.
|
/// niri's config file watcher to notice the changes.
|
||||||
LoadConfigFile {},
|
LoadConfigFile {
|
||||||
|
/// Path of a new config file to load.
|
||||||
|
///
|
||||||
|
/// If unset, reloads the current config file.
|
||||||
|
#[cfg_attr(feature = "clap", arg(long))]
|
||||||
|
path: Option<String>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change in window or column size.
|
/// Change in window or column size.
|
||||||
|
|||||||
+2
-2
@@ -2318,9 +2318,9 @@ impl State {
|
|||||||
}
|
}
|
||||||
self.niri.queue_redraw_all();
|
self.niri.queue_redraw_all();
|
||||||
}
|
}
|
||||||
Action::LoadConfigFile => {
|
Action::LoadConfigFile(path) => {
|
||||||
if let Some(watcher) = &self.niri.config_file_watcher {
|
if let Some(watcher) = &self.niri.config_file_watcher {
|
||||||
watcher.load_config();
|
watcher.load_config(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Action::MruConfirm => {
|
Action::MruConfirm => {
|
||||||
|
|||||||
+9
-1
@@ -463,7 +463,8 @@ async fn process(ctx: &ClientCtx, request: Request) -> Reply {
|
|||||||
fn validate_action(action: &Action) -> Result<(), String> {
|
fn validate_action(action: &Action) -> Result<(), String> {
|
||||||
if let Action::Screenshot { path, .. }
|
if let Action::Screenshot { path, .. }
|
||||||
| Action::ScreenshotScreen { path, .. }
|
| Action::ScreenshotScreen { path, .. }
|
||||||
| Action::ScreenshotWindow { path, .. } = action
|
| Action::ScreenshotWindow { path, .. }
|
||||||
|
| Action::LoadConfigFile { path } = action
|
||||||
{
|
{
|
||||||
if let Some(path) = path {
|
if let Some(path) = path {
|
||||||
// Relative paths are resolved against the niri compositor's working directory, which
|
// Relative paths are resolved against the niri compositor's working directory, which
|
||||||
@@ -474,6 +475,13 @@ fn validate_action(action: &Action) -> Result<(), String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Action::LoadConfigFile { path: Some(path) } = action {
|
||||||
|
let p = Path::new(path);
|
||||||
|
if !p.is_file() {
|
||||||
|
return Err(format!("path does not point to a file: {path}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-4
@@ -14,7 +14,7 @@ use crate::niri::State;
|
|||||||
const POLLING_INTERVAL: Duration = Duration::from_millis(500);
|
const POLLING_INTERVAL: Duration = Duration::from_millis(500);
|
||||||
|
|
||||||
pub struct Watcher {
|
pub struct Watcher {
|
||||||
load_config: mpsc::Sender<()>,
|
load_config: mpsc::Sender<Option<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WatcherInner {
|
struct WatcherInner {
|
||||||
@@ -67,7 +67,15 @@ impl Watcher {
|
|||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut should_load = match load_config_rx.recv_timeout(POLLING_INTERVAL) {
|
let mut should_load = match load_config_rx.recv_timeout(POLLING_INTERVAL) {
|
||||||
Ok(()) => true,
|
Ok(path) => {
|
||||||
|
if let Some(path) = path {
|
||||||
|
inner = WatcherInner::new(
|
||||||
|
ConfigPath::Explicit(PathBuf::from(path)),
|
||||||
|
Vec::new(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
Err(mpsc::RecvTimeoutError::Disconnected) => break,
|
Err(mpsc::RecvTimeoutError::Disconnected) => break,
|
||||||
Err(mpsc::RecvTimeoutError::Timeout) => false,
|
Err(mpsc::RecvTimeoutError::Timeout) => false,
|
||||||
};
|
};
|
||||||
@@ -105,8 +113,8 @@ impl Watcher {
|
|||||||
Self { load_config }
|
Self { load_config }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_config(&self) {
|
pub fn load_config(&self, path: Option<String>) {
|
||||||
let _ = self.load_config.send(());
|
let _ = self.load_config.send(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user