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 : GTK 4 and applications icons : how to include an application icon in a portable way?
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.
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 had to dig a lot before finding the answer and ... it is a bit fuzzy.
Since the apparition of the Freedesktop Icon Theme Specification the communication of the icon from the software to the Windows Manager (WM) is different.
As far as I understand, now the system will look for a ".desktop" file which have to summarize the link between an executable and a named icon. The named icon is then found in a directory structure build like the example in my question. The major difference is that it should be in one of the standardized directory which are :
XDG_DATA_HOME/icons
or XDG_DATA_DIRS/icons
$HOME/.icons
(for retrocompatibility but seems to not be the current "way to do"XDG_DATA_HOME
seems to be classically empty on my systems and its default value when empty is $HOME/.local/share
according to the freedesktop specification.
XDG_DATA_DIR
is classically not empty with value like /usr/share
etc.
On my system for example :
echo $XDG_DATA_DIRS
/usr/share/plasma:/home/theuser/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share:/var/lib/snapd/desktop
If XDG_DATA_DIR is empty, the value that replace it is /usr/local/share/:/usr/share/
It means that in modern world post-"Freedesktop specification", programs don't directly inform the system of their icons anymore. And on modern display protocol like Wayland, it is not possible anymore for an application to communicate to the system a pixmap representing the icons used by the program. The .desktop files and the icons directory of your application is now mandatory on those systems.
More importantly, it means that function like gtk_window_set_icon_name
is now just a « fallback mechanism » according to the devs of Gnome with whom I discussed here about the problem.
As a Fallback mechanism it could be just ignored by the Windows Manager. And more importantly : as a fallback mechanism it seems to be left aside by the Gnome devs ... which didn't really reacts to the bug I exposed and redirect me on the use of .desktop files.
So, with those information, I have done this to solve the problem :
~/.local/share/icons
my_application.desktop
file containing this :#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Type=Application
Name=myapplication
Exec=PATH_to_my_executable
Comment=blabla
Icon=my-icon
Terminal=false
Categories=Utility;GTK;
~/.local/share/applications
And it works ! (after a reboot ...)
The icon is no longer fuzzy.
Some additional information :
The result work when launching directly the .desktop file but also when launching the executable directly. Interestingly, launching a similar executable which is not int the same directory that the one written in the desktop file also seems to work. But I don't really understand the magic here.
Some say that calling gtk-update-icon-cache
on the icon directory help performance and is sometimes mandatory. I have tested that without noticing the change, and I have a big interrogation point of this thing on a KDE-based system ... (how QT manage its caches ?). It could help to save the reboot on gtk based system.
Copying the .desktop file can be done by hand or by using specific command :
In the same way it is possible to automate the copying of the icons by using the command : xdg-desktop-icon
But it seems that it should be used icon by icon which can be slow if you have no script to automate that and the directories ready.
xdg-icon-resource forceupdate
can also be used to avoid the call to ``gtk-update-icon-cache`, it seems to encapsulate that and to adapt to the system (should work on KDE system too) and could be a good way to automate thing in a system-agnostic way.
For compatibility I imagine that this is still a good thing to keep the old way to do (gtk_window_set_icon_name) to keep the code compatible with older system or with mac/windows systems.