mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-22 02:01:55 +07:00
Add ConfigLoaded event to IPC, option to disable built-in notification (#1829)
* feat: config reload ipc event * cleanups * Rename and move the new config option * rename to ConfigLoaded and emit at connection --------- Co-authored-by: Ivan Molodetskikh <yalterz@gmail.com>
This commit is contained in:
@@ -60,6 +60,8 @@ pub struct Config {
|
|||||||
#[knuffel(child, default)]
|
#[knuffel(child, default)]
|
||||||
pub hotkey_overlay: HotkeyOverlay,
|
pub hotkey_overlay: HotkeyOverlay,
|
||||||
#[knuffel(child, default)]
|
#[knuffel(child, default)]
|
||||||
|
pub config_notification: ConfigNotification,
|
||||||
|
#[knuffel(child, default)]
|
||||||
pub animations: Animations,
|
pub animations: Animations,
|
||||||
#[knuffel(child, default)]
|
#[knuffel(child, default)]
|
||||||
pub gestures: Gestures,
|
pub gestures: Gestures,
|
||||||
@@ -1047,6 +1049,12 @@ pub struct HotkeyOverlay {
|
|||||||
pub hide_not_bound: bool,
|
pub hide_not_bound: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub struct ConfigNotification {
|
||||||
|
#[knuffel(child)]
|
||||||
|
pub disable_failed: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq, Eq)]
|
#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct Clipboard {
|
pub struct Clipboard {
|
||||||
#[knuffel(child)]
|
#[knuffel(child)]
|
||||||
@@ -4769,6 +4777,9 @@ mod tests {
|
|||||||
skip_at_startup: true,
|
skip_at_startup: true,
|
||||||
hide_not_bound: false,
|
hide_not_bound: false,
|
||||||
},
|
},
|
||||||
|
config_notification: ConfigNotification {
|
||||||
|
disable_failed: false,
|
||||||
|
},
|
||||||
animations: Animations {
|
animations: Animations {
|
||||||
off: false,
|
off: false,
|
||||||
slowdown: FloatOrInt(
|
slowdown: FloatOrInt(
|
||||||
|
|||||||
@@ -1399,6 +1399,16 @@ pub enum Event {
|
|||||||
/// The new state of the overview.
|
/// The new state of the overview.
|
||||||
is_open: bool,
|
is_open: bool,
|
||||||
},
|
},
|
||||||
|
/// The configuration was reloaded.
|
||||||
|
///
|
||||||
|
/// You will always receive this event when connecting to the event stream, indicating the last
|
||||||
|
/// config load attempt.
|
||||||
|
ConfigLoaded {
|
||||||
|
/// Whether the loading failed.
|
||||||
|
///
|
||||||
|
/// For example, the config file couldn't be parsed.
|
||||||
|
failed: bool,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for WorkspaceReferenceArg {
|
impl FromStr for WorkspaceReferenceArg {
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ pub struct EventStreamState {
|
|||||||
|
|
||||||
/// State of the overview.
|
/// State of the overview.
|
||||||
pub overview: OverviewState,
|
pub overview: OverviewState,
|
||||||
|
|
||||||
|
/// State of the config.
|
||||||
|
pub config: ConfigState,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The workspaces state communicated over the event stream.
|
/// The workspaces state communicated over the event stream.
|
||||||
@@ -73,6 +76,13 @@ pub struct OverviewState {
|
|||||||
pub is_open: bool,
|
pub is_open: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The config state communicated over the event stream.
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct ConfigState {
|
||||||
|
/// Whether the last config load attempt had failed.
|
||||||
|
pub failed: bool,
|
||||||
|
}
|
||||||
|
|
||||||
impl EventStreamStatePart for EventStreamState {
|
impl EventStreamStatePart for EventStreamState {
|
||||||
fn replicate(&self) -> Vec<Event> {
|
fn replicate(&self) -> Vec<Event> {
|
||||||
let mut events = Vec::new();
|
let mut events = Vec::new();
|
||||||
@@ -80,6 +90,7 @@ impl EventStreamStatePart for EventStreamState {
|
|||||||
events.extend(self.windows.replicate());
|
events.extend(self.windows.replicate());
|
||||||
events.extend(self.keyboard_layouts.replicate());
|
events.extend(self.keyboard_layouts.replicate());
|
||||||
events.extend(self.overview.replicate());
|
events.extend(self.overview.replicate());
|
||||||
|
events.extend(self.config.replicate());
|
||||||
events
|
events
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,6 +99,7 @@ impl EventStreamStatePart for EventStreamState {
|
|||||||
let event = self.windows.apply(event)?;
|
let event = self.windows.apply(event)?;
|
||||||
let event = self.keyboard_layouts.apply(event)?;
|
let event = self.keyboard_layouts.apply(event)?;
|
||||||
let event = self.overview.apply(event)?;
|
let event = self.overview.apply(event)?;
|
||||||
|
let event = self.config.apply(event)?;
|
||||||
Some(event)
|
Some(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -244,3 +256,21 @@ impl EventStreamStatePart for OverviewState {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EventStreamStatePart for ConfigState {
|
||||||
|
fn replicate(&self) -> Vec<Event> {
|
||||||
|
vec![Event::ConfigLoaded {
|
||||||
|
failed: self.failed,
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply(&mut self, event: Event) -> Option<Event> {
|
||||||
|
match event {
|
||||||
|
Event::ConfigLoaded { failed } => {
|
||||||
|
self.failed = failed;
|
||||||
|
}
|
||||||
|
event => return Some(event),
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -459,6 +459,14 @@ pub fn handle_msg(msg: Msg, json: bool) -> anyhow::Result<()> {
|
|||||||
Event::OverviewOpenedOrClosed { is_open: opened } => {
|
Event::OverviewOpenedOrClosed { is_open: opened } => {
|
||||||
println!("Overview toggled: {opened}");
|
println!("Overview toggled: {opened}");
|
||||||
}
|
}
|
||||||
|
Event::ConfigLoaded { failed } => {
|
||||||
|
let status = if failed {
|
||||||
|
"with an error"
|
||||||
|
} else {
|
||||||
|
"successfully"
|
||||||
|
};
|
||||||
|
println!("Config loaded {status}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -762,4 +762,15 @@ impl State {
|
|||||||
state.apply(event.clone());
|
state.apply(event.clone());
|
||||||
server.send_event(event);
|
server.send_event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ipc_config_loaded(&mut self, failed: bool) {
|
||||||
|
let Some(server) = &self.niri.ipc_server else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let mut state = server.event_stream_state.borrow_mut();
|
||||||
|
|
||||||
|
let event = Event::ConfigLoaded { failed };
|
||||||
|
state.apply(event.clone());
|
||||||
|
server.send_event(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -241,6 +241,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
// Show the config error notification right away if needed.
|
// Show the config error notification right away if needed.
|
||||||
if config_errored {
|
if config_errored {
|
||||||
state.niri.config_error_notification.show();
|
state.niri.config_error_notification.show();
|
||||||
|
state.ipc_config_loaded(true);
|
||||||
} else if let Some(path) = config_created_at {
|
} else if let Some(path) = config_created_at {
|
||||||
state.niri.config_error_notification.show_created(path);
|
state.niri.config_error_notification.show_created(path);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,11 @@ impl ConfigErrorNotification {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn show(&mut self) {
|
pub fn show(&mut self) {
|
||||||
|
let c = self.config.borrow();
|
||||||
|
if c.config_notification.disable_failed {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if self.created_path.is_some() {
|
if self.created_path.is_some() {
|
||||||
self.created_path = None;
|
self.created_path = None;
|
||||||
self.buffers.borrow_mut().clear();
|
self.buffers.borrow_mut().clear();
|
||||||
|
|||||||
+11
-4
@@ -5,7 +5,7 @@ use std::sync::mpsc;
|
|||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
use std::{io, thread};
|
use std::{io, thread};
|
||||||
|
|
||||||
use niri_config::ConfigPath;
|
use niri_config::{Config, ConfigPath};
|
||||||
use smithay::reexports::calloop::channel::SyncSender;
|
use smithay::reexports::calloop::channel::SyncSender;
|
||||||
|
|
||||||
use crate::niri::State;
|
use crate::niri::State;
|
||||||
@@ -137,10 +137,17 @@ pub fn setup(state: &mut State, config_path: &ConfigPath) {
|
|||||||
state
|
state
|
||||||
.niri
|
.niri
|
||||||
.event_loop
|
.event_loop
|
||||||
.insert_source(rx, |event, _, state| match event {
|
.insert_source(
|
||||||
calloop::channel::Event::Msg(config) => state.reload_config(config),
|
rx,
|
||||||
|
|event: calloop::channel::Event<Result<Config, ()>>, _, state| match event {
|
||||||
|
calloop::channel::Event::Msg(config) => {
|
||||||
|
let failed = config.is_err();
|
||||||
|
state.reload_config(config);
|
||||||
|
state.ipc_config_loaded(failed);
|
||||||
|
}
|
||||||
calloop::channel::Event::Closed => (),
|
calloop::channel::Event::Closed => (),
|
||||||
})
|
},
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
state.niri.config_file_watcher = Some(Watcher::new(config_path.clone(), process, tx));
|
state.niri.config_file_watcher = Some(Watcher::new(config_path.clone(), process, tx));
|
||||||
|
|||||||
@@ -49,6 +49,10 @@ hotkey-overlay {
|
|||||||
skip-at-startup
|
skip-at-startup
|
||||||
hide-not-bound
|
hide-not-bound
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config-notification {
|
||||||
|
disable-failed
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### `spawn-at-startup`
|
### `spawn-at-startup`
|
||||||
@@ -277,3 +281,18 @@ hotkey-overlay {
|
|||||||
```
|
```
|
||||||
|
|
||||||
You can customize which binds the hotkey overlay shows using the [`hotkey-overlay-title` property](./Configuration:-Key-Bindings.md#custom-hotkey-overlay-titles).
|
You can customize which binds the hotkey overlay shows using the [`hotkey-overlay-title` property](./Configuration:-Key-Bindings.md#custom-hotkey-overlay-titles).
|
||||||
|
|
||||||
|
### `config-notification`
|
||||||
|
|
||||||
|
<sup>Since: next release</sup>
|
||||||
|
|
||||||
|
Settings for the config created/failed notification.
|
||||||
|
|
||||||
|
Set the `disable-failed` flag to disable the "Failed to parse the config file" notification.
|
||||||
|
For example, if you have a custom one.
|
||||||
|
|
||||||
|
```kdl
|
||||||
|
config-notification {
|
||||||
|
disable-failed
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user