From 148cb2f82ab27525293a11aa2256addbe6757306 Mon Sep 17 00:00:00 2001 From: zerolover Date: Wed, 29 Jul 2026 16:54:58 +0800 Subject: [PATCH] fix(linux): set window icon and application ID (#254) Set app_id "tty7" on every platform (WM_CLASS on X11, desktop-entry match on Wayland) and attach a 256px _NET_WM_ICON to X11 windows. macOS and Windows already get their icons from the bundle / exe resource. --- src/ui/windows.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/ui/windows.rs b/src/ui/windows.rs index d53c2292..c8e6e640 100644 --- a/src/ui/windows.rs +++ b/src/ui/windows.rs @@ -606,6 +606,20 @@ fn close_window_for(cx: &mut App, workspace: WorkspaceId) { /// `window.json` fallback, then a centred default — each cascaded so it does /// not land exactly on an existing window. fn window_options(cx: &mut App, workspace: Option) -> WindowOptions { + // X11 needs the icon on the native window itself for taskbars and window + // switchers. Wayland resolves the same application identity through the + // desktop entry when tty7 is packaged. + #[cfg(any(target_os = "linux", target_os = "freebsd"))] + static APP_ICON: std::sync::LazyLock>> = + std::sync::LazyLock::new(|| { + image::load_from_memory(include_bytes!("../../assets/app-icon.png")) + .ok() + // The source asset is 1024×1024, but _NET_WM_ICON ships raw + // pixels to the X server per window (~4 MB at full size) and + // taskbars want at most 256px anyway. + .map(|image| std::sync::Arc::new(image.thumbnail(256, 256).into_rgba8())) + }); + let remember = cx.global::().remember_window_size; let remembered = remember .then(|| { @@ -645,6 +659,9 @@ fn window_options(cx: &mut App, workspace: Option) -> WindowOptions WindowOptions { window_bounds: Some(window_bounds), + app_id: Some("tty7".to_owned()), + #[cfg(any(target_os = "linux", target_os = "freebsd"))] + icon: APP_ICON.as_ref().cloned(), // Start from the component defaults but nudge the traffic lights down // so they stay vertically centred in our taller (40px) title bar — see // `TitleBar::new().h(..)` in `app.rs`. `apply_theme` re-pins the same