Department of Engineering

IT Services

The Nautilus File Manager - internals

In order to have a better idea of how to deal with some gnome desktop issues on SuSE (in particular how to set system-wide defaults for which application to run when files are clicked on) I started reading the documentation. The notes below are cobbled together from various sources (often incomplete even when they're official) and may well include my own additional misunderstandings. We're using Nautilus 2.22.2 on SuSE 11. Some of the underlying mechanisms and file locations changed with Nautilus 2.22, which complicates the situation. Also daemons and caches are used, so if you're updating without rebooting you'll need to know how to clear these caches, etc.

Nautilus calls upon various other facilities, so first I'll deal with those. Some of them are heavily implicated in the problems we have.

Window Managers

Metacity is the default window manager. By enabling "desktop effects" you can replace this by Compiz which has many more features. The Window Manager doesn't seem implicated in the Nautilus problems we have (though it has problems of its own - openGL applications don't work well with it).

File handling

With the 2.22 release, Nautilus has been ported from Gnome-vfs to the newly introduced gvfs for basic I/O operations. Its routines can be called so that they block - i.e. don't return until they've done their job - or they can be used asynchronously. Nautilus uses only asynchronous I/O operations - i.e. it can call file-handing routines without having to wait for previous calls to finish. gvfs consists of two parts: a shared library which is loaded by applications supporting GIO; and gvfs itself, a collection of daemons which communicate with each other and the GIO module over D-Bus ( GIO is a new library for I/O, and D-Bus is essentially an implementation of inter-process communication). gvfs runs a single master daemon (gvfsd) that keeps track of the current gvfs mounts.

MIME

MIME (Multipurpose Internet Mail Extensions) is a way to identify the format of a file and decide how it should be dealt with. Mailers and Web browsers use it. Nautilus depends on this heavily in order to decide which icon to use when displaying a file, and to decide what to do when the file is clicked on.

As well as dealing with file-handling, GIO also includes the GNOME mimetype system. It contains code that can detect the mimetype of files, and a database that lets you map from mimetypes to the application that can handle it. It also allows for per-user overrides of this database so that users can configure their own preferred application for different types of files.

The details matter to us here, so here goes!

MIME file contents

The Mime-related information needed by gvfs includes

  1. Data used to deduce the MIME type for a file.
  2. For each MIME type, a human language description
  3. For each application, a human readable name.
  4. For each application, information about how it should be invoked, which includes the name of the command, whether file locations should be passed as URIs or as file system paths, whether multiple files can be opened with a single command, and whether the application should be opened inside a terminal window.
  5. For each application, a list of MIME types for files that application can open when passed as command line arguments and schemes for locations it can understand as command line arguments.
  6. For each MIME type, an ordered list of preferred applications and components for each user level, from most to least preferred. This list need not include all applications that can open files of this MIME type.
  7. For some MIME types, a file name that specifies which icon to use when displaying a file of this type.

To get information (stored either with gnomevfs or gvfs) about a particular file (say ~/final.pdf) you can use

  • gvfs-info ~/final.pdf
    This displays info including the following
      name: final.pdf
      type: regular
      standard::content-type: application/pdf
      standard::icon: GThemedIcon:0x612640
    
    but not a "Default app"
  • gnomevfs-info ~/final.pdf
    This displays info including the following
      Name        : final.pdf
      Type        : Regular
      MIME type   : application/pdf
      Default app : AdobeReader.desktop
    
  • xdg-mime query filetype ~/final.pdf
    returns
      application/pdf
    
    XDG aims to provide generic support for various desktop programs. I don't know whether Nautilus uses the routines, though the XML files used to set up the MIME types it uses are in standard XDG locations.

Gnome MIME defaults

Default settings for MIME type and application information are stored in several places. Some of the configuration can be extended or overridden by other modules when they are installed or by user preferences.

SuSEconfig is automatically executed by Yast whenever packages are installed, updated or removed. But if any packages are installed via command line i.e by simple rpm commands then SuSEconfig needs to be invoked manually. It takes configuration options from lots of files and processes them, often converting them into another file format usable by specific applications (for example, it configures the menus for several window managers based on what apps you have installed). It uses /sbin/conf.d/SuSEconfig.* files - /sbin/conf.d/SuSEconfig.glib2 is worth looking at. On our system, the desktop files sought are

    ${XDG_DATA_DIRS:-/usr/local/share:/usr/share}/applications/*.desktop

and the file created is /var/cache/gio-2.0/defaults.list which on our system starts with

   [Default Applications]
   application/arj=xarchiver.desktop

However, on our system gnome seems to use /usr/share/applications/defaults.list.

/etc/gnome_defaults.conf starts with a useful description of the algorithm used.

# After any change of this file run
# SuSEconfig --module glib2
#
# This list is a source for defaults.list.
#
# If application in this list is installed, it is used as default in GNOME.
# It works in following way:
# 1. Read this file.
# 2. Collect all available desktop files.
# 3. Go through all declared MIME types and search for default application
#    for defaults.list in following order:
# 3.1 Installed application listed here for certain MIME type.
# 3.2 Installed application listed here as preferred default.
# 3.3 Installed application listed here as default.
# 3.4 Installed application with GNOME in Categories.
# 3.5 Installed application with GTK in Categories.
# 3.6 Installed application.
#
# Syntax:
# Use xxx as default for all MIME types it declares (see 3.3):
# xxx.desktop
# Use xxx as preferred default for all MIME types it declares (see 3.2):
# !xxx.desktop
# Use xxx as default for mime/type (see 3.1):
# mime/type=xxx.desktop

The "desktop files" are files associated with icons. For example, here is /opt/Adobe/Reader9/Resource/Support/AdobeReader.desktop

[Desktop Entry]
Name=Adobe Reader 9
MimeType=application/pdf;application/vnd.fdf;application/vnd.adobe.pdx;applicati
on/vnd.adobe.xdp+xml;application/vnd.adobe.xfdf;
Exec=acroread 
Type=Application
GenericName=PDF Viewer
Terminal=false
Icon=AdobeReader9
Caption=PDF Viewer
X-KDE-StartupNotify=false
Categories=Application;Office;Viewer;X-Red-Hat-Base;
InitialPreference=9

There are also desktop files in /usr/share/applications/kde4/ which also has a mimeinfo.cache file with contents like

[MIME Cache]
image/jpeg=gimp.desktop;kde4-okularApplication_kimgio.desktop;kde4-gwenview.desktop;imageviewer.desktop;eog.desktop;f-spot-view.desktop;
image/x-pcx=gimp.desktop;kde4-okularApplication_kimgio.desktop;imageviewer.desktop;eog.desktop;f-spot-view.desktop;

application/x-rar=file-roller.desktop;xarchiver.desktop;kde4-ark.desktop;

etc. I don't know what uses this cache file.

MIME system and user file locations

The MIME database is created from the set of files located in the $XDG_DATA_HOME/mime and $XDG_DATA_DIRS/mime directories. We have $XDG_DATA_HOME unset and $XDG_DATA_DIRS set to

  /usr/local/share:/usr/share:/usr/share/gdm:/etc/opt/kde3/share:/opt/kde3/share

If these environment variables are unset, they default to ~/.local/share and /usr/local/share:/usr/share respectively. Each environment variable can be a colon separated list of directories. The user's database at $XDG_DATA_HOME/mime has precedence over the system database at $XDG_DATA_DIRS/mime.

The update-mime-database program creates the default files in these system directories by reading from freedesktop.org.xml (???). Doing

  update-mime-database /usr/share/mime

updates the databases (in particular /usr/share/mime/mime.cache) under /usr/share/mime. Note that mime.cache needs to be world readable, and that the umask at install time isn't always correct.

Adding extensions to this can be done with appropriate xml files in, for instance, /usr/share/mime/packages. e.g. /usr/share/mime/packages/nautilus.xml

Rather than change the existing files, user defined mime types can be added to ~/.local/sharemime/packages/Overrides.xml

To modify the database for all users, make changes to the file Overrides.xml in a system $XDG_DATA_DIRS/mime/packages directory. After changes are made, you must always run the update-mime-database application, with the directory location of the MIME database as the first parameter.

When users change settings using the right-button on a file and change this panel
openwithprops.png
~/.local/share/applications/mimeapps.list is written to, containing something like

[Added Associations]
image/jpeg=eog.desktop;
text/plain=kde4-kopete.desktop;

[Removed Associations]
image/jpeg=kde-amarok.desktop;

These modify the initial system defaults. The first of these "Added Associations" is used as the default application for such files from then on.

Note that some apps (firefox notably) still get their MIME information from /etc/mime.types and /etc/mailcap so you may need to duplicate information.

Storing configurable settings

gconf does this. We have gconf2. gconf-editor lets user set defaults for many programs, including Nautilus. Values can also be set or read from the command line - e.g.

    gconftool-2 --get /apps/nautilus/desktop/home_icon_visible

will return true or false. The pathname here starts from /etc/gconf/gconf.xml.schemas. The files there refer to or /etc/gconf/gconf.xml.schemas/schemes, which is where the real info is, in files called %gconf.xml.

The current GConf implementation involves a per-user daemon (gconfd). This daemon's primary purpose is to notify applications when a configuration value has changed. As a secondary task, it caches values, so each application doesn't have to parse XML files. Since the daemon caches values it may not notice when new schemas are installed from "make install" or an RPM/deb package. However, it is possible to notify the daemon to re-load its caches by sending it a SIGHUP signal.

~/.gconfd contains the following GConf daemon details:

  • Configuration information.
  • Lock information for objects that are referenced by an Interoperable Object Reference (IOR).
  • State information for objects that are referenced by an IOR.

The daemon normally exits a couple of minutes after the last application using it has exited.

~/.gnome2 Contains user-specific application data that is not stored in the GConf repository (e.g. Window location information, and Desktop entry files for panel launchers).

There's also ~/.gconf, under which user preferences are stored. To restore their default nautilus preferences a user needs to run

   gconftool-2 --direct --config-source ~/.gconf/apps/nautilus --recursive-unset

What's /etc/gconf/?

Bonobo

Bonobo is the GNOME component model - a way to create reusable software components for use by other programs. It's based on CORBA. Components in general are a way to declare public interfaces for well specified operations, so that objects implementing these can be found at runtime. Bonobo in the GNOME 2 platform consists of three parts, bonobo-activation, libbonobo and libbonoboui. bonobo-activation is a database of installed components that allows you to write queries asking for components that satisfy some requirements. libbonobo is the user interface independent part of the component framework. libbonoboui contains user interface specific parts of the framework, in particular the BonoboControl interface that allows you to embed a user interface object in an application. Controls use an xml-based description of the menus and toolbars of an application so that menu items and toolbar buttons from different components can be merged into the same set of menus.

OAF is the new object activation framework for GNOME. Since many GNOME applications utilize CORBA, a framework for locating and activating these applications is necessary. OAF, the Object Activation Framework, provides a simple method for finding and running the CORBA objects available on a computer system. Distributed operation is supported, allowing activation of objects on a network of computers being used in a GNOME desktop. The flexibility of OAF enables it to be used outside of GNOME programs, allowing non-GNOME CORBA applications to be utilized alongside GNOME applications.

Nautilus mainly uses Bonobo for the BonoboControl interface, in order to embed file and directory views into the Nautilus window. However, the metadata handling does use the user interface independent parts of bonobo.

The GNOME release team plans to deprecate Bonobo sometime after GNOME 2.0, but it's used currently on our system.

Start-up

The /usr/share/gnome/default.session file lists what programs are initially run. Our file has gnome-wm (currently the Metacity window manager), gnome-panel (which runs the panels in the GNOME Desktop), and nautilus.

Nautilus

Nautilus itself is made up of several parts. Apart from the main executable there are executables and libraries for some of the components. There is also the public library libnautilus and its headers, used by third parties that want to implement nautilus extensions.

When a file is clicked on, the attributes of the file are used to figure out the default component to use for the URI. This is done by constructing a bonobo-activation query. Components are matched in the following order:

  • component specified in the metadata for the location (set if the user visited the location with a non-default component before), (metadata is stored as an xml file per directory in $HOME/.nautilus/metafiles). For example, the *Desktop.xml file there has
    <?xml version="1.0"?>
    <directory><file name="Trash" icon_position="64,442"/>
    <file name="ksnapshot.desktop" timestamp="1187177245" icon_position="64,522"/>
    
    etc. The metadata system is implemented as a Bonobo server that handles all accesses to the metadata files.
  • default gnome-vfs component for the mimetype
  • gnome-vfs short list of components for the mimetype
  • components that lists the mimetype or the super-mimetype (e.g. image/*) in the bonobo:supported_mime_types attribute.

Modules

Add-ons include

  • nautilus-open-terminal (lets you to open a terminal in arbitrary local folders using right-click)
  • seahorse (for PGP encryption)

References

Questions

  • One document said that Nautilus now uses gvfs/gio instead of gnomevfs for MIME info. Another said that Nautilus gets such info via bonobo which once used gnomevfs. Does Nautilus still use bonobo? Does bonobo still use gnomevfs?
  • How should /var/cache/gio-2.0/defaults.list and /usr/share/applications/defaults.list be synchronised?
  • Are the files under /usr/share/applications/kde4/ (in particular mimeinfo.cache) used? I think the files are, because /usr/share/ is in $XDG_DATA_DIRS, but what about the cache file?