78 lines
2.6 KiB
Rust
78 lines
2.6 KiB
Rust
|
|
// Copyright 2022-2022 Tauri Programme within The Commons Conservancy
|
||
|
|
// SPDX-License-Identifier: Apache-2.0
|
||
|
|
// SPDX-License-Identifier: MIT
|
||
|
|
|
||
|
|
#![allow(unused)]
|
||
|
|
|
||
|
|
use tao::event_loop::{ControlFlow, EventLoopBuilder};
|
||
|
|
use tray_icon::{
|
||
|
|
menu::{AboutMetadata, Menu, MenuEvent, MenuItem, PredefinedMenuItem},
|
||
|
|
TrayIconBuilder, TrayIconEvent,
|
||
|
|
};
|
||
|
|
|
||
|
|
fn main() {
|
||
|
|
let path = concat!(env!("CARGO_MANIFEST_DIR"), "/icon.png");
|
||
|
|
|
||
|
|
let event_loop = EventLoopBuilder::new().build();
|
||
|
|
|
||
|
|
let tray_menu = Menu::new();
|
||
|
|
|
||
|
|
let test = MenuItem::new("Test", true, None);
|
||
|
|
let quit_i = MenuItem::new("Quit", true, None);
|
||
|
|
tray_menu.append_items(&[&test, &PredefinedMenuItem::separator(), &quit_i]);
|
||
|
|
|
||
|
|
let mut tray_icon = None;
|
||
|
|
|
||
|
|
let menu_channel = MenuEvent::receiver();
|
||
|
|
let tray_channel = TrayIconEvent::receiver();
|
||
|
|
|
||
|
|
event_loop.run(move |event, _, control_flow| {
|
||
|
|
*control_flow = ControlFlow::Wait;
|
||
|
|
|
||
|
|
if let tao::event::Event::NewEvents(tao::event::StartCause::Init) = event {
|
||
|
|
let icon = load_icon(std::path::Path::new(path));
|
||
|
|
|
||
|
|
// We create the icon once the event loop is actually running
|
||
|
|
// to prevent issues like https://github.com/tauri-apps/tray-icon/issues/90
|
||
|
|
tray_icon = Some(
|
||
|
|
TrayIconBuilder::new()
|
||
|
|
.with_menu(Box::new(tray_menu.clone()))
|
||
|
|
.with_tooltip("tao - awesome windowing lib")
|
||
|
|
.with_icon(icon)
|
||
|
|
.build()
|
||
|
|
.unwrap(),
|
||
|
|
);
|
||
|
|
|
||
|
|
// We have to request a redraw here to have the icon actually show up.
|
||
|
|
// Tao only exposes a redraw method on the Window so we use core-foundation directly.
|
||
|
|
#[cfg(target_os = "macos")]
|
||
|
|
unsafe {
|
||
|
|
use core_foundation::runloop::{CFRunLoopGetMain, CFRunLoopWakeUp};
|
||
|
|
|
||
|
|
let rl = CFRunLoopGetMain();
|
||
|
|
CFRunLoopWakeUp(rl);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if let Ok(event) = menu_channel.try_recv() {
|
||
|
|
if event.id == quit_i.id() {
|
||
|
|
tray_icon.take();
|
||
|
|
*control_flow = ControlFlow::Exit;
|
||
|
|
}
|
||
|
|
println!("{event:?}");
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
fn load_icon(path: &std::path::Path) -> tray_icon::Icon {
|
||
|
|
let (icon_rgba, icon_width, icon_height) = {
|
||
|
|
let image = image::open(path)
|
||
|
|
.expect("Failed to open icon path")
|
||
|
|
.into_rgba8();
|
||
|
|
let (width, height) = image.dimensions();
|
||
|
|
let rgba = image.into_raw();
|
||
|
|
(rgba, width, height)
|
||
|
|
};
|
||
|
|
tray_icon::Icon::from_rgba(icon_rgba, icon_width, icon_height).expect("Failed to open icon")
|
||
|
|
}
|