App version
linux-rust @ 672e65ad (nightly librepods-x86_64.AppImage, built 2026-06-12)
Variant
Rust rewrite (linux-rust branch)
Distro and version
CachyOS (rolling)
Desktop environment / compositor
niri 26.04 (Wayland)
Install method (only official sources)
AppImage
AirPods model
Other / not sure — the bug is device-independent; it only concerns the window's Wayland app_id.
What happened
On Wayland the LibrePods toplevel advertises an empty app_id. Panels and docks key their icon lookup off app_id → .desktop entry, so LibrePods shows a blank placeholder instead of an icon. It also means any other app_id-less window on the system (a browser picture-in-picture window, for instance) gets grouped into the same taskbar entry.
Settings { id: Some("librepods") } is set in start_ui, but on Linux iced never reads that field — it only reads the per-window window::Settings::platform_specific.application_id, which is left at its Default value of "".
Expected: app_id == "librepods".
Actual: app_id == "".
Reproduction
- Launch LibrePods under any Wayland compositor.
- Query the toplevel's
app_id:
$ niri msg -j windows | jq -r '.[] | "\(.app_id // "<null>")\t\(.title)"'
md.obsidian.Obsidian Today's Meetings - obsidian - Obsidian 1.13.7
t3code T3 Code (Nightly)
localsend LocalSend
LibrePods <-- empty app_id
helium Inbox | Fastmail - Helium
Cause
linux-rust/src/ui/window.rs:54-59 sets the application-level id:
.settings(Settings {
id: Some("librepods".to_string()),
...
})
In iced 0.14 that id reaches iced_winit::conversion::window_attributes as the _id parameter — and the only block that consumes _id is gated to the BSDs (winit/src/conversion.rs#L78-L89):
#[cfg(any(
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
{
use ::winit::platform::wayland::WindowAttributesExtWayland;
if let Some(id) = _id {
attributes = attributes.with_name(id.clone(), id);
}
}
The block that actually compiles on Linux reads a different field — the per-window one (winit/src/conversion.rs#L137-L163):
#[cfg(target_os = "linux")]
{
#[cfg(feature = "wayland")]
{
use winit::platform::wayland::WindowAttributesExtWayland;
attributes = attributes.with_name(
&settings.platform_specific.application_id,
&settings.platform_specific.application_id,
);
}
}
core/src/window/settings/linux.rs declares application_id: String under #[derive(Default)], so an untouched window::Settings::default() produces with_name("", "").
Suggested fix
Set it on the window settings at both window::Settings::default() sites in linux-rust/src/ui/window.rs (lines 143 and 280):
let mut settings = window::Settings::default();
settings.min_size = Some(Size::new(400.0, 300.0));
settings.platform_specific.application_id = "librepods".to_string();
librepods matches the basename of librepods.desktop, which is what iced's own docs recommend and what panels expect.
Additional context
Two related things I ran into while tracking this down:
1. The window icon path is relative and resolved at runtime. At window.rs:145 and window.rs:282:
settings.icon = window::icon::from_file("../../assets/icon.png").ok();
That resolves against the process working directory, so it fails for any normal launch, and .ok() swallows the error silently. include_bytes! plus window::icon::from_file_data would embed it the same way the font already is on line 56.
2. The AUR package ships no icon or desktop entry. librepods-git installs only usr/bin/librepods and the licence, so packaged installs have nothing for an Icon= key to point at even once app_id is correct. The AppImage already carries a good 256×256 me.kavishdevar.librepods.png and a librepods.desktop; installing those into usr/share/icons/hicolor/ and usr/share/applications/ would cover it. (Related: #384.)
App version
linux-rust@672e65ad(nightlylibrepods-x86_64.AppImage, built 2026-06-12)Variant
Rust rewrite (
linux-rustbranch)Distro and version
CachyOS (rolling)
Desktop environment / compositor
niri 26.04 (Wayland)
Install method (only official sources)
AppImage
AirPods model
Other / not sure — the bug is device-independent; it only concerns the window's Wayland
app_id.What happened
On Wayland the LibrePods toplevel advertises an empty
app_id. Panels and docks key their icon lookup offapp_id→.desktopentry, so LibrePods shows a blank placeholder instead of an icon. It also means any otherapp_id-less window on the system (a browser picture-in-picture window, for instance) gets grouped into the same taskbar entry.Settings { id: Some("librepods") }is set instart_ui, but on Linux iced never reads that field — it only reads the per-windowwindow::Settings::platform_specific.application_id, which is left at itsDefaultvalue of"".Expected:
app_id == "librepods".Actual:
app_id == "".Reproduction
app_id:Cause
linux-rust/src/ui/window.rs:54-59sets the application-level id:In iced 0.14 that
idreachesiced_winit::conversion::window_attributesas the_idparameter — and the only block that consumes_idis gated to the BSDs (winit/src/conversion.rs#L78-L89):The block that actually compiles on Linux reads a different field — the per-window one (
winit/src/conversion.rs#L137-L163):core/src/window/settings/linux.rsdeclaresapplication_id: Stringunder#[derive(Default)], so an untouchedwindow::Settings::default()produceswith_name("", "").Suggested fix
Set it on the window settings at both
window::Settings::default()sites inlinux-rust/src/ui/window.rs(lines 143 and 280):librepodsmatches the basename oflibrepods.desktop, which is what iced's own docs recommend and what panels expect.Additional context
Two related things I ran into while tracking this down:
1. The window icon path is relative and resolved at runtime. At
window.rs:145andwindow.rs:282:That resolves against the process working directory, so it fails for any normal launch, and
.ok()swallows the error silently.include_bytes!pluswindow::icon::from_file_datawould embed it the same way the font already is on line 56.2. The AUR package ships no icon or desktop entry.
librepods-gitinstalls onlyusr/bin/librepodsand the licence, so packaged installs have nothing for anIcon=key to point at even onceapp_idis correct. The AppImage already carries a good 256×256me.kavishdevar.librepods.pngand alibrepods.desktop; installing those intousr/share/icons/hicolor/andusr/share/applications/would cover it. (Related: #384.)