Add notification when switching keyboard layout

This commit is contained in:
2025-02-06 17:55:19 +01:00
parent 7f3405dcf0
commit e1ba66c1be
4 changed files with 82 additions and 5 deletions

View File

@ -7,6 +7,7 @@ mod battery;
mod eww; mod eww;
mod hyprland; mod hyprland;
mod niri; mod niri;
mod notify;
mod output; mod output;
mod pulse; mod pulse;
mod util; mod util;

View File

@ -1,6 +1,6 @@
use std::collections::HashMap; use std::{collections::HashMap, time::Duration};
use crate::{eww, WmCommand, Workspace}; use crate::{eww, notify::Notify, WmCommand, Workspace};
use eyre::{bail, eyre, Context}; use eyre::{bail, eyre, Context};
use niri_ipc::{socket::Socket, WorkspaceReferenceArg}; use niri_ipc::{socket::Socket, WorkspaceReferenceArg};
@ -30,7 +30,13 @@ pub fn handle(command: WmCommand) -> eyre::Result<()> {
.map(|(reply, _)| reply)? .map(|(reply, _)| reply)?
.map_err(|e| eyre!("niri error: {e}"))?; .map_err(|e| eyre!("niri error: {e}"))?;
eww::update_var("keyboard_layout", &get_keyboard_layout(true)?)?; let layout = &get_keyboard_layout(true)?;
Notify::new("Keyboard Layout")
.with_body(layout)
.with_expire(Duration::from_secs(1))
//.with_unique("keyboard-layout") // TODO: fix PATH so niri can call notify-send
.send()?;
eww::update_var("keyboard_layout", &layout)?;
} }
WmCommand::KeyboardLayout { short } => { WmCommand::KeyboardLayout { short } => {
println!("{}", get_keyboard_layout(short)?); println!("{}", get_keyboard_layout(short)?);

70
src/notify.rs Normal file
View File

@ -0,0 +1,70 @@
use std::{process::Command, time::Duration};
use crate::util::CommandExt;
pub struct Notify {
summary: String,
body: Option<String>,
expire: Option<Duration>,
// If set, only one notification with this ID may be shown at once.
unique_id: Option<String>,
}
impl Notify {
pub fn new(summary: impl Into<String>) -> Self {
Self {
summary: summary.into(),
body: None,
expire: None,
unique_id: None,
}
}
pub fn with_body(self, body: impl Into<String>) -> Self {
Self {
body: Some(body.into()),
..self
}
}
pub fn with_expire(self, expire: impl Into<Duration>) -> Self {
Self {
expire: Some(expire.into()),
..self
}
}
pub fn with_unique(self, unique_id: impl Into<String>) -> Self {
Self {
unique_id: Some(unique_id.into()),
..self
}
}
pub fn send(&self) -> eyre::Result<()> {
let Notify {
summary,
body,
expire,
unique_id,
} = self;
let mut command = match unique_id {
Some(id) => {
let mut command = Command::new("notify-set");
command.arg(id);
command
}
None => Command::new("notify-send"),
};
command
.arg(summary)
.args(body)
.args(expire.map(|d| format!("--expire-time={}", d.as_millis().to_string())))
.just_exec()?;
Ok(())
}
}

View File

@ -1,6 +1,6 @@
use eyre::{eyre, Context}; use eyre::{eyre, Context};
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use std::{fmt::Write, str}; use std::{fmt::Write, process::Command, str};
pub trait CommandExt: Sized { pub trait CommandExt: Sized {
fn just_exec(&mut self) -> eyre::Result<String>; fn just_exec(&mut self) -> eyre::Result<String>;
@ -16,7 +16,7 @@ pub trait CommandExt: Sized {
} }
} }
impl CommandExt for std::process::Command { impl CommandExt for Command {
fn just_exec(&mut self) -> eyre::Result<String> { fn just_exec(&mut self) -> eyre::Result<String> {
let error = self.error(); let error = self.error();
let output = self let output = self