From 7f4a453cc87b586430768914a75e0c5592d578de Mon Sep 17 00:00:00 2001 From: Kingtous Date: Sat, 10 Dec 2022 10:57:21 +0800 Subject: [PATCH] opt: listen status for system tray on Linux --- Cargo.lock | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++--- Cargo.toml | 1 + src/tray.rs | 42 ++++++++++++++++++++-------- 3 files changed, 108 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 237369d2c..469828592 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2007,7 +2007,7 @@ version = "0.15.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "140b2f5378256527150350a8346dbdb08fadc13453a7a2d73aecd5fab3c402a7" dependencies = [ - "gio-sys", + "gio-sys 0.15.10", "glib-sys 0.15.10", "gobject-sys 0.15.10", "libc", @@ -2022,7 +2022,7 @@ checksum = "32e7a08c1e8f06f4177fb7e51a777b8c1689f743a7bc11ea91d44d2226073a88" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", - "gio-sys", + "gio-sys 0.15.10", "glib-sys 0.15.10", "gobject-sys 0.15.10", "libc", @@ -2078,7 +2078,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-io", - "gio-sys", + "gio-sys 0.15.10", "glib 0.15.12", "libc", "once_cell", @@ -2098,6 +2098,19 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "gio-sys" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9b693b8e39d042a95547fc258a7b07349b1f0b48f4b2fa3108ba3c51c0b5229" +dependencies = [ + "glib-sys 0.16.3", + "gobject-sys 0.16.3", + "libc", + "system-deps 6.0.3", + "winapi 0.3.9", +] + [[package]] name = "glib" version = "0.10.3" @@ -2137,6 +2150,28 @@ dependencies = [ "thiserror", ] +[[package]] +name = "glib" +version = "0.16.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cd04d150a2c63e6779f43aec7e04f5374252479b7bed5f45146d9c0e821f161" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys 0.16.3", + "glib-macros 0.16.3", + "glib-sys 0.16.3", + "gobject-sys 0.16.3", + "libc", + "once_cell", + "smallvec", + "thiserror", +] + [[package]] name = "glib-macros" version = "0.10.1" @@ -2168,6 +2203,21 @@ dependencies = [ "syn", ] +[[package]] +name = "glib-macros" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e084807350b01348b6d9dbabb724d1a0bb987f47a2c85de200e98e12e30733bf" +dependencies = [ + "anyhow", + "heck 0.4.0", + "proc-macro-crate 1.2.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "glib-sys" version = "0.10.1" @@ -2188,6 +2238,16 @@ dependencies = [ "system-deps 6.0.3", ] +[[package]] +name = "glib-sys" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61a4f46316d06bfa33a7ac22df6f0524c8be58e3db2d9ca99ccb1f357b62a65" +dependencies = [ + "libc", + "system-deps 6.0.3", +] + [[package]] name = "glob" version = "0.3.0" @@ -2216,6 +2276,17 @@ dependencies = [ "system-deps 6.0.3", ] +[[package]] +name = "gobject-sys" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3520bb9c07ae2a12c7f2fbb24d4efc11231c8146a86956413fb1a79bb760a0f1" +dependencies = [ + "glib-sys 0.16.3", + "libc", + "system-deps 6.0.3", +] + [[package]] name = "gstreamer" version = "0.16.7" @@ -2382,7 +2453,7 @@ dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", "gdk-sys", - "gio-sys", + "gio-sys 0.15.10", "glib-sys 0.15.10", "gobject-sys 0.15.10", "libc", @@ -4522,6 +4593,7 @@ dependencies = [ "flexi_logger", "flutter_rust_bridge", "flutter_rust_bridge_codegen", + "glib 0.16.5", "gtk", "hbb_common", "hound", diff --git a/Cargo.toml b/Cargo.toml index a783b1abe..2be48eca9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -69,6 +69,7 @@ url = { version = "2.1", features = ["serde"] } reqwest = { version = "0.11", features = ["blocking", "json", "rustls-tls"], default-features=false } chrono = "0.4.23" cidr-utils = "0.5.9" +glib = "0.16.5" [target.'cfg(not(any(target_os = "android", target_os = "linux")))'.dependencies] cpal = "0.13.5" diff --git a/src/tray.rs b/src/tray.rs index 3658739a4..b73e46301 100644 --- a/src/tray.rs +++ b/src/tray.rs @@ -88,6 +88,9 @@ pub fn start_tray() { /// This function will block current execution, show the tray icon and handle events. #[cfg(target_os = "linux")] pub fn start_tray() { + use std::time::Duration; + + use glib::{clone, Continue}; use gtk::traits::{GtkMenuItemExt, MenuShellExt, WidgetExt}; info!("configuring tray"); @@ -106,9 +109,9 @@ pub fn start_tray() { crate::client::translate("Stop service".to_owned()) }; let menu_item_service = gtk::MenuItem::with_label(label.as_str()); - menu_item_service.connect_activate(move |item| { + menu_item_service.connect_activate(move |_| { let _lock = crate::ui_interface::SENDER.lock().unwrap(); - update_tray_service_item(item); + change_service_state(); }); menu.append(&menu_item_service); // show tray item @@ -116,6 +119,16 @@ pub fn start_tray() { appindicator.set_menu(&mut menu); // start event loop info!("Setting tray event loop"); + // check the connection status for every second + glib::timeout_add_local( + Duration::from_secs(1), + clone!(@strong menu_item_service as item => move || { + let _lock = crate::ui_interface::SENDER.lock().unwrap(); + update_tray_service_item(&item); + // continue to trigger the next status check + Continue(true) + }), + ); gtk::main(); } else { error!("Tray process exit now"); @@ -123,17 +136,25 @@ pub fn start_tray() { } #[cfg(target_os = "linux")] +fn change_service_state() { + if is_service_stoped() { + debug!("Now try to start service"); + crate::ipc::set_option("stop-service", ""); + } else { + debug!("Now try to stop service"); + crate::ipc::set_option("stop-service", "Y"); + } +} + +#[cfg(target_os = "linux")] +#[inline] fn update_tray_service_item(item: >k::MenuItem) { use gtk::traits::GtkMenuItemExt; if is_service_stoped() { - debug!("Now try to start service"); - item.set_label(&crate::client::translate("Stop service".to_owned())); - crate::ipc::set_option("stop-service", ""); - } else { - debug!("Now try to stop service"); item.set_label(&crate::client::translate("Start Service".to_owned())); - crate::ipc::set_option("stop-service", "Y"); + } else { + item.set_label(&crate::client::translate("Stop service".to_owned())); } } @@ -189,10 +210,10 @@ pub fn make_tray() { match mode { dark_light::Mode::Dark => { icon_path = "mac-tray-light.png"; - }, + } dark_light::Mode::Light => { icon_path = "mac-tray-dark.png"; - }, + } } if let Ok(mut tray) = TrayItem::new(&crate::get_app_name(), icon_path) { tray.add_label(&format!( @@ -211,4 +232,3 @@ pub fn make_tray() { } } } -