Making xdg-open more resilient?

xdg-open doesn’t know to unset any env vars for library paths, XDG_*_DIRs and so on that were set for the program calling it, and then the child process is called with a pile of additional unexpected libraries or config directories that might make it fail to start. An example of this in the wild is Discord can't open links in Firefox · Issue #78961 · NixOS/nixpkgs · GitHub

I tried to work around this by making a wrapper for xdg-open
[xdg-open-wrapper] which starts from a fresh environment but this only works for apps which don’t use buildFHSUserEnv. If you run this inside one of those, /etc/profile will look like [Example /etc/profile when in a FHS sandbox].

So you are worse off and many things won’t be set at all, and of course you’re in the sandbox now so if you start a browser it’s in the FHS sandbox of an unrelated program which we don’t want to happen.

My next idea was to try having a socket in XDG_RUNTIME_DIR which is used to signal an xdg-open request and a program running outside the sandbox waiting for them which can start xdg-open there, but I don’t know how to go about doing this correctly.

What’s a generic way to have a service start that needs to start after the desktop environment with DISPLAY and XAUTHORITY, or wayland equivalents available?

Or is there some other way to get xdg-open running in a clean env outside any FHS sandbox and without extra env vars wrappers set piling up and potentially breaking things?

I think I’ve spent a good few hours tinkering with this, all I wanted was to get the links in games I launch through lutris working. >.>

[xdg-open-wrapper]

env -i USER="$USER" HOME="$HOME" DISPLAY="$DISPLAY" XDG_CURRENT_DESKTOP=X-Generic XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR XAUTHORITY=$XAUTHORITY bash -lc 'xdg-open'"$@"`

[Example /etc/profile when in a FHS sandbox]

export PS1='lutris-chrootenv:\u@\h:\w\$ '
export LOCALE_ARCHIVE='/usr/lib/locale/locale-archive'
export LD_LIBRARY_PATH="/run/opengl-driver/lib:/run/opengl-driver-32/lib:/usr/lib:/usr/lib32${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH"
export PATH="/run/wrappers/bin:/usr/bin:/usr/sbin:$PATH"
export TZDIR='/etc/zoneinfo'

# Force compilers and other tools to look in default search paths
unset NIX_ENFORCE_PURITY
export NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu=1
export NIX_CFLAGS_COMPILE='-idirafter /usr/include'
export NIX_CFLAGS_LINK='-L/usr/lib -L/usr/lib32'
export NIX_LDFLAGS='-L/usr/lib -L/usr/lib32'
export PKG_CONFIG_PATH=/usr/lib/pkgconfig
export ACLOCAL_PATH=/usr/share/aclocal
1 Like

Related issue found while testing: makeDesktopItem files aren't executable · Issue #152059 · NixOS/nixpkgs · GitHub

I have a workaround which gets my particular situation working here nixos-configs/default.nix at 67e9e5849355ad71674ba15d185dbbaee1629bbc · LunNova/nixos-configs · GitHub - I can open links inside lutris/steam games now and firefox launches.

I’m not happy with it, it’s probably very fragile, and I don’t know how to proceed towards a proper solution like the one I hoped for in the original post.

This reminds me of the “portals” that flatpaks use, which is a very similar feature all things considered. Maybe try and see if you can integrate with xdg-desktop-portal somehow? It isn’t flatpak specific as I understand it.

1 Like

Great!

That actually already works on my plasma 5 session, the necessary dbus call is:

gdbus call --session
–dest org.freedesktop.portal.Desktop
–object-path /org/freedesktop/portal/desktop
–method org.freedesktop.portal.OpenURI.OpenURI
“” “https://example.com/” {}

Don’t have time to test thoroughly at the moment.

1 Like

Seems to be working well using that approach.

Hosted by Flying Circus.