Community-driven coverage of elementary OS — news, guides & forums
Dark abstract low-poly geometric landscape with layered triangular facets in deep navy, charcoal, and muted teal, illuminated by a soft electric-blue glow near the horizon

News roundups, tutorials, application guides, and forums — built by users, for users of the elegant Linux distribution.

elementary weekly
#20
Latest roundup · 18 Apr 2015
Freya Release
Final
Covered in weekly #19 & #20
Forum Topics
Active
Installation, customization & more

Custom desktop actions and right-click menus in elementary OS

elementary OS users frequently want to extend Pantheon Files without reaching for a fork or swapping out the file manager. The right-click menu is one of the few surfaces on the desktop where small customisations still feel like personal expressions of taste, and once you understand the underlying scaffolding, you can build a context menu that does almost anything your shell can do.

The good news is that elementary OS inherits the freedesktop.org conventions for desktop entries, the same dialect used across GNOME, KDE and XFCE. A custom right-click entry is just a small text file with the right keys, dropped into the right folder, and your file manager picks it up without a restart. From there you can chain scripts, pass file paths, and even react to MIME types.

This guide walks through that scaffolding from the ground up. Whether you live in Brisbane and want a one-click action for a recurring task, or you are somewhere in regional New South Wales cobbling together a photo resizer for client deliveries, the steps are the same and the toolkit is already on your system.

Understanding the file manager context layer

Pantheon Files is built on GTK and GVfs, which means it speaks the same desktop entry dialect as the rest of your Linux desktop. When you right-click a file, the file manager asks Gio what desktop actions, scripts and applications are registered for that file's MIME type, then assembles them into the menu you see on screen. A "custom action" is simply a regular .desktop file that declares itself eligible for that menu by advertising a list of MIME types in its [Desktop Entry] header.

The system reads two locations by default. Actions stored under /usr/share/contractor/ or shipped as .contract packages are visible to every user on the machine and are typically managed through a graphical app like Contractor. Items placed in ~/.local/share/contractor/ or ~/.local/share/applications/ are personal: they affect only your account, which is exactly what most Australians want when they are configuring their own laptops, since it sidesteps the need for sudo and avoids touching shared machines at a coworking space in Melbourne or a quiet corner of the local library in Adelaide.

You can inspect what is already registered with gio mime application/pdf or by browsing the contents of those folders with ls. A neat trick is to right-click an interesting file and choose "Open with another app": the list you see there is exactly the union of what is discoverable to GVfs, so anything you add to the right folder appears alongside the defaults next time you open the menu.

Anatomy of a desktop entry file

A desktop entry file is a plain INI-style text document that ends in .desktop or .contract. The format is governed by the freedesktop.org Desktop Entry Specification, and elementary OS does not need anything beyond that. The minimum viable custom action needs a handful of keys: Type=Application, a Name= that shows up in the menu, an Exec= that runs when clicked, and at least one MIME type or a single-file reference.

A working example looks like this:

[Desktop Entry]
Type=Application
Name=Open in Geany
Exec=geany %f
MimeType=text/plain;text/x-shellscript;application/x-python;
Icon=accessories-text-editor

The %f field code tells the launcher to hand a single file path to the command. %F would hand several paths at once; %u hands a single URL, and %U hands several URLs. These placeholders are essential plumbing, because without them your action would launch but with nothing to act on. Picking the right field code is the difference between an action that runs once per file and one that batches them together.

You should also give every action a unique Name= so the menu does not collapse two entries into one. Adding a Comment= and a stock Icon name from the Adwaita theme is what makes the entry look native. Refresh the desktop cache with update-desktop-database ~/.local/share/applications/ or by logging out and back in, and your action appears the next time you right-click a matching file.

Building your first action with a terminal command

Let's build a practical example: an action that opens the current folder in a fresh Terminal instance. This is the kind of small win that turns a mouse-driven file manager into a launchpad, especially when you spend a lot of time moving between directories.

Create ~/.local/share/applications/open-in-terminal.desktop with this content:

[Desktop Entry]
Version=1.0
Type=Application
Name=Open Terminal Here
Exec=io.elementary.terminal --new-tab %f
Icon=utilities-terminal
MimeType=inode/directory;
StartupNotify=true

Save it, then update the desktop database with update-desktop-database ~/.local/share/applications/. Open Pantheon Files, navigate to a folder, right-click it, and you should see "Open Terminal Here" in the context menu. If it does not appear immediately, a quick logout forces a fresh read of the user database.

A common stumbling block on older setups is the trust prompt that elementary OS still shows for unverified .desktop files in /usr/share. Because the action in this example lives inside your home directory, you do not need to worry about that prompt, but if you ever copy an action into /usr/share/applications, run gio set to mark it trusted, or you will see the entry twice with a warning icon. Once the menu entry works, you can chain multiple actions together by writing a small bash dispatcher script and calling it from Exec=.

Passing selected files into a script

Once you understand field codes, the real magic begins. Selecting ten photos in Pantheon Files and right-clicking should trigger an action that processes all of them, not just one. To do this, the Exec= line must include %F (uppercase, multiple files) rather than %f, and the script receiving them must understand how to iterate over them.

A minimal bash handler looks like this:

#!/bin/bash
for f in "$@"; do
    echo "Resizing $f via ImageMagick"
    convert "$f" -resize 1600x1600\> "/tmp/out_$(basename "$f")"
done
zenity --info --text="Resized $# files"

Save it as ~/.local/bin/resize-batch.sh, mark it executable with chmod +x, and the matching .desktop entry can simply say Exec=/home/yourname/.local/bin/resize-batch.sh %F. Select a batch of JPEGs and trigger the action; ImageMagick runs once per file and a tidy notification appears at the end.

Where uploads matter, embedding a passthrough step that uses rsync or rclone with an Australian mirror can shave minutes off a bulk upload to a host with edge presence in Sydney or Singapore. The same applies to paths that need quoting cleanly: bash needs double quotes around each $f, because filenames in Australian Linux installations often contain spaces from photo albums copied across from phones.

Power user tricks with multiple files and mime types

MIME filtering is what keeps a custom menu from becoming cluttered. Instead of letting "Convert with HandBrake" appear on a text document, restrict it to video files by listing only video/* in MimeType. The launcher then hides the entry for everything else. This small discipline keeps the right-click menu tidy once you have half a dozen custom actions and do not want to scroll through them every time.

You can chain commands with Exec=command1;command2, though elementary OS prefers you call a wrapper script rather than chain inline. For actions that should appear on multiple selections but not single files, you can ship two .desktop entries with different field codes, or add a TryExec= key that points to a helper script and short-circuits the menu when the dependency is missing. That is a clean way to deploy the same action to colleagues who may not have ImageMagick or HandBrake installed on every workstation.

For cases where your action needs to talk back to the file manager or another app, declare DBusActivatable=true and back it with a service file in ~/.local/share/dbus-1/services/. That is what working desktop integration between elementary OS and online accounts looks like under the hood, and it pairs naturally with the Google and Nextcloud integration guide, which covers how services hand off credentials through the same plumbing.

Distributing and backing up your custom actions

Once you have a small collection of custom actions, you will want to back them up or share them with friends, family, or a local Linux user group meeting in a pub in Fitzroy. The simplest approach is to tarball the entire ~/.local/share/applications/ folder and keep it in the same place you back up dotfiles. Restoring is just unpacking the directory on a fresh install, running update-desktop-database, and the menu is back to where you left it.

For sharing, the culturally appropriate unit is the .deb package. Tools such as dh-make or elementary's Contractor utility wrap a directory of .desktop and .icon files into an installable bundle, complete with a postinst script that copies the icons into /usr/share and registers the action for every user on the machine. That is how community-maintained action packs and a handful of Australian-curated bundles get distributed through GitHub.

If your action touches anything that could be considered personal data, even just a path that crosses the network, it is worth checking the policy framework reference against Australian practice. The Notifiable Data Breaches scheme under the Privacy Act 1988 obliges organisations above the relevant turnover threshold to report serious breaches, and while a desktop action is just a launcher, the script body can handle file contents, so it pays to think about provenance before shipping.

Comparing desktop action approaches

Now that you have seen several techniques, it helps to lay them side by side. The table below sets out the three most common ways Australians extend Pantheon Files: a hand-written .desktop file, a packaged .contractor bundle, and a DBus-activated service. Pick the one whose trade-offs match your situation.

Approach Best for Maintenance Visibility
Hand-written .desktop in ~/.local/share/applications Personal workflows, quick experiments, single-user laptops Edit one file, no build step You only
Packaged .contractor bundle (.deb) Sharing with friends, family machines, community packs Requires packaging and an icon set All users on the box
DBus-activated service Actions that talk to running apps or online accounts Needs a service descriptor and review You, with system service integration

Hand-written entries are the fastest path from idea to running action. Packaged entries are the right choice the moment you want to share, and they keep the installer honest about dependencies. DBus-activated entries shine when the action is reactive, like letting elementary OS notify a running instance of Photos when a new folder is opened. None of these approaches requires root, which is why many sysadmins at Australian schools and small businesses use the personal folder for experimentation before promoting an action into a packaged bundle that survives reinstalls.

The decision often comes down to how many people benefit. If you are the only person who uses a particular script, plain ~/.local/share/applications/ wins every time because there is nothing to coordinate. If you want the same action to appear on the family desktop, or for a small studio in Perth where everyone edits the same RAW photos, the .contractor bundle pays for itself within a week. DBus-activated entries are rarer, but they are the only way to share state with a long-running process, and the elementary OS team has been steadily adding this pattern to default apps.

A handful of things are worth carrying away: the right-click menu is a polite mirror of what is on your filesystem. Every custom action is a .desktop file you have authored, and once field codes, MIME types, and a destination folder make sense, you stop being a consumer of the desktop and start shaping it. Keep your actions in a folder you back up, share them with someone who could benefit, and remember that a thoughtfully named entry turns a busy afternoon of renaming and resizing into a single click rather than a chore.

Browse the News Archive
Latest Updates

From the elementary weekly series

Low-poly faceted abstract render in dark charcoal and electric blue tones, suggesting a news bulletin or announcement
elementary news

elementary weekly #20

The first week with the final Freya release — community reactions, tips, and early impressions gathered in one roundup.

Abstract low-poly geometric scene in midnight blue and soft cyan, conveying a live broadcast or event atmosphere
elementary news

elementary SPECIAL

A live Hangouts event with the elementary OS founders, held on 11 April 2015, discussing the Freya final release.

Low-poly faceted render in deep navy and muted teal with subtle amber highlights, suggesting a tutorial or guide
Tips and Tricks

Timeshift Guide

How to use Timeshift — the intuitive system restore utility for elementary OS — to recover from configuration mishaps.

Explore

Topics & Resources

Dive into guides, application recommendations, and community discussions covering every aspect of elementary OS.