#icons #tray #menu #api-bindings

betrayer

与 winit 集成良好的简单托盘图标

2 个不稳定版本

0.2.0 2024 年 4 月 20 日
0.1.0 2023 年 12 月 29 日

#179 in GUI

Download history 1421/week @ 2024-05-04 2718/week @ 2024-05-11 2165/week @ 2024-05-18 1823/week @ 2024-05-25 1288/week @ 2024-06-01 1812/week @ 2024-06-08 1259/week @ 2024-06-15 1037/week @ 2024-06-22 1032/week @ 2024-06-29 967/week @ 2024-07-06 902/week @ 2024-07-13 947/week @ 2024-07-20 1096/week @ 2024-07-27 1020/week @ 2024-08-03 889/week @ 2024-08-10 711/week @ 2024-08-17

每月 3,876 次下载

MIT 许可证

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

平台说明

WindowsMac 上,此库使用平台原生工具包,因此需要在同一线程上运行事件循环。

Linux 上,此库使用 org.kde.StatusNotifierItem DBus API,因此需要支持此 API 的桌面环境。Ubuntu 可能需要 libayatana-appindicator 包。

此库将启动自己的线程来处理 DBus 通信,因此不需要额外的事件循环。

待办事项

通用

  • 支持更改图标
  • 独立模式,控制主线程
  • 更多菜单元素
  • 更多托盘选项

Windows

  • 当任务栏重启时重新创建托盘

Linux

  • 支持在现有的异步执行器上创建托盘,以避免启动线程
  • 优雅地处理 DBus 配置更改
  • 使用操作系统管理的临时文件以避免在恐慌时泄漏图标?

Mac

  • 添加图标支持
  • 一般更多测试,我对 Mac 开发一无所知,并在几乎无法工作的 VM 中随意创作。

依赖项

~0–47MB
~759K SLoC