diff --git a/nixos/modules/services/desktops/flatpak.nix b/nixos/modules/services/desktops/flatpak.nix index d191eeff990f..23480e652675 100644 --- a/nixos/modules/services/desktops/flatpak.nix +++ b/nixos/modules/services/desktops/flatpak.nix @@ -3,26 +3,45 @@ with lib; -{ +let + cfg = config.services.flatpak; +in { ###### interface options = { services.flatpak = { enable = mkEnableOption "flatpak"; + + extraPortals = mkOption { + type = types.listOf types.package; + default = []; + description = '' + List of additional portals to add to path. Portals allow interaction + with system, like choosing files or taking screenshots. At minimum, + a desktop portal implementation should be listed. GNOME already + adds xdg-desktop-portal-gtk; for KDE, there + is xdg-desktop-portal-kde. Other desktop + environments will probably want to do the same. + ''; + }; }; }; ###### implementation - config = mkIf config.services.flatpak.enable { + config = mkIf cfg.enable { environment.systemPackages = [ pkgs.flatpak ]; - services.dbus.packages = [ pkgs.flatpak ]; + services.dbus.packages = [ pkgs.flatpak pkgs.xdg-desktop-portal ] ++ cfg.extraPortals; - systemd.packages = [ pkgs.flatpak ]; + systemd.packages = [ pkgs.flatpak pkgs.xdg-desktop-portal ] ++ cfg.extraPortals; - environment.variables.PATH = [ - "$HOME/.local/share/flatpak/exports/bin" - "/var/lib/flatpak/exports/bin" - ]; + environment.variables = { + PATH = [ + "$HOME/.local/share/flatpak/exports/bin" + "/var/lib/flatpak/exports/bin" + ]; + + XDG_DESKTOP_PORTAL_PATH = map (p: "${p}/share/xdg-desktop-portal/portals") cfg.extraPortals; + }; }; } diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix index 10e8ef0ed381..27b62df7097c 100644 --- a/nixos/modules/services/x11/desktop-managers/gnome3.nix +++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix @@ -120,6 +120,7 @@ in { services.xserver.libinput.enable = mkDefault true; # for controlling touchpad settings via gnome control center services.udev.packages = [ pkgs.gnome3.gnome-settings-daemon ]; systemd.packages = [ pkgs.gnome3.vino ]; + services.flatpak.extraPortals = [ pkgs.xdg-desktop-portal-gtk ]; # If gnome3 is installed, build vim for gtk3 too. nixpkgs.config.vim.gui = "gtk3"; diff --git a/pkgs/development/libraries/xdg-desktop-portal/default.nix b/pkgs/development/libraries/xdg-desktop-portal/default.nix index 6721d5f00acb..98bd8ba23bb5 100644 --- a/pkgs/development/libraries/xdg-desktop-portal/default.nix +++ b/pkgs/development/libraries/xdg-desktop-portal/default.nix @@ -14,6 +14,10 @@ in stdenv.mkDerivation rec { sha256 = "06gipd51snvlp2jp68v2c8rwbsv36kjzg9xacm81n1w4b2dpz4g0"; }; + patches = [ + ./respect-path-env-var.patch + ]; + nativeBuildInputs = [ autoreconfHook pkgconfig libxml2 ]; buildInputs = [ glib pipewire fuse ]; diff --git a/pkgs/development/libraries/xdg-desktop-portal/respect-path-env-var.patch b/pkgs/development/libraries/xdg-desktop-portal/respect-path-env-var.patch new file mode 100644 index 000000000000..f884899ecd19 --- /dev/null +++ b/pkgs/development/libraries/xdg-desktop-portal/respect-path-env-var.patch @@ -0,0 +1,76 @@ +--- a/src/xdg-desktop-portal.c ++++ b/src/xdg-desktop-portal.c +@@ -177,38 +177,50 @@ + static void + load_installed_portals (void) + { +- const char *portal_dir = PKGDATADIR "/portals"; +- g_autoptr(GFile) dir = g_file_new_for_path (portal_dir); +- g_autoptr(GFileEnumerator) enumerator = NULL; + +- enumerator = g_file_enumerate_children (dir, "*", G_FILE_QUERY_INFO_NONE, NULL, NULL); ++ g_auto(GStrv) portal_dir_list; ++ int i; ++ const char *portal_dir = g_getenv ("XDG_DESKTOP_PORTAL_PATH"); ++ ++ if (portal_dir == NULL) ++ portal_dir = PKGDATADIR "/portals"; + +- if (enumerator == NULL) +- return; ++ portal_dir_list = g_strsplit (portal_dir, G_SEARCHPATH_SEPARATOR_S, 0); + +- while (TRUE) ++ for (i = 0; portal_dir_list[i] != NULL; i++) + { +- g_autoptr(GFileInfo) info = g_file_enumerator_next_file (enumerator, NULL, NULL); +- g_autoptr(GFile) child = NULL; +- g_autofree char *path = NULL; +- const char *name; +- g_autoptr(GError) error = NULL; ++ portal_dir = portal_dir_list[i]; ++ g_autoptr(GFile) dir = g_file_new_for_path (portal_dir); ++ g_autoptr(GFileEnumerator) enumerator = NULL; ++ enumerator = g_file_enumerate_children (dir, "*", G_FILE_QUERY_INFO_NONE, NULL, NULL); + +- if (info == NULL) +- break; ++ if (enumerator == NULL) ++ continue; + +- name = g_file_info_get_name (info); ++ while (TRUE) ++ { ++ g_autoptr(GFileInfo) info = g_file_enumerator_next_file (enumerator, NULL, NULL); ++ g_autoptr(GFile) child = NULL; ++ g_autofree char *path = NULL; ++ const char *name; ++ g_autoptr(GError) error = NULL; + +- if (!g_str_has_suffix (name, ".portal")) +- continue; ++ if (info == NULL) ++ break; + +- child = g_file_enumerator_get_child (enumerator, info); +- path = g_file_get_path (child); ++ name = g_file_info_get_name (info); + +- if (!register_portal (path, &error)) +- { +- g_warning ("Error loading %s: %s", path, error->message); +- continue; ++ if (!g_str_has_suffix (name, ".portal")) ++ continue; ++ ++ child = g_file_enumerator_get_child (enumerator, info); ++ path = g_file_get_path (child); ++ ++ if (!register_portal (path, &error)) ++ { ++ g_warning ("Error loading %s: %s", path, error->message); ++ continue; ++ } + } + } +