2 个不稳定版本
0.2.0 | 2024 年 4 月 20 日 |
---|---|
0.1.0 | 2023 年 12 月 29 日 |
#179 in GUI
每月 3,876 次下载
65KB
1.5K SLoC
Betrayer
Betrayer 是一个用于创建托盘图标的库,专门设计用于与 winit
和其他现有库良好集成。
示例
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
enum Signal {
Profile(u32),
Open,
Quit
}
fn main() -> Result<()> {
let event_loop = EventLoopBuilder::with_user_event()
.build()?;
let mut selected = 0;
let tray = TrayIconBuilder::new()
.with_icon(Icon::from_rgba(vec![255u8; 32 * 32 * 4], 32, 32)?)
.with_tooltip("Demo System Tray")
.with_menu(build_menu(selected))
// with `winit` feature:
.build_event_loop(&event_loop, |e| Some(e))?;
// without:
//.build({
// let proxy = event_loop.create_proxy();
// move |s| {let _ = proxy.send_event(s); }
//})?;
event_loop.set_control_flow(ControlFlow::Wait);
event_loop.run(|event, evtl| {
match event {
Event::UserEvent(event) => {
println!("tray event: {:?}", event);
if let TrayEvent::Menu(signal) = event {
match signal {
Signal::Profile(i) => {
if selected != i {
selected = i;
tray.set_tooltip(format!("Active Profile: {selected}"));
tray.set_menu(build_menu(selected));
}
},
Signal::Open => {}
Signal::Quit => evtl.exit()
}
}
}
_ => {}
}
})?;
Ok(())
}
fn build_menu(selected: u32) -> Menu<Signal> {
Menu::new([
MenuItem::menu("Profiles", (0..5)
.map(|i| MenuItem::check_button(format!("Profile {}", i + 1), Signal::Profile(i),selected == i))),
MenuItem::separator(),
MenuItem::button("Open", Signal::Open),
MenuItem::button("Quit", Signal::Quit)
])
}
平台说明
在 Windows 和 Mac 上,此库使用平台原生工具包,因此需要在同一线程上运行事件循环。
在 Linux 上,此库使用 org.kde.StatusNotifierItem
DBus API,因此需要支持此 API 的桌面环境。Ubuntu 可能需要 libayatana-appindicator
包。
此库将启动自己的线程来处理 DBus 通信,因此不需要额外的事件循环。
待办事项
通用
- 支持更改图标
- 独立模式,控制主线程
- 更多菜单元素
- 更多托盘选项
Windows
- 当任务栏重启时重新创建托盘
Linux
- 支持在现有的异步执行器上创建托盘,以避免启动线程
- 优雅地处理 DBus 配置更改
- 使用操作系统管理的临时文件以避免在恐慌时泄漏图标?
Mac
- 添加图标支持
- 一般更多测试,我对 Mac 开发一无所知,并在几乎无法工作的 VM 中随意创作。
依赖项
~0–47MB
~759K SLoC