From eb965535a4c843f0508abbff083dcf0c3864be48 Mon Sep 17 00:00:00 2001 From: ooks-io Date: Sat, 2 Dec 2023 22:26:17 +1300 Subject: [PATCH] add: xdg-portal home-manager module --- home/ooks/base/shell/default.nix | 1 - home/ooks/base/shell/lf/default.nix | 5 +- home/ooks/features/essentials/default.nix | 1 + home/ooks/features/essentials/gtk.nix | 2 + home/ooks/ookst480s.nix | 2 +- modules/home-manager/default.nix | 1 + modules/home-manager/xdg-portal.nix | 164 ++++++++++++++++++++++ system/ookst480s/ookst480s.nix | 7 - 8 files changed, 173 insertions(+), 10 deletions(-) create mode 100644 modules/home-manager/xdg-portal.nix diff --git a/home/ooks/base/shell/default.nix b/home/ooks/base/shell/default.nix index 93d8737..cdf5093 100644 --- a/home/ooks/base/shell/default.nix +++ b/home/ooks/base/shell/default.nix @@ -9,7 +9,6 @@ ./fish.nix ./pfetch.nix ./starship.nix - ./joshuto ./helix ]; home.packages = with pkgs; [ diff --git a/home/ooks/base/shell/lf/default.nix b/home/ooks/base/shell/lf/default.nix index f2e5c4a..b0258df 100644 --- a/home/ooks/base/shell/lf/default.nix +++ b/home/ooks/base/shell/lf/default.nix @@ -1,5 +1,8 @@ { pkgs, config, ... }: -#TODO mkif wayland for previewer +#TODO - mkif wayland for previewer +# - manage previewer dependencies better +# - ripdrag support +# - color parity with eza { xdg.configFile."lf/icons".source = ./icons; diff --git a/home/ooks/features/essentials/default.nix b/home/ooks/features/essentials/default.nix index f263796..6284191 100644 --- a/home/ooks/features/essentials/default.nix +++ b/home/ooks/features/essentials/default.nix @@ -10,4 +10,5 @@ ./yt-dlp.nix ./playerctl.nix ]; + xdg-portal.enable = true; } diff --git a/home/ooks/features/essentials/gtk.nix b/home/ooks/features/essentials/gtk.nix index f5d42a1..fa77bbe 100644 --- a/home/ooks/features/essentials/gtk.nix +++ b/home/ooks/features/essentials/gtk.nix @@ -27,4 +27,6 @@ rec { "Net/IconThemeName" = "${gtk.iconTheme.name}"; }; }; + + xdg-portal.extraPortals = [ pkgs.xdg-desktop-portal-gtk ]; } diff --git a/home/ooks/ookst480s.nix b/home/ooks/ookst480s.nix index 2719cbd..eaad0c8 100644 --- a/home/ooks/ookst480s.nix +++ b/home/ooks/ookst480s.nix @@ -17,4 +17,4 @@ colorscheme = inputs.nix-colors.colorSchemes.gruvbox-dark-soft; -} \ No newline at end of file +} diff --git a/modules/home-manager/default.nix b/modules/home-manager/default.nix index 5a9ebb9..6fd968d 100644 --- a/modules/home-manager/default.nix +++ b/modules/home-manager/default.nix @@ -1,4 +1,5 @@ { fonts = import ./fonts.nix; monitors = import ./monitors.nix; + xdg-portal = import ./xdg-portal.nix; } diff --git a/modules/home-manager/xdg-portal.nix b/modules/home-manager/xdg-portal.nix new file mode 100644 index 0000000..1244d9b --- /dev/null +++ b/modules/home-manager/xdg-portal.nix @@ -0,0 +1,164 @@ +{ config, pkgs, lib, ... }: + +let + inherit (lib) + mapAttrsToList mkEnableOption mkIf mkMerge mkOption optional optionalString + types; + + associationOptions = with types; + attrsOf (coercedTo (either (listOf str) str) + (x: lib.concatStringsSep ";" (lib.toList x)) str); + +in { + meta.maintainers = [ lib.maintainers.misterio77 ]; + + options.xdg.portal = { + enable = mkEnableOption (lib.mdDoc + "[xdg desktop integration](https://github.com/flatpak/xdg-desktop-portal)") + // { + default = false; + }; + + extraPortals = mkOption { + type = types.listOf types.package; + default = [ ]; + description = lib.mdDoc '' + 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 and KDE already + adds `xdg-desktop-portal-gtk`; and + `xdg-desktop-portal-kde` respectively. On other desktop + environments you probably want to add them yourself. + ''; + }; + + gtkUsePortal = mkOption { + type = types.bool; + visible = false; + default = false; + description = lib.mdDoc '' + Sets environment variable `GTK_USE_PORTAL` to `1`. + This will force GTK-based programs ran outside Flatpak to respect and use XDG Desktop Portals + for features like file chooser but it is an unsupported hack that can easily break things. + Defaults to `false` to respect its opt-in nature. + ''; + }; + + xdgOpenUsePortal = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc '' + Sets environment variable `NIXOS_XDG_OPEN_USE_PORTAL` to `1` + This will make `xdg-open` use the portal to open programs, which resolves bugs involving + programs opening inside FHS envs or with unexpected env vars set from wrappers. + See [#160923](https://github.com/NixOS/nixpkgs/issues/160923) for more info. + ''; + }; + + config = mkOption { + type = types.attrsOf associationOptions; + default = { }; + example = { + x-cinnamon = { default = [ "xapp" "gtk" ]; }; + pantheon = { + default = [ "pantheon" "gtk" ]; + "org.freedesktop.impl.portal.Secret" = [ "gnome-keyring" ]; + }; + common = { default = [ "gtk" ]; }; + }; + description = lib.mdDoc '' + Sets which portal backend should be used to provide the implementation + for the requested interface. For details check {manpage}`portals.conf(5)`. + + Configs will be linked to `/etx/xdg/xdg-desktop-portal/` with the name `$desktop-portals.conf` + for `xdg.portal.config.$desktop` and `portals.conf` for `xdg.portal.config.common` + as an exception. + ''; + }; + + configPackages = mkOption { + type = types.listOf types.package; + default = [ ]; + example = lib.literalExpression "[ pkgs.gnome.gnome-session ]"; + description = lib.mdDoc '' + List of packages that provide XDG desktop portal configuration, usually in + the form of `share/xdg-desktop-portal/$desktop-portals.conf`. + + Note that configs in `xdg.portal.config` will be preferred if set. + ''; + }; + }; + + config = let + cfg = config.xdg.portal; + + joinedPortals = pkgs.buildEnv { + name = "xdg-portals"; + paths = cfg.extraPortals; + pathsToLink = + [ "/share/xdg-desktop-portal/portals" "/share/applications" ]; + }; + + portalConfigPath = n: + "share/xdg-desktop-portal/${ + optionalString (n != "common") "${n}-" + }portals.conf"; + mkPortalConfig = desktop: conf: + pkgs.writeTextDir (portalConfigPath desktop) + (lib.generators.toINI { } { preferred = conf; }); + + joinedPortalConfigs = pkgs.buildEnv { + name = "xdg-portal-configs"; + ignoreCollisions = true; # Let config override configPackages cfgs + paths = (mapAttrsToList mkPortalConfig cfg.config) ++ cfg.configPackages; + pathsToLink = [ "/share/xdg-desktop-portal" ]; + }; + in mkIf cfg.enable (mkMerge [ + { + warnings = optional (cfg.configPackages == [ ] && cfg.config == { }) '' + xdg-desktop-portal 1.17 reworked how portal implementations are loaded, you + should either set `xdg.portal.config` or `xdg.portal.configPackages` + to specify which portal backend to use for the requested interface. + + https://github.com/flatpak/xdg-desktop-portal/blob/1.18.1/doc/portals.conf.rst.in + + If you simply want to keep the behaviour in < 1.17, which uses the first + portal implementation found in lexicographical order, use the following: + + xdg.portal.config.common.default = "*"; + ''; + + assertions = [{ + assertion = cfg.extraPortals != [ ]; + message = + "Setting xdg.portal.enable to true requires a portal implementation in xdg.portal.extraPortals such as xdg-desktop-portal-gtk or xdg-desktop-portal-kde."; + }]; + + # Make extraPortals systemd units available to the user + home.packages = [ pkgs.xdg-desktop-portal ] ++ cfg.extraPortals; + + systemd.user.services.xdg-desktop-portal = { + Unit = { + Description = "Portal service"; + PartOf = "graphical-session.target"; + }; + Service = { + Environment = [ + "XDG_DESKTOP_PORTAL_DIR=${joinedPortals}/share/xdg-desktop-portal/portals" + ] ++ (optional (cfg.configPackages != [ ]) + "NIXOS_XDG_DESKTOP_PORTAL_CONFIG_DIR=${joinedPortalConfigs}/share/xdg-desktop-portal"); + Type = "dbus"; + BusName = "org.freedesktop-portal.Desktop"; + ExecStart = "${pkgs.xdg-desktop-portal}/libexec/xdg-desktop-portal"; + Slice = "session.slice"; + }; + }; + } + # This module uses mkMerge because HM's home.sessionVariables are (at the + # time of writing) scalars, which do not work with mkIf + (mkIf cfg.gtkUsePortal { home.sessionVariables.GTK_USE_PORTAL = "1"; }) + (mkIf cfg.xdgOpenUsePortal { + home.sessionVariables.NIXOS_XDG_OPEN_USE_PORTAL = "1"; + }) + ]); +} diff --git a/system/ookst480s/ookst480s.nix b/system/ookst480s/ookst480s.nix index a11b260..3a5200b 100644 --- a/system/ookst480s/ookst480s.nix +++ b/system/ookst480s/ookst480s.nix @@ -53,13 +53,6 @@ kdeconnect.enable = true; }; -# XDG Portal -# ------------------------------------------------------------------------------------------------ - - xdg.portal = { - enable = true; - wlr.enable = true; - }; hardware = { opengl = {