Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apps launched by xdg-open can misbehave when called from FHS envs or wrapped programs #160923

Open
LunNova opened this issue Feb 19, 2022 · 89 comments

Comments

@LunNova
Copy link
Member

LunNova commented Feb 19, 2022

Describe the bug

When calling xdg-open from a FHS env or wrapped app, it tries to launch the associated program directly while either having unexpected/unrelated environment variables like LD_PRELOAD set or worse being in an FHS env which is entirely missing some dependencies.

Ideally, xdg-open when used in a FHS env or wrapped package would use xdg-desktop-portal to launch apps instead, similarly to how flatpaks use this to open other applications outside of the package.

There is partial upstream support for this but it only applies in flatpaks:
https://github.com/freedesktop/xdg-utils/blob/1a58bc28f6844898532daf9ee1bf6da7764955a9/scripts/xdg-open.in#L250
https://github.com/freedesktop/xdg-utils/blob/d11b33ec7f24cfb1546f6b459611d440013bdc72/scripts/xdg-utils-common.in#L361-L363
It also doesn't handle local files correctly.

An example script which also handles files is here.

Steps To Reproduce

One example of this issue, although there are many related issues in different contexts.

Steps to reproduce the behavior:

  1. Launch lutris under KDE
  2. Click a link in it or an app launched by it
  3. KDE thinks firefox's .desktop item isn't owned by root as it's owned by nobody in the FHS sandbox and refuses to start it

Expected behavior

The xdg-open package in NixOS should use xdg-desktop-portal to launch apps/urls/etc when possible as if it is inside a flatpak to avoid running apps in unexpected FHS envs or with unexpected env from wrappers.

Screenshots

Opening a link in FFXIV under lutris
Error if you click yes

Notify maintainers

@edolstra - xdg-utils maintainer entry
@Atemu @illegalprime @wentasah - work on bwrap FHS envs

Metadata

Please run nix-shell -p nix-info --run "nix-info -m" and paste the result.

[user@system:~]$ nix-shell -p nix-info --run "nix-info -m"
 - system: `"x86_64-linux"`
 - host os: `Linux 5.15.19-xanmod1-tt, NixOS, 22.05 (Quokka)`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.7.0pre20220127_558c4ee`
 - channels(root): `"nixos-21.11.333896.a640d8394f3"`
 - channels(lun): `""`
 - nixpkgs: `/etc/nix/path/nixpkgs`
@LunNova
Copy link
Member Author

LunNova commented Feb 19, 2022

Related issues:

@LunNova
Copy link
Member Author

LunNova commented Feb 19, 2022

@Atemu
Copy link
Member

Atemu commented Feb 19, 2022

The xdg-open package in NixOS should use xdg-desktop-portal to launch apps/urls/etc when possible as if it is inside a flatpak to avoid running apps in unexpected FHS envs or with unexpected env from wrappers.

Before we reinvent any wheels, how does Flatpak solve this problem?

@LunNova
Copy link
Member Author

LunNova commented Feb 19, 2022

xdg-utils detects $XDG_RUNTIME_DIR/flatpak-info existing and uses xdg-desktop-portal. This implementation is incomplete and will only handle URLs but hopefully it wouldn't be too hard to get local file support added upstream like in the script I linked.

I'm not sure if making xdg-open think it's in a flatpak in general is safe or if it'd be better to get a more nix-specific toggle added.

@Atemu
Copy link
Member

Atemu commented Feb 19, 2022

I'm not sure if making xdg-open think it's in a flatpak in general is safe

I mean, it basically is?

Is there a non-Flatpak-specific way to handle portals? I imagine Snap and AppImage must be doing it somehow too. If they also use the Flatpak method, we should use it too. If they use a more generic way, we should use that.

@LunNova
Copy link
Member Author

LunNova commented Feb 19, 2022

I was concerned that telling xdg-utils it's in a flatpak by making sure that flatpak-info exists would cause problems with unrelated things.

@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/who-uses-nixos-with-kde/18212/10

@PAI5REECHO
Copy link

So is this why links from Discord open in Chrome instead of my default browser? 🤔

@LunNova
Copy link
Member Author

LunNova commented Apr 24, 2022

@PAI5REECHO

So is this why links from Discord open in Chrome instead of my default browser? thinking

It's possible although it's probably not that, it's more likely an issue with the xdg associations.

If you use home-manager, try something like xdg-mime-apps.nix

@PAI5REECHO
Copy link

@LunNova

it's more likely an issue with the xdg associations

It's not that, firefox is the only thing I have set in my .config/mimeapps.list

@LunNova
Copy link
Member Author

LunNova commented May 14, 2022

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/dev/modules/exported/xdg-open-workaround.nix and https://github.com/LunNova/nixos-configs/blob/dev/packages/xdg-open-with-portal/default.nix

Is this approach worth upstreaming?

@ShamrockLee
Copy link
Contributor

ShamrockLee commented Jun 10, 2022

Is #176962 related to this issue?

@SuperSandro2000
Copy link
Member

@LunNova yes please

@schlichtanders
Copy link

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/dev/modules/exported/xdg-open-workaround.nix and https://github.com/LunNova/nixos-configs/blob/dev/packages/xdg-open-with-portal/default.nix

Is this approach worth upstreaming?

I would be glad if this problem can be solved generically, as it effects many applications (for me for example zettlr and marktext). I haven't tried your workaround, but it looks good when looking at the files.

@LunNova How can I install your nixos module?

@LunNova
Copy link
Member Author

LunNova commented Jul 23, 2022

Add github:LunNova/nixos-configs/main as a flake input:

inputs = {
  ...
  lunnova-nixos-configs.url = "github:LunNova/nixos-configs/main";
  ...
}

Add it as an argument to outputs, then add lunnova-nixos-configs.nixosModules.xdg-open-workaround into the modules list you're passing to lib.nixosSystem.

Not sure how best to do it if you don't use flakes.

I'll try to get a PR to include this in nixpkgs shortly.

@deifactor
Copy link
Contributor

@LunNova I haven't completely tried your approach, but one thing I noticed is that on my system ulimit -Sn is 1024, so just running exec 9999< /some/file fails. Maybe pick your favorite three-digit number as the fd?

@LunNova
Copy link
Member Author

LunNova commented Aug 16, 2022

Been somewhat distracted, hope to make a PR for this tonight. (Yes, this comment is an accountability post for myself so I'll actually do it :))

@LunNova LunNova mentioned this issue Aug 18, 2022
13 tasks
@LunNova
Copy link
Member Author

LunNova commented Aug 18, 2022

Draft PR up here: #187293

@LunNova
Copy link
Member Author

LunNova commented Aug 18, 2022

@deifactor I swapped it to use bash's "new" (from 2009 lol) syntax for auto selecting an available FD instead, hopefully that works on your machine!

@deifactor
Copy link
Contributor

Looks like it works (that is, exec {foo}< /etc/passwd; echo $foo echoes 10, so I assume this means the syntax is compatible). Thanks!

@deifactor
Copy link
Contributor

Not commenting on the quality of the fix itself, more "how did we get here".

So if I understand correctly, the problem is that your FHS application can have an arbitrary environment, which get passed to xdg-open, which get in turn passed down to Firefox. On most distributions, this isn't a problem because you don't do weird stuff with environment variables (or if you do, you do so for your entire user session so you'll break firefox immediately), but nixpkgs' isolation means that the FHS application might have LD_PRELOAD, LD_LIBRARY_PATH, or some other weird thing set that isn't set when invoking it normally.

  1. Doesn't any solution that involves gdbus (or any 'wrapper' program) run the risk of having the same issue if you set some env variable in a way that makes gdbus sad?
  2. Can we fix this by just having xdg-open clear out variables that are suspected to be problematic (LD_*)? Obviously having any fix is better than nothing, but it feels a little weird that this solution relies on the fact that portals happen to exist, if that makes sense.

@LunNova
Copy link
Member Author

LunNova commented Sep 7, 2022

Doesn't any solution that involves gdbus (or any 'wrapper' program) run the risk of having the same issue if you set some env variable in a way that makes gdbus sad?

Yes, but it has a limited scope as once you manage to make a dbus call you're talking to the portal which isn't inheriting your environment, and it's only one combination to test (your program's env/fhs + gdbus) instead of your program's env/fhs + any other program in your system it might launch.

Can we fix this by just having xdg-open clear out variables that are suspected to be problematic (LD_*)? Obviously having any fix is better than nothing, but it feels a little weird that this solution relies on the fact that portals happen to exist, if that makes sense.

This works for wrapped programs but not FHS envs. FHS envs use namespaces/cgroups, you can't undo this just by clearing an environment variable.

If your solution only needs to work for wrapped programs, clearing a set of env variables works.

@huantianad
Copy link
Contributor

We would need to enable xdg portals in general by default too, right? Is there any issue with that?

@lilyinstarlight
Copy link
Member

lilyinstarlight commented Jul 16, 2023

Perhaps particular desktop environment NixOS modules can just enable it themselves when the module is compatible with it?

For example the GNOME and Plasma NixOS modules and I guess now i3 could enable it by default (once your PR is merged), but for anyone who is using a module that will not support it out-of-the-box (e.g. sway) or is putting together their own DE/WM without a NixOS module and does not having portals fully-working, enabling it by default would just lead to very surprising behavior with no useful warnings or error messages to indicate what is wrong

We would need to enable xdg portals in general by default too, right? Is there any issue with that?

The xdgOpenUsePortal option only has any effect when portals themselves are also enabled (but as mentioned, just because they are enabled don't mean they are fully working or that the needed portals are added)

@unode
Copy link
Member

unode commented Sep 4, 2023

Sorry to highjack the thread but I seem to be encountering issues with Joplin Desktop again. Opening links in Firefox works (as discussed above) but opening an embedded PDF in an external app doesn't.

The PATH update suggestions mentioned in another ticket didn't have an effect.

It's also difficult to debug as I can't seem to replicate the behavior with systemd-run --user -t. In that case, when opening a PDF, I get a dialog asking which program to use (Evince, Zathura, ...)

How are you troubleshooting these issues and making sure that the cause of the problem is not a different one from what is described in this thread?

@dyfrgi
Copy link

dyfrgi commented Dec 5, 2023

Freedesktop deleted their xdg-utils repo here so I can't see whether https://github.com/freedesktop/xdg-utils/pull/12 was declined or just not merged. I filed https://gitlab.freedesktop.org/xdg/xdg-utils/-/issues/240 asking upstream to implement a similar override. Thanks for this work. Perhaps this should be turned on by default for home-manager when running in an FHS env as I expect this will be a problem for many apps installed in that way.

@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/cant-open-steam-links-from-proton-games/36734/4

@larsivi
Copy link

larsivi commented Dec 25, 2023

This issue (I assume) is preventing me from logging into the JetBrains Toolbox.
I have KDE Plasma and have vivaldi as my default browser. Nixos updated to latest stable.

To login (I have a subscription that must be checked to give me access to the various applications), it redirects to the browser. First I get the "KIO-client" warning, not actually opening anything in Vivaldi. If I switch to Firefox, I am able to get to the app approval in the browser. However, Firefox appears to not be able to deal with this.

I then took the url that was opened in Firefox, copied it over in Vivaldi, then approved it there. This then opened up an xdg-open dialog (the link is jetbrains://) which when clicked on does absolutely nothing.

I'm fairly new to nixos, so I'm not entirely sure where to look up the relevant logs etc

@newzubakhin
Copy link

@larsivi

I then took the url that was opened in Firefox, copied it over in Vivaldi, then approved it there. This then opened up an xdg-open dialog (the link is jetbrains://) which when clicked on does absolutely nothing.

As I can see, Jetbrains Toolbox from nixpks doesn't handle jetbrains:// links at all. You can check .desktop in the archive from the official site and copy MimeType=x-scheme-handler section from it.

@Atemu
Copy link
Member

Atemu commented Dec 26, 2023

That looks like a fairly trivial fix on the Nixpkgs side.

@Prn-Ice
Copy link

Prn-Ice commented Feb 4, 2024

For anyone with the KDE/vscodeFHS issue. I think you can fix it with some of the suggestions here. Remember to restart your PC after updating the portal settings.

What worked for me was

  • Add this to your system nix configs

    xdg.portal = {
        enable = true;
        xdgOpenUsePortal = true;
      };
  • Install xdg-utils with home-manager

@viscountexx
Copy link

viscountexx commented Mar 19, 2024

For anyone with the KDE/vscodeFHS issue. I think you can fix it with some of the suggestions here. Remember to restart your PC after updating the portal settings.

What worked for me was

* Add this to your system nix configs
  ```nix
  xdg.portal = {
      enable = true;
      xdgOpenUsePortal = true;
    };
  ```

* Install `xdg-utils` with home-manager

Assuming that this option works in most/all use cases and doesn't break anything:

  1. Should this be considered fixed and the issue closed?
  2. This should probably be prioritized as either a default inclusion in the sample system Nix config for graphical systems (at least if you're using the KDE installer?), a default when you enable KDE, or mentioned very clearly in the docs as a recommended option to set. I suspect that'd make for an issue or forum discussion that stands on its own, yeah?

@LunNova
Copy link
Member Author

LunNova commented Apr 9, 2024

@K900 thoughts on changing the plasma 6 defaults like @viscountexx suggested? We could set the env var only in the plasma 6 session so it doesn't impact non-plasma sessions.

@K900
Copy link
Contributor

K900 commented Apr 9, 2024

We could mkDefault it I guess, but I'd be very careful with the potential side effects.

@sbuller
Copy link

sbuller commented Apr 10, 2024

So, I just stumbled on this while debugging an issue with a URL handler. The xdgOpenUsePortal definitely deals with the issue, but I end up with a much bigger problem. All of a sudden xdg-open seems to have a split personality. I call xdg-mime query default inode/directory, and it (properly) tells me org.kde.dolphin.desktop, but when I xdg-open ~ I get VSCodium trying to open the directory. I have since discovered that gio mime inode/directory (mentioned above) simply lists the desktop files it finds in alphabetical order, rather than consulting the preferences set in KDE. My reading of this is that xdg-open, part way through, is forgetting that it's running on KDE.

@sbuller
Copy link

sbuller commented Apr 12, 2024

So, I decided to go the route of making .desktop files executable, and made an overlay to handle the bulk of it. It doesn't work with every package, but it seems to work for many.

  executableDesktopFiles = final: _prev: let
    pkgs = import inputs.nixpkgs {
      system = "x86_64-linux";
      config.allowUnfree = true;
    };
    fixDesktop = name: pkg: pkgs.runCommand "${name}-exedesk" {} ''
      mkdir -p $out/share/applications
      cp -ur ${pkg.out}/* $out/
      cp -nL ${pkg.out}/share/applications/* $out/share/applications || true
      for f in $out/share/applications/*; do
        target=$(readlink -f "$f")
        if [ -L "$f" ]; then
          rm "$f"
          cp "$target" "$f"
        fi
        chmod +x "$f"
      done
    '';
  in builtins.mapAttrs fixDesktop {
    inherit (pkgs)
      audacity
      blender
      brave
      ...
    ;
  };

@deftdawg
Copy link

Based on the discussion here and the fact Firefox (with an executable .desktop file which brave doesn't have) works perfectly, while Joplin-Desktop opening links -> Brave browser does this:
image
image

I'm having this same challenge... I'll give @sbuller's overlay a try and hope for a less hacky fix to this issue to eventually emerge. 🍻

@deftdawg
Copy link

Tried to incorporate @sbuller's overlay into my /etc/nixos/configuration.nix, unfortunately it didn't work as is... My brain is a bit cooked (long day), I tweaked the config into this which produces an infinite recursion error. 😪

 # MARK: Joplin-Desktop -> Brave URL Open fix
 nixpkgs.overlays = [
    (final: _prev: let
      # pkgs = import inputs.nixpkgs {
      #   system = "x86_64-linux";
      #   config.allowUnfree = true;
      # };
      fixDesktop = name: pkg: pkgs.runCommand "${name}-exedesk" {} ''
        mkdir -p $out/share/applications
        cp -ur ${pkg.out}/* $out/
        cp -nL ${pkg.out}/share/applications/* $out/share/applications || true
        for f in $out/share/applications/*; do
          target=$(readlink -f "$f")
          if [ -L "$f" ]; then
            rm "$f"
            cp "$target" "$f"
          fi
          chmod +x "$f"
        done
      '';
    in builtins.mapAttrs fixDesktop {
      inherit (pkgs)
      brave;
    }
    )
  ];

@sbuller
Copy link

sbuller commented Apr 14, 2024

Sorry about that whole let pkgs=... business, I was trying to deal with infinite recursion myself and it took a bit of doing before I got something working. You should replace pkgs and _prev with prev. To clarify, the underscore on _prev is just there to show it's not being used currently and should be removed when you start using prev in place of pkgs.

@LunNova
Copy link
Member Author

LunNova commented Apr 14, 2024

If that fixes launching you're probably launching the handler for that filetype inside the FHS bubblewrap container for the app you tried to open it from, so it's not a great solution.

I recommend trying to get portals working correctly rather than marking .desktop files +x. KDE only thinks they need +x when it tries to launch inside a bubblewrap FHS containers because the .desktop files look like they're owned by nobody:nobody.

#107826 decided making them executable was a bad idea.

@deftdawg
Copy link

If that fixes launching you're probably launching the handler for that filetype inside the FHS bubblewrap container for the app you tried to open it from, so it's not a great solution.

#107826 decided making them executable was a bad idea.

Yep, it's bad, I don't disagree... however that issue is also from 4 years ago and this issue is over 2 years old. This problem is annoying, I'll live with the risks using the workaround for it until there's a proper fix.

Here's the full working code for @sbuller's workaround for anyone else that wants:

  # MARK: Joplin-Desktop -> Brave URL open workaround (credit: sbuller)
  nixpkgs.overlays = [
    (final: prev: let
      fixDesktop = name: pkg: prev.runCommand "${name}-exedesk" {} ''
        mkdir -p $out/share/applications
        cp -ur ${pkg.out}/* $out/
        cp -nL ${pkg.out}/share/applications/* $out/share/applications || true
        for f in $out/share/applications/*; do
          target=$(readlink -f "$f")
          if [ -L "$f" ]; then
            rm "$f"
            cp "$target" "$f"
          fi
          chmod +x "$f"
        done
      '';
    in builtins.mapAttrs fixDesktop {
      inherit (prev)
      brave;
    }
    )
  ];

@sbuller
Copy link

sbuller commented Apr 15, 2024

I'm really struggling with debugging DBus here. Is it possible that kde / xdg-desktop-portal-kde just doesn't implement OpenURI, and when gdbus tries to call it gdbus just falls back to gio which then uses a default gnome config?

@LunNova
Copy link
Member Author

LunNova commented Apr 15, 2024

The KDE portal should support OpenURI.

What do you have set under xdg.portal? There's a config attrset under it which controls which portals are used under which desktop environments. Maybe that priority is set up incorrectly 🤔

Here's an example which sets it for KDE and i3 in case that helps.

    xdg.portal = {
      enable = true;
      xdgOpenUsePortal = true;
      # I think the name under config has to match up with the value of XDG_CURRENT_DESKTOP.
      # kde portal by default, fallback to anything for KDE and i3
      # I don't set this for KDE in my personal config and it seems to work fine.
      config.KDE.default = [ "kde" "*" ];
      config.${"none+i3"}.default = [ "kde" "*" ];
      extraPortals = [
        pkgs.xdg-desktop-portal-gtk
        pkgs.xdg-desktop-portal-wlr
      ];
    };

@sbuller
Copy link

sbuller commented Apr 15, 2024

I'd had

xdg.portal = {
  enable = true;
  xdgOpenUsePortal = true;
  wlr.enable = true;
  extraPortals = [ pkgs.xdg-desktop-portal-kde ];
};

but no variation that I've tried has made any difference, including an exact copy of the above. In every instance (when xdgOpenUsePortal is set) xdg-open ~ uses vscodium, while kde-open uses dolphin.

I went and looked through https://github.com/KDE/xdg-desktop-portal-kde, and found no mention of OpenURI, but I'm not sure if that's the right place to look.

@sbuller
Copy link

sbuller commented Apr 16, 2024

Explicitly setting xdg.mime.{addedAssociations,defaultApplications} works around the issue for the mimetypes which I've set. This is unsatisfactory however, as I don't get to benefit from the long list of associations set by my desktop environment.

@lilyinstarlight
Copy link
Member

lilyinstarlight commented Apr 27, 2024

Just a heads-up, we should probably update xdgUsePortal to use the env vars from https://gitlab.freedesktop.org/xdg/xdg-utils/-/merge_requests/112 if it is merged (seems likely) and remove our own patch

@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/alvr-cant-launch-steamvr-steam-desktop-is-not-executable/43845/10

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests