refactor: improve tray icon/menu implementation.
This commit is contained in:
parent
559b0e843c
commit
0a4c10de34
|
@ -28,7 +28,6 @@ fn main() {
|
|||
winuser::ShowWindow(wincon::GetConsoleWindow(), winuser::SW_HIDE);
|
||||
}
|
||||
|
||||
|
||||
std::env::set_var("RUST_LOG", "trace");
|
||||
pretty_env_logger::init();
|
||||
let checker = TrayApp::new();
|
||||
|
|
109
src/tray.rs
109
src/tray.rs
|
@ -12,7 +12,10 @@ use tray_icon::{
|
|||
menu::{Menu, MenuEvent, MenuItem},
|
||||
TrayIcon, TrayIconBuilder,
|
||||
};
|
||||
use winapi::um::{wincon::GetConsoleWindow, winuser::{self, ShowWindow, SW_SHOW}};
|
||||
use winapi::um::{
|
||||
wincon::GetConsoleWindow,
|
||||
winuser::{self, ShowWindow, SW_SHOW},
|
||||
};
|
||||
|
||||
const BATTERY_UPDATE_INTERVAL: std::time::Duration = std::time::Duration::from_secs(60);
|
||||
const DEVICE_FETCH_INTERVAL: std::time::Duration = std::time::Duration::from_secs(5);
|
||||
|
@ -39,12 +42,59 @@ impl MemoryDevice {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct TrayInner {
|
||||
tray_icon: Rc<Mutex<Option<TrayIcon>>>,
|
||||
console_state: Arc<Mutex<bool>>,
|
||||
menu_items: Arc<Mutex<Vec<MenuItem>>>,
|
||||
}
|
||||
|
||||
impl TrayInner {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
tray_icon: Rc::new(Mutex::new(None)),
|
||||
console_state: Arc::new(Mutex::new(false)),
|
||||
menu_items: Arc::new(Mutex::new(Vec::new())),
|
||||
}
|
||||
}
|
||||
|
||||
fn create_menu(&self) -> Menu {
|
||||
let tray_menu = Menu::new();
|
||||
|
||||
let show_console_item = MenuItem::new("Show Log Window", true, None);
|
||||
let quit_item = MenuItem::new("Exit", true, None);
|
||||
|
||||
let mut menu_items = self.menu_items.lock().unwrap();
|
||||
menu_items.push(show_console_item);
|
||||
menu_items.push(quit_item);
|
||||
|
||||
tray_menu
|
||||
.append_items(&[&menu_items[0], &menu_items[1]])
|
||||
.unwrap();
|
||||
tray_menu
|
||||
}
|
||||
|
||||
fn build_tray(
|
||||
tray_icon: &Rc<Mutex<Option<TrayIcon>>>,
|
||||
tray_menu: &Menu,
|
||||
icon: tray_icon::Icon,
|
||||
) {
|
||||
let tray_builder = TrayIconBuilder::new()
|
||||
.with_menu(Box::new(tray_menu.clone()))
|
||||
.with_tooltip("Service is running")
|
||||
.with_icon(icon)
|
||||
.build();
|
||||
|
||||
match tray_builder {
|
||||
Ok(tray) => *tray_icon.lock().unwrap() = Some(tray),
|
||||
Err(err) => error!("Failed to create tray icon: {}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TrayApp {
|
||||
device_manager: Arc<Mutex<DeviceManager>>,
|
||||
devices: Arc<Mutex<HashMap<u32, MemoryDevice>>>,
|
||||
tray_icon: Rc<Mutex<Option<TrayIcon>>>,
|
||||
console_state: Arc<Mutex<bool>>,
|
||||
menu_items: Arc<Mutex<Vec<MenuItem>>>
|
||||
tray_inner: TrayInner,
|
||||
}
|
||||
|
||||
impl TrayApp {
|
||||
|
@ -52,16 +102,14 @@ impl TrayApp {
|
|||
Self {
|
||||
device_manager: Arc::new(Mutex::new(DeviceManager::new())),
|
||||
devices: Arc::new(Mutex::new(HashMap::new())),
|
||||
tray_icon: Rc::new(Mutex::new(None)),
|
||||
console_state: Arc::new(Mutex::new(false)),
|
||||
menu_items: Arc::new(Mutex::new(Vec::new()))
|
||||
tray_inner: TrayInner::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(&self) {
|
||||
let icon = Self::create_icon();
|
||||
let event_loop = EventLoopBuilder::new().build();
|
||||
let tray_menu = self.create_menu();
|
||||
let tray_menu = self.tray_inner.create_menu();
|
||||
|
||||
let (sender, receiver) = mpsc::channel();
|
||||
|
||||
|
@ -82,20 +130,6 @@ impl TrayApp {
|
|||
tray_icon::Icon::from_rgba(rgba, width, height).expect("Failed to create icon")
|
||||
}
|
||||
|
||||
fn create_menu(&self) -> Menu {
|
||||
let tray_menu = Menu::new();
|
||||
|
||||
let show_console_item = MenuItem::new("Show Log Window", true, None);
|
||||
let quit_item = MenuItem::new("Exit", true, None);
|
||||
|
||||
let mut menu_items = self.menu_items.lock().unwrap();
|
||||
menu_items.push(show_console_item);
|
||||
menu_items.push(quit_item);
|
||||
|
||||
tray_menu.append_items(&[&menu_items[0], &menu_items[1]]).unwrap();
|
||||
tray_menu
|
||||
}
|
||||
|
||||
fn spawn_device_fetch_thread(&self, tx: mpsc::Sender<Vec<u32>>) {
|
||||
let devices = Arc::clone(&self.devices);
|
||||
let device_manager = Arc::clone(&self.device_manager);
|
||||
|
@ -151,11 +185,11 @@ impl TrayApp {
|
|||
tray_menu: Menu,
|
||||
rx: mpsc::Receiver<Vec<u32>>,
|
||||
) {
|
||||
let tray_icon = Rc::clone(&self.tray_icon);
|
||||
let devices = Arc::clone(&self.devices);
|
||||
let device_manager = Arc::clone(&self.device_manager);
|
||||
let console_state = Arc::clone(&self.console_state);
|
||||
let menu_items = Arc::clone(&self.menu_items);
|
||||
let tray_icon = Rc::clone(&self.tray_inner.tray_icon);
|
||||
let console_state = Arc::clone(&self.tray_inner.console_state);
|
||||
let menu_items = Arc::clone(&self.tray_inner.menu_items);
|
||||
|
||||
let menu_channel = MenuEvent::receiver();
|
||||
|
||||
|
@ -169,7 +203,9 @@ impl TrayApp {
|
|||
}
|
||||
|
||||
if let tao::event::Event::NewEvents(tao::event::StartCause::Init) = event {
|
||||
Self::build_tray(&tray_icon, &tray_menu, icon.clone());
|
||||
// We create the icon once the event loop is actually running
|
||||
// to prevent issues like https://github.com/tauri-apps/tray-icon/issues/90
|
||||
TrayInner::build_tray(&tray_icon, &tray_menu, icon.clone());
|
||||
}
|
||||
|
||||
if let Ok(event) = menu_channel.try_recv() {
|
||||
|
@ -182,12 +218,12 @@ impl TrayApp {
|
|||
let mut visible = console_state.lock().unwrap();
|
||||
|
||||
if *visible {
|
||||
unsafe {ShowWindow(GetConsoleWindow(), winuser::SW_HIDE)};
|
||||
unsafe { ShowWindow(GetConsoleWindow(), winuser::SW_HIDE) };
|
||||
show_console_item.set_text("Show Log Window");
|
||||
trace!("hiding log window");
|
||||
*visible = false;
|
||||
} else {
|
||||
unsafe {ShowWindow(GetConsoleWindow(), SW_SHOW)};
|
||||
unsafe { ShowWindow(GetConsoleWindow(), SW_SHOW) };
|
||||
show_console_item.set_text("Hide Log Window");
|
||||
trace!("showing log window");
|
||||
*visible = true
|
||||
|
@ -201,23 +237,6 @@ impl TrayApp {
|
|||
});
|
||||
}
|
||||
|
||||
fn build_tray(
|
||||
tray_icon: &Rc<Mutex<Option<TrayIcon>>>,
|
||||
tray_menu: &Menu,
|
||||
icon: tray_icon::Icon,
|
||||
) {
|
||||
let tray_builder = TrayIconBuilder::new()
|
||||
.with_menu(Box::new(tray_menu.clone()))
|
||||
.with_tooltip("Service is running")
|
||||
.with_icon(icon)
|
||||
.build();
|
||||
|
||||
match tray_builder {
|
||||
Ok(tray) => *tray_icon.lock().unwrap() = Some(tray),
|
||||
Err(err) => error!("Failed to create tray icon: {}", err),
|
||||
}
|
||||
}
|
||||
|
||||
fn update(
|
||||
devices: &Arc<Mutex<HashMap<u32, MemoryDevice>>>,
|
||||
manager: &Arc<Mutex<DeviceManager>>,
|
||||
|
|
Loading…
Reference in New Issue