GTK4PythonTutorial
GTK4PythonTutorial copied to clipboard
Adding an application icon
Has anyone had success with adding an application icon for Wayland sessions? I'm posting this issue both to ask for help and to show what I've done so far.
The "right" way to do it
GTK4 applications are expected to follow the Freedesktop Icon Theme Specification. Icons should be installed to the icon directory, typically /usr/share/icons
or ~/.local/share/icons
. The icon is supposed to be named according to the application ID, such as com.example.myapp.svg
Then the application icon can be set for a window by using the set_icon_name
method.
my_window = Gtk.Window()
my_window.set_icon_name("com.example.myapp")
However, this doesn't work for all use cases, such as AppImages. When using an AppImage intergration program like AppImageLauncher, icons are saved to the desktop with a hash, using a format similar to appimagekit_3e227aae859f2298ca6d5802f48f6f5b_com.example.myapp.svg
so these icons won't be found using the above code. There is, however, a workaround.
The workaround
By adapting some code found in this StackExchange question, we can get an icon to show for our application.
icon_theme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default())
icon_theme.add_search_path("/path/to/resource/directory")
This, in addition to the earlier code block for our window, will allow us to add an icon for our application. There's one problem, though. Adding an application icon only seems to work for Xorg sessions. I've been unsuccessful at getting this method to work for Wayland.
I'm honestly a bit stumped with this one. Anyone have a clue as to how to get this working?
I might add that, in general, using importlib is the recommended pythonic way of pointing to module resources, in this case to get a path for Gtk.IconTheme.add_search_path
.
Updating that example (tested on Python 3.9+), assuming your module is my_package
with a subdirectory (aka PEP 420 python namespace) called icons
(containing an directory tree like hicolor/scalable/apps/icon.svg
):
icon_theme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default())
module_spec = importlib.util.find_spec('my_package.icons')
search_locations = module_spec.submodule_search_locations if module_spec else ()
for path in search_locations:
icon_theme.add_search_path(path)
Just don't forget to specify zip_save=False
on your package metadata and add that icon package namespace to your package data.