#status-bar #macos #systray #ns-status-bar #sysbar

system_status_bar_macos

用于与 macOS 系统状态栏交互的库,或者更简单地说,用于使用 [NSStatusBar systemStatusBar]

4 个版本

0.1.3 2023 年 7 月 20 日
0.1.2 2023 年 7 月 20 日
0.1.1 2023 年 7 月 20 日
0.1.0 2023 年 7 月 20 日

#68macOS 和 iOS API

每月 23 次下载

MIT/Apache

34KB
530

system_status_bar_macos

用于与 macOS 系统状态栏交互的库,或者更简单地说,用于使用 [NSStatusBar systemStatusBar]

screenshot

示例 1: Hello, World!

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();
}

没有异步运行时

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, |_| { });
}

示例 2: 在状态栏显示 CPU 使用情况

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;
    }
}

没有异步运行时

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()));
    });
}

示例 3: 显示菜单(可点击的,不可点击的,并具有子菜单)

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();
}

没有异步运行时

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, |_| { });
}

示例 4: 更新菜单

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;
    }
}

没有异步运行时

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),
        ]));
    });
}

示例 5: 中断事件循环

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();
}

没有异步运行时

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();
}

许可: MIT OR Apache-2.0

依赖项

~0–2.7MB
~57K SLoC