GTK 4 used only 48x48 application icon that leads to fuzzy icons. GTK2 works fine

In GTK4 the icon system for displaying the apps have changed.

In GTK3/GTK2 we could use simple commands like gtk_window_set_icon() or gtk_window_set_default_icon_from_file() or gtk_window_set_icon_list().

In GTK4 these commands are gone and we have to use the system of theming defined by the Freedesktop Icon Theme Specification (which could be also used in GTK3). I have dug into what it means in practical in this previous question :

And finally the resulting code is quite simple :

    icon_theme = gtk_icon_theme_get_for_display (gdk_display_get_default ());
    gtk_icon_theme_add_search_path(icon_theme,path_to_my_ressource_directory); 

    if(gtk_icon_theme_has_icon(icon_theme,"my-icon")!=1)
       {
        // manage error
       }
    
    gtk_window_set_default_icon_name("my-icon"); // default icon for all windows if nothing is set explicitly if I understand well. 
    
    window = gtk_application_window_new (app);
    gtk_window_set_title (GTK_WINDOW (window), "Your app");
    gtk_window_set_icon_name(GTK_WINDOW (window),"my-icon"); // set explicitly the icon for the min window

Assuming that the ressource_directory is defined like that :

/ressources$ ls
hicolor  icon-theme.cache

cd hicolor/

/ressources/hicolor$ ls
128x128  150x150  192x192  256x256  310x310  48x48  512x512  64x64  72x72  96x96 scalable

/ressources/hicolor$ cd 128x128
/ressources/hicolor/128x128$ ls
apps

/ressources/hicolor/128x128$ cd apps
/ressources/hicolor/128x128/apps$ ls
my-icon.png

And it now works, i have my wonderfull icon when i launch the application.

Buuuuuttttt … the reality is that the icon is fuzzy, whereas in the GTK2 version of my application, it is not.

iconss

The first icon from the bottom is my application in GTK2, the second icon (the fuzzy one) is the same appli in GTK4.

The result is a fuzzy icon. I have made some tests on the icons and it seems that under the hood GTK use only the 48x48 icon in this context in GTK4, which give a fuzzy icon when it is used in other context.

Is it a bug of GTK ? Is it a bad interaction with my desktop environment (KDE here) ? Or is it an error from my side ?

And more importantly : how to correct this dissatisfying result ?

I believe the desktop will get its icon from the .desktop file, not the application itself. If these icons are in the correct place when installed (ie. /usr/share/icons/hicolor, the desktop should use the appropriate size if you provide the icon name (ie. my-icon, not a path).

If you’re interested in including icons in the binary, you’ll probably want to look at GResource and more conveniently GtkApplication's automatic resource handling.

I am not sure about your explanation. Imho : you are confused about two different things.

I was talking about the icon used when you open the application, the icon in the taskbar. As far as I understand, this icon is defined via the “gtk_window_set_icon_name” function , not by the .desktop.

The .desktop file is here to tell the operating system about the icon to use prior to the launch of the application, because the OS has no other way to know it when the application is not launched. It is the icon on a shortcut to the application on the desktop, for example.

This is two different cases.

Also, notice that your proposition doesn’t really change the nature of the problem IMHO. First : you assume that putting icons in /usr/share/icons is mandatory to put an icon, but it is not : as far as I know you can specify a specific icon in both methods : in the .desktop files method (by putting the complete path) and in the “I specify to the system the icon to use for minimising the window” method. (Via the gtk_icon_theme_add_search_path.).

Finally : the Gresource system that you propose is just here for the second method, it is an alternative to the “gtk_icon_theme_add_search_path” so it doesn’t change the nature of the problem, it simply helps the programmer to manage its resource, previously load with gtk_icon_theme_add_search_path for example, by including this resource in the binary instead of using gtk_icon_theme_add_search_path. But it should change nothing to the problem presented here …

No, in GNOME Shell the icon is determined by the desktop file at all times. The icon set using gtk_window_set_icon_name() can only be used in X11, and it’s only looked at as a fallback there.

In order:

  1. the icon in the desktop file
  2. if the icon is missing, and you’re on X11, use the icon set with gtk_window_set_icon_name()
  3. if the icon is missing, use the icon name set using gtk_window_set_default_icon_name().

In all of these cases, you need the icon to be a named one, which means adding it to the icon theme.

Without having access to your code, my assumption is that what you’re seeing is the desktop trying to upscale an icon set using gtk_window_set_icon_name(). You should provide a high resolution icon, or at least a scalable icon in your desktop file.

I don’t think that is true for Ubuntu’s dash-to-dock extension (as seen in the screenshot), it’s definitively not true for GNOME.

The window icon is only used as a fallback if a window cannot be matched to a .desktop file, and only for windows that use the X11 backend (because window icons aren’t part of any wayland protocol implemented in GNOME).

Hum, interesting, maybe this point should be added in the documentation ?
I don’t really understand the « and you are on X11 » . Why is that so ? So gtk_window_set_icon_name() has no effect at all on wayland ?
If that is the case, it really should be added in the documentation of GTK4 ^^

I have put the code in the first post :

The part that load the icon is really short :

 icon_theme = gtk_icon_theme_get_for_display (gdk_display_get_default ());
    gtk_icon_theme_add_search_path(icon_theme,path_to_my_ressource_directory); 

    if(gtk_icon_theme_has_icon(icon_theme,"my-icon")!=1)
       {
        // manage error
       }
    
    gtk_window_set_default_icon_name("my-icon"); // default icon for all windows if nothing is set explicitly if I understand well. 
    
    window = gtk_application_window_new (app);
    gtk_window_set_title (GTK_WINDOW (window), "Your app");
    gtk_window_set_icon_name(GTK_WINDOW (window),"my-icon"); // set explicitly the icon for the min window

My icon is in the directory MY_APP_DIRECTORY/ressources/hicolor which contain the following directory :

128x128  150x150  192x192  256x256  310x310  48x48  512x512  64x64  72x72  96x96 scalable

In each one there is an apps directory and a png icon in this apps directory, (my-icon.png), with the right size of course. (except in scalable where there is an svg icon).

The icon used is indeed the 48x48, because if i put a text on each icon its that one. But, as far as i understand, it shouldn’t. And it is not the case in previous version of GTK.

This point rise a question : if i understand well, there is no way anymore to have a portable application with an icon used for the window (when minimizing etc.) on wayland ?

This is only relevant for GNOME Shell and Wayland.

It already does:

On some platforms, the window icon is not used at all.

“Some platforms” can apply to any windowing system supported by GTK; this can change depending on capabilities added to GTK or the windowing system itself, so it cannot be a precise list.

The intent of that sentence is to tell the app developer that they cannot specifically rely on the function having the same effect on any platform.

GTK only passes a 48px icon if you specify the icon name and the icon theme finds a scalable icon, because the EWMH (which defines _NET_WM_ICON) does not support scalable icons.

Yes, there is: always define the named icon in the desktop file.

No it is not the source of the problem.
I have tested without the scalable directory and it is the same result. I have recheck and i confirm that thhe problem is the same.

That’s what the code does if an icon has no sizing information.

Hum, but a desktop file which is puts nearby the application executable will be taken into account when launching the portable executable ?

If your definition of “portable” is “a singe executable without external files like .desktop or icon” then no.

That’s not really new by the way, we have considered .desktop files non-optional since at least GNOME 3 10+ years ago.

Now we’re moving way past the context.

What’s a “portable executable”? If you mean something that can be moved around your system, then: no. But nothing works that way in Linux.

Linux applications—in the post-2001, post-desktop-entry-specification sense of “Linux application”—are a binary installed in a well known location, and a desktop entry file installed in $XDG_DATA_DIR/applications (or $XDG_DATA_HOME/applications). If you’re using named icons, the you also need to install the icons into the hicolor icon theme directory.

No. You really don’t want your compositor scraping your home folder for “nearby .desktop files”. It must be placed in the applications directory in one of the $XDG_DATA_DIRS or $XDG_DATA_HOME.

Thanks, it is not clear for me in which context the « sizing » info is given to the function and when it is not. But Ok.

It is not really my definition. I just mean a directory which contains all the necessary to launch the application, without installing it. It can have a .desktop file near the application.

After digging it seems that, at least in the wayland protocol, it is possible to tell to the system that the desktop file to consider for the application is this one or another (and so to point to a local desktop file). I don’t know if this is possible with GTK.

Also, i have to notice that this doesn’t really solve the original problem. In my original question i am in a case where gtk_icon_theme_add_search_path / gtk_window_set_icon_name seems to work. It is maybe a fallback solution that don’t work with other protocol like wayland but it works in my precise case.
But the function seems to take only 48x48 image into account. (instead of taking into account other size in the directory like what is writen in the code linked by ebassi)

That’s not how Linux applications work, sorry. If you want a self-contained application then I recommend you look at tools like Flatpak.

This has nothing to do with GTK. You would need to modify the XDG_DATA_DIRS environment variable, but that has a ton of side effects, which is why nobody does that.

As far as i understand, it is done like this at least by QT :
https://doc.qt.io/qt-6/qguiapplication.html#desktopFileName-prop

I do not know if it modify XDG_DATA_DIRS under the hood (i don’t think so) but it seems to tell to the wm , by one way or another, to use a precise desktop file.

That method still assumes that the desktop file is inside the XDG_DATA_DIRS/XDG_DATA_HOME because that’s where the desktop environment/windowing system will look for it.

Ok, so i resume :

Under the freedesktop specification and so, on many modern system : the old way when an apps tells the system about its icons, even for the minimising icons etc. is … hum … completely obsolete ? And it should not be used ?
It includes the gtk_window_set_icon_name and gtk_window_set_default_icon_name functions (and also including the icons in Gressource way i guess ? ).

All the communication between the apps and desktop environnement (about the icons) should now be done via .desktop files puts in XDG_DATA_DIRS/XDG_DATA_HOME and it exists no way to tell the WM about local desktop file which should be used (or we have to modify XDG_DATA_DIRS/XDG_DATA_HOME which is not good)

The function like gtk_window_set_icon_name still work but are not the “way to do”.

Am i good ? :smiling_face:

I notice though that it is a bit fuzzy : documentation is not really clear about those points and I guess that a multi system application need to have the two system to ensure compatibility with OS that do not follow the freedesktop specification ?