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);
|
winuser::ShowWindow(wincon::GetConsoleWindow(), winuser::SW_HIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::env::set_var("RUST_LOG", "trace");
|
std::env::set_var("RUST_LOG", "trace");
|
||||||
pretty_env_logger::init();
|
pretty_env_logger::init();
|
||||||
let checker = TrayApp::new();
|
let checker = TrayApp::new();
|
||||||
|
|
109
src/tray.rs
109
src/tray.rs
|
@ -12,7 +12,10 @@ use tray_icon::{
|
||||||
menu::{Menu, MenuEvent, MenuItem},
|
menu::{Menu, MenuEvent, MenuItem},
|
||||||
TrayIcon, TrayIconBuilder,
|
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 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);
|
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 {
|
pub struct TrayApp {
|
||||||
device_manager: Arc<Mutex<DeviceManager>>,
|
device_manager: Arc<Mutex<DeviceManager>>,
|
||||||
devices: Arc<Mutex<HashMap<u32, MemoryDevice>>>,
|
devices: Arc<Mutex<HashMap<u32, MemoryDevice>>>,
|
||||||
tray_icon: Rc<Mutex<Option<TrayIcon>>>,
|
tray_inner: TrayInner,
|
||||||
console_state: Arc<Mutex<bool>>,
|
|
||||||
menu_items: Arc<Mutex<Vec<MenuItem>>>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TrayApp {
|
impl TrayApp {
|
||||||
|
@ -52,16 +102,14 @@ impl TrayApp {
|
||||||
Self {
|
Self {
|
||||||
device_manager: Arc::new(Mutex::new(DeviceManager::new())),
|
device_manager: Arc::new(Mutex::new(DeviceManager::new())),
|
||||||
devices: Arc::new(Mutex::new(HashMap::new())),
|
devices: Arc::new(Mutex::new(HashMap::new())),
|
||||||
tray_icon: Rc::new(Mutex::new(None)),
|
tray_inner: TrayInner::new(),
|
||||||
console_state: Arc::new(Mutex::new(false)),
|
|
||||||
menu_items: Arc::new(Mutex::new(Vec::new()))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&self) {
|
pub fn run(&self) {
|
||||||
let icon = Self::create_icon();
|
let icon = Self::create_icon();
|
||||||
let event_loop = EventLoopBuilder::new().build();
|
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();
|
let (sender, receiver) = mpsc::channel();
|
||||||
|
|
||||||
|
@ -82,20 +130,6 @@ impl TrayApp {
|
||||||
tray_icon::Icon::from_rgba(rgba, width, height).expect("Failed to create icon")
|
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>>) {
|
fn spawn_device_fetch_thread(&self, tx: mpsc::Sender<Vec<u32>>) {
|
||||||
let devices = Arc::clone(&self.devices);
|
let devices = Arc::clone(&self.devices);
|
||||||
let device_manager = Arc::clone(&self.device_manager);
|
let device_manager = Arc::clone(&self.device_manager);
|
||||||
|
@ -151,11 +185,11 @@ impl TrayApp {
|
||||||
tray_menu: Menu,
|
tray_menu: Menu,
|
||||||
rx: mpsc::Receiver<Vec<u32>>,
|
rx: mpsc::Receiver<Vec<u32>>,
|
||||||
) {
|
) {
|
||||||
let tray_icon = Rc::clone(&self.tray_icon);
|
|
||||||
let devices = Arc::clone(&self.devices);
|
let devices = Arc::clone(&self.devices);
|
||||||
let device_manager = Arc::clone(&self.device_manager);
|
let device_manager = Arc::clone(&self.device_manager);
|
||||||
let console_state = Arc::clone(&self.console_state);
|
let tray_icon = Rc::clone(&self.tray_inner.tray_icon);
|
||||||
let menu_items = Arc::clone(&self.menu_items);
|
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();
|
let menu_channel = MenuEvent::receiver();
|
||||||
|
|
||||||
|
@ -169,7 +203,9 @@ impl TrayApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let tao::event::Event::NewEvents(tao::event::StartCause::Init) = event {
|
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() {
|
if let Ok(event) = menu_channel.try_recv() {
|
||||||
|
@ -182,12 +218,12 @@ impl TrayApp {
|
||||||
let mut visible = console_state.lock().unwrap();
|
let mut visible = console_state.lock().unwrap();
|
||||||
|
|
||||||
if *visible {
|
if *visible {
|
||||||
unsafe {ShowWindow(GetConsoleWindow(), winuser::SW_HIDE)};
|
unsafe { ShowWindow(GetConsoleWindow(), winuser::SW_HIDE) };
|
||||||
show_console_item.set_text("Show Log Window");
|
show_console_item.set_text("Show Log Window");
|
||||||
trace!("hiding log window");
|
trace!("hiding log window");
|
||||||
*visible = false;
|
*visible = false;
|
||||||
} else {
|
} else {
|
||||||
unsafe {ShowWindow(GetConsoleWindow(), SW_SHOW)};
|
unsafe { ShowWindow(GetConsoleWindow(), SW_SHOW) };
|
||||||
show_console_item.set_text("Hide Log Window");
|
show_console_item.set_text("Hide Log Window");
|
||||||
trace!("showing log window");
|
trace!("showing log window");
|
||||||
*visible = true
|
*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(
|
fn update(
|
||||||
devices: &Arc<Mutex<HashMap<u32, MemoryDevice>>>,
|
devices: &Arc<Mutex<HashMap<u32, MemoryDevice>>>,
|
||||||
manager: &Arc<Mutex<DeviceManager>>,
|
manager: &Arc<Mutex<DeviceManager>>,
|
||||||
|
|
Loading…
Reference in New Issue