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
5 Likes

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 https://github.com/LunNova/nixos-configs/blob/67e9e5849355ad71674ba15d185dbbaee1629bbc/packages/xdg-open-handlr/default.nix - 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.

1 Like

Thanks for the examples; I was able to solve a similar issue I was having with Todoist: Opening links in Todoist (electron app)

I’ve implemented a workaround for this as a nixos module which is exposed at nixosModules.xdg-open-workaround in github:LunNova/nixos-configs/dev .

Implementation at https://github.com/LunNova/nixos-configs/blob/04544c82759529313756caea179f334d64659562/modules/exported/xdg-open-workaround.nix and https://github.com/LunNova/nixos-configs/blob/04544c82759529313756caea179f334d64659562/packages/xdg-open-with-portal/default.nix

I’d appreciate some feedback on the approach and testing before trying to upstream it.

1 Like

nixos/xdg/xdg-open: init by LunNova · Pull Request #187293 · NixOS/nixpkgs · GitHub - draft PR adding a module for this in tree.

Going to test this on our personal machines for a while before marking it ready for review, of course feel free to test/comment!

1 Like

I’ve done this but in a complicated way. Taking security into account I think this is the only sane thing to do.

1 Like