#[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::*; thread_local! { static SYSTEM: RefCell = 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("I'm a parrot"); mi.connect_activate(|_| { gtk::main_quit(); }); m.append(&mi); indicator.set_menu(&mut m); m.show_all(); return indicator; } fn main() { gtk::init().unwrap(); let mut icon_pack = IconPack::new("./res", "parrot", PackVariant::Dark).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(); }