[GH-ISSUE #1213] GTK4 icon:* does not load #7393

Closed
opened 2026-05-23 02:54:14 +01:00 by JakeStanger · 3 comments
Owner

Originally created by @azertyfun on GitHub (Oct 23, 2025).
Original GitHub issue: https://github.com/JakeStanger/ironbar/issues/1213

Describe the bug

There are two places where "icon:[...]" is declared in the code: battery.rs and bluetooth/mod.rs. Neither one loads properly since the switch to GTK4 (bluetooth device names are redacted):

Image

Unicode icons render just fine.

Image

To reproduce
Steps to reproduce the behavior:

  1. Add module bluetooth
  2. Click popup
  3. Observe icons show a placeholder

Expected behavior

Icons should load properly (this is ironbar 0.17.1 with exact same config):

Image

System information:

  • Distro: Arch Linux
  • Compositor: Hyprland
  • Ironbar version: ironbar-git-0.17.1.r54.g828b0b5-1

Configuration

Config
position = "top"
height = 24

[[start]]
type = "workspaces"
all_monitors = false
hidden = ["special:magic"]
icon_size = 16


[[center]]
type = "focused"
icon_size = 16


[[end]]
type = "music"
icon_size = 16

[end.truncate]
mode = "end"
max_length = 100

[[end]]
type = "sys_info"
format = [
    " {cpu_percent}%",
    " {memory_percent}%",
    "󰋊 {disk_percent@/}%",
    "󰓢 {net_down} / {net_up} Mbps",
]

[end.interval]
memory = 30
cpu = 1
temps = 5
disks = 300
networks = 3


[[end]]
type = "custom"
class = "custom-gpclient"
show_if = "~/.local/bin/waybar-gpclient check-enabled"

[[end.bar]]
label = "{{ ~/.local/bin/waybar-gpclient }} VPN"
name = "vpn-btn"
type = "button"
on_click = "! ~/.local/bin/waybar-gpclient onclick"


[[end]]
type = "custom"
class = "custom-k8s"
show_if = "~/.local/bin/waybar-kubernetes check-enabled"

[[end.bar]]
name = "custom-k8s"
label = "{{ ~/.local/bin/waybar-kubernetes get | jq .text -r }}"
type = "button"
on_click = "! ~/.local/bin/sway-k8s-tofi"

[[end]]
type = "volume"
format = "{icon} {percentage}%"
max_volume = 100

[end.icons]
volume_high = "󰕾"
volume_medium = "󰖀"
volume_low = "󰕿"
muted = "󰝟"

[end.truncate]
mode = "end"
length = 50


[[end]]
type = "bluetooth"
icon_size = 16

[[end]]
type = "battery"
icon_size = 16

[end.thresholds]
warning = 30
critical = 15

[end.icons]
closed_none = "󰍥"
closed_some = "󱥂"
closed_dnd = "󱅯"
open_none = "󰍡"
open_some = "󱥁"
open_dnd = "󱅮"


[[end]]
type = "clock"
format = "%Y-%m-%d %H:%M:%S"


[[end]]
type = "notifications"
show_count = true


[[end]]
type = "tray"
icon_size = 12
Styles
@define-color rosewater #f2d5cf;
@define-color flamingo #eebebe;
@define-color pink #f4b8e4;
@define-color mauve #ca9ee6;
@define-color red #e78284;
@define-color maroon #ea999c;
@define-color peach #ef9f76;
@define-color yellow #e5c890;
@define-color green #a6d189;
@define-color teal #81c8be;
@define-color sky #99d1db;
@define-color sapphire #85c1dc;
@define-color blue #8caaee;
@define-color lavender #babbf1;
@define-color text #c6d0f5;
@define-color subtext1 #b5bfe2;
@define-color subtext0 #a5adce;
@define-color overlay2 #949cbb;
@define-color overlay1 #838ba7;
@define-color overlay0 #737994;
@define-color surface2 #626880;
@define-color surface1 #51576d;
@define-color surface0 #414559;
@define-color base #303446;
@define-color mantle #292c3c;
@define-color crust #232634;

.container box * {
    /* min-height: 0;*/
    font-size: 12px;
}

button {
    caret-color: white;
    background-image: none;
    border: none;
    min-height: 0;
    margin: 0;
    padding: 0 inherit;
}

.background {
    background-color: shade(@base, 0.9);
    color: @text;
}

.workspaces .item {
    background-color: transparent;
}

.workspaces .item.focused {
    background-color: @surface1;
}

.workspaces .item.visible {
    color: @crust;
    background-color: @overlay1;
}

.workspaces .item.urgent {
    background-color: @red;
}

.clock,
.battery,
.sysinfo,
.volume,
.custom-gpclient,
.tray,
.notifications,
.music,
.custom-k8s {
    color: @crust;
    margin: 0px 5px;
}

.custom-gpclient {
    background-color: @green;
}

.custom-k8s {
    background-color: @surface1;
    color: @text;
}

.custom-k8s.k8s-dev {
    background-color: @green;
    color: @text;
}

.custom-k8s.k8s-test {
    background-color: @yellow;
}

.custom-k8s.k8s-prod {
    background-color: @red;
}

.custom-k8s.k8s-unknown {
    background-color: @blue;
}

.custom-k8s.k8s-disconnected {
    background-color: @surface1;
    color: @text;
}

.music {
    background-color: @flamingo;
}

.bluetooth {
    background-color: @teal;
}

.popup-bluetooth {
    min-height: 300px;
    min-width: 300px;
}

.clock {
    background-color: @surface0;
    color: @text;
}

.battery {
    background-color: @green;
}

.battery.warning {
    background-color: @pink;
}

.battery.critical {
    background-color: @red;
}

.sysinfo .item {
    border-radius: 8px;
    padding: 0 3px;
}

.sysinfo .item:nth-child(1) {
    background-color: @teal;
}

.sysinfo .item:nth-child(2) {
    background-color: @mauve;
}

.sysinfo .item:nth-child(3) {
    background-color: @blue;
}

.sysinfo .item:nth-child(4) {
    background-color: @flamingo;
}

.volume {
    background-color: @yellow;
}

.tray {
    background-color: shade(@blue, 0.8);
}

Additional context

I know for a fact the battery icon exists:

Image

I do not have any experience troubleshooting GTK applications so I don't really know where to start. If you can't reproduce the issue, can you point me to where the loading of these icons is supposed to happen so I can drill down to the issue?

Screenshots

Originally created by @azertyfun on GitHub (Oct 23, 2025). Original GitHub issue: https://github.com/JakeStanger/ironbar/issues/1213 **Describe the bug** There are two places where ` "icon:[...]"` is declared in the code: `battery.rs` and `bluetooth/mod.rs`. Neither one loads properly since the switch to GTK4 (bluetooth device names are redacted): <img width="345" height="355" alt="Image" src="https://github.com/user-attachments/assets/cd9395f8-468d-4e6c-887d-c7506ae3d043" /> Unicode icons render just fine. <img width="552" height="28" alt="Image" src="https://github.com/user-attachments/assets/8478388a-c249-480e-b475-d4537eae2a1b" /> **To reproduce** Steps to reproduce the behavior: 1. Add module `bluetooth` 2. Click popup 3. Observe icons show a placeholder **Expected behavior** Icons should load properly (this is ironbar 0.17.1 with exact same config): <img width="281" height="157" alt="Image" src="https://github.com/user-attachments/assets/77a7f31c-dc74-4534-81e9-fec89df1a555" /> **System information:** - Distro: Arch Linux - Compositor: Hyprland - Ironbar version: `ironbar-git-0.17.1.r54.g828b0b5-1` **Configuration** <!-- Share your bar configuration and stylesheet as applicable: --> <details><summary>Config</summary> ``` position = "top" height = 24 [[start]] type = "workspaces" all_monitors = false hidden = ["special:magic"] icon_size = 16 [[center]] type = "focused" icon_size = 16 [[end]] type = "music" icon_size = 16 [end.truncate] mode = "end" max_length = 100 [[end]] type = "sys_info" format = [ " {cpu_percent}%", " {memory_percent}%", "󰋊 {disk_percent@/}%", "󰓢 {net_down} / {net_up} Mbps", ] [end.interval] memory = 30 cpu = 1 temps = 5 disks = 300 networks = 3 [[end]] type = "custom" class = "custom-gpclient" show_if = "~/.local/bin/waybar-gpclient check-enabled" [[end.bar]] label = "{{ ~/.local/bin/waybar-gpclient }} VPN" name = "vpn-btn" type = "button" on_click = "! ~/.local/bin/waybar-gpclient onclick" [[end]] type = "custom" class = "custom-k8s" show_if = "~/.local/bin/waybar-kubernetes check-enabled" [[end.bar]] name = "custom-k8s" label = "{{ ~/.local/bin/waybar-kubernetes get | jq .text -r }}" type = "button" on_click = "! ~/.local/bin/sway-k8s-tofi" [[end]] type = "volume" format = "{icon} {percentage}%" max_volume = 100 [end.icons] volume_high = "󰕾" volume_medium = "󰖀" volume_low = "󰕿" muted = "󰝟" [end.truncate] mode = "end" length = 50 [[end]] type = "bluetooth" icon_size = 16 [[end]] type = "battery" icon_size = 16 [end.thresholds] warning = 30 critical = 15 [end.icons] closed_none = "󰍥" closed_some = "󱥂" closed_dnd = "󱅯" open_none = "󰍡" open_some = "󱥁" open_dnd = "󱅮" [[end]] type = "clock" format = "%Y-%m-%d %H:%M:%S" [[end]] type = "notifications" show_count = true [[end]] type = "tray" icon_size = 12 ``` </details> <details><summary>Styles</summary> ```css @define-color rosewater #f2d5cf; @define-color flamingo #eebebe; @define-color pink #f4b8e4; @define-color mauve #ca9ee6; @define-color red #e78284; @define-color maroon #ea999c; @define-color peach #ef9f76; @define-color yellow #e5c890; @define-color green #a6d189; @define-color teal #81c8be; @define-color sky #99d1db; @define-color sapphire #85c1dc; @define-color blue #8caaee; @define-color lavender #babbf1; @define-color text #c6d0f5; @define-color subtext1 #b5bfe2; @define-color subtext0 #a5adce; @define-color overlay2 #949cbb; @define-color overlay1 #838ba7; @define-color overlay0 #737994; @define-color surface2 #626880; @define-color surface1 #51576d; @define-color surface0 #414559; @define-color base #303446; @define-color mantle #292c3c; @define-color crust #232634; .container box * { /* min-height: 0;*/ font-size: 12px; } button { caret-color: white; background-image: none; border: none; min-height: 0; margin: 0; padding: 0 inherit; } .background { background-color: shade(@base, 0.9); color: @text; } .workspaces .item { background-color: transparent; } .workspaces .item.focused { background-color: @surface1; } .workspaces .item.visible { color: @crust; background-color: @overlay1; } .workspaces .item.urgent { background-color: @red; } .clock, .battery, .sysinfo, .volume, .custom-gpclient, .tray, .notifications, .music, .custom-k8s { color: @crust; margin: 0px 5px; } .custom-gpclient { background-color: @green; } .custom-k8s { background-color: @surface1; color: @text; } .custom-k8s.k8s-dev { background-color: @green; color: @text; } .custom-k8s.k8s-test { background-color: @yellow; } .custom-k8s.k8s-prod { background-color: @red; } .custom-k8s.k8s-unknown { background-color: @blue; } .custom-k8s.k8s-disconnected { background-color: @surface1; color: @text; } .music { background-color: @flamingo; } .bluetooth { background-color: @teal; } .popup-bluetooth { min-height: 300px; min-width: 300px; } .clock { background-color: @surface0; color: @text; } .battery { background-color: @green; } .battery.warning { background-color: @pink; } .battery.critical { background-color: @red; } .sysinfo .item { border-radius: 8px; padding: 0 3px; } .sysinfo .item:nth-child(1) { background-color: @teal; } .sysinfo .item:nth-child(2) { background-color: @mauve; } .sysinfo .item:nth-child(3) { background-color: @blue; } .sysinfo .item:nth-child(4) { background-color: @flamingo; } .volume { background-color: @yellow; } .tray { background-color: shade(@blue, 0.8); } ``` </details> **Additional context** I know for a fact the battery icon exists: <img width="1430" height="484" alt="Image" src="https://github.com/user-attachments/assets/92f45362-f0ac-4293-96eb-e075ed263e21" /> I do not have any experience troubleshooting GTK applications so I don't really know where to start. If you can't reproduce the issue, can you point me to where the loading of these icons is supposed to happen so I can drill down to the issue? **Screenshots** <!-- If applicable, add screenshots to help explain your problem. -->
Author
Owner

@JakeStanger commented on GitHub (Oct 23, 2025):

It may be an issue with the icon being symbolic. They've been a bit of a pain in the past (#1039).

I'm a bit short on time for the next few days, so a couple of references if you did want to take a look:

Location resolution:
github.com/JakeStanger/ironbar@828b0b5738/src/image/provider.rs (L181)

Icon loading:
github.com/JakeStanger/ironbar@828b0b5738/src/image/provider.rs (L240-L254)

I think symbolic icon loading can be somewhat controlled via the flags.

<!-- gh-comment-id:3436087232 --> @JakeStanger commented on GitHub (Oct 23, 2025): It may be an issue with the icon being symbolic. They've been a bit of a pain in the past (#1039). I'm a bit short on time for the next few days, so a couple of references if you did want to take a look: Location resolution: https://github.com/JakeStanger/ironbar/blob/828b0b5738a26b46584c499b309f74519b98ab4e/src/image/provider.rs#L181 Icon loading: https://github.com/JakeStanger/ironbar/blob/828b0b5738a26b46584c499b309f74519b98ab4e/src/image/provider.rs#L240-L254 I think symbolic icon loading can be somewhat controlled via the flags.
Author
Owner

@azertyfun commented on GitHub (Oct 23, 2025):

What a ride. I'll spare you the numerous rabbit holes I fell down while tracking where the theme settings come from. In the end the issue is that if a Settings portal is present, GTK4 will use that. But I had kitty's portal as my "preferred" settings portal, which means that GTK4 used fallback values for all settings including theming (GTK_DEBUG=icontheme, you can see here it's using "gnome" theme which I haven't set but is the fallback value for portals):

looking up icon battery-full-charged-symbolic for scale 1
        lookup name: battery-full-charged-symbolic
No icon found in gnome (or fallbacks) for: battery-full-charged-symbolic
        lookup name: image-missing

Combined with the fact that there aren't any symbolic icons in hicolor (the only fallback for whatever icon theme is used, in this case gnome which isn't even installed on my machine), this means the symbolic icons are fully unresolvable.

I've updated my hyprland-portals.conf to set org.freedesktop.impl.portal.Settings=kitty;gtk and the issue went away. I created https://github.com/kovidgoyal/kitty/issues/9144.

<!-- gh-comment-id:3437406481 --> @azertyfun commented on GitHub (Oct 23, 2025): What a ride. I'll spare you the numerous rabbit holes I fell down while tracking where the theme settings come from. In the end the issue is that if a `Settings` portal is present, GTK4 will use that. But I had kitty's portal as my "preferred" settings portal, which means that GTK4 used [fallback values](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gdk/wayland/gdksettings-wayland.c#L269) for all settings including theming (`GTK_DEBUG=icontheme`, you can see here it's using "gnome" theme which I haven't set but is the fallback value for portals): ``` looking up icon battery-full-charged-symbolic for scale 1 lookup name: battery-full-charged-symbolic No icon found in gnome (or fallbacks) for: battery-full-charged-symbolic lookup name: image-missing ``` Combined with the fact that there aren't any symbolic icons in `hicolor` (the only fallback for whatever icon theme is used, in this case `gnome` which isn't even installed on my machine), this means the symbolic icons are fully unresolvable. I've updated my `hyprland-portals.conf` to set `org.freedesktop.impl.portal.Settings=kitty;gtk` and the issue went away. I created https://github.com/kovidgoyal/kitty/issues/9144.
Author
Owner

@azertyfun commented on GitHub (Oct 23, 2025):

Nevermind, I actually need to make a PR here as well. The set_icon_theme implementation is slightly incorrect as it does not set the Display. Unless I apply this patch I still do not have my icons:

diff --git a/src/image/provider.rs b/src/image/provider.rs
index 4465f3d..d798b68 100644
--- a/src/image/provider.rs
+++ b/src/image/provider.rs
@@ -343,12 +343,16 @@ impl Provider {
     pub fn set_icon_theme(&self, theme: Option<&str>) {
         trace!("Setting icon theme to {:?}", theme);
 
-        *self.icon_theme.borrow_mut() = if theme.is_some() {
+        let icon_theme = if theme.is_some() {
             let icon_theme = IconTheme::new();
             icon_theme.set_theme_name(theme);
-            Some(icon_theme)
+            icon_theme
         } else {
-            Some(IconTheme::default())
+            IconTheme::default()
         };
+
+        icon_theme.set_display(Some(crate::get_display()).as_ref());
+
+        *self.icon_theme.borrow_mut() = Some(icon_theme);
     }
 }
<!-- gh-comment-id:3437439907 --> @azertyfun commented on GitHub (Oct 23, 2025): Nevermind, I actually need to make a PR here as well. The `set_icon_theme` implementation is slightly incorrect as it does not set the `Display`. Unless I apply this patch I still do not have my icons: ```diff diff --git a/src/image/provider.rs b/src/image/provider.rs index 4465f3d..d798b68 100644 --- a/src/image/provider.rs +++ b/src/image/provider.rs @@ -343,12 +343,16 @@ impl Provider { pub fn set_icon_theme(&self, theme: Option<&str>) { trace!("Setting icon theme to {:?}", theme); - *self.icon_theme.borrow_mut() = if theme.is_some() { + let icon_theme = if theme.is_some() { let icon_theme = IconTheme::new(); icon_theme.set_theme_name(theme); - Some(icon_theme) + icon_theme } else { - Some(IconTheme::default()) + IconTheme::default() }; + + icon_theme.set_display(Some(crate::get_display()).as_ref()); + + *self.icon_theme.borrow_mut() = Some(icon_theme); } } ```
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
JakeStanger/ironbar#7393
No description provided.