Allow substitutions in on_click commands

main
Tassilo Horn 3 years ago
parent 8d37fd95d1
commit 1cb4b5cc42
  1. 12
      swayr/src/shared/cfg.rs
  2. 9
      swayr/src/shared/fmt.rs
  3. 6
      swayrbar/src/bar.rs
  4. 4
      swayrbar/src/module.rs
  5. 48
      swayrbar/src/module/window.rs

@ -87,6 +87,9 @@ where
.arg("Thanks!")
.spawn()
.ok();
log::debug!("Created new config in {}.", path.to_string_lossy());
} else {
log::debug!("Loaded config from {}.", path.to_string_lossy());
}
let mut file = OpenOptions::new()
.read(true)
@ -96,5 +99,12 @@ where
.unwrap();
let mut buf: String = String::new();
file.read_to_string(&mut buf).unwrap();
toml::from_str::<T>(&buf).expect("Invalid config.")
match toml::from_str::<T>(&buf) {
Ok(cfg) => cfg,
Err(err) => {
log::error!("Invalid config: {}", err);
log::error!("Using default configuration.");
T::default()
}
}
}

@ -22,6 +22,7 @@ use std::fmt;
pub enum FmtArg {
I64(i64),
I32(i32),
F64(f64),
F32(f32),
String(String),
@ -33,6 +34,12 @@ impl From<i64> for FmtArg {
}
}
impl From<i32> for FmtArg {
fn from(x: i32) -> FmtArg {
FmtArg::I32(x)
}
}
impl From<f64> for FmtArg {
fn from(x: f64) -> FmtArg {
FmtArg::F64(x)
@ -62,6 +69,7 @@ impl ToString for FmtArg {
match self {
FmtArg::String(x) => x.clone(),
FmtArg::I64(x) => x.to_string(),
FmtArg::I32(x) => x.to_string(),
FmtArg::F64(x) => x.to_string(),
FmtArg::F32(x) => x.to_string(),
}
@ -77,6 +85,7 @@ impl FormatArgument for FmtArg {
match self {
Self::String(val) => fmt::Display::fmt(&val, f),
Self::I64(val) => fmt::Display::fmt(&val, f),
Self::I32(val) => fmt::Display::fmt(&val, f),
Self::F64(val) => fmt::Display::fmt(&val, f),
Self::F32(val) => fmt::Display::fmt(&val, f),
}

@ -101,7 +101,10 @@ fn handle_click(
for m in mods.iter() {
if let Some(on_click) = m.get_on_click_map(&name, &instance) {
if let Some(cmd) = on_click.get(&button_str) {
execute_command(cmd);
match m.subst_args(cmd) {
Some(cmd) => execute_command(&cmd),
None => execute_command(cmd),
}
return Some(());
}
}
@ -111,6 +114,7 @@ fn handle_click(
}
fn execute_command(cmd: &[String]) {
log::debug!("Executing cmd: {:?}", cmd);
match p::Command::new(&cmd[0]).args(&cmd[1..]).spawn() {
Ok(_child) => (),
Err(err) => {

@ -44,4 +44,8 @@ pub trait BarModuleFn: Sync + Send {
}
}
fn build(&self) -> s::Block;
fn subst_args<'a>(&'a self, _cmd: &'a [String]) -> Option<Vec<String>> {
// None means, no substitution are to be made.
None
}
}

@ -16,6 +16,7 @@
//! The window `swayrbar` module.
use std::collections::HashMap;
use std::sync::Mutex;
use crate::config;
use crate::module::BarModuleFn;
@ -28,11 +29,15 @@ const NAME: &str = "window";
pub struct BarModuleWindow {
config: config::ModuleConfig,
pid: Mutex<i32>,
}
impl BarModuleFn for BarModuleWindow {
fn create(config: config::ModuleConfig) -> Box<dyn BarModuleFn> {
Box::new(BarModuleWindow { config })
Box::new(BarModuleWindow {
config,
pid: Mutex::new(0),
})
}
fn default_config(instance: String) -> config::ModuleConfig {
@ -41,13 +46,19 @@ impl BarModuleFn for BarModuleWindow {
instance,
format: "🪟 {title} — {app_name}".to_owned(),
html_escape: Some(false),
on_click: Some(HashMap::from([(
on_click: Some(HashMap::from([
(
"Left".to_owned(),
vec![
"swayr".to_owned(),
"switch-to-urgent-or-lru-window".to_owned(),
],
)])),
),
(
"Right".to_owned(),
vec!["kill".to_owned(), "{pid}".to_owned()],
),
])),
}
}
@ -62,10 +73,14 @@ impl BarModuleFn for BarModuleWindow {
.find(|n| n.focused && n.get_type() == ipc::Type::Window);
let text = match focused_win {
Some(win) => {
format_placeholders!(&self.config.format,
let mut pid = self.pid.lock().expect("Couldn't lock pid!");
*pid = win.pid.unwrap_or(-1);
format_placeholders!(
&self.config.format,
self.config.is_html_escape(), {
"title" | "name" => win.get_name(),
"app_name" => win.get_app_name(),
"pid" => *pid,
})
}
None => String::new(),
@ -90,4 +105,29 @@ impl BarModuleFn for BarModuleWindow {
separator_block_width: None,
}
}
fn get_on_click_map(
&self,
name: &str,
instance: &str,
) -> Option<&HashMap<String, Vec<String>>> {
let cfg = self.get_config();
if name == cfg.name && instance == cfg.instance {
cfg.on_click.as_ref()
} else {
None
}
}
fn subst_args<'a>(&'a self, cmd: &'a [String]) -> Option<Vec<String>> {
let cmd = cmd
.iter()
.map(|arg| {
format_placeholders!(arg, false, {
"pid" => *self.pid.lock().expect("Could not lock pid."),
})
})
.collect();
Some(cmd)
}
}

Loading…
Cancel
Save