Schneegans / Gnome-Pie

A pie menu launcher for linux. Read the release announcement of version 0.7.2 at https://schneegans.github.io/news/2018/10/30/gnome-pie-072 Or have a look at the homepage!
http://schneegans.github.io/gnome-pie.html
MIT License
310 stars 54 forks source link

failure to load icons #170

Open deliciouslytyped opened 5 years ago

deliciouslytyped commented 5 years ago

I'm using NixOS which uses an nonstandard FHS and this probably makes finding icons hard. I don't really know how to use vala so this probably wouldn't be that easy to implement myself; could Gnome-Pie use https://valadoc.org/gtk+-3.0/Gtk.Window.get_icon.html as a fallback for getting icons instead of storing some kind of string name that may or may not be found later?

I looked at the code and on my system I think I go down this branch, because d-feet shows the desktop file being returned empty: https://github.com/Simmesimme/Gnome-Pie/blob/6c57eb7df894812bfbe9a6a545c1573d0072e168/src/actionGroups/windowListGroup.vala#L205-L208

An example of a warning I get:

[WARNING] Icon "quassel irc - #nixos (freenode) — quassel irc" not found! Using default icon...
[MESSAGE] Error loading image file: Failed to open file “/org/gtk/libgtk/icons/24x24/status/image-missing.png”: No such file or directory

I don't know if the warning message is just returning the wrong string, but that icon name also seems overspecific to find anything? I might be able to fix the missing default icon issue but that's not really going to be a solution.

deliciouslytyped commented 5 years ago

Some more info: BAMF ( https://launchpad.net/bamf https://git.launchpad.net/bamf/ ) appears to use entries in desktop files to get icon file paths. Finding desktop files probably fails somehow on NixOS. However with the way Gnome-Pie currently operates, you have this problem two-fold, because even if BAMF somehow did return icon file path, Gnome-Pie uses some sort of symbolic name that must again be resolved. There do appear to be some cases when I was exploring with d-feet where BAMF would return a path to temporary icon file in /tmp/.

deliciouslytyped commented 5 years ago

Since GTK appears to expose functionality to get raw icon Pixbufs from existing windows (per https://valadoc.org/gtk+-3.0/Gtk.Window.get_icon.html ), I believe this would be the most reliable way to get icons for the application switcher.

Schneegans commented 5 years ago

Thanks for reporting the issue! The variable "window" is not a Gtk.Window but a Wnck.Window and I think that there is no way of converting those. However, Wnck.Window also has a get_icon() method.

The returned icon seems to have a fixed size of 32x32 pixels. This is pretty small and will look very blurry in most cases. Furthermore I am not sure where the icon comes from - it might happen that it contains only a fallback icon in your specific case.

In order to test this, you could add one line of code to the file you already looked at. Just write something like window.get_icon().save("/tmp/" + icon_name + ".png", "png"); into this line:

https://github.com/Simmesimme/Gnome-Pie/blob/6c57eb7df894812bfbe9a6a545c1573d0072e168/src/actionGroups/windowListGroup.vala#L213

This will store all icons as png's in /tmp. You can check them and see if it would be worth the effort!

I think in general the way icons are treated in Gnome-Pie is good. In GLib world an icon is always referenced by a name, as the user can install various icon themes (which he may also change while Gnome-Pie is running!). Therefore there are classes like Glib.ThemedIcon. Therfore it might be better to fix Wnck or Bamf on NixOS instead.... Anyways, lets see whether using Wnck.Window.get_icon() would help you!

deliciouslytyped commented 5 years ago

Hm. That seems a bit problematic. I don't know enough about how icon handling works to really say, but from what little I understand of NixOS there isn't really any good way for some sort of global database to collect icons in, applications are quite decentralized, and installations are immutable (worked around by using environment variables for various things - of course user data directories are still mutable). It would be possible, albeit disappointing, for things to need to be installed globally to work. Not that it is necessarily Gnome-Pie's problem, I just haven't thought of a clear solution yet.

Thanks for the fast reply!

deliciouslytyped commented 5 years ago

Whats up with "quassel irc - #nixos (freenode) — quassel irc" though, shouldn't it just be "quassel" or something?

jtojnar commented 5 years ago

One issue with Gtk.Window.get_icon() is that on Wayland, windows do not really have icons – WMs are supposed to find them from desktop files. But again, Bamf does not work on Wayland, so maybe the issue is moot.

On NixOS, we sort of solve the issue by linking desktop files to a profile path mentioned in XDG_DATA_DIRS (e.g. /run/current-system/sw/share). This obviously does not happen when package is not installed to a profile: for example, when using nix run or nix-shell, or when running the result of nix-build. Unfortunately, such global state (systemd services are an another example) is at odds with purity of Nix so we need to rely on environment variables and global directories created by NixOS modules.

If you have properly configured NixOS system, though, picking up the desktop files and the mentioned icons should work fine for applications installed into a global (environment.systemPackages) or local (nix-env) profile as both are listed in XDG_DATA_DIRS.

deliciouslytyped commented 5 years ago

Since I forgot to link it earlier, here is d-feet https://nixos.org/nixos/packages.html#d-feet https://wiki.gnome.org/Apps/DFeet, which is an example of something that can be used to explore BAMF outputs.

@jtojnar do you have and ideas for nonglobal things? I haven't found any previous work but I have no doubt it exists. Edit: I meant stuff that isnt installed to the profile, i.e. precisely as you said, nix-shell, or whatever.

jtojnar commented 5 years ago

I would say this is an issue with libwnck:

$ nix-shell -p python3 python3.pkgs.pygobject3 libwnck3 gobject-introspection --run python3
Python 3.7.4 (default, Jul  8 2019, 18:31:06) 
[GCC 7.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from gi.repository import Wnck
__main__:1: PyGIWarning: Wnck was imported without specifying a version first. Use gi.require_version('Wnck', '3.0') before import to ensure that the right version gets loaded.
>>> screen = Wnck.Screen.get_default()
>>> screen.force_update()
>>> w = screen.get_active_window()
>>> w.has_icon_name()
True
>>> w.get_icon_name()
'nix-shell /home/jtojnar/Projects/nixpkgs'
jtojnar commented 5 years ago

The following is certainly wrong, as WnckApplication does not have icon names implemented:

https://github.com/Simmesimme/Gnome-Pie/blob/6c57eb7df894812bfbe9a6a545c1573d0072e168/src/actionGroups/windowListGroup.vala#L210-L211

As for windows, the docs say the library uses weird heuristics. Looking at the source code, it turns out it looks for certain X properties:

https://gitlab.gnome.org/GNOME/libwnck/blob/3.32.0/libwnck/xutils.c#L1261-1279

$ xprop _NET_WM_VISIBLE_ICON_NAME
_NET_WM_VISIBLE_ICON_NAME:  not found.
$ xprop _NET_WM_ICON_NAME
_NET_WM_ICON_NAME(UTF8_STRING) = "nix-shell /home/jtojnar/Projects/nixpkgs"

It is here, where the incorrect icon name from the REPL above comes from.

Not sure why GNOME Terminal does not set it correctly.

jtojnar commented 5 years ago

Apparently, GTK sets the _NET_WM_ICON_NAME to title, unless icon is set explicitly. That makes the libwnck useless for obtaining icon of majority of applications.

jtojnar commented 5 years ago

Actually, I found out that WM_ICON_NAME hint does not actually represent a name of the icon but rather a title for a window when it is iconified (minimized), see ICCCM. So GTK handles it correctly but almost everything else is confused by the misleading name, including EWMH spec.

LinuxLikeUnix commented 2 years ago

In the "Applications" pie, all of my windows/apps in the "Group: window list" slice, have this image:

err