Library for interacting with the system's status bar for macOS, or more simply, the one for using [NSStatusBar systemStatusBar]
.
![screenshot](https://private-user-images.githubusercontent.com/10735/254837478-b3e2787b-77fe-4dd5-a560-6633042d5066.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk1NjA4MzMsIm5iZiI6MTczOTU2MDUzMywicGF0aCI6Ii8xMDczNS8yNTQ4Mzc0NzgtYjNlMjc4N2ItNzdmZS00ZGQ1LWE1NjAtNjYzMzA0MmQ1MDY2LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjE0VDE5MTUzM1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTkwNTI4NTdmYjJmMzM3M2Q2YTAxNDZkMWU4NDQ0Yjc2OWJmNmRlYWVkYzI0MWQ1YjM3M2E3OGY2MTZlZjM2YTEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.AgWz70AYV-_D-asfRVOB2ZvcuskIYUbicjE67CIZyA8)
use system_status_bar_macos::*;
use tokio::*;
#[tokio::main(flavor = "current_thread")]
async fn main() {
let _status_item = StatusItem::new("HELLO_WORLD", Menu::new(vec![]));
spawn(async_infinite_event_loop(time::sleep)).await.unwrap();
}
without async runtime:
use std::sync::mpsc::channel;
use system_status_bar_macos::*;
fn main() {
let _status_item = StatusItem::new("HELLO_WORLD", Menu::new(vec![]));
let (_sender, receiver) = channel::<()>();
sync_infinite_event_loop(receiver, |_| { });
}
use system_status_bar_macos::*;
use sysinfo::*;
use tokio::*;
#[tokio::main(flavor = "current_thread")]
async fn main() {
spawn(async_infinite_event_loop(time::sleep));
let mut status_item = StatusItem::new("", Menu::new(vec![]));
loop {
let mut sys = System::new_all();
sys.refresh_all();
status_item.set_title(format!("CPU Usage: {:3.2}%", sys.global_cpu_info().cpu_usage()));
time::sleep(time::Duration::from_secs(1)).await;
}
}
without async runtime:
use std::{
sync::mpsc::channel,
thread::*,
time::*,
cell::*,
};
use system_status_bar_macos::*;
use sysinfo::*;
fn main() {
let (sender, receiver) = channel::<()>();
// thread that sends command to event loop
spawn(move || {
loop {
sender.send(()).unwrap();
sleep(Duration::from_secs(1));
}
});
let status_item = RefCell::new(StatusItem::new("", Menu::new(vec![])));
sync_infinite_event_loop(receiver, move |_| {
let mut sys = System::new_all();
sys.refresh_all();
status_item.borrow_mut().set_title(format!("CPU Usage: {:3.2}%", sys.global_cpu_info().cpu_usage()));
});
}
use system_status_bar_macos::*;
use tokio::*;
#[tokio::main(flavor = "current_thread")]
async fn main() {
let event_loop = spawn(async_infinite_event_loop(time::sleep));
let _status_item = StatusItem::new("TITLE", Menu::new(vec![
MenuItem::new("UNCLICKABLE MENU", None, None),
MenuItem::new("CLICKABLE MENU", Some(Box::new(|| {
println!("clicked!");
})), None),
MenuItem::new("PARENT MENU", None, Some(Menu::new(vec![
MenuItem::new("SUBMENU", None, None),
MenuItem::new("SUBMENU", None, None),
]))),
]));
event_loop.await.unwrap();
}
without async runtime:
use std::sync::mpsc::channel;
use system_status_bar_macos::*;
fn main() {
let _status_item = StatusItem::new("TITLE", Menu::new(vec![
MenuItem::new("UNCLICKABLE MENU", None, None),
MenuItem::new("CLICKABLE MENU", Some(Box::new(|| {
println!("clicked!");
})), None),
MenuItem::new("PARENT MENU", None, Some(Menu::new(vec![
MenuItem::new("SUBMENU", None, None),
MenuItem::new("SUBMENU", None, None),
]))),
]));
let (_sender, receiver) = channel::<()>();
sync_infinite_event_loop(receiver, |_| { });
}
use system_status_bar_macos::*;
use sysinfo::*;
use tokio::*;
#[tokio::main(flavor = "current_thread")]
async fn main() {
spawn(async_infinite_event_loop(time::sleep));
let mut status_item = StatusItem::new("", Menu::new(vec![]));
loop {
let mut sys = System::new_all();
sys.refresh_all();
status_item.set_title(format!("CPU Usage: {:3.2}%", sys.global_cpu_info().cpu_usage()));
status_item.set_menu(Menu::new(vec![
MenuItem::new(format!("Used {} bytes memory", sys.used_memory()), None, None),
MenuItem::new(format!("Used {} bytes swap", sys.used_swap()), None, None),
]));
time::sleep(time::Duration::from_secs(1)).await;
}
}
without async runtime
use std::{
sync::mpsc::channel,
thread::*,
time::*,
cell::*,
};
use system_status_bar_macos::*;
use sysinfo::*;
fn main() {
let (sender, receiver) = channel::<()>();
// thread that sends command to event loop
spawn(move || {
loop {
sender.send(()).unwrap();
sleep(Duration::from_secs(1));
}
});
let status_item = RefCell::new(StatusItem::new("", Menu::new(vec![])));
sync_infinite_event_loop(receiver, move |_| {
let mut sys = System::new_all();
sys.refresh_all();
status_item.borrow_mut().set_title(format!("CPU Usage: {:3.2}%", sys.global_cpu_info().cpu_usage()));
status_item.borrow_mut().set_menu(Menu::new(vec![
MenuItem::new(format!("Used {} bytes memory", sys.used_memory()), None, None),
MenuItem::new(format!("Used {} bytes swap", sys.used_swap()), None, None),
]));
});
}
use system_status_bar_macos::*;
use tokio::*;
#[tokio::main(flavor = "current_thread")]
async fn main() {
let (event_loop, terminator) = async_event_loop(time::sleep);
let event_loop = spawn(event_loop);
let _status_item = StatusItem::new("EXAMPLE", Menu::new(vec![]));
time::sleep(time::Duration::from_secs(10)).await;
terminator.terminate(); // break event loop
event_loop.await.unwrap();
}
without async runtime
use std::{
sync::mpsc::channel,
thread::*,
time::*,
};
use system_status_bar_macos::*;
fn main() {
let _status_item = StatusItem::new("EXAMPLE", Menu::new(vec![]));
let (_sender, receiver) = channel::<()>();
let (event_loop, terminator) = sync_event_loop(receiver, |_| { });
spawn(move || {
sleep(Duration::from_secs(10));
terminator.terminate(); // break event loop
});
event_loop();
}
License: MIT OR Apache-2.0