diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-01-28 17:15:47 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-01-28 17:15:47 +0400 |
| commit | 51243a0a505a533057e7326fbbae882420f0d363 (patch) | |
| tree | ca93ffe3434df7c4ef9a49f507a94ec214d0e629 | |
| parent | 0ebcc3e0d6ff7eda50d54fce312d0d1a42bd8224 (diff) | |
| download | niri-51243a0a505a533057e7326fbbae882420f0d363.tar.gz niri-51243a0a505a533057e7326fbbae882420f0d363.tar.bz2 niri-51243a0a505a533057e7326fbbae882420f0d363.zip | |
Show notification about creating a default config
| -rw-r--r-- | src/config_error_notification.rs | 52 | ||||
| -rw-r--r-- | src/main.rs | 6 |
2 files changed, 51 insertions, 7 deletions
diff --git a/src/config_error_notification.rs b/src/config_error_notification.rs index 37e0f2e8..773f3a13 100644 --- a/src/config_error_notification.rs +++ b/src/config_error_notification.rs @@ -1,5 +1,6 @@ use std::cell::RefCell; use std::collections::HashMap; +use std::path::{Path, PathBuf}; use std::time::Duration; use pangocairo::cairo::{self, ImageSurface}; @@ -26,6 +27,10 @@ const BORDER: i32 = 4; pub struct ConfigErrorNotification { state: State, buffers: RefCell<HashMap<i32, Option<MemoryRenderBuffer>>>, + + // If set, this is a "Created config at {path}" notification. If unset, this is a config error + // notification. + created_path: Option<PathBuf>, } enum State { @@ -43,10 +48,25 @@ impl ConfigErrorNotification { Self { state: State::Hidden, buffers: RefCell::new(HashMap::new()), + created_path: None, } } + pub fn show_created(&mut self, created_path: Option<PathBuf>) { + if self.created_path != created_path { + self.created_path = created_path; + self.buffers.borrow_mut().clear(); + } + + self.state = State::Showing(Animation::new(0., 1., Duration::from_millis(250))); + } + pub fn show(&mut self) { + if self.created_path.is_some() { + self.created_path = None; + self.buffers.borrow_mut().clear(); + } + // Show from scratch even if already showing to bring attention. self.state = State::Showing(Animation::new(0., 1., Duration::from_millis(250))); } @@ -65,7 +85,15 @@ impl ConfigErrorNotification { State::Showing(anim) => { anim.set_current_time(target_presentation_time); if anim.is_done() { - self.state = State::Shown(target_presentation_time + Duration::from_secs(4)); + let duration = if self.created_path.is_some() { + // Make this quite a bit longer because it comes with a monitor modeset + // (can take a while) and an important hotkeys popup diverting the + // attention. + Duration::from_secs(8) + } else { + Duration::from_secs(4) + }; + self.state = State::Shown(target_presentation_time + duration); } } State::Shown(deadline) => { @@ -96,11 +124,12 @@ impl ConfigErrorNotification { } let scale = output.current_scale().integer_scale(); + let path = self.created_path.as_deref(); let mut buffers = self.buffers.borrow_mut(); let buffer = buffers .entry(scale) - .or_insert_with_key(move |&scale| render(scale).ok()); + .or_insert_with_key(move |&scale| render(scale, path).ok()); let buffer = buffer.as_ref()?; let elem = MemoryRenderBufferRenderElement::from_buffer( @@ -138,11 +167,22 @@ impl ConfigErrorNotification { } } -fn render(scale: i32) -> anyhow::Result<MemoryRenderBuffer> { +fn render(scale: i32, created_path: Option<&Path>) -> anyhow::Result<MemoryRenderBuffer> { let _span = tracy_client::span!("config_error_notification::render"); let padding = PADDING * scale; + let mut text = String::from(TEXT); + let mut border_color = (1., 0.3, 0.3); + if let Some(path) = created_path { + text = format!( + "Created a default config file at \ + <span face='monospace' bgcolor='#000000'>{:?}</span>", + path + ); + border_color = (0.5, 1., 0.5); + }; + let mut font = FontDescription::from_string(FONT); font.set_absolute_size((font.size() * scale).into()); @@ -150,7 +190,7 @@ fn render(scale: i32) -> anyhow::Result<MemoryRenderBuffer> { let cr = cairo::Context::new(&surface)?; let layout = pangocairo::create_layout(&cr); layout.set_font_description(Some(&font)); - layout.set_markup(TEXT); + layout.set_markup(&text); let (mut width, mut height) = layout.pixel_size(); width += padding * 2; @@ -168,7 +208,7 @@ fn render(scale: i32) -> anyhow::Result<MemoryRenderBuffer> { cr.move_to(padding.into(), padding.into()); let layout = pangocairo::create_layout(&cr); layout.set_font_description(Some(&font)); - layout.set_markup(TEXT); + layout.set_markup(&text); cr.set_source_rgb(1., 1., 1.); pangocairo::show_layout(&cr, &layout); @@ -178,7 +218,7 @@ fn render(scale: i32) -> anyhow::Result<MemoryRenderBuffer> { cr.line_to(width.into(), height.into()); cr.line_to(0., height.into()); cr.line_to(0., 0.); - cr.set_source_rgb(1., 0.3, 0.3); + cr.set_source_rgb(border_color.0, border_color.1, border_color.2); cr.set_line_width((BORDER * scale).into()); cr.stroke()?; drop(cr); diff --git a/src/main.rs b/src/main.rs index e56e6fe0..cb8ebea6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -156,6 +156,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { info!("starting version {}", &version()); // Load the config. + let mut config_created = false; let path = cli.config.or_else(|| { let default_path = default_config_path()?; let default_parent = default_path.parent().unwrap(); @@ -179,6 +180,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { 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) => { @@ -255,7 +257,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { }; // Set up config file watcher. - let _watcher = if let Some(path) = path { + let _watcher = if let Some(path) = path.clone() { let (tx, rx) = calloop::channel::sync_channel(1); let watcher = Watcher::new(path.clone(), tx); event_loop @@ -280,6 +282,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { // Show the config error notification right away if needed. if config_errored { state.niri.config_error_notification.show(); + } else if config_created { + state.niri.config_error_notification.show_created(path); } // Run the compositor. |
