Compare commits

...

3 Commits

Author SHA1 Message Date
00079662df Added power module 2025-06-07 16:15:56 -07:00
c2eee03ac2 Trimmed progress display 2025-06-07 16:15:34 -07:00
eba6f977ec Code clean up 2025-06-07 16:15:17 -07:00
5 changed files with 164 additions and 22 deletions

View File

@@ -1,7 +1,4 @@
use std::fs::File;
// use std::path::Path;
// use std::io::prelude::*;
// use regex::Regex;
use std::io::{self, BufRead, BufReader};
use std::thread;
use std::time::Duration;
@@ -26,15 +23,15 @@ struct CpuTimes {
impl CpuTimes {
pub fn new() -> Self {
CpuTimes {
user: 0,
nice: 0,
system: 0,
idle: 0,
iowait: 0,
irq: 0,
softirq: 0,
steal: 0,
guest: 0,
user: 0,
nice: 0,
system: 0,
idle: 0,
iowait: 0,
irq: 0,
softirq: 0,
steal: 0,
guest: 0,
guest_nice: 0
}
}
@@ -98,15 +95,15 @@ impl UnibarModuleCpu {
if fields.len() >= 8 {
return Ok(CpuTimes {
user: fields[0],
nice: fields[1],
system: fields[2],
idle: fields[3],
iowait: fields[4],
irq: fields[5],
softirq: fields[6],
steal: fields[7],
guest: if fields.len() > 8 { fields[8] } else { 0 },
user: fields[0],
nice: fields[1],
system: fields[2],
idle: fields[3],
iowait: fields[4],
irq: fields[5],
softirq: fields[6],
steal: fields[7],
guest: if fields.len() > 8 { fields[8] } else { 0 },
guest_nice: if fields.len() > 9 { fields[9] } else { 0 },
});
}

View File

@@ -66,7 +66,7 @@ impl bar_modules::BarModuleActions for UnibarModuleMusic {
parts.push(format!("{}", self.current_stdout));
if self.opts.music_progress {
parts.push(format!("[{}]", self.progress_stdout));
parts.push(format!("[{}]", self.progress_stdout.trim()));
}
return format!("{}", parts.join(" "));

View File

@@ -0,0 +1,142 @@
use std::process::{Stdio, Command};
//use std::collections::HashMap;
use regex::Regex;
use crate::common;
use crate::bar_modules;
#[derive(Clone)]
pub struct UnibarModulePower {
opts: common::AppOptions,
power_info: PowerData,
}
#[derive(Debug, Default, Clone)]
struct PowerData {
charging: bool,
level: u64,
}
impl PowerData {
pub fn new() -> Self {
PowerData {
charging: true,
level: 100,
}
}
}
impl UnibarModulePower {
// --------------------
pub fn new(o :common::AppOptions) -> Self {
UnibarModulePower {
opts: o,
power_info: PowerData::new(),
}
}
}
impl bar_modules::BarModuleActions for UnibarModulePower {
// --------------------
fn generate_data(&mut self) {
// Following command is used to get power data:
// % upower -i /org/freedesktop/UPower/devices/DisplayDevice
//
// In UPower, the "display device" is a special object that represents the combined
// power status that should be shown in desktop environments.
//
// Purpose:
//
// It acts as a central point of information for the power icon displayed in your
// system's notification area or taskbar.
// Instead of desktop environments having to query all individual power sources,
// they can access this single "display device" to get a summary of the overall
// power status.
//
// Key characteristics:
//
// Composite device: It combines information from multiple power sources
// (like batteries, UPS) to provide a unified view.
// Object path: It has a dedicated object path, typically
// /org/freedesktop/UPower/devices/DisplayDevice.
// Properties: It exposes properties like Type, State, Percentage, TimeToEmpty,
// TimeToFull, and IconName to describe the device's status and
// icon representation.
// Dynamic Type: Unlike real devices, the Type of the display device can
// change (e.g., from Battery to UPS) depending on the current power situation.
//
// In essence, the "display device" simplifies power management for desktop environments
// by providing a convenient interface to show the relevant power information to the user.
//
let power_dump = Command::new("upower")
.arg("--dump")
.stdout(Stdio::piped())
.output()
.unwrap();
let power_str = String::from_utf8(power_dump.stdout).unwrap();
let lines: Vec<&str> = power_str.split('\n').map(|s| s.trim()).collect();
let mut found_device: bool = false;
// let devices: HashMap<String, HashMap<String, String>>::new();
// let cur_dev: HashMap<String, String>::new();
for line in lines {
if line.is_empty() { continue };
let dev_re = Regex::new(r"^Device:\s+(.*)").unwrap();
if let Some(caps) = dev_re.captures(line) {
if let Some((last, _els)) = &caps[1].split('/').collect::<Vec<_>>().split_last() {
if self.opts.debug {
println!("-----> Power dump - Device - {:#?}", last);
}
if last.to_string() == "DisplayDevice" {
found_device = true;
}
}
}
if found_device {
let level_re = Regex::new(r"^percentage:\s+(\d+)").unwrap();
if let Some(caps) = level_re.captures(line) {
self.power_info.level = caps[1].parse().unwrap_or(0);
if self.opts.debug {
println!("-----> Power dump - level - {:#?}", self.power_info.level);
}
}
let state_re = Regex::new(r"^state:\s+(\S+)").unwrap();
if let Some(caps) = state_re.captures(line) {
self.power_info.charging = caps[1].to_string() != "discharging";
if self.opts.debug {
println!("-----> Power dump - charging - {:#?}", self.power_info.charging);
}
}
}
// if self.opts.debug {
// println!("-----> Power dump {:#?}", line);
// }
}
}
// --------------------
fn get_content(&self) -> String {
// return format!("{}", parts.join(" "));
return format!("{:.0}%", self.power_info.level);
}
// --------------------
fn get_icon(&self) -> String {
match self.power_info.charging {
true => return "🔌".to_string(),
false => return "🔋".to_string()
}
}
}
impl bar_modules::BarModuleDebug for UnibarModulePower {
// --------------------
fn post_debug(&self) {
}
}

View File

@@ -22,3 +22,4 @@ pub mod bar_module_music;
pub mod bar_module_network;
pub mod bar_module_memory;
pub mod bar_module_cpu;
pub mod bar_module_power;

View File

@@ -57,6 +57,7 @@ impl Unibar {
Box::new(bar_modules::bar_module_music::UnibarModuleMusic::new(self.opts.clone())),
Box::new(bar_modules::bar_module_memory::UnibarModuleMemory::new(self.opts.clone())),
Box::new(bar_modules::bar_module_cpu::UnibarModuleCpu::new(self.opts.clone())),
Box::new(bar_modules::bar_module_power::UnibarModulePower::new(self.opts.clone())),
Box::new(bar_modules::bar_module_network::UnibarModuleNetwork::new(self.opts.clone())),
Box::new(bar_modules::bar_module_weather::UnibarModuleWeather::new(self.opts.clone())),
];
@@ -88,6 +89,7 @@ impl Unibar {
Box::new(bar_modules::bar_module_memory::UnibarModuleMemory::new(self.opts.clone())),
Box::new(bar_modules::bar_module_network::UnibarModuleNetwork::new(self.opts.clone())),
Box::new(bar_modules::bar_module_cpu::UnibarModuleCpu::new(self.opts.clone())),
Box::new(bar_modules::bar_module_power::UnibarModulePower::new(self.opts.clone())),
];
for md in bar_modules_debugged {
md.post_debug();