You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
95 lines
2.9 KiB
Rust
95 lines
2.9 KiB
Rust
#[macro_use]
|
|
mod err;
|
|
mod pack;
|
|
|
|
pub use err::*;
|
|
|
|
use libappindicator::*;
|
|
use gtk::prelude::*;
|
|
use pack::*;
|
|
use std::cell::RefCell;
|
|
use std::time::{Duration, Instant};
|
|
use sysinfo::*;
|
|
use include_dir::{include_dir, Dir};
|
|
|
|
static EMBEDDED_RES: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/res");
|
|
|
|
thread_local! {
|
|
static SYSTEM: RefCell<System> = RefCell::new(System::new_all());
|
|
}
|
|
|
|
fn update_frame_time() -> Duration {
|
|
return SYSTEM.with(|system| {
|
|
let mut system = system.borrow_mut();
|
|
system.refresh_cpu_specifics(CpuRefreshKind::new().with_cpu_usage());
|
|
let num_cpus = system.cpus().len();
|
|
let load: f32 = system.cpus().iter()
|
|
.map(|cpu| cpu.cpu_usage() / num_cpus as f32)
|
|
.sum();
|
|
return Duration::from_millis(10 + 2 * load as u64); // min 10 (~100Hz), max 210 (~5Hz)
|
|
})
|
|
}
|
|
|
|
fn init_indicator(icon_pack: &IconPack) -> AppIndicator {
|
|
let mut indicator = AppIndicator::new("parrotd", "");
|
|
indicator.set_icon_theme_path(icon_pack.pack_path());
|
|
indicator.set_status(AppIndicatorStatus::Active);
|
|
let mut m = gtk::Menu::new();
|
|
let mi = gtk::CheckMenuItem::with_label("Exit");
|
|
mi.connect_activate(|_| {
|
|
gtk::main_quit();
|
|
});
|
|
m.append(&mi);
|
|
let mi = gtk::CheckMenuItem::with_label("Parrotd by PeterCxy");
|
|
m.append(&mi);
|
|
indicator.set_menu(&mut m);
|
|
m.show_all();
|
|
return indicator;
|
|
}
|
|
|
|
fn main() {
|
|
gtk::init().unwrap();
|
|
|
|
let tmp_dir = tempfile::tempdir();
|
|
|
|
let _tmp_dir = tmp_dir.as_ref();
|
|
let res_dir = std::env::var("PARROTD_RESOURCE_DIR").unwrap_or_else(|_| {
|
|
let tmp_dir = _tmp_dir.expect("Cannot create temporary directory");
|
|
EMBEDDED_RES.extract(tmp_dir.path()).unwrap();
|
|
tmp_dir.path().to_str().unwrap().to_string()
|
|
});
|
|
let pack_name = std::env::var("PARROTD_ICON_PACK").unwrap_or("parrot".to_owned());
|
|
let variant = PackVariant::parse(
|
|
&std::env::var("PARROTD_VARIANT").unwrap_or("dark".to_owned())).expect("Invalid variant name");
|
|
|
|
let mut icon_pack = IconPack::new(res_dir, &pack_name, variant).unwrap();
|
|
let mut indicator = init_indicator(&icon_pack);
|
|
|
|
// Animation task
|
|
let mut last_update = Instant::now();
|
|
let mut last_update_frame_time = Instant::now();
|
|
let mut frame_time = update_frame_time();
|
|
glib::timeout_add_local(Duration::from_millis(1) /* we need granularity */, move || {
|
|
let now = Instant::now();
|
|
|
|
if now - last_update_frame_time >= Duration::from_millis(100) {
|
|
// Update frame time
|
|
frame_time = update_frame_time();
|
|
last_update_frame_time = now;
|
|
}
|
|
|
|
if now - last_update >= frame_time {
|
|
// Update animation
|
|
indicator.set_icon(icon_pack.next_icon_path());
|
|
last_update = now;
|
|
}
|
|
Continue(true)
|
|
});
|
|
|
|
gtk::main();
|
|
|
|
if let Ok(tmp_dir) = tmp_dir {
|
|
tmp_dir.close().unwrap();
|
|
}
|
|
}
|