Read and Change Desktop Defaults with xdg-settings

xdg-settings reads and changes exactly two things: the default browser and URL scheme handlers. It will tell you the property names with --list rather than make you guess. This guide uses xdg-utils 1.1.3, supplied here by Ubuntu package version 1.1.3-4.1ubuntu3, to inspect the current default, check a candidate, and change the setting when you are ready.

Allow about ten minutes. You need a shell inside a graphical desktop session and an installed application with a desktop entry such as firefox.desktop. The commands are normally unprivileged; the manual specifically says xdg-settings is for a desktop session and is not recommended as root.

Checkpoint: this command changes desktop defaults, not the contents of a browser configuration file. Over a text-only SSH session, query results may come back empty or the action may fail because there is no desktop session to update.

1. Confirm the installed command

Check which executable will run and record its version. These are read-only and need no sudo:

$ command -v xdg-settings
/usr/bin/xdg-settings
$ xdg-settings --version
xdg-settings 1.1.3
$ dpkg-query -W -f='\${Package} \${Version}\n' xdg-utils
xdg-utils 1.1.3-4.1ubuntu3

The interface is small: get reads a property, check compares it with a value, and set changes it. Ask the installed command which properties it knows rather than guessing names:

$ xdg-settings --list
Known properties:
  default-url-scheme-handler    Default handler for URL scheme
  default-web-browser           Default web browser

That list is the real local contract: this installation does not promise every desktop environment supports every possible setting.

2. Read the current default browser

Query the browser property without changing anything:

$ xdg-settings get default-web-browser
firefox.desktop

The output is a desktop file name, not usually a full executable path. Yours might be chromium.desktop, google-chrome.desktop, or another entry from the desktop environment. An empty result is still a result worth investigating: it can mean this session has nothing available through the backend.

Do not turn that output into a command to run. A desktop file describes an application association and can contain launch fields that are not safe to treat as shell syntax.

3. Check a candidate without changing the setting

Use check when a script or setup note needs a yes-or-no answer:

$ xdg-settings check default-web-browser firefox.desktop
yes
$ printf 'exit status: %s\n' "$?"
exit status: 0

A negative check prints no. On this xdg-utils implementation, both a successful match and a successful non-match return status 0, so read the printed word if your automation needs to tell them apart: do not rely on $? alone.

The manual also warns that check can say no even when get prints the same value, because the check tests underlying settings that might only partly agree. Treat that as evidence of a partial or desktop-specific configuration, not a reason to keep re-running the command.

4. Inspect a URL scheme handler

Scheme handlers need a sub-property. To find what handles mailto: links:

$ xdg-settings get default-url-scheme-handler mailto
evolution.desktop

Replace mailto with the scheme you actually need, such as https, using a scheme name only, no : and no complete URL. Check what your desktop exposes first, then query it:

$ xdg-settings --list
Known properties:
  default-url-scheme-handler    Default handler for URL scheme
  default-web-browser           Default web browser
$ xdg-settings get default-url-scheme-handler mailto

If the command rejects the property or sub-property, stop at the error. A missing handler is different from a handler whose application is not installed: check the package and desktop entry through your normal package tools rather than adding sudo to xdg-settings.

5. Save the old value before making a change

Warning: changing a default is a real state change. It affects how applications in the desktop session open links. Before using set, save the exact value get returns somewhere you can read back later:

$ old_browser=$(xdg-settings get default-web-browser)
$ printf 'previous browser: %s\n' "$old_browser"
previous browser: firefox.desktop

Check that the value is plausible before proceeding; an empty result is not a useful rollback value. Find the desktop file you intend to use from the applications actually installed on this machine, and copy its name exactly.

6. Set and verify the browser

Use the desktop file name as the value. This is ordinary user-level configuration and does not need elevated privileges:

$ xdg-settings set default-web-browser google-chrome.desktop
$ xdg-settings get default-web-browser
google-chrome.desktop
$ xdg-settings check default-web-browser google-chrome.desktop
yes

set normally prints no success message, so verify with both get and check. If another program changes the association between those commands, the results can differ. The target desktop file must exist in an application-data directory visible to the session; inventing a name does not install an application.

Recovery: use the saved value rather than guessing:

$ xdg-settings set default-web-browser "$old_browser"
$ xdg-settings get default-web-browser
firefox.desktop

If you did not save the old value, use xdg-settings get default-web-browser and your desktop's settings panel to work out the replacement. Do not assume firefox.desktop exists just because Firefox is installed under a different packaging system.

7. Set a mail handler only after checking it

The same pattern applies to a scheme handler: save the current value, change one scheme, then query it again:

$ old_mailer=$(xdg-settings get default-url-scheme-handler mailto)
$ printf 'previous mail handler: %s\n' "$old_mailer"
previous mail handler: evolution.desktop
$ xdg-settings set default-url-scheme-handler mailto thunderbird.desktop
$ xdg-settings get default-url-scheme-handler mailto
thunderbird.desktop
$ xdg-settings set default-url-scheme-handler mailto "$old_mailer"

Replace both desktop file names with applications that are actually installed. This example can affect links opened by unrelated programs, so avoid running it in a shared session unless the change really is intended for that user. Verify the final restore with one more get.

8. Diagnose failures without escalating privileges

Use the exit codes to separate mistakes from unavailable desktop support. Status 1 is a command-line syntax failure, status 2 is a missing file argument, status 3 is a missing required tool, and status 4 is an action that failed. The command may also print a short diagnostic:

$ xdg-settings get definitely-not-a-property
xdg-settings - get various settings from the desktop environment
Synopsis
...
$ printf 'exit status: %s\n' "$?"
exit status: 1

The synopsis text above is abbreviated because the help output itself is the useful part, not a stable error message. Re-run xdg-settings --list, check the spelling, and confirm the shell belongs to the intended desktop session. Running as root usually changes the wrong user's settings and does not fix a missing session bus or application entry.

Done means