Yesterday I've upgraded some packages on my Debian system. Surprisingly applications using Gnome libraries stopped to open URIs using applications defined in GConf /desktop/gnome/url-handlers. So I've checked if gnome-open is able to open a URI:
$ gnome-open http://wodny.org Error showing url: No application is registered as handling this file
The short (picture) version of the text below is available.
This was interesting. I realized that gnome-open first downloaded headers from the specified URI and then searched for a helper application according to the found Content-Type.
At first I was surprised that some Gnome libs do secret work behind my back.
The ability to download something in the background comes from backends installed. The HTTP one came from the gvfs-backends package.
So I was dealing with the GVfs "a userspace virtual file system with backends for protocols like SFTP, FTP, DAV, SMB, ObexFTP. GVFS is the replacement for GNOME-VFS". Specifically I was also dealing with its part - GIO "a new shared library that is part of GLib and provides the API for GVFS".
So I read some API documentation. This was quite fun. GIO can take a URI from me and provide a magic File interface to it. I looked through some source code. I like the magical special function called g_app_info_launch_default_for_uri. It first searches for a handler for the scheme used (for example http) and if it doesn't find one - it determines the content type using a backend. For the HTTP backend a HEAD request is sent and the Content-Type header is used. Then it searches for a handler for that content type.
I've also used Python to do some debug.
>>> import gio >>> gio.app_info_get_default_for_uri_scheme("http")The call returned nothing, while it should have returned something like this:
<gio.unix.DesktopAppInfo at 0xb76972d4: iceweasel>
So for some reason GConf /desktop/gnome/url-handlers settings were not taken into account and instead of ending the search on the scheme handler it continued through the content type phase (as I didn't define a handler for text/html - it has failed).
During the upgrade there was a lot of packages being installed. One of them was libfm. It comes with a module called libgiofm.so, which resides in /usr/lib/gio/modules. This module provides a GIO extension and registers an implementation of the G_DESKTOP_APP_INFO_LOOKUP_EXTENSION_POINT_NAME (gio-desktop-app-info-lookup) extension point.
Looking through /usr/lib/gio/modules/giomodule.cache I noticed that libgiofm.so isn't the only one providing this extension. There was also the libgiogconf.so module (from the gvfs package). And libgiogconf.so was here earlier as it's the Gnome's module for reading GConf settings.
When an extension registers itself it also sets its priority. The Gnome module registers itself with priority value of 10. The libfm one registers itself with priority value of 9 if it detects a Gnome session via the GNOME_DESKTOP_SESSION_ID environmental variable or 90 if it doesn't.
As I'm using Openbox, the module doesn't detect the variable. With priority 90 it takes precedence over the Gnome module. I didn't define scheme handlers for the libfm (for example using libfm-pref-apps) so GIO didn't know what to do with URIs.
For now I'm going to use a workaround. I will set the GNOME_DESKTOP_SESSION_ID environmental variable. But There are two problems with that:
- I don't have Gnome, but neither do I have LXDE - I just use some applications from both under Openbox
- I could set this variable for example in .bashrc, but:
- I can't really find any documentation on this variable
- I've found a comment, where someone suggests it's deprecated
I could define applications through libfm-pref-apps, but it has less options than GConf, I have a problem with launching mutt with mailto: URIs and I don't want to duplicate settings.
I've sent the libfm developers a request to change that behaviour and allow to change the priority for example via XDG system/user's settings.