NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
16.48k stars 12.98k forks source link

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

Open LunNova opened 2 years ago

LunNova commented 2 years ago

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 commented 1 year ago

Potential workaround for i3 users if your xdg-desktop-portal is failing to start your browser due to path issues:

    services.xserver.windowManager.i3.extraSessionCommands = ''
      systemctl --user import-environment PATH
    '';
tobiasBora commented 1 year ago

Is this supposed to work in steam-run? I just tried it and it fails. See the issue here https://github.com/NixOS/nixpkgs/issues/237581

lilyinstarlight commented 1 year ago

@LunNova

What's the correct way to do this?

services.xserver.windowManager.i3.extraSessionCommands = ''
      systemctl --user import-environment PATH
    '';

As far as I know, using either dbus-update-activation-environment --systemd (which updates the systemd user session environment) or systemctl --user import-environment is the correct way to do that

I did think about making a PR to add /run/current-system/sw/bin to the default PATH for the xdg-desktop-portal systemd user service to avoid having to import PATH, but to be honest importing PATH (as well as XDG_DATA_DIRS, etc.) in each window manager's config is probably the more "correct" fix and I believe is what GNOME shell does

tobiasBora commented 1 year ago

Hum wait, I’m very confused, I just rebooted without adding anything and now it works! Not sure what happened…

Also, any idea why we don’t enable xdgOpenUsePortal = true; by default?

Naxdy commented 1 year ago

With xdgOpenUsePortal = true;, Lutris is still not properly opening links for me. Running xdg-open in systemd-run --user -t -S works however.

Any ideas what could cause this ?

Slabity commented 12 months ago

Just want to drop in here and note that xdgOpenUsePortal completely breaks xdg-open on my system. With it enabled, something as simple as xdg-open https://google.com/ fails to open up firefox, despite xdg-mime query default x-scheme-handler/https and xdg-settings get default-web-browser both reporting firefox.desktop.

I tried to debug it, but honestly there's just no error or debug messages that I could find that led me in the right direction.

As a note, I am using Sway. I'm not sure if there's some startup commands I need to add to get it working properly.

Atemu commented 12 months ago

@Slabity which portal do you have configured?

Slabity commented 12 months ago

@Slabity which portal do you have configured?

I'm just gonna post what I think is relevant. Here's what I have for my NixOS configuration:

programs.sway = {
  enable = true;
  wrapperFeatures.gtk = true;
};

environment.sessionVariables = {
  GTK_USE_PORTAL = "1";
};

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

And for home-manager:

wayland.windowManager.sway = {
  enable = true;
  systemd.enable = true;
  package = null;
  config = { ... };
};

I'm not entirely sure if I need to run some sort of systemd or dbus-* command to my startup, but I had what was on the unofficial NixOS wiki here for a bit: https://nixos.wiki/wiki/Sway

Though neither the dbus-sway-environment or configure-gtk parts affected the behavior, so I no longer have them.

My full config can be found here: https://github.com/Slabity/nix-flakes

Atemu commented 12 months ago

I don't know how home-manager plays into this. What you need is that the GTK portal user service is running. In DBUS, you should see a service implementing the portal thingies such as file picker.

If portals are not working in general, you can't verify whether this works or not.

lilyinstarlight commented 12 months ago

Though neither the dbus-sway-environment or configure-gtk parts affected the behavior, so I no longer have them.

You do need something like dbus-sway-environment (or at least have sway run dbus-update-activation-environment --systemd --all) but make sure it includes all environment variables from your sway config, not just WAYLAND_DISPLAY (some like XDG_DATA_DIRS and PATH are also needed for the portal xdg-open to work correctly)

Ideally we make the NixOS module automatically handle all that, but sway is kinda a diy sort of thing, so portals are not quite functional out-of-the-box in your NixOS config

You can use the command systemd-run --user -t gio mime x-scheme-handler/https to test whether it'll work in a portal or not, since it should roughly emulate the environment the portal runs in

Slabity commented 12 months ago

Thanks @Atemu and @lilyinstarlight. Calling dbus-update-activation-environment --systemd --all does seem to fix everything with xdgOpenUsePortal enabled.

I'm not certain, but I think there might be an underlying issue in the home-manager sway module. From what I can tell, the NixOS module creates /etc/sway/config.d/nixos.conf that contains exec dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP, but since my configuration is part of home-manager this config never actually gets executed.

On the other hand, home-manager does automatically include the following at the end of the config:

exec "/nix/store/29n5vxmqjfy4qips1x66hq6y2m9q0qlp-dbus-1.14.8/bin/dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP XDG_SESSION_TYPE NIXOS_OZONE_WL; systemctl --user start sway-session.target"

So it sounds like both the NixOS and home-manager sway modules might not be adding all the necessary environment variables to this list? Presumably the XDG_DATA_DIRS and PATH ones?

Out of curiosity, is there any issue with just using --all instead of listing each variable? Would it be worth updating the NixOS module to use that instead?

LunNova commented 12 months ago

Also, any idea why we don’t enable xdgOpenUsePortal = true; by default?

It could do with some more time to bake, there are too many people running into issues with it.

lilyinstarlight commented 12 months ago

So it sounds like both the NixOS and home-manager sway modules might not be adding all the necessary environment variables to this list? Presumably the XDG_DATA_DIRS and PATH ones?

Yeah it's missing those necessary variables for xdg-open in portals (portals can otherwise probably work with the variables they have though, e.g. for screenshare or file chooser)

Out of curiosity, is there any issue with just using --all instead of listing each variable? Would it be worth updating the NixOS module to use that instead?

I don't realistically think there are issues, but maybe some people would not prefer that. I've not tried to get that changed. I think that is effectively the same as what DEs like GNOME do though

LunNova commented 11 months ago

https://github.com/NixOS/nixpkgs/pull/243834 - this should fix xdgOpenUsePortal with nixos's i3 session.

Once that's in should we consider turning on xdgOpenUsePortal by default and closing this issue? Are there any other known cases where it doesn't work?

huantianad commented 11 months ago

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

lilyinstarlight commented 11 months ago

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 commented 10 months ago

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 commented 7 months ago

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 commented 6 months ago

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 commented 6 months ago

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 commented 6 months ago

@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 commented 6 months ago

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

Prn-Ice commented 5 months ago

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

viscountexx commented 3 months ago

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 commented 2 months ago

@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 commented 2 months ago

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

sbuller commented 2 months ago

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 commented 2 months ago

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 commented 2 months ago

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. :beers:

deftdawg commented 2 months ago

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. :sleepy:

 # 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 commented 2 months ago

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 commented 2 months ago

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.

https://github.com/NixOS/nixpkgs/issues/107826 decided making them executable was a bad idea.

deftdawg commented 2 months ago

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 commented 2 months ago

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 commented 2 months ago

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 :thinking:

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 commented 2 months ago

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 commented 2 months ago

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 commented 2 months ago

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 commented 1 week ago

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