2023-02-09 21:28:42 +08:00
|
|
|
pub fn start_tray() {
|
|
|
|
use hbb_common::{allow_err, log};
|
|
|
|
allow_err!(make_tray());
|
|
|
|
}
|
|
|
|
|
|
|
|
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},
|
2023-06-07 23:08:50 +08:00
|
|
|
TrayEvent, TrayIconBuilder,
|
2023-02-23 20:01:50 +08:00
|
|
|
};
|
2023-06-05 20:27:48 +08:00
|
|
|
let icon;
|
2023-06-25 00:45:33 +08:00
|
|
|
#[cfg(target_os = "macos")]
|
2023-06-05 20:27:48 +08:00
|
|
|
{
|
|
|
|
let mode = dark_light::detect();
|
2023-06-25 00:45:33 +08:00
|
|
|
const LIGHT: &[u8] = include_bytes!("../res/mac-tray-light-x2.png");
|
|
|
|
const DARK: &[u8] = include_bytes!("../res/mac-tray-dark-x2.png");
|
2023-06-05 20:27:48 +08:00
|
|
|
icon = match mode {
|
|
|
|
dark_light::Mode::Dark => LIGHT,
|
|
|
|
_ => DARK,
|
|
|
|
};
|
|
|
|
}
|
2023-06-25 00:45:33 +08:00
|
|
|
#[cfg(not(target_os = "macos"))]
|
2023-06-05 20:27:48 +08:00
|
|
|
{
|
|
|
|
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);
|
2023-06-06 01:47:02 +08:00
|
|
|
let open_i = MenuItem::new(crate::client::translate("Open".to_owned()), true, None);
|
|
|
|
tray_menu.append_items(&[&open_i, &quit_i]);
|
2023-02-23 20:01:50 +08:00
|
|
|
|
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;
|
|
|
|
|
2023-06-06 01:47:02 +08:00
|
|
|
let open_func = move || {
|
2023-07-01 16:21:36 +08:00
|
|
|
if cfg!(not(feature = "flutter"))
|
2023-06-30 22:13:16 +08:00
|
|
|
{
|
|
|
|
crate::run_me::<&str>(vec![]).ok();
|
|
|
|
return;
|
|
|
|
}
|
2023-06-06 01:47:02 +08:00
|
|
|
#[cfg(target_os = "macos")]
|
|
|
|
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-06-07 23:08:50 +08:00
|
|
|
#[cfg(target_os = "linux")]
|
2023-06-10 18:24:03 +08:00
|
|
|
if !std::process::Command::new("xdg-open")
|
|
|
|
.arg("rustdesk://")
|
|
|
|
.spawn()
|
|
|
|
.is_ok()
|
|
|
|
{
|
|
|
|
crate::run_me::<&str>(vec![]).ok();
|
|
|
|
}
|
2023-06-06 01:47:02 +08:00
|
|
|
};
|
|
|
|
|
2023-02-09 21:28:42 +08:00
|
|
|
event_loop.run(move |_event, _, control_flow| {
|
|
|
|
if !docker_hiden {
|
2023-06-05 20:27:48 +08:00
|
|
|
#[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-06-06 01:47:02 +08:00
|
|
|
*control_flow = ControlFlow::WaitUntil(
|
|
|
|
std::time::Instant::now() + std::time::Duration::from_millis(100),
|
|
|
|
);
|
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() {
|
2023-07-02 11:22:52 +08:00
|
|
|
/* failed in windows, seems no permission to check system process
|
2023-06-10 22:26:30 +08:00
|
|
|
if !crate::check_process("--server", false) {
|
|
|
|
*control_flow = ControlFlow::Exit;
|
|
|
|
return;
|
|
|
|
}
|
2023-07-02 11:22:52 +08:00
|
|
|
*/
|
2023-08-12 15:17:00 +08:00
|
|
|
if !crate::platform::uninstall_service(false) {
|
|
|
|
*control_flow = ControlFlow::Exit;
|
|
|
|
}
|
2023-06-06 01:47:02 +08:00
|
|
|
} else if event.id == open_i.id() {
|
|
|
|
open_func();
|
2023-02-23 20:01:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-07 23:08:50 +08:00
|
|
|
if let Ok(_event) = tray_channel.try_recv() {
|
2023-06-06 01:47:02 +08:00
|
|
|
#[cfg(target_os = "windows")]
|
2023-06-07 23:08:50 +08:00
|
|
|
if _event.event == tray_icon::ClickEvent::Left {
|
2023-06-06 01:47:02 +08:00
|
|
|
open_func();
|
2023-02-23 20:01:50 +08:00
|
|
|
}
|
2023-02-09 21:28:42 +08:00
|
|
|
}
|
|
|
|
});
|
2022-11-18 18:36:25 +08:00
|
|
|
}
|