// 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"), "/examples/icon.png"); let event_loop = EventLoopBuilder::new().build(); let tray_menu = Menu::new(); let quit_i = MenuItem::new("Quit", true, None); tray_menu.append_items(&[ &PredefinedMenuItem::about( None, Some(AboutMetadata { name: Some("tao".to_string()), copyright: Some("Copyright tao".to_string()), ..Default::default() }), ), &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| { // We add delay of 16 ms (60fps) to event_loop to reduce cpu load. // This can be removed to allow ControlFlow::Poll to poll on each cpu cycle // Alternatively, you can set ControlFlow::Wait or use TrayIconEvent::set_event_handler, // see https://github.com/tauri-apps/tray-icon/issues/83#issuecomment-1697773065 *control_flow = ControlFlow::WaitUntil( std::time::Instant::now() + std::time::Duration::from_millis(16), ); 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:?}"); } if let Ok(event) = tray_channel.try_recv() { 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") }