rustdesk/src/tray.rs

108 lines
3.6 KiB
Rust
Raw Normal View History

2023-02-09 21:28:42 +08:00
/// Start a tray icon in Linux
///
/// [Block]
/// This function will block current execution, show the tray icon and handle events.
#[cfg(target_os = "linux")]
pub fn start_tray() {}
#[cfg(any(target_os = "macos", target_os = "windows"))]
2023-02-09 21:28:42 +08:00
pub fn start_tray() {
use hbb_common::{allow_err, log};
allow_err!(make_tray());
}
#[cfg(any(target_os = "macos", target_os = "windows"))]
2023-02-09 21:28:42 +08:00
pub fn make_tray() -> hbb_common::ResultType<()> {
// https://github.com/tauri-apps/tray-icon/blob/dev/examples/tao.rs
use hbb_common::anyhow::Context;
use tao::event_loop::{ControlFlow, EventLoopBuilder};
2023-02-23 20:01:50 +08:00
use tray_icon::{
menu::{Menu, MenuEvent, MenuItem},
ClickEvent, TrayEvent, TrayIconBuilder,
};
let icon;
#[cfg(target_os = "macos")]
{
let mode = dark_light::detect();
const LIGHT: &[u8] = include_bytes!("../res/mac-tray-light-x2.png");
const DARK: &[u8] = include_bytes!("../res/mac-tray-dark-x2.png");
icon = match mode {
dark_light::Mode::Dark => LIGHT,
_ => DARK,
};
}
#[cfg(target_os = "windows")]
{
icon = include_bytes!("../res/tray-icon.ico");
}
2023-02-09 21:28:42 +08:00
let (icon_rgba, icon_width, icon_height) = {
let image = image::load_from_memory(icon)
.context("Failed to open icon path")?
.into_rgba8();
let (width, height) = image.dimensions();
let rgba = image.into_raw();
(rgba, width, height)
};
let icon = tray_icon::icon::Icon::from_rgba(icon_rgba, icon_width, icon_height)
.context("Failed to open icon")?;
2022-11-18 18:36:25 +08:00
2023-02-09 21:28:42 +08:00
let event_loop = EventLoopBuilder::new().build();
2023-02-23 20:01:50 +08:00
let tray_menu = Menu::new();
let quit_i = MenuItem::new(crate::client::translate("Exit".to_owned()), true, None);
tray_menu.append_items(&[&quit_i]);
2023-02-09 21:28:42 +08:00
let _tray_icon = Some(
TrayIconBuilder::new()
2023-02-23 20:01:50 +08:00
.with_menu(Box::new(tray_menu))
2023-02-09 21:28:42 +08:00
.with_tooltip(format!(
"{} {}",
crate::get_app_name(),
crate::lang::translate("Service is running".to_owned())
))
.with_icon(icon)
.build()?,
);
2023-02-23 20:01:50 +08:00
let menu_channel = MenuEvent::receiver();
2023-02-09 21:28:42 +08:00
let tray_channel = TrayEvent::receiver();
let mut docker_hiden = false;
event_loop.run(move |_event, _, control_flow| {
if !docker_hiden {
#[cfg(target_os = "macos")]
2023-02-09 21:28:42 +08:00
crate::platform::macos::hide_dock();
docker_hiden = true;
2022-11-18 18:36:25 +08:00
}
2023-02-23 19:28:30 +08:00
*control_flow = ControlFlow::Wait;
2023-02-09 21:28:42 +08:00
2023-02-23 20:01:50 +08:00
if let Ok(event) = menu_channel.try_recv() {
if event.id == quit_i.id() {
#[cfg(target_os = "macos")]
2023-02-23 20:01:50 +08:00
crate::platform::macos::uninstall(false);
#[cfg(any(target_os = "linux", target_os = "windows"))]
crate::platform::uninstall_service(false).ok();
2023-02-23 20:01:50 +08:00
}
println!("{event:?}");
}
if let Ok(event) = tray_channel.try_recv() {
if event.event == ClickEvent::Double {
#[cfg(target_os = "macos")]
2023-02-23 20:01:50 +08:00
crate::platform::macos::handle_application_should_open_untitled_file();
#[cfg(target_os = "windows")]
{
use std::os::windows::process::CommandExt;
use std::process::Command;
Command::new("cmd")
.arg("/c")
.arg("start rustdesk://")
.creation_flags(winapi::um::winbase::CREATE_NO_WINDOW)
.spawn()
.ok();
}
2023-02-23 20:01:50 +08:00
}
2023-02-09 21:28:42 +08:00
}
});
2022-11-18 18:36:25 +08:00
}