windows/mac tray tooltip show controlled session count

* ubuntu 22.04 can't see tooltip

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages 2023-09-09 09:45:05 +08:00
parent 45b0e7dc01
commit c254eebea2
37 changed files with 135 additions and 14 deletions

View File

@ -234,6 +234,8 @@ pub enum Data {
#[cfg(windows)] #[cfg(windows)]
SyncWinCpuUsage(Option<f64>), SyncWinCpuUsage(Option<f64>),
FileTransferLog(String), FileTransferLog(String),
#[cfg(any(windows, target_os = "macos"))]
ControlledSessionCount(usize),
} }
#[tokio::main(flavor = "current_thread")] #[tokio::main(flavor = "current_thread")]
@ -482,6 +484,16 @@ async fn handle(data: Data, stream: &mut Connection) {
#[cfg(all(feature = "flutter", feature = "plugin_framework"))] #[cfg(all(feature = "flutter", feature = "plugin_framework"))]
#[cfg(not(any(target_os = "android", target_os = "ios")))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
Data::Plugin(plugin) => crate::plugin::ipc::handle_plugin(plugin, stream).await, Data::Plugin(plugin) => crate::plugin::ipc::handle_plugin(plugin, stream).await,
#[cfg(any(windows, target_os = "macos"))]
Data::ControlledSessionCount(_) => {
allow_err!(
stream
.send(&Data::ControlledSessionCount(
crate::Connection::alive_conns().len()
))
.await
);
}
_ => {} _ => {}
} }
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", "安装成功!"), ("Installation Successful!", "安装成功!"),
("Installation failed!", "安装失败!"), ("Installation failed!", "安装失败!"),
("Reverse mouse wheel", "鼠标滚轮反向"), ("Reverse mouse wheel", "鼠标滚轮反向"),
("{} sessions", "{}个会话"),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", "Installation erfolgreich!"), ("Installation Successful!", "Installation erfolgreich!"),
("Installation failed!", "Installation fehlgeschlagen!"), ("Installation failed!", "Installation fehlgeschlagen!"),
("Reverse mouse wheel", "Mausrad rückwärts drehen"), ("Reverse mouse wheel", "Mausrad rückwärts drehen"),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", "Instalación exitosa"), ("Installation Successful!", "Instalación exitosa"),
("Installation failed!", "La instalación ha fallado"), ("Installation failed!", "La instalación ha fallado"),
("Reverse mouse wheel", "Invertir rueda del ratón"), ("Reverse mouse wheel", "Invertir rueda del ratón"),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", "Instalasi berhasil!"), ("Installation Successful!", "Instalasi berhasil!"),
("Installation failed!", "Instalasi gagal!"), ("Installation failed!", "Instalasi gagal!"),
("Reverse mouse wheel", "Balikkan arah scroll mouse!"), ("Reverse mouse wheel", "Balikkan arah scroll mouse!"),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", "Installazione completata"), ("Installation Successful!", "Installazione completata"),
("Installation failed!", "Installazione fallita"), ("Installation failed!", "Installazione fallita"),
("Reverse mouse wheel", "Rotella mouse inversa"), ("Reverse mouse wheel", "Rotella mouse inversa"),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", "Instalacja zakończona!"), ("Installation Successful!", "Instalacja zakończona!"),
("Installation failed!", "Instalacja nie powiodła się"), ("Installation failed!", "Instalacja nie powiodła się"),
("Reverse mouse wheel", "Odwróć rolkę myszki"), ("Reverse mouse wheel", "Odwróć rolkę myszki"),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", "Установка выполнена успешно!"), ("Installation Successful!", "Установка выполнена успешно!"),
("Installation failed!", "Установка не выполнена!"), ("Installation failed!", "Установка не выполнена!"),
("Reverse mouse wheel", "Реверсировать колесо мыши"), ("Reverse mouse wheel", "Реверсировать колесо мыши"),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Installation Successful!", ""), ("Installation Successful!", ""),
("Installation failed!", ""), ("Installation failed!", ""),
("Reverse mouse wheel", ""), ("Reverse mouse wheel", ""),
("{} sessions", ""),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -1,5 +1,11 @@
use crate::{client::translate, ipc::Data};
use hbb_common::{allow_err, log, tokio};
use std::{
sync::{Arc, Mutex},
time::Duration,
};
pub fn start_tray() { pub fn start_tray() {
use hbb_common::{allow_err, log};
allow_err!(make_tray()); allow_err!(make_tray());
} }
@ -40,29 +46,42 @@ pub fn make_tray() -> hbb_common::ResultType<()> {
let event_loop = EventLoopBuilder::new().build(); let event_loop = EventLoopBuilder::new().build();
let tray_menu = Menu::new(); let tray_menu = Menu::new();
let quit_i = MenuItem::new(crate::client::translate("Exit".to_owned()), true, None); let quit_i = MenuItem::new(translate("Exit".to_owned()), true, None);
let open_i = MenuItem::new(crate::client::translate("Open".to_owned()), true, None); let open_i = MenuItem::new(translate("Open".to_owned()), true, None);
tray_menu.append_items(&[&open_i, &quit_i]); tray_menu.append_items(&[&open_i, &quit_i]);
let tooltip = |count: usize| {
let _tray_icon = Some( if count == 0 {
TrayIconBuilder::new() format!(
.with_menu(Box::new(tray_menu))
.with_tooltip(format!(
"{} {}", "{} {}",
crate::get_app_name(), crate::get_app_name(),
crate::lang::translate("Service is running".to_owned()) translate("Service is running".to_owned()),
)) )
} else {
format!(
"{} - {}\n{}",
crate::get_app_name(),
translate("Ready".to_owned()),
translate("{".to_string() + &format!("{count}") + "} sessions"),
)
}
};
let tray_icon = Some(
TrayIconBuilder::new()
.with_menu(Box::new(tray_menu))
.with_tooltip(tooltip(0))
.with_icon(icon) .with_icon(icon)
.build()?, .build()?,
); );
let tray_icon = Arc::new(Mutex::new(tray_icon));
let menu_channel = MenuEvent::receiver(); let menu_channel = MenuEvent::receiver();
let tray_channel = TrayEvent::receiver(); let tray_channel = TrayEvent::receiver();
#[cfg(not(target_os = "linux"))]
let (ipc_sender, ipc_receiver) = std::sync::mpsc::channel::<Data>();
let mut docker_hiden = false; let mut docker_hiden = false;
let open_func = move || { let open_func = move || {
if cfg!(not(feature = "flutter")) if cfg!(not(feature = "flutter")) {
{
crate::run_me::<&str>(vec![]).ok(); crate::run_me::<&str>(vec![]).ok();
return; return;
} }
@ -89,6 +108,11 @@ pub fn make_tray() -> hbb_common::ResultType<()> {
} }
}; };
// ubuntu 22.04 can't see tooltip
#[cfg(not(target_os = "linux"))]
std::thread::spawn(move || {
start_query_session_count(ipc_sender.clone());
});
event_loop.run(move |_event, _, control_flow| { event_loop.run(move |_event, _, control_flow| {
if !docker_hiden { if !docker_hiden {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
@ -121,5 +145,55 @@ pub fn make_tray() -> hbb_common::ResultType<()> {
open_func(); open_func();
} }
} }
#[cfg(not(target_os = "linux"))]
if let Ok(data) = ipc_receiver.try_recv() {
match data {
Data::ControlledSessionCount(count) => {
tray_icon
.lock()
.unwrap()
.as_mut()
.map(|t| t.set_tooltip(Some(tooltip(count))));
}
_ => {}
}
}
}); });
} }
#[cfg(not(target_os = "linux"))]
#[tokio::main(flavor = "current_thread")]
async fn start_query_session_count(sender: std::sync::mpsc::Sender<Data>) {
let mut last_count = 0;
loop {
if let Ok(mut c) = crate::ipc::connect(1000, "").await {
let mut timer = tokio::time::interval(Duration::from_secs(1));
loop {
tokio::select! {
res = c.next() => {
match res {
Err(err) => {
log::error!("ipc connection closed: {}", err);
break;
}
Ok(Some(Data::ControlledSessionCount(count))) => {
if count != last_count {
last_count = count;
sender.send(Data::ControlledSessionCount(count)).ok();
}
}
_ => {}
}
}
_ = timer.tick() => {
c.send(&Data::ControlledSessionCount(0)).await.ok();
}
}
}
}
hbb_common::sleep(1.).await;
}
}