How to create custom thumbnailers for Nautilus, Nemo, and Caja?

Solution 1:

References

  • gnome-desktop-thumbnail.c (official)
  • Writing a GNOME thumbnailer
  • Thumbnail Managing Standard

The following sections provide important details about the thumbnailing process as well as steps to create custom thumbnailers for Nautilus, Nemo, and Caja that haven't been mentioned in the documents above.

It should be noted that Nautilus refers to recent versions of Nautilus that implement thumbnailing sandboxing. On Ubuntu, they are the versions of Nautilus that uses libgnome-desktop 3.28.2 or newer.

Thumbnailer & Thumbnailer Entry

To generate thumbnails for files, two basic things are needed:

  • A thumbnailer program (or just thumbnailer): a program that can in one way or another convert files into PNG images, preferably with an option to resize images. Some examples are convert, ffmpeg, gdk-pixbuf-thumbnailer, etc.
  • A thumbnailer entry: a text file with the .thumbnailer extension that resides in either ~/.local/share/thumbnailers or /usr/share/thumbnailers. This file connects the thumbnailer program to the type(s) of files the program will create thumbnails for. A thumbnailer entry looks something like this:
    [Thumbnailer Entry]
    TryExec=/usr/bin/gdk-pixbuf-thumbnailer
    Exec=/usr/bin/gdk-pixbuf-thumbnailer -s %s %i %o
    MimeType=image/jpeg;image/png;image/gif;image/tiff;
    

Each thumbnailer entry is in a key-file format that supports three keys:

  • TryExec: (Optional) this key is used to check whether the thumbnailer program is installed. Its value is the path to the thumbnailer program or the name of the program that can be found in the $PATH environment variable. If the program is not present or is not executable, the command in the Exec key will not be executed. Nautilus, however, ignores this key and always tries to execute the thumbnailer.

  • Exec: (Required) the command to be executed to generate thumbnails. This command consists of the thumbnailer program's full path or its name (in the current $PATH) followed by space-separated arguments. An argument can be one of a few special parameters that are automatically replaced before being passed to the thumbnailer:

    • %i: (Required if %u is not used) the full path of the file being thumbnailed, for example:
      /home/calico/Pictures/image.jpg
      /home/calico/Music/Pop Music/audio.mp3
      
      The path is passed as a single argument to the thumbnailer program regardless of whether it contains spaces or other special characters.
    • %u: (Required if %i is not used) the URI of the file being thumbnailed. %u should be used instead of %i if the thumbnailer program can handle the URI syntax. Local files are passed as file://<full-path-to-file>, for instance:
      file:///home/calico/Pictures/image.jpg
      file:///home/calico/Music/Pop%20Music/audio.mp3
      
    • %o: (Required) the full path of the output thumbnail. Nautilus, Nemo, and Caja respectively write the output image to:
      /tmp/gnome-desktop-thumbnailer-XXXXXX/gnome-desktop-thumbnailer.png
      /tmp/.gnome_desktop_thumbnail.XXXXXX
      /tmp/.mate_desktop_thumbnail.XXXXXX
      
      XXXXXX is a 6-character string consisting of uppercase letters and numbers. Each output image file is given a unique XXXXXX.
    • %s: (Optional) the default thumbnail size in pixels. If used, %s is replaced with either 128 (by Caja or older versions of Nemo) or 256 (by Nautilus or newer versions of Nemo).
  • MimeType: (Required) the MIME type(s) of the files the thumbnailer program will generate thumbnails for. Multiple MIME types are separated by a semicolon. See Steps to create a custom thumbnailer section for details about how to get the mime-type of each file.

Notes for the Exec key:

  • Generally, only one of %i or %u is used in the command.
  • Literal percentage characters are escaped as %% (e.g. use 50%% for 50 percent).
  • See Desktop Entry Specification - The Exec key for more details.

Let's take the thumbnailer entry above as an example: gdk-pixbuf-thumbnailer is used as the thumbnailer program for JPEG, PNG, GIF, and TIFF images. If we open a folder, say, /home/calico/Pictures, which contains image.gif:

  • Nemo (on Ubuntu 20.04 or later) will execute this command:
    /usr/bin/gdk-pixbuf-thumbnailer -s 256 /home/calico/Pictures/image.gif /tmp/.gnome_desktop_thumbnail.1ABC20
    
  • Caja will execute this command:
    /usr/bin/gdk-pixbuf-thumbnailer -s 128 /home/calico/Pictures/image.gif /tmp/.mate_desktop_thumbnail.DE3450
    
  • Nautilus (with libgnome-desktop 3.37.2 or newer) will do the following:
    • Create a temporary directory: /tmp/gnome-desktop-thumbnailer-67FG80.
    • Mount that directory on /tmp in the sandbox.
    • Mount image.gif on /tmp/image.gif in the sandbox.
    • Execute this command (inside the sandbox):
      /usr/bin/gdk-pixbuf-thumbnailer -s 256 /tmp/image.gif /tmp/gnome-desktop-thumbnailer.png
      

Thumbnailer Script

Only one command is executed from a thumbnailer entry: the first string (separated from others by a space) after Exec= is considered the name or path of the program to be executed and everything after that is considered arguments to be passed to the program. However, there are many cases in which multiple commands are needed to create a proper thumbnail. For example, dwebp can convert a WebP image to PNG format in one command, but it needs help from other programs, such as webpmux and bc, to calculate the appropriate width and height for the output image. In such cases, a thumbnailer script is put to use.

  • A thumbnailer script: a script that contains commands for creating thumbnails. It could be a shell script, a Python script, etc., depending on the types of files and programs involved. Shell scripts are very commonly used and they look something like this:
    #!/bin/bash
    
     in_file="$1"
        size="$2"
    out_file="$3"
    
    <command>
    <another-command>
    
    <thumbnailer-program> -i "$in_file" -s "$size" -o "$out_file"
    

A script can be used directly as the program to be executed or as a text file containing commands. For example:

# a script used as a program
Exec=/home/calico/Documents/example-thumbnailer-script %i %s %o
# a script used as a file containing commands
Exec=bash /home/calico/Documents/example-thumbnailer-script %i %s %o

If a shell script is employed, the arguments after the path of the script (e.g. %i, %s, and %o) are assigned to the positional parameters ($1, $2, $3, etc.) in the script.

See this answer and this article for examples of shell scripts that create thumbnails for WebP images and APK files respectively or this article for an example of a Python script that create thumbnails for MRC images.

Steps to create a custom thumbnailer

  1. Find and install a thumbnailer program

    Find a program that can convert the type of files you want to thumbnail to PNG format. Before installing a new program, you might want to try pre-installed thumbnailers:

    • gdk-pixbuf-thumbnailer: the default thumbnailer for images on GNOME and GNOME-based desktops.
    • totem-video-thumbnailer and ffmpegthumbnailer: the default thumbnailers for videos on GNOME and Cinnamon/MATE desktops respectively.
    • evince-thumbnailer, xreader-thumbnailer, and atril-thumbnailer: the default thumbnailers for PDFs and other document files on GNOME, Cinnamon, and MATE desktops respectively.
    • gnome-thumbnail-font and mate-thumbnail-font: the default thumbnailers for fonts on GNOME/Cinnamon and MATE desktops respectively.

    Try invoking them manually in a terminal to create a PNG image from an input file. For example:

    cd ~/Pictures
    gdk-pixbuf-thumbnailer -s 256 example.webp out.png
    ffmpegthumbnailer -s 256 -i example.webp -o out.png
    

    If these programs cannot handle the type of files you want to thumbnail, it's time to look for new thumbnailers. convert (from imagemagick) and ffmpeg are commonly used for supporting a wide variety of file formats. You can install them with:

    sudo apt install imagemagick
    sudo apt install ffmpeg
    

    You can also choose to use a program that specializes in handling certain types of files. For example, dwebp and opj_decompress are specifically designed to decode WebP images and JPEG-2000 images respectively.

  2. Get the MIME type of the files to be thumbnailed

    • Right-click a file of the type you want to thumbnail, select Properties.
    • On the Basic tab, pay attention to the Type field. The MIME type is shown in parentheses.

    Alternatively, you can use xdg-mime. For example, to get the mime-type of example.pdf in ~/Documents, issue this command:

    xdg-mime query filetype ~/Documents/example.pdf
    
  3. Create a thumbnailer script (if necessary)

    • If more than one command or program is needed to generate thumbnails for your files, use a text editor such as nano or gedit to create a thumbnailer script that contains those commands.
    • If you use Nemo or Caja, you can put the script somewhere in your home directory. If you use Nautilus, however, you can only place the script in directories that are mounted on the sandbox (see Thumbnailing issuesFailed thumbnails due to sandboxed thumbnailers below). If you are not sure, /usr/local/bin is recommended.
    • If the script is to be used as a program, you have to make it executable. For example:
      chmod +x /home/calico/Documents/webp-thumbnailer-script
      sudo chmod +x /usr/local/bin/psd-thumbnailer-script
      
  1. Create a thumbnailer entry
    • Use a text editor to create a thumbnailer entry (a text file with the .thumbnailer extension). Give it a descriptive name, such as webp.thumbnailer or psd.thumbnailer.

    • Place the thumbnailer entry in ~/.local/share/thumbnailers or /usr/share/thumbnailers so that it is available to the current user or all users respectively. If you plan to put it in /usr/share/thumbnailers, using nano to create and edit the entry is strongly recommended. For example:

      sudo nano /usr/share/thumbnailers/webp.thumbnailer
      
    • As for the contents of the entry (see Thumbnailer & Thumbnailer Entry above for details):

      • The first line of the file must be: [Thumbnailer Entry]
      • Use the TryExec key if you want to check whether a program or script is present and executable.
      • Specify the name or path of the program to be executed and arguments to be passed to it in the Exec key. If a thumbnailer script is used, it must be either the program or an argument (see Thumbnailer Script above for details).
      • Put the mime-type found in step 2 in the MimeType key. If this key is to contain multiple mime-types, separate each of them with a semicolon (;) and optionally end the value of the key with a semicolon.
  1. Clear old cached thumbnails and restart the file manager
    • After a new thumbnailer entry is created, the file manager should be fully closed so that it can properly scan for and register the entry. You can do this by issuing one of these commands:
      nautilus -q
      nemo -q
      caja -q
      
    • Next, delete the cache of failed thumbnails to force the file manager to regenerate thumbnails for files that previous thumbnailers failed to generate thumbnails for:
      rm -r ~/.cache/thumbnails/fail
      
    • Optionally, delete all cached thumbnails if unoptimized thumbnailer entries or scripts were used previously:
      rm -r ~/.cache/thumbnails/*
      
    • Finally, reopen the file manager. Files whose mime-type is in the MimeType key should have their thumbnails now. If not, it means something goes wrong, but never fear, that's what the following sections are for.

Troubleshooting thumbnailers

One of the best way to find out what went wrong with thumbnailers is to run the file manager with debugging messages enabled:

  • First, fully close the file manager with one of these commands:
    nautilus -q
    nemo -q
    caja -q
    
  • Clear all cached thumbnails:
    rm -r ~/.cache/thumbnails/*
    
  • Launch the file manager from a terminal with debugging code enabled:
    • Nautilus (from this):
      G_MESSAGES_DEBUG=all NAUTILUS_DEBUG=Window nautilus
      
    • Nemo:
      nemo --debug
      
    • Caja (from this): issue the following command, then type run and press Enter
      gdb caja
      
  • Go to ~/.cache/thumbnails, which should be empty by now.
  • Open a folder containing files of the type you want to thumbnail in a new tab. From here, three things may happen:
    • A large or normal directory is created in ~/.cache/thumbnails. This means thumbnailing succeeded and thumbnails were generated for your files.
    • No directory is created in ~/.cache/thumbnails (i.e. the directory remains empty). This means the command in the Exec key was not executed and, as a result, no thumbnail was created. See the next section for possible causes of this situation.
    • A fail directory is created in ~/.cache/thumbnails. This means the file manager did try to execute the command in the Exec key, but there was something that prevented thumbnails from being created, resulting in failed thumbnails. The error messages from the terminal might provide clues as to what went wrong. You can also find some common causes in the next section.
  • Quit debugging mode:
    • Nautilus & Nemo: close the file manager and press Ctrl+C in the terminal.
    • Caja: close the file manager, press Enter in the terminal, then type quit and press Enter.

Notes:

  • With older versions of Nemo that do not provide the --debug option, use gdb instead:

    gdb nemo
    
  • If you are using Caja in a MATE session (e.g. on Ubuntu MATE), you must run gdb as root (see this for more details):

    sudo gdb caja
    

    In this case, you can only troubleshoot thumbnailer entries in /usr/share/thumbnailers and thumbnailer scripts outside the home directory.

    Alternatively, you can use Eclipse to debug Caja and thumbnailers.

Thumbnailing issues

This section discusses several situations that could lead to no thumbnails or failed thumbnails.

No thumbnails for large files

Nautilus, Nemo, and Caja set a size limit for thumbnailable files. A file whose size is above this limit will only get a generic icon, regardless of whether there is a valid thumbnailer program for its type.

To change this size limit:

  • Open the file manager, go to PreferencesPreview (Nemo, Caja) or Search & Preview (Nautilus) tab.
  • Choose a file size from Only for files smaller than.

No thumbnails for remote files

When you browse files on other computers over networks, Nautilus, Nemo, and Caja by default do not create thumbnails for them.

To enable thumbnail previews for those files:

  • Open the file manager, go to PreferencesPreview (Nemo, Caja) or Search & Preview (Nautilus) tab.
  • Set Show thumbnails to All Files (Nautilus), Yes (Nemo), or Always (Caja).

No thumbnails for files in certain folders

Nemo may disable thumbnailing for files in certain folders:

  • Open a folder, then click View in the menu bar.
  • If Show Thumbnails is not checked, then thumbnailing is disabled for files in that folder.
  • Click Edit in the menu bar → PreferencesPreview tab.
  • If Inherit thumbnail visibility from parent is checked, then thumbnailing for files in subfolders of that folder may also be turned off.

To re-enable thumbnail previews for files in a folder:

  • Open the folder, then click View in the menu bar.
  • Make sure Show Thumbnails is checked.

No thumbnails for certain file types

The file manager may disable thumbnailing for certain mime-types. To check whether this is the case, issue one of these commands, for Nautilus, Nemo, and Caja respectively:

gsettings get org.gnome.desktop.thumbnailers disable
gsettings get org.cinnamon.desktop.thumbnailers disable
gsettings get org.mate.thumbnailers disable

If the result is [] or [''], then the file manager does not disable thumbnailing for any file types. However, if there are mime-types in the brackets, for example ['image/jp2'], ['image/jp2', 'application/x-ms-dos-executable'], etc., then thumbnails for files of those types will not be created.

To enable thumbnail previews for all file types, issue one of these commands (for Nautilus, Nemo, and Caja respectively):

gsettings set org.gnome.desktop.thumbnailers disable "[]"
gsettings set org.cinnamon.desktop.thumbnailers disable "[]"
gsettings set org.mate.thumbnailers disable "[]"

Alternatively, you can use dconf Editor:

  • First, install dconf-editor:
    sudo apt install dconf-editor
    
  • Open dconf Editor, then go to one of these places (for Nautilus, Nemo, and Caja respectively):
    • orggnomedesktopthumbnailersdisable.
    • orgcinnamondesktopthumbnailersdisable.
    • orgmatedesktopthumbnailersdisable.
  • Turn off Use default value.
  • Change the value in the Custom value box to either [] or [''] to enable thumbnailing for all file types or selectively remove certain mime-types from the list to only re-enable previews for those types.
  • Click Apply in the bottom-right corner of the window.

No thumbnails for all files

Thumbnail previews might be disabled for all files. There are two places that you have to check:

  • File manager preferences:

    • Open the file manager, go to PreferencesPreview (Nemo, Caja) or Search & Preview (Nautilus) tab.
    • If Show thumbnails is set to No (Nemo) or Never (Nautilus, Caja), the file manager will not create or show thumbnails for any files.
    • To re-enable previews, set Show thumbnails to Local Files Only (Nemo, Caja) or Files on this computer only (Nautilus). Alternatively, you can set this feature to All Files (Nautilus), Yes (Nemo), or Always (Caja) to also preview remote files.
  • Desktop environment settings:

    Issue one of these commands, for Nautilus, Nemo, and Caja respectively:

    gsettings get org.gnome.desktop.thumbnailers disable-all
    gsettings get org.cinnamon.desktop.thumbnailers disable-all
    gsettings get org.mate.thumbnailers disable-all
    

    The result should be false, which is the default, but if it is true, then all thumbnailers are disabled and, as a result, no thumbnails will be generated.

    To re-enable thumbnailers, issue one of these commands (for Nautilus, Nemo, and Caja respectively):

    gsettings set org.gnome.desktop.thumbnailers disable-all false
    gsettings set org.cinnamon.desktop.thumbnailers disable-all false
    gsettings set org.mate.thumbnailers disable-all false
    

    Alternatively, you can use dconf Editor:

    • First, install dconf-editor:
      sudo apt install dconf-editor
      
    • Open dconf Editor, then go to one of these places (for Nautilus, Nemo, and Caja respectively):
      • orggnomedesktopthumbnailers
      • orgcinnamondesktopthumbnailers
      • orgmatedesktopthumbnailers
    • Turn off Disable all external thumbnailers.
    • Click Reload in the top-right corner of the window.

Failed thumbnails due to missing codecs

The codecs needed by a thumbnailer program to thumbnail certain file types might not be available because they are not bundled with the program or provided by one of its dependencies. For example, totem-video-thumbnailer needs gstreamer1.0-libav to thumbnail MP4 and other video files, but gstreamer1.0-libav is only a suggested package and is, therefore, not installed with totem-video-thumbnailer.

To track down missing codecs, try creating a PNG image from a file of the type to be thumbnailed using the thumbnailer program in a terminal. The error messages from the terminal might give clues about which codec libraries are necessary for the conversion. If the program has a verbose option, you might want to use it for more debugging information. For example:

totem-video-thumbnailer --size 256 --verbose in.webp out.png

Another way is to try suggested packages and see if any of them provide the required codecs:

  • Use apt-cache depends to get the list of suggested packages. For instance:
    apt-cache depends totem | grep Suggest
    apt-cache depends ffmpegthumbnailer | grep Suggest
    
  • Use apt-cache show to get the information of each suggested package. For example:
    apt-cache show gstreamer1.0-libav
    apt-cache show gstreamer1.0-plugins-bad
    
  • If the information can't help you determine which package contains the codecs, you may want to try installing suggested packages one by one.

It should be noted that it's also possible that the codec is unavailable in the official repositories or the program in question does not support the type of files you are trying to thumbnail at all. In such cases, it is advisable to visit the official website for the program to get more information on supported formats or simply use another thumbnailer.

Failed thumbnails due to incorrect filename extensions

The files you are trying to preview may have incorrect filename extensions, which results in inappropriate thumbnailers are called to thumbnail them. As an example, I used to have some files with the .jpg extension, but they were actually WebP images. The file manager saw them as JPEG images regardless and passed them to gdk-pixbuf-thumbnailer. Since the program could not handle WebP images, thumbnailing failed.

To fix this problem, you need to get the true types of those files using the file tool and rename them accordingly. For example, to check the type of image.png in ~/Pictures, issue this command:

file ~/Pictures/image.png

If the file is truly a PNG image, the output would be similar to this:

/home/calico/Pictures/image.png: PNG image data, 1024 x 640, 8-bit/color RGB, non-interlaced

As file scans the contents of a file to determine its type, even if you try giving the file a different extension, the result would be the same:

/home/calico/Pictures/image.png.gif: PNG image data, 1024 x 640, 8-bit/color RGB, non-interlaced

Interestingly, if you check the mime-type of the file using xdg-mime before and after changing the extension, there will be two different results:

$ xdg-mime query filetype ~/Pictures/image.png
image/png
$ mv ~/Pictures/image.png ~/Pictures/image.png.gif
$ xdg-mime query filetype ~/Pictures/image.png.gif
image/gif

Failed thumbnails due to unrecognized image file format

As can be seen in the Thumbnailer & Thumbnailer Entry section, Nemo and Caja (and also older versions of Nautilus) give each output thumbnail a random .XXXXXX suffix instead of an image extension. If the thumbnailer program does not default to writing files in PNG format (or a format supported by gdk-pixbuf-thumbnailer), it will not be able to create thumbnails for those file managers.

Fortunately, programs that are designed to be a thumbnailer, such as ffmpegthumbnailer and totem-video-thumbnailer, usually create PNG thumbnails by default. With other programs that do not default to this, the format of the output file must be explicitly specified to ensure that a valid thumbnail is generated.

It is best if the program has a convenient option for specifying the format. For example, convert has png:, and ffmpeg has -f apng:

Exec=/usr/bin/convert %i png:%o
Exec=/usr/bin/ffmpeg -i %i -f apng %o

For programs that have no such option, the universal solution is to first give the output file the .png suffix and then rename it the original filename given by the file manager. This can be done in a shell script. For instance:

#!/bin/bash

infile="$1"
outfile="$2"

/usr/bin/opj_decompress -i "$infile" -o "$outfile".png
mv "$outfile".png "$outfile"

Even though the output image file can be in any format supported by gdk-pixbuf-thumbnailer (JPEG, PNG, BMP, GIF, TGA, etc.), creating thumbnails in the PNG format is recommended for security reasons.

Failed thumbnails due to sandboxed thumbnailers

Recent versions of Nautilus sandbox thumbnailers and only allow the thumbnailing process access to certain directories. If the thumbnailer program needs files or resides in a directory outside the sandbox, thumbnailing will fail.

To get the list of directories that are mounted on the sandbox, do the following:

  • Fully close Nautilus with:
    nautilus -q
    
  • Clear all cached thumbnails:
    rm -r ~/.cache/thumbnails/*
    
  • Launch Nautilus from the terminal with debugging code enabled:
    G_MESSAGES_DEBUG=all NAUTILUS_DEBUG=Window nautilus
    
  • Go to a folder containing thumbnailable files (images, videos, etc.).
  • Find in the terminal a message similar to this:
    About to launch script: bwrap --ro-bind /usr /usr --ro-bind /etc/ld.so.cache /etc/ld.so.cache --symlink
    /usr//bin /bin --symlink /usr//lib64 /lib64 --symlink /usr//lib /lib --symlink /usr//sbin /sbin --ro-bind-try
    /var/cache/fontconfig /var/cache/fontconfig --ro-bind-try /etc/alternatives /etc/alternatives --proc /proc --dev
    /dev --chdir / --setenv GIO_USE_VFS local --unshare-all --die-with-parent --setenv G_MESSAGES_DEBUG all --bind 
    /tmp/gnome-desktop-thumbnailer-90H120 /tmp --ro-bind /home/calico/Pictures/image.webp /tmp/image.webp --seccomp
    36 /usr/bin/gdk-pixbuf-thumbnailer -s 256 file:///tmp/image.webp /tmp/gnome-desktop-thumbnailer.png
    
  • Pay attention to the --bind, --ro-bind, --ro-bind-try, and --symlink options. The argument right after each of them is a file or directory mounted on the sandbox.

To avoid failed thumbnails when using Nautilus:

  • If you use thumbnailer scripts, make sure that they are placed in a directory mounted on the sandbox (e.g. /usr/local/bin).
  • If the thumbnailer program really needs files in directories outside the sandbox, a script such as this one by Nicolas Bernaerts can be used to add those directories to the sandbox. However, doing so may defeat the purpose of sandboxing thumbnailers, so it might be better to use another thumbnailer program that has no problem with the sandbox.

For more details about the sandboxing program (bubblewrap) and its options, run this command:

man bwrap