Xdg-desktop-portal - org.freedesktop.portal No such interface FileChooser on Window Manager

I’m using the leftwm window manager, and having issues with xdg portal setup. Heres what I have in my configuration.nix:

  services.xserver.windowManager.leftwm.enable = true;

  xdg.portal.enable = true;
  xdg.portal.xdgOpenUsePortal = true;
  xdg.portal.extraPortals = [
    pkgs.xdg-desktop-portal-kde
  ];
  xdg.portal.config.common.default = [ "kde" ];

I have a own compiled (soon to hopefully be submitted to nixpkgs) version of rerun-cli, but I cannot open the load/save a file. Looking at dbus-monitor I’m getting the following:

error time=1708984342.078847 sender=:1.57 -> destination=:1.19 error_name=org.freedesktop.DBus.Error.UnknownMethod reply_serial=63
   string "No such interface “org.freedesktop.portal.FileChooser” on object at path /org/freedesktop/portal/desktop"
method call time=1708984342.078912 sender=:1.19 -> destination=org.freedesktop.DBus serial=64 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=RemoveMatch
   string "type='signal',sender='org.freedesktop.portal.Desktop',interface='org.freedesktop.portal.Request',member='Response',path='/org/freedesktop/portal/desktop/request/1_19/ashpd_hQu3X2wQuL'"
method return time=1708984342.078919 sender=org.freedesktop.DBus -> destination=:1.19 serial=53 reply_serial=64
method call time=1708984342.079013 sender=:1.19 -> destination=org.freedesktop.DBus serial=65 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=RemoveMatch
   string "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',path='/org/freedesktop/DBus',arg0='org.freedesktop.portal.Desktop'"
method return time=1708984342.079021 sender=org.freedesktop.DBus -> destination=:1.19 serial=54 reply_serial=65

How can I get this working?

First, you can see what portals are available by running door-knocker:

nix run nixpkgs#door-knocker

I had a similar issue with a quite different setup: xfce+i3 with the following config:

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

I determined the issue was that xdg-desktop-portal-gtk was running too late and solved it as follows:

    systemd.user.services.xdg-desktop-portal-gtk = {
      wantedBy = [ "xdg-desktop-portal.service" ];
      before = [ "xdg-desktop-portal.service" ];
    };

I don’t know if that applies in your case.

1 Like

Actually this hack stopped working. Maybe it’s just a timing issue so any change can make the issue go away or resurface. I had made the hypothesis that it was due to a race adding environment variables to systemd units and starting the units, but it’s not the case: by adding a unit waiting for the full environment to be there, I still get the issue

    systemd.user.services."wait-for-envvar@" = {
      description = "wait for environment variable %i to be set in systemd units";
      path = with pkgs; [ systemd coreutils gnugrep ];
      script = ''
        ispresent () {
          systemctl --user show-environment | cut -d= -f1 | grep -x "$__thevar"
        }
        while ! ispresent; do
          sleep 0.1;
        done
      '';
      environment.__thevar = "%i";
      serviceConfig = {
        Type = "oneshot";
        TimeoutStartSec = "60";
      };
    };
    systemd.user.services.xdg-desktop-portal = rec {
      after = [ "wait-for-envvar@DESKTOP_SESSION.service" ];
      wants = after;
    };
    systemd.user.services.xdg-desktop-portal-gtk = rec {
      after = [ "wait-for-envvar@DESKTOP_SESSION.service" ];
      wants = after;
    };

So after spending way too much time in gdb I think I found the source of my issue:
glib ignores desktop files whose executable is not in PATH. In my case I was clicking on a https link, and ~/.nix-profile/bin was not in PATH for xdg-desktop-portal.service because it was started to early. As a result, I would get a dialog telling me I had no application able to open this URI.

I think I fixed this by having the service wait a little bit more:

    systemd.user.services."wait-for-full-path" = {
      description = "wait for systemd units to have full PATH";
      wantedBy = [ "xdg-desktop-portal.service" ];
      before = [ "xdg-desktop-portal.service" ];
      path = with pkgs; [ systemd coreutils gnugrep ];
      script = ''
        ispresent () {
          systemctl --user show-environment | grep -E '^PATH=.*/.nix-profile/bin'
        }
        while ! ispresent; do
          sleep 0.1;
        done
      '';
      serviceConfig = {
        Type = "oneshot";
        TimeoutStartSec = "60";
      };
    };

However now that I think I have understood the cause of my issue, I think yours is a different one.

1 Like