This commit is contained in:
gallant 2023-10-18 15:28:44 -05:00
commit 439b46b0fc
7 changed files with 553 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

320
Cargo.lock generated Normal file
View file

@ -0,0 +1,320 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bumpalo"
version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
[[package]]
name = "cc"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
dependencies = [
"libc",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-targets",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
[[package]]
name = "iana-time-zone"
version = "0.1.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "js-sys"
version = "0.3.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
[[package]]
name = "log"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "mach"
version = "0.3.3"
dependencies = [
"libc",
]
[[package]]
name = "mach"
version = "0.3.3"
source = "git+https://github.com/gallantcrusader/mach#d29ede89c7ac20d3342ad7027ffefb9e1e37d1c3"
dependencies = [
"libc",
]
[[package]]
name = "num-traits"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "proc-macro2"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
[[package]]
name = "sketchybar-rs"
version = "0.1.0"
dependencies = [
"cc",
"libc",
"mach 0.3.3 (git+https://github.com/gallantcrusader/mach)",
]
[[package]]
name = "sktchrs"
version = "0.1.0"
dependencies = [
"chrono",
"lazy_static",
"libc",
"mach 0.3.3",
"sketchybar-rs",
]
[[package]]
name = "syn"
version = "2.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "wasm-bindgen"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
[[package]]
name = "windows-core"
version = "0.51.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"

13
Cargo.toml Normal file
View file

@ -0,0 +1,13 @@
[package]
name = "sktchrs"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
chrono = { version = "0.4.31", features = ["clock"] }
lazy_static = "1.4.0"
libc = "0.2.149"
mach = {path = "../mach/"}
sketchybar-rs = {path = "../sketchybar-rs/"}

BIN
helper2 Executable file

Binary file not shown.

20
src/clock.rs Normal file
View file

@ -0,0 +1,20 @@
use chrono::prelude::*;
pub struct Clock {
pub command: String,
}
impl Clock {
pub fn new() -> Self {
Clock {
command: String::new(),
}
}
pub fn update(&mut self) {
let t: DateTime<Utc> = Utc::now();
let time = t.format("%H:%M");
let date = t.format("%a %d. %b");
self.command = format!("--set calendar icon=\"{}\" label=\"{}\"", date, time);
}
}

126
src/cpu.rs Normal file
View file

@ -0,0 +1,126 @@
use libc::mach_host_self;
use mach::message::mach_msg_type_number_t;
use std::io;
use std::str;
use mach::kern_return::KERN_SUCCESS;
use mach::host_info::*;
use mach::machine::*;
static TOPPROC: &str = "/bin/ps -Aceo pid,pcpu,comm -r";
static FILTER_PATTERN: &str = "com.apple.";
#[derive()]
pub struct CPU {
pub host: mach::mach_types::host_t,
pub count: mach_msg_type_number_t,
pub load: host_cpu_load_info_data_t,
pub prev_load: host_cpu_load_info_data_t,
pub has_prev_load: bool,
pub command: String,
}
impl CPU {
pub fn new() -> Self {
CPU {
host: unsafe{ mach_host_self()},
count: HOST_CPU_LOAD_INFO_COUNT,
load: host_cpu_load_info_data_t {
cpu_ticks: [0; CPU_STATE_MAX as usize],
},
prev_load: host_cpu_load_info_data_t {
cpu_ticks: [0; CPU_STATE_MAX as usize],
},
has_prev_load: false,
command: String::new(),
}
}
pub fn update(&mut self) {
let error = unsafe {
libc::host_statistics(
self.host,
HOST_CPU_LOAD_INFO as i32,
&self.load as *const _ as host_info_t,
&self.count as *const _ as *mut mach_msg_type_number_t,
)
};
if error != KERN_SUCCESS {
println!("Error: Could not read CPU host statistics.");
return;
}
if self.has_prev_load {
let delta_user = self.load.cpu_ticks[CPU_STATE_USER as usize]
- self.prev_load.cpu_ticks[CPU_STATE_USER as usize];
let delta_system = self.load.cpu_ticks[CPU_STATE_SYSTEM as usize]
- self.prev_load.cpu_ticks[CPU_STATE_SYSTEM as usize];
let delta_idle = self.load.cpu_ticks[CPU_STATE_IDLE as usize]
- self.prev_load.cpu_ticks[CPU_STATE_IDLE as usize];
let user_perc = delta_user as f64 / (delta_system as f64 + delta_user as f64 + delta_idle as f64);
let sys_perc = delta_system as f64 / (delta_system as f64 + delta_user as f64 + delta_idle as f64);
let total_perc = user_perc + sys_perc;
let top_proc = match get_top_process(TOPPROC, FILTER_PATTERN) {
Ok(process) => process,
Err(_) => String::new(),
};
let color = if total_perc >= 0.7 {
getenv("RED")
} else if total_perc >= 0.3 {
getenv("ORANGE")
} else if total_perc >= 0.1 {
getenv("YELLOW")
} else {
getenv("LABEL_COLOR")
};
self.command = format!(
"--push cpu.sys {:.2} --push cpu.user {:.2} --set cpu.percent label={:.0}% label.color={} --set cpu.top label=\"{}\"",
sys_perc,
user_perc,
total_perc * 100.0,
color,
top_proc
);
} else {
self.command = String::new();
}
self.prev_load = self.load;
self.has_prev_load = true;
}
}
fn get_top_process(command: &str, filter_pattern: &str) -> Result<String, io::Error> {
let output = std::process::Command::new("sh")
.arg("-c")
.arg(command)
.output()?;
let output_str = String::from_utf8_lossy(&output.stdout);
let top_process = output_str.lines().nth(2).unwrap_or("");
let top_process = top_process
.splitn(2, filter_pattern)
.last()
.unwrap_or(top_process);
Ok(top_process.to_string())
}
fn getenv(env_var: &str) -> String {
match std::env::var(env_var) {
Ok(val) => val,
Err(_) => String::new(),
}
}

73
src/main.rs Normal file
View file

@ -0,0 +1,73 @@
mod cpu;
mod clock;
use std::env;
use std::process;
use cpu::CPU;
use clock::Clock;
use std::sync::Mutex;
use std::sync::Arc;
use lazy_static::lazy_static;
lazy_static!{
static ref G_CPU: Arc<Mutex<CPU>> = Arc::new(Mutex::new(CPU::new()));
static ref G_CLOCK: Arc<Mutex<Clock>> = Arc::new(Mutex::new(Clock::new()));
}
pub extern "C" fn handler(env: sketchybar_rs::Env) {
// Environment variables passed from sketchybar can be accessed as seen below
let name = env.get_v_for_c("NAME");
let sender = env.get_v_for_c("SENDER");
let info = env.get_v_for_c("INFO");
let selected = env.get_v_for_c("SELECTED");
if selected.len() > 0 {
// Space items
let width = if selected == "true" {
"0"
} else {
"dynamic"
};
let command = format!(
"--animate tanh 20 --set {} icon.highlight={} label.width={}",
name,
selected,
width
);
println!("{}", name);
sketchybar_rs::message(&command).unwrap();
} else if sender == "front_app_switched" {
// front_app item
let command = format!("--set {} label=\"{}\"", name, info);
sketchybar_rs::message(&command).unwrap();
} else if sender == "routine" || sender == "forced" {
// CPU and Clock routine updates
let mut cpu = G_CPU.lock().unwrap();
let mut clock = G_CLOCK.lock().unwrap();
cpu.update();
clock.update();
if !cpu.command.is_empty() && !clock.command.is_empty() {
let command = format!("{} {}", cpu.command, clock.command);
sketchybar_rs::message(&command);
}
drop(cpu);
drop(clock);
}
}
fn main() {
let mut args = env::args();
let program_name = args.next().unwrap();
if args.len() < 1 {
eprintln!("Usage: {} <bootstrap name>", program_name);
process::exit(1);
}
let bootstrap_name = args.next().unwrap();
sketchybar_rs::server_begin(handler, &bootstrap_name);
}