aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-01-28 17:15:47 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2024-01-28 17:15:47 +0400
commit51243a0a505a533057e7326fbbae882420f0d363 (patch)
treeca93ffe3434df7c4ef9a49f507a94ec214d0e629 /src
parent0ebcc3e0d6ff7eda50d54fce312d0d1a42bd8224 (diff)
downloadniri-51243a0a505a533057e7326fbbae882420f0d363.tar.gz
niri-51243a0a505a533057e7326fbbae882420f0d363.tar.bz2
niri-51243a0a505a533057e7326fbbae882420f0d363.zip
Show notification about creating a default config
Diffstat (limited to 'src')
-rw-r--r--src/config_error_notification.rs52
-rw-r--r--src/main.rs6
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.