- Work best with org.freedesktop.FileManager1.common
- Alternative
- Installation
- Configuration
- Test
- For developers
- Usage
- Tricks (Optional)
- Documentation
- License
[xdg-desktop-portal] backend for choosing files with your favorite file chooser. By default, it will use the yazi file manager, but this is customizable. Based on [xdg-desktop-portal-wlr] (xdpw).
Having trouble with "Open in Folder" in your web browser’s download manager — where it doesn’t highlight the downloaded file or respect your file manager configuration? If so, check out this file manager D-Bus service. There's a preview section to help you understand what it does: https://github.com/boydaihungst/org.freedesktop.FileManager1.common
By combining xdg-desktop-portal-termfilechooser with org.freedesktop.FileManager1.common,
you'll get a file-opening experience similar to macOS and Windows.
For NixOs, more configurations, and better support, see:
https://github.com/hunkyburrito/xdg-desktop-portal-termfilechooser
For Arch:
yay -S xdg-desktop-portal-termfilechooser-boydaihungst-gitOn apt-based systems:
sudo apt install xdg-desktop-portal build-essential ninja-build meson libinih-dev libsystemd-dev scdocFor Arch, see the dependencies in the AUR package.
git clone https://github.com/boydaihungst/xdg-desktop-portal-termfilechooser-
Remove legacy files:
cd xdg-desktop-portal-termfilechooser chmod +x remove_legacy_file.sh && sudo remove_legacy_file.sh
-
Then check and update if you are using any old version of wrapper script:
$HOME/.config/xdg-desktop-portal-termfilechooser/ANY-wrapper.shIf you use wrapper scripts from/usr/share/xdg-desktop-portal-termfilechooser/ANY-wrapper.sh, then it always up to date. -
Build and install:
meson build --prefix=/usr ninja -C build sudo ninja -C build install
Copy the config and any of the wrapper scripts in contrib dir to ~/.config/xdg-desktop-portal-termfilechooser.
Edit the config file to set your preferred terminal emulator and file manager applications.
For terminal emulator. You can set the TERMCMD environment variable instead of edit wrapper file.
So you only need to copy config. By default wrappers is placed at /usr/share/xdg-desktop-portal-termfilechooser/
Example:
-
$HOME/.profile -
.bashrc# use wezterm intead of kitty export TERMCMD="wezterm start --always-new-process"
-
$HOME/.config/xdg-desktop-portal-termfilechooser/configor$XDG_CONFIG_HOME/xdg-desktop-portal-termfilechooser/configUse yazi wrapper instead of ranger wrapper:[filechooser] cmd=/usr/share/xdg-desktop-portal-termfilechooser/yazi-wrapper.sh default_dir=$HOME
-
Use custom yazi wrapper instead of default wrapper:
[filechooser] cmd=$HOME/.config/xdg-desktop-portal-termfilechooser/yazi-wrapper.sh default_dir=$HOME
-
or
[filechooser] cmd=$XDG_CONFIG_HOME/xdg-desktop-portal-termfilechooser/yazi-wrapper.sh default_dir=$HOME
The default_dir is used in case the app, which triggers download/upload or select file/folder, doesn't suggested location to save/open file/directory or suggested a relative path to its CWD, which we can't access from dbus message.
For example in firefox it's $HOME the first time, after successfully selected/saved file, it will remember the last selected location.
This location is suggested by the app (e.g. firefox), not by xdg-desktop-portal-termfilechooser itself. Normally, it remember the last selected location based on file extension. Rare case like Obsidian, always suggest relative path = ., so we have to fallback to default_dir, because we don't know where the CWD of Obsidian is.
-
If your xdg-desktop-portal version is >=
1.18.0, then you can specify the portal for FileChooser in~/.config/xdg-desktop-portal/portals.conffile (see the flatpak docs and ArchWiki):# Get version of xdg-desktop-portal xdg-desktop-portal --version # If xdg-desktop-portal not on $PATH, try: /usr/libexec/xdg-desktop-portal --version
Or, if it says
No such file or directory:# Run command below to get the location of xdg-desktop-portal, which is ExecStart=COMMAND systemctl cat --user xdg-desktop-portal.service /path/to/xdg-desktop-portal -l TRACE -r[preferred] org.freedesktop.impl.portal.FileChooser=termfilechooser
-
If your
xdg-desktop-portal --versionis older, you can removeFileChooserfromInterfacesof the{gtk;kde;…}.portalfiles:find /usr/share/xdg-desktop-portal/portals -name '*.portal' -not -name 'termfilechooser.portal' \ -exec grep -q 'FileChooser' '{}' \; \ -exec sudo sed -i'.bak' 's/org\.freedesktop\.impl\.portal\.FileChooser;\?//g' '{}' \;
-
Restart the portal service:
systemctl --user restart xdg-desktop-portal.service
GTK_USE_PORTAL=1 zenity --file-selection
GTK_USE_PORTAL=1 zenity --file-selection --directory
GTK_USE_PORTAL=1 zenity --file-selection --multiple
# Change `USER` to your `username`:
GTK_USE_PORTAL=1 zenity --file-selection --save --filename='/home/USER/save_file_$.txtand additional options: --multiple, --directory, --save.
-
After editing termfilechooser's config, restart its service:
systemctl --user restart xdg-desktop-portal-termfilechooser.service
-
Debug the termfilechooser:
systemctl --user stop xdg-desktop-portal-termfilechooser.service /usr/lib/xdg-desktop-portal-termfilechooser -l TRACE -r
Or, if it says
No such file or directory:# Run command below to get the location of xdg-desktop-portal-termfilechooser, which is ExecStart=COMMAND systemctl --user cat xdg-desktop-portal-termfilechooser.service. /path/to/xdg-desktop-portal-termfilechooser -l TRACE -rThis way the output from the wrapper scripts (e.g.
yazi-wrapper.sh) will be written to the same terminal. Then try to reproduce the bug. Finally, upload create an issue and upload logs, app use xdg-open to open/save file and the custom wrapper script if you use it. -
Since this merge request in GNOME,
GTK_USE_PORTAL=1seems to be replaced withGDK_DEBUG=portals. -
See also: Troubleshooting section in ArchWiki.
- Stop service:
systemctl --user stop xdg-desktop-portal-termfilechooser.service - Build and run in debug mode:
meson build --prefix=/usr --reconfigure && ninja -C build && ./build/xdg-desktop-portal-termfilechooser -l TRACE -r - Monitor dbus message:
dbus-monitor --session "interface='org.freedesktop.portal.FileChooser'" - Explain dbus message values meaning: https://github.com/flatpak/xdg-desktop-portal/blob/main/data/org.freedesktop.portal.FileChooser.xml
Firefox has a setting in its about:config to always use XDG desktop portal's file chooser: set widget.use-xdg-desktop-portal.file-picker to 1. See https://wiki.archlinux.org/title/Firefox#XDG_Desktop_Portal_integration.
If you use yazi-wrapper.sh, you could install boydaihungst/hover-after-moved.yazi. So when you move placeholder file to other directory, yazi will auto hover over it. The placeholder file is created by termfilechooser when you save/download a file.
If you use any wrapper.sh with wezterm, you could add the following lua script to wezterm.lua.
So when wezterm is open with your preferred file manager, it will display workspace name beside the cwd path:
local wezterm = require("wezterm")
wezterm.on("format-window-title", function(tab, pane, tabs, panes, config)
local ws = wezterm.mux.get_active_workspace()
local title = tab.active_pane.title
if ws ~= "default" then
return string.format("[%s] %s", ws, title)
end
return title
end)Also open your preferred wrapper.sh and edit the line termcmd= to termcmd="${TERMCMD:-/usr/bin/wezterm start --class 'yazi' --workspace $(quote_string "$TITLE")}"
Results:
Open your preferred wrapper.sh and edit --class or --app-id in the line termcmd= to whatever value you want.
For example kitty + yazi: termcmd="${TERMCMD:-kitty --app-id 'yazi-selector' --title $(quote_string "$TITLE")}"
hyprland.conf floating window with app-id/class = yazi-selector:
windowrulev2 = float, class:^yazi-selector$
windowrulev2 = size 80% 90%, class:^yazi-selector$See man 5 xdg-desktop-portal-termfilechooser.
MIT
xdg-desktop-portal
original author: GermainZ
xdg-desktop-portal-wlr
ranger
yazi
lf
fzf
nnn
vifm