Fixed tray icon on linux

This commit is contained in:
Alexandr Bogomiakov
2025-07-24 04:04:15 +03:00
parent 3cc326e8dc
commit f4eb46afce
3 changed files with 33 additions and 4 deletions

1
Cargo.lock generated
View File

@@ -2683,6 +2683,7 @@ dependencies = [
"egui", "egui",
"env_logger", "env_logger",
"futures", "futures",
"gtk",
"hostname", "hostname",
"log", "log",
"notify", "notify",

View File

@@ -46,11 +46,15 @@ winit = { version = "0.30", optional = true }
env_logger = "0.11" env_logger = "0.11"
urlencoding = "2.1" urlencoding = "2.1"
# Linux-specific dependencies for GTK tray support
[target.'cfg(target_os = "linux")'.dependencies]
gtk = { version = "0.18", optional = true }
[features] [features]
default = ["server", "web", "gui"] default = ["server", "web", "gui"]
cli = ["server", "web"] cli = ["server", "web"]
desktop = ["gui"] desktop = ["gui"]
gui = ["tray-icon", "eframe", "egui", "winit", "notify", "notify-debouncer-mini"] gui = ["tray-icon", "eframe", "egui", "winit", "notify", "notify-debouncer-mini", "gtk"]
server = [] server = []
web = [] web = []

View File

@@ -15,6 +15,10 @@ use winit::{
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
use winit::platform::macos::EventLoopBuilderExtMacOS; use winit::platform::macos::EventLoopBuilderExtMacOS;
// GTK initialization for Linux tray support
#[cfg(target_os = "linux")]
static GTK_INIT: std::sync::Once = std::sync::Once::new();
use super::{ use super::{
create_tooltip, create_tray_icon, start_auto_sync_task, update_sync_status, update_tray_menu, create_tooltip, create_tray_icon, start_auto_sync_task, update_sync_status, update_tray_menu,
SyncStatus, TrayMenuIds, SyncStatus, TrayMenuIds,
@@ -223,6 +227,15 @@ impl ApplicationHandler<crate::gui::UserEvent> for TrayApplication {
fn resumed(&mut self, _event_loop: &winit::event_loop::ActiveEventLoop) { fn resumed(&mut self, _event_loop: &winit::event_loop::ActiveEventLoop) {
if self.tray_icon.is_none() { if self.tray_icon.is_none() {
info!("Creating tray icon"); info!("Creating tray icon");
// Initialize GTK on Linux before creating tray icon
#[cfg(target_os = "linux")]
GTK_INIT.call_once(|| {
if let Err(e) = gtk::init() {
error!("Failed to initialize GTK: {}", e);
}
});
let settings = self.settings.lock().unwrap(); let settings = self.settings.lock().unwrap();
let sync_status = self.sync_status.lock().unwrap(); let sync_status = self.sync_status.lock().unwrap();
@@ -244,10 +257,10 @@ impl ApplicationHandler<crate::gui::UserEvent> for TrayApplication {
error!("Failed to create tray icon. This usually means the required system libraries are not installed."); error!("Failed to create tray icon. This usually means the required system libraries are not installed.");
error!("On Ubuntu/Debian, try installing: sudo apt install libayatana-appindicator3-1"); error!("On Ubuntu/Debian, try installing: sudo apt install libayatana-appindicator3-1");
error!("Alternative: sudo apt install libappindicator3-1"); error!("Alternative: sudo apt install libappindicator3-1");
error!("KHM will continue running but without system tray integration."); error!("KHM will exit as system tray integration is required for desktop mode.");
error!("You can still use --settings-ui to access the settings window.");
// Don't exit, just continue without tray icon // Exit if tray icon creation fails
std::process::exit(1);
} }
} }
} }
@@ -275,6 +288,17 @@ impl ApplicationHandler<crate::gui::UserEvent> for TrayApplication {
/// Run tray application /// Run tray application
pub async fn run_tray_app() -> std::io::Result<()> { pub async fn run_tray_app() -> std::io::Result<()> {
// Initialize GTK early on Linux
#[cfg(target_os = "linux")]
{
if let Err(e) = gtk::init() {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!("Failed to initialize GTK: {}", e),
));
}
}
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
let event_loop = { let event_loop = {
use winit::platform::macos::ActivationPolicy; use winit::platform::macos::ActivationPolicy;