Merge branch 'rustdesk:master' into add/scam_warning
This commit is contained in:
		
						commit
						19e49a7de7
					
				| @ -404,7 +404,7 @@ pub fn core_main() -> Option<Vec<String>> { | ||||
|             crate::ui_interface::start_option_status_sync(); | ||||
|         } else if args[0] == "--cm-no-ui" { | ||||
|             #[cfg(feature = "flutter")] | ||||
|             #[cfg(not(any(target_os = "android", target_os = "ios")))] | ||||
|             #[cfg(not(any(target_os = "android", target_os = "ios", target_os = "windows")))] | ||||
|             crate::flutter::connection_manager::start_cm_no_ui(); | ||||
|             return None; | ||||
|         } else { | ||||
|  | ||||
| @ -157,6 +157,7 @@ fn handle_config_options(config_options: HashMap<String, String>) { | ||||
|     Config::set_options(options); | ||||
| } | ||||
| 
 | ||||
| #[allow(unused)] | ||||
| #[cfg(not(any(target_os = "ios")))] | ||||
| pub fn is_pro() -> bool { | ||||
|     PRO.lock().unwrap().clone() | ||||
|  | ||||
							
								
								
									
										12
									
								
								src/ipc.rs
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/ipc.rs
									
									
									
									
									
								
							| @ -234,6 +234,8 @@ pub enum Data { | ||||
|     #[cfg(windows)] | ||||
|     SyncWinCpuUsage(Option<f64>), | ||||
|     FileTransferLog(String), | ||||
|     #[cfg(any(windows, target_os = "macos"))] | ||||
|     ControlledSessionCount(usize), | ||||
| } | ||||
| 
 | ||||
| #[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(not(any(target_os = "android", target_os = "ios")))] | ||||
|         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 | ||||
|             ); | ||||
|         } | ||||
|         _ => {} | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										62
									
								
								src/lang.rs
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								src/lang.rs
									
									
									
									
									
								
							| @ -1,5 +1,7 @@ | ||||
| use hbb_common::regex::Regex; | ||||
| use std::ops::Deref; | ||||
| 
 | ||||
| mod ar; | ||||
| mod ca; | ||||
| mod cn; | ||||
| mod cs; | ||||
| @ -17,6 +19,7 @@ mod it; | ||||
| mod ja; | ||||
| mod ko; | ||||
| mod kz; | ||||
| mod lt; | ||||
| mod nl; | ||||
| mod pl; | ||||
| mod ptbr; | ||||
| @ -32,8 +35,6 @@ mod tr; | ||||
| mod tw; | ||||
| mod ua; | ||||
| mod vn; | ||||
| mod lt; | ||||
| mod ar; | ||||
| 
 | ||||
| pub const LANGS: &[(&str, &str)] = &[ | ||||
|     ("en", "English"), | ||||
| @ -137,16 +138,67 @@ pub fn translate_locale(name: String, locale: &str) -> String { | ||||
|         "ar" => ar::T.deref(), | ||||
|         _ => en::T.deref(), | ||||
|     }; | ||||
|     let (name, placeholder_value) = extract_placeholder(&name); | ||||
|     let replace = |s: &&str| { | ||||
|         let mut s = s.to_string(); | ||||
|         if let Some(value) = placeholder_value.as_ref() { | ||||
|             s = s.replace("{}", &value); | ||||
|         } | ||||
|         s | ||||
|     }; | ||||
|     if let Some(v) = m.get(&name as &str) { | ||||
|         if v.is_empty() { | ||||
|             if lang != "en" { | ||||
|                 if let Some(v) = en::T.get(&name as &str) { | ||||
|                     return v.to_string(); | ||||
|                     return replace(v); | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             return v.to_string(); | ||||
|             return replace(v); | ||||
|         } | ||||
|     } | ||||
|     name | ||||
|     replace(&name.as_str()) | ||||
| } | ||||
| 
 | ||||
| // Matching pattern is {}
 | ||||
| // Write {value} in the UI and {} in the translation file
 | ||||
| //
 | ||||
| // Example:
 | ||||
| // Write in the UI: translate("There are {24} hours in a day")
 | ||||
| // Write in the translation file: ("There are {} hours in a day", "{} hours make up a day")
 | ||||
| fn extract_placeholder(input: &str) -> (String, Option<String>) { | ||||
|     if let Ok(re) = Regex::new(r#"\{(.*?)\}"#) { | ||||
|         if let Some(captures) = re.captures(input) { | ||||
|             if let Some(inner_match) = captures.get(1) { | ||||
|                 let name = re.replace(input, "{}").to_string(); | ||||
|                 let value = inner_match.as_str().to_string(); | ||||
|                 return (name, Some(value)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     (input.to_string(), None) | ||||
| } | ||||
| 
 | ||||
| mod test { | ||||
|     #[test] | ||||
|     fn test_extract_placeholders() { | ||||
|         use super::extract_placeholder as f; | ||||
| 
 | ||||
|         assert_eq!(f(""), ("".to_string(), None)); | ||||
|         assert_eq!( | ||||
|             f("{3} sessions"), | ||||
|             ("{} sessions".to_string(), Some("3".to_string())) | ||||
|         ); | ||||
|         assert_eq!(f(" } { "), (" } { ".to_string(), None)); | ||||
|         // Allow empty value
 | ||||
|         assert_eq!( | ||||
|             f("{} sessions"), | ||||
|             ("{} sessions".to_string(), Some("".to_string())) | ||||
|         ); | ||||
|         // Match only the first one
 | ||||
|         assert_eq!( | ||||
|             f("{2} times {4} makes {8}"), | ||||
|             ("{} times {4} makes {8}".to_string(), Some("2".to_string())) | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", "安装成功!"), | ||||
|         ("Installation failed!", "安装失败!"), | ||||
|         ("Reverse mouse wheel", "鼠标滚轮反向"), | ||||
|         ("{} sessions", "{}个会话"), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -543,6 +543,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("HSV Color", "HSV-Farbe"), | ||||
|         ("Installation Successful!", "Installation erfolgreich!"), | ||||
|         ("Installation failed!", "Installation fehlgeschlagen!"), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("Reverse mouse wheel", "Mausrad rückwärts drehen"), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", "Instalación exitosa"), | ||||
|         ("Installation failed!", "La instalación ha fallado"), | ||||
|         ("Reverse mouse wheel", "Invertir rueda del ratón"), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -541,8 +541,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Change Color", "Ganti warna"), | ||||
|         ("Primary Color", "Warna utama"), | ||||
|         ("HSV Color", "Warna HSV"), | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("Installation Successful!", "Instalasi berhasil!"), | ||||
|         ("Installation failed!", "Instalasi gagal!"), | ||||
|         ("Reverse mouse wheel", "Balikkan arah scroll mouse!"), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", "Installazione completata"), | ||||
|         ("Installation failed!", "Installazione fallita"), | ||||
|         ("Reverse mouse wheel", "Rotella mouse inversa"), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -528,21 +528,22 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Move tab to new window", "Przenieś zakładkę do nowego okna"), | ||||
|         ("Can not be empty", "Nie może być puste"), | ||||
|         ("Already exists", "Już istnieje"), | ||||
|         ("Change Password", ""), | ||||
|         ("Refresh Password", ""), | ||||
|         ("ID", ""), | ||||
|         ("Grid View", ""), | ||||
|         ("List View", ""), | ||||
|         ("Select", ""), | ||||
|         ("Toggle Tags", ""), | ||||
|         ("pull_ab_failed_tip", ""), | ||||
|         ("push_ab_failed_tip", ""), | ||||
|         ("synced_peer_readded_tip", ""), | ||||
|         ("Change Color", ""), | ||||
|         ("Primary Color", ""), | ||||
|         ("HSV Color", ""), | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("Change Password", "Zmień hasło"), | ||||
|         ("Refresh Password", "Odśwież hasło"), | ||||
|         ("ID", "ID"), | ||||
|         ("Grid View", "Widok siatki"), | ||||
|         ("List View", "Widok listy"), | ||||
|         ("Select", "Wybierz"), | ||||
|         ("Toggle Tags", "Przełącz tagi"), | ||||
|         ("pull_ab_failed_tip", "Aktualizacja książki adresowej nie powiodła się"), | ||||
|         ("push_ab_failed_tip", "Nie udało się zsynchronizować książki adresowej z serwerem"), | ||||
|         ("synced_peer_readded_tip", "Urządzenia, które były obecne w ostatnich sesjach, zostaną ponownie dodane do książki adresowej"), | ||||
|         ("Change Color", "Zmień kolor"), | ||||
|         ("Primary Color", "Kolor podstawowy"), | ||||
|         ("HSV Color", "Kolor HSV"), | ||||
|         ("Installation Successful!", "Instalacja zakończona!"), | ||||
|         ("Installation failed!", "Instalacja nie powiodła się"), | ||||
|         ("Reverse mouse wheel", "Odwróć rolkę myszki"), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", "Установка выполнена успешно!"), | ||||
|         ("Installation failed!", "Установка не выполнена!"), | ||||
|         ("Reverse mouse wheel", "Реверсировать колесо мыши"), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -544,5 +544,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = | ||||
|         ("Installation Successful!", ""), | ||||
|         ("Installation failed!", ""), | ||||
|         ("Reverse mouse wheel", ""), | ||||
|         ("{} sessions", ""), | ||||
|     ].iter().cloned().collect(); | ||||
| } | ||||
|  | ||||
| @ -1351,6 +1351,12 @@ impl Connection { | ||||
|                     log::error!("ipc to connection manager exit: {}", err); | ||||
|                 } | ||||
|             }); | ||||
|             #[cfg(all(windows, feature = "flutter"))] | ||||
|             std::thread::spawn(|| { | ||||
|                 if crate::is_server() && !crate::check_process("--tray", false) { | ||||
|                     crate::platform::run_as_user(vec!["--tray"]).ok(); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -2406,7 +2412,10 @@ async fn start_ipc( | ||||
|     if let Ok(s) = crate::ipc::connect(1000, "_cm").await { | ||||
|         stream = Some(s); | ||||
|     } else { | ||||
|         #[allow(unused_mut)] | ||||
|         #[allow(unused_assignments)] | ||||
|         let mut args = vec!["--cm"]; | ||||
|         #[cfg(not(windows))] | ||||
|         if crate::hbbs_http::sync::is_pro() && password::hide_cm() { | ||||
|             args.push("--hide"); | ||||
|         } | ||||
|  | ||||
							
								
								
									
										102
									
								
								src/tray.rs
									
									
									
									
									
								
							
							
						
						
									
										102
									
								
								src/tray.rs
									
									
									
									
									
								
							| @ -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() { | ||||
|     use hbb_common::{allow_err, log}; | ||||
|     allow_err!(make_tray()); | ||||
| } | ||||
| 
 | ||||
| @ -40,31 +46,44 @@ pub fn make_tray() -> hbb_common::ResultType<()> { | ||||
|     let event_loop = EventLoopBuilder::new().build(); | ||||
| 
 | ||||
|     let tray_menu = Menu::new(); | ||||
|     let quit_i = MenuItem::new(crate::client::translate("Exit".to_owned()), true, None); | ||||
|     let open_i = MenuItem::new(crate::client::translate("Open".to_owned()), true, None); | ||||
|     let quit_i = MenuItem::new(translate("Exit".to_owned()), true, None); | ||||
|     let open_i = MenuItem::new(translate("Open".to_owned()), true, None); | ||||
|     tray_menu.append_items(&[&open_i, &quit_i]); | ||||
| 
 | ||||
|     let _tray_icon = Some( | ||||
|         TrayIconBuilder::new() | ||||
|             .with_menu(Box::new(tray_menu)) | ||||
|             .with_tooltip(format!( | ||||
|     let tooltip = |count: usize| { | ||||
|         if count == 0 { | ||||
|             format!( | ||||
|                 "{} {}", | ||||
|                 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) | ||||
|             .build()?, | ||||
|     ); | ||||
|     let tray_icon = Arc::new(Mutex::new(tray_icon)); | ||||
| 
 | ||||
|     let menu_channel = MenuEvent::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 open_func = move || { | ||||
|         if cfg!(not(feature = "flutter")) | ||||
|         { | ||||
|         crate::run_me::<&str>(vec![]).ok(); | ||||
|         return; | ||||
|         if cfg!(not(feature = "flutter")) { | ||||
|             crate::run_me::<&str>(vec![]).ok(); | ||||
|             return; | ||||
|         } | ||||
|         #[cfg(target_os = "macos")] | ||||
|         crate::platform::macos::handle_application_should_open_untitled_file(); | ||||
| @ -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| { | ||||
|         if !docker_hiden { | ||||
|             #[cfg(target_os = "macos")] | ||||
| @ -121,5 +145,55 @@ pub fn make_tray() -> hbb_common::ResultType<()> { | ||||
|                 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; | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user