Config for the swayrbar

main
Tassilo Horn 2 years ago
parent 160b7d645c
commit cdb62c0ce8
  1. 17
      src/bar.rs
  2. 43
      src/bar/config.rs
  3. 10
      src/bar/module.rs
  4. 46
      src/bar/module/battery.rs
  5. 34
      src/bar/module/date.rs
  6. 48
      src/bar/module/sysinfo.rs
  7. 37
      src/bar/module/window.rs
  8. 2
      src/fmt_replace.rs

@ -20,6 +20,7 @@ use env_logger::Env;
use serde_json; use serde_json;
use std::thread; use std::thread;
pub mod config;
pub mod module; pub mod module;
pub fn start() { pub fn start() {
@ -28,10 +29,18 @@ pub fn start() {
thread::spawn(handle_input); thread::spawn(handle_input);
let mods: Vec<Box<dyn BarModuleFn>> = vec![ let mods: Vec<Box<dyn BarModuleFn>> = vec![
crate::bar::module::window::BarModuleWindow::init(), module::window::BarModuleWindow::create(
crate::bar::module::sysinfo::BarModuleSysInfo::init(), module::window::BarModuleWindow::default_config("0".to_owned()),
crate::bar::module::battery::BarModuleBattery::init(), ),
crate::bar::module::date::BarModuleDate::init(), module::sysinfo::BarModuleSysInfo::create(
module::sysinfo::BarModuleSysInfo::default_config("0".to_owned()),
),
module::battery::BarModuleBattery::create(
module::battery::BarModuleBattery::default_config("0".to_owned()),
),
module::date::BarModuleDate::create(
module::date::BarModuleDate::default_config("0".to_owned()),
),
]; ];
generate_status(&mods); generate_status(&mods);
} }

@ -0,0 +1,43 @@
// Copyright (C) 2022 Tassilo Horn <tsdh@gnu.org>
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <https://www.gnu.org/licenses/>.
//! TOML configuration for swayrbar.
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
pub struct Config {
pub refresh_interval: f32,
pub modules: Vec<String>,
pub module_configs: Vec<ModuleConfig>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ModuleConfig {
pub module_type: String,
pub instance: String,
pub format: String,
pub html_escape: bool,
}
impl Default for Config {
fn default() -> Self {
Config {
refresh_interval: 1.0,
modules: vec!["date/0".to_owned()],
module_configs: vec![],
}
}
}

@ -13,6 +13,7 @@
// You should have received a copy of the GNU General Public License along with // You should have received a copy of the GNU General Public License along with
// this program. If not, see <https://www.gnu.org/licenses/>. // this program. If not, see <https://www.gnu.org/licenses/>.
use crate::bar::config;
use swaybar_types as s; use swaybar_types as s;
pub mod battery; pub mod battery;
@ -21,12 +22,15 @@ pub mod sysinfo;
pub mod window; pub mod window;
pub trait BarModuleFn { pub trait BarModuleFn {
fn init() -> Box<dyn BarModuleFn> fn create(config: config::ModuleConfig) -> Box<dyn BarModuleFn>
where where
Self: Sized; Self: Sized;
fn name() -> String fn default_config(instance: String) -> config::ModuleConfig
where where
Self: Sized; Self: Sized;
fn instance(&self) -> String; fn name() -> &'static str
where
Self: Sized;
fn instance(&self) -> &str;
fn build(&self) -> s::Block; fn build(&self) -> s::Block;
} }

@ -15,6 +15,7 @@
//! The date `swayrbar` module. //! The date `swayrbar` module.
use crate::bar::config;
use crate::bar::module::BarModuleFn; use crate::bar::module::BarModuleFn;
use crate::fmt_replace::fmt_replace; use crate::fmt_replace::fmt_replace;
use battery as bat; use battery as bat;
@ -22,7 +23,7 @@ use std::cell::RefCell;
use swaybar_types as s; use swaybar_types as s;
pub struct BarModuleBattery { pub struct BarModuleBattery {
pub instance: String, config: config::ModuleConfig,
manager: RefCell<bat::Manager>, manager: RefCell<bat::Manager>,
} }
@ -42,23 +43,25 @@ fn get_refreshed_batteries(
Ok(bats) Ok(bats)
} }
fn get_text(manager: &RefCell<bat::Manager>, fmt: &str) -> String { fn get_text(
manager: &RefCell<bat::Manager>,
cfg: &config::ModuleConfig,
) -> String {
match get_refreshed_batteries(manager) { match get_refreshed_batteries(manager) {
Ok(bats) => { Ok(bats) => {
fmt_replace!(&fmt, false, { fmt_replace!(&cfg.format, cfg.html_escape, {
"state_of_charge" => bats.iter() "state_of_charge" => bats.iter()
.map(|b| b.state_of_charge().value) .map(|b| b.state_of_charge().value)
.sum::<f32>() .sum::<f32>()
/ bats.len() as f32 * 100 as f32, / bats.len() as f32 * 100_f32,
"state_of_health" => bats.iter() "state_of_health" => bats.iter()
.map(|b| b.state_of_health().value) .map(|b| b.state_of_health().value)
.sum::<f32>() .sum::<f32>()
/ bats.len() as f32 * 100 as f32, / bats.len() as f32 * 100_f32,
"state" => bats.iter() "state" => bats.iter()
.map(|b| format!("{:?}", b.state())) .map(|b| format!("{:?}", b.state()))
.next() .next()
.unwrap_or(String::new()), .unwrap_or_default(),
}) })
} }
Err(err) => format!("{}", err), Err(err) => format!("{}", err),
@ -66,30 +69,37 @@ fn get_text(manager: &RefCell<bat::Manager>, fmt: &str) -> String {
} }
impl BarModuleFn for BarModuleBattery { impl BarModuleFn for BarModuleBattery {
fn init() -> Box<dyn BarModuleFn> { fn create(config: config::ModuleConfig) -> Box<dyn BarModuleFn> {
Box::new(BarModuleBattery { Box::new(BarModuleBattery {
instance: "0".to_string(), config,
manager: RefCell::new( manager: RefCell::new(
bat::Manager::new().expect("Could not create Manager"), bat::Manager::new().expect("Could not create Manager"),
), ),
}) })
} }
fn name() -> String { fn default_config(instance: String) -> config::ModuleConfig {
String::from("battery") config::ModuleConfig {
module_type: Self::name().to_owned(),
instance,
format: "🔋 Bat: {state_of_charge:{:5.1}}%, {state}, Health: {state_of_health:{:5.1}}%".to_owned(),
html_escape: true,
}
}
fn name() -> &'static str {
"battery"
} }
fn instance(&self) -> String { fn instance(&self) -> &str {
self.instance.clone() &self.config.instance
} }
fn build(&self) -> s::Block { fn build(&self) -> s::Block {
let fmt = let text = get_text(&self.manager, &self.config);
"🔋 Bat: {state_of_charge:{:5.1}}%, {state}, Health: {state_of_health:{:5.1}}%";
let text = get_text(&self.manager, fmt);
s::Block { s::Block {
name: Some(Self::name()), name: Some(Self::name().to_owned()),
instance: Some(self.instance.clone()), instance: Some(self.config.instance.clone()),
full_text: text, full_text: text,
align: Some(s::Align::Right), align: Some(s::Align::Right),
markup: Some(s::Markup::Pango), markup: Some(s::Markup::Pango),

@ -15,34 +15,42 @@
//! The date `swayrbar` module. //! The date `swayrbar` module.
use crate::bar::module::config;
use crate::bar::module::BarModuleFn; use crate::bar::module::BarModuleFn;
use swaybar_types as s; use swaybar_types as s;
pub struct BarModuleDate { pub struct BarModuleDate {
pub instance: String, config: config::ModuleConfig,
} }
impl BarModuleFn for BarModuleDate { impl BarModuleFn for BarModuleDate {
fn init() -> Box<dyn BarModuleFn> { fn default_config(instance: String) -> config::ModuleConfig {
Box::new(BarModuleDate { config::ModuleConfig {
instance: "0".to_string(), module_type: "date".to_owned(),
}) instance,
format: "⏰ %F %X".to_owned(),
html_escape: false,
}
}
fn create(cfg: config::ModuleConfig) -> Box<dyn BarModuleFn> {
Box::new(BarModuleDate { config: cfg })
} }
fn name() -> String { fn name() -> &'static str {
String::from("date") "date"
} }
fn instance(&self) -> String { fn instance(&self) -> &str {
self.instance.clone() &self.config.instance
} }
fn build(&self) -> s::Block { fn build(&self) -> s::Block {
let d = chrono::Local::now().format("⏰ %F %X").to_string(); let text = chrono::Local::now().format(&self.config.format).to_string();
s::Block { s::Block {
name: Some(Self::name()), name: Some(Self::name().to_owned()),
instance: Some(self.instance.clone()), instance: Some(self.config.instance.clone()),
full_text: d, full_text: text,
align: Some(s::Align::Right), align: Some(s::Align::Right),
markup: Some(s::Markup::Pango), markup: Some(s::Markup::Pango),
short_text: None, short_text: None,

@ -15,6 +15,7 @@
//! The date `swayrbar` module. //! The date `swayrbar` module.
use crate::bar::config;
use crate::bar::module::BarModuleFn; use crate::bar::module::BarModuleFn;
use crate::fmt_replace::fmt_replace; use crate::fmt_replace::fmt_replace;
use std::cell::RefCell; use std::cell::RefCell;
@ -25,18 +26,18 @@ use sysinfo::ProcessorExt;
use sysinfo::SystemExt; use sysinfo::SystemExt;
pub struct BarModuleSysInfo { pub struct BarModuleSysInfo {
pub instance: String, config: config::ModuleConfig,
system: RefCell<si::System>, system: RefCell<si::System>,
} }
struct Updater { struct OnceRefresher {
cpu: Once, cpu: Once,
memory: Once, memory: Once,
} }
impl Updater { impl OnceRefresher {
fn new() -> Updater { fn new() -> OnceRefresher {
Updater { OnceRefresher {
cpu: Once::new(), cpu: Once::new(),
memory: Once::new(), memory: Once::new(),
} }
@ -51,15 +52,15 @@ impl Updater {
} }
} }
fn get_cpu_usage(sys: &RefCell<si::System>, upd: &Updater) -> f32 { fn get_cpu_usage(sys: &RefCell<si::System>, upd: &OnceRefresher) -> f32 {
upd.refresh_cpu(sys); upd.refresh_cpu(sys);
sys.borrow().global_processor_info().cpu_usage() sys.borrow().global_processor_info().cpu_usage()
} }
fn get_memory_usage(sys: &RefCell<si::System>, upd: &Updater) -> f64 { fn get_memory_usage(sys: &RefCell<si::System>, upd: &OnceRefresher) -> f64 {
upd.refresh_memory(sys); upd.refresh_memory(sys);
let sys = sys.borrow(); let sys = sys.borrow();
sys.used_memory() as f64 * 100 as f64 / sys.total_memory() as f64 sys.used_memory() as f64 * 100_f64 / sys.total_memory() as f64
} }
#[derive(Debug)] #[derive(Debug)]
@ -72,7 +73,7 @@ enum LoadAvg {
fn get_load_average( fn get_load_average(
sys: &RefCell<si::System>, sys: &RefCell<si::System>,
avg: LoadAvg, avg: LoadAvg,
upd: &Updater, upd: &OnceRefresher,
) -> f64 { ) -> f64 {
upd.refresh_cpu(sys); upd.refresh_cpu(sys);
let load_avg = sys.borrow().load_average(); let load_avg = sys.borrow().load_average();
@ -84,28 +85,27 @@ fn get_load_average(
} }
impl BarModuleFn for BarModuleSysInfo { impl BarModuleFn for BarModuleSysInfo {
fn init() -> Box<dyn BarModuleFn> { fn create(config: config::ModuleConfig) -> Box<dyn BarModuleFn> {
Box::new(BarModuleSysInfo { Box::new(BarModuleSysInfo {
instance: "0".to_string(), config,
system: RefCell::new(si::System::new_all()), system: RefCell::new(si::System::new_all()),
}) })
} }
fn name() -> String { fn name() -> &'static str {
String::from("sysinfo") "sysinfo"
} }
fn instance(&self) -> String { fn instance(&self) -> &str {
self.instance.clone() &self.config.instance
} }
fn build(&self) -> s::Block { fn build(&self) -> s::Block {
let fmt = "💻 CPU: {cpu_usage:{:4.1}}% Mem: {mem_usage:{:4.1}}% Load: {load_avg_1:{:4.2}} / {load_avg_5:{:4.2}} / {load_avg_15:{:4.2}}"; let updater = OnceRefresher::new();
let updater = Updater::new();
s::Block { s::Block {
name: Some(Self::name()), name: Some(Self::name().to_owned()),
instance: Some(self.instance.clone()), instance: Some(self.config.instance.clone()),
full_text: fmt_replace!(fmt, true, { full_text: fmt_replace!(&self.config.format, self.config.html_escape, {
"cpu_usage" => get_cpu_usage(&self.system, &updater), "cpu_usage" => get_cpu_usage(&self.system, &updater),
"mem_usage" => get_memory_usage(&self.system, &updater), "mem_usage" => get_memory_usage(&self.system, &updater),
"load_avg_1" => get_load_average(&self.system, "load_avg_1" => get_load_average(&self.system,
@ -131,4 +131,12 @@ impl BarModuleFn for BarModuleSysInfo {
separator_block_width: None, separator_block_width: None,
} }
} }
fn default_config(instance: String) -> config::ModuleConfig {
config::ModuleConfig {
module_type: "sysinfo".to_owned(),
instance,
format: "💻 CPU: {cpu_usage:{:4.1}}% Mem: {mem_usage:{:4.1}}% Load: {load_avg_1:{:4.2}} / {load_avg_5:{:4.2}} / {load_avg_15:{:4.2}}".to_owned(),
html_escape: true }
}
} }

@ -15,6 +15,7 @@
//! The window `swayrbar` module. //! The window `swayrbar` module.
use crate::bar::config;
use crate::bar::module::BarModuleFn; use crate::bar::module::BarModuleFn;
use crate::fmt_replace::fmt_replace; use crate::fmt_replace::fmt_replace;
use crate::ipc; use crate::ipc;
@ -22,40 +23,48 @@ use crate::ipc::NodeMethods;
use swaybar_types as s; use swaybar_types as s;
pub struct BarModuleWindow { pub struct BarModuleWindow {
pub instance: String, config: config::ModuleConfig,
} }
impl BarModuleFn for BarModuleWindow { impl BarModuleFn for BarModuleWindow {
fn init() -> Box<dyn BarModuleFn> { fn create(config: config::ModuleConfig) -> Box<dyn BarModuleFn> {
Box::new(BarModuleWindow { Box::new(BarModuleWindow { config })
instance: "0".to_string(), }
})
fn default_config(instance: String) -> config::ModuleConfig {
config::ModuleConfig {
module_type: Self::name().to_owned(),
instance,
format: "🪟 {title} — {app_name}".to_owned(),
html_escape: true,
}
} }
fn name() -> String { fn name() -> &'static str {
String::from("window") "window"
} }
fn instance(&self) -> String { fn instance(&self) -> &str {
self.instance.clone() &self.config.instance
} }
fn build(&self) -> s::Block { fn build(&self) -> s::Block {
let fmt = "🪟 {title} — {app_name}";
let root = ipc::get_root_node(false); let root = ipc::get_root_node(false);
let focused_win = root let focused_win = root
.iter() .iter()
.find(|n| n.focused && n.get_type() == ipc::Type::Window); .find(|n| n.focused && n.get_type() == ipc::Type::Window);
let text = match focused_win { let text = match focused_win {
Some(win) => fmt_replace!(&fmt, false, { Some(win) => {
fmt_replace!(&self.config.format, self.config.html_escape, {
"title" |"name" => win.get_name(), "title" |"name" => win.get_name(),
"app_name" => win.get_app_name(), "app_name" => win.get_app_name(),
}), })
}
None => String::new(), None => String::new(),
}; };
s::Block { s::Block {
name: Some(Self::name()), name: Some(Self::name().to_owned()),
instance: Some(self.instance.clone()), instance: Some(self.config.instance.clone()),
full_text: text, full_text: text,
align: Some(s::Align::Left), align: Some(s::Align::Left),
markup: Some(s::Markup::Pango), markup: Some(s::Markup::Pango),

@ -34,7 +34,7 @@ pub fn maybe_html_escape(do_it: bool, text: String) -> String {
} }
macro_rules! fmt_replace { macro_rules! fmt_replace {
( $fmt_str:expr, $html_escape:ident, ( $fmt_str:expr, $html_escape:expr,
{ $( $($pat:pat)|+ => $exp:expr, )+ } { $( $($pat:pat)|+ => $exp:expr, )+ }
) => { ) => {
$crate::fmt_replace::PLACEHOLDER_RX $crate::fmt_replace::PLACEHOLDER_RX

Loading…
Cancel
Save