Skip to content

[Bug] Icon theme lookup fails for app_icon parameter while image-path hint works #693

@shayonpal

Description

@shayonpal

Description

When sending notifications via notify-send --icon=ICON_NAME, SwayNC displays a fallback text symbol (ⓘ) instead of the actual icon. However, using --hint=string:image-path:/path/to/icon.png with the same icon works perfectly.

Steps to Reproduce

# This fails - shows fallback symbol
notify-send "Test" "Icon name lookup" --icon=dialog-information

# This works - shows actual icon
notify-send "Test" "Direct path" --hint=string:image-path:/usr/share/icons/Adwaita/symbolic/status/dialog-information-symbolic.svg

Expected Behavior

Both methods should display the icon. The --icon parameter should resolve the icon name via GTK4's IconTheme lookup.

Actual Behavior

  • --icon=dialog-information → Shows fallback text "ⓘ"
  • --hint=string:image-path:/path → Shows actual icon correctly

Investigation Results

GTK4 icon lookup works outside SwayNC

import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk, Gdk

display = Gdk.Display.get_default()
theme = Gtk.IconTheme.get_for_display(display)
print(theme.get_theme_name())  # Colloid-Purple-Dark
print(theme.has_icon('dialog-information'))  # True

This confirms GTK4 can find the icons correctly.

D-Bus message inspection

The notification is sent correctly:

method call ... member=Notify
   string "notify-send"
   uint32 0
   string "dialog-information"  <-- app_icon parameter
   string "Test"
   string "Icon name lookup"
   ...

Code analysis

Looking at notification.vala, the app_icon handling differs from image_path:

// For image_path - checks if it's a theme icon:
if (!img_path_exists) {
    img_path_exists = icon_theme.has_icon(param.image_path);
    img_path_is_theme_icon = img_path_exists;
}

// For app_icon - only checks if it's a file:
app_icon_exists = File.new_for_path(app_icon_uri).query_exists();
// No theme icon check here!

In functions.vala, set_image_uri does try icon lookup as fallback:

if (img.storage_type == Gtk.ImageType.EMPTY) {
    unowned Gdk.Display display = Gdk.Display.get_default();
    unowned Gtk.IconTheme icon_theme = Gtk.IconTheme.get_for_display(display);
    if (icon_theme.has_icon(uri)) {
        img.set_from_icon_name(uri);
    }
}

However, this lookup appears to fail even though identical Python code succeeds. Possible causes:

  1. Gdk.Display.get_default() returns different/null display in SwayNC context
  2. IconTheme instance differs between notification widget context and default display
  3. Timing issue where display isn't fully initialized when lookup occurs

Workaround

Created a wrapper script that resolves icon names to paths before calling notify-send:

#!/bin/bash
# Resolve icon name to path using GTK4
icon_path=$(python3 -c "
import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk, Gdk
display = Gdk.Display.get_default()
theme = Gtk.IconTheme.get_for_display(display)
icon = theme.lookup_icon('$1', None, 64, 1, Gtk.TextDirection.LTR, 0)
if icon and icon.get_file():
    print(icon.get_file().get_path())
")
notify-send "Title" "Body" --hint=string:image-path:"$icon_path"

Environment

  • SwayNC version: 0.12.4
  • OS: Fedora Asahi Remix 42 (Linux 6.17.12)
  • Desktop: Hyprland 0.53.1 (Wayland)
  • GTK4 version: 4.18
  • Icon theme: Colloid-Purple-Dark (also tested with Adwaita)
  • Display scaling: 1.6x HiDPI

Additional Notes

  • Apps that send image-data or image-path hints (like Kitty terminal) display icons correctly
  • Only app_icon parameter (icon name lookup) fails
  • The icon files exist and are found by GTK4 Python - only SwayNC's internal lookup fails

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions