about summary refs log tree commit diff
diff options
context:
space:
mode:
authorK900 <me@0upti.me>2024-02-26 09:12:06 +0300
committerGitHub <noreply@github.com>2024-02-26 09:12:06 +0300
commit92b9d11129f9134f4592d3c75cb6764c1c2cfece (patch)
tree5430e8592a97b10dedfa316f7146eb4d62913d66
parente3474e1d1e53b70e2b2af73ea26d6340e82f6b8b (diff)
parente722c5616095cf5cacc25acfb76ebf165be25feb (diff)
Merge pull request #282377 from hcsch/pipewire-wireplumber-config-packages
nixos/pipewire: add configPackages options
-rw-r--r--nixos/modules/services/desktops/pipewire/pipewire.nix51
-rw-r--r--nixos/modules/services/desktops/pipewire/wireplumber.nix113
2 files changed, 122 insertions, 42 deletions
diff --git a/nixos/modules/services/desktops/pipewire/pipewire.nix b/nixos/modules/services/desktops/pipewire/pipewire.nix
index da409030b3a35..238259c212bb7 100644
--- a/nixos/modules/services/desktops/pipewire/pipewire.nix
+++ b/nixos/modules/services/desktops/pipewire/pipewire.nix
@@ -1,11 +1,15 @@
-# pipewire service.
+# PipeWire service.
 { config, lib, pkgs, ... }:
 
 with lib;
 
 let
   json = pkgs.formats.json {};
-  mapToFiles = location: config: concatMapAttrs (name: value: { "pipewire/${location}.conf.d/${name}.conf".source = json.generate "${name}" value;}) config;
+  mapToFiles = location: config: concatMapAttrs (name: value: { "share/pipewire/${location}.conf.d/${name}.conf" = json.generate "${name}" value; }) config;
+  extraConfigPkgFromFiles = locations: filesSet: pkgs.runCommand "pipewire-extra-config" { } ''
+    mkdir -p ${lib.concatMapStringsSep " " (l: "$out/share/pipewire/${l}.conf.d") locations}
+    ${lib.concatMapStringsSep ";" ({name, value}: "ln -s ${value} $out/${name}") (lib.attrsToList filesSet)}
+  '';
   cfg = config.services.pipewire;
   enable32BitAlsaPlugins = cfg.alsa.support32Bit
                            && pkgs.stdenv.isx86_64
@@ -19,13 +23,33 @@ let
     mkdir -p "$out/lib"
     ln -s "${cfg.package.jack}/lib" "$out/lib/pipewire"
   '';
+
+  configPackages = cfg.configPackages;
+
+  extraConfigPkg = extraConfigPkgFromFiles
+    [ "pipewire" "client" "client-rt" "jack" "pipewire-pulse" ]
+    (
+      mapToFiles "pipewire" cfg.extraConfig.pipewire
+      // mapToFiles "client" cfg.extraConfig.client
+      // mapToFiles "client-rt" cfg.extraConfig.client-rt
+      // mapToFiles "jack" cfg.extraConfig.jack
+      // mapToFiles "pipewire-pulse" cfg.extraConfig.pipewire-pulse
+    );
+
+  configs = pkgs.buildEnv {
+    name = "pipewire-configs";
+    paths = configPackages
+      ++ [ extraConfigPkg ]
+      ++ lib.optionals cfg.wireplumber.enable cfg.wireplumber.configPackages;
+    pathsToLink = [ "/share/pipewire" ];
+  };
 in {
   meta.maintainers = teams.freedesktop.members ++ [ lib.maintainers.k900 ];
 
   ###### interface
   options = {
     services.pipewire = {
-      enable = mkEnableOption (lib.mdDoc "pipewire service");
+      enable = mkEnableOption (lib.mdDoc "PipeWire service");
 
       package = mkPackageOption pkgs "pipewire" { };
 
@@ -33,7 +57,7 @@ in {
         default = true;
         type = types.bool;
         description = lib.mdDoc ''
-          Automatically run pipewire when connections are made to the pipewire socket.
+          Automatically run PipeWire when connections are made to the PipeWire socket.
         '';
       };
 
@@ -200,6 +224,15 @@ in {
           '';
         };
       };
+
+      configPackages = lib.mkOption {
+        type = lib.types.listOf lib.types.package;
+        default = [];
+        description = lib.mdDoc ''
+          List of packages that provide PipeWire configuration, in the form of
+          `share/pipewire/*/*.conf` files.
+        '';
+      };
     };
   };
 
@@ -283,12 +316,8 @@ in {
       "alsa/conf.d/99-pipewire-default.conf" = mkIf cfg.alsa.enable {
         source = "${cfg.package}/share/alsa/alsa.conf.d/99-pipewire-default.conf";
       };
-    }
-    // mapToFiles "pipewire" cfg.extraConfig.pipewire
-    // mapToFiles "client" cfg.extraConfig.client
-    // mapToFiles "client-rt" cfg.extraConfig.client-rt
-    // mapToFiles "jack" cfg.extraConfig.jack
-    // mapToFiles "pipewire-pulse" cfg.extraConfig.pipewire-pulse;
+      pipewire.source = "${configs}/share/pipewire";
+    };
 
     environment.sessionVariables.LD_LIBRARY_PATH =
       lib.mkIf cfg.jack.enable [ "${cfg.package.jack}/lib" ];
@@ -301,7 +330,7 @@ in {
           "audio"
           "video"
         ] ++ lib.optional config.security.rtkit.enable "rtkit";
-        description = "Pipewire system service user";
+        description = "PipeWire system service user";
         isSystemUser = true;
         home = "/var/lib/pipewire";
         createHome = true;
diff --git a/nixos/modules/services/desktops/pipewire/wireplumber.nix b/nixos/modules/services/desktops/pipewire/wireplumber.nix
index 95a7ece26c5d2..dc4d726d76327 100644
--- a/nixos/modules/services/desktops/pipewire/wireplumber.nix
+++ b/nixos/modules/services/desktops/pipewire/wireplumber.nix
@@ -14,60 +14,111 @@ in
         type = lib.types.bool;
         default = config.services.pipewire.enable;
         defaultText = lib.literalExpression "config.services.pipewire.enable";
-        description = lib.mdDoc "Whether to enable Wireplumber, a modular session / policy manager for PipeWire";
+        description = lib.mdDoc "Whether to enable WirePlumber, a modular session / policy manager for PipeWire";
       };
 
       package = lib.mkOption {
         type = lib.types.package;
         default = pkgs.wireplumber;
         defaultText = lib.literalExpression "pkgs.wireplumber";
-        description = lib.mdDoc "The wireplumber derivation to use.";
+        description = lib.mdDoc "The WirePlumber derivation to use.";
+      };
+
+      configPackages = lib.mkOption {
+        type = lib.types.listOf lib.types.package;
+        default = [ ];
+        description = lib.mdDoc ''
+          List of packages that provide WirePlumber configuration, in the form of
+          `share/wireplumber/*/*.lua` files.
+        '';
       };
-    };
-  };
 
-  config = lib.mkIf cfg.enable {
-    assertions = [
-      {
-        assertion = !config.hardware.bluetooth.hsphfpd.enable;
-        message = "Using Wireplumber conflicts with hsphfpd, as it provides the same functionality. `hardware.bluetooth.hsphfpd.enable` needs be set to false";
-      }
-    ];
+      extraLv2Packages = lib.mkOption {
+        type = lib.types.listOf lib.types.package;
+        default = [];
+        example = lib.literalExpression "[ pkgs.lsp-plugins ]";
+        description = lib.mdDoc ''
+          List of packages that provide LV2 plugins in `lib/lv2` that should
+          be made available to WirePlumber for [filter chains][wiki-filter-chain].
 
-    environment.systemPackages = [ cfg.package ];
+          Config packages have their required LV2 plugins added automatically,
+          so they don't need to be specified here.
 
-    environment.etc."wireplumber/main.lua.d/80-nixos.lua" = lib.mkIf (!pwUsedForAudio) {
-      text = ''
-        -- Pipewire is not used for audio, so prevent it from grabbing audio devices
+          [wiki-filter-chain]: https://docs.pipewire.org/page_module_filter_chain.html
+        '';
+      };
+    };
+  };
+
+  config =
+    let
+      pwNotForAudioConfigPkg = pkgs.writeTextDir "share/wireplumber/main.lua.d/80-pw-not-for-audio.lua" ''
+        -- PipeWire is not used for audio, so prevent it from grabbing audio devices
         alsa_monitor.enable = function() end
       '';
-    };
-    environment.etc."wireplumber/main.lua.d/80-systemwide.lua" = lib.mkIf config.services.pipewire.systemWide {
-      text = ''
+      systemwideConfigPkg = pkgs.writeTextDir "wireplumber/main.lua.d/80-systemwide.lua" ''
         -- When running system-wide, these settings need to be disabled (they
         -- use functions that aren't available on the system dbus).
         alsa_monitor.properties["alsa.reserve"] = false
         default_access.properties["enable-flatpak-portal"] = false
       '';
-    };
-    environment.etc."wireplumber/bluetooth.lua.d/80-systemwide.lua" = lib.mkIf config.services.pipewire.systemWide {
-      text = ''
+      systemwideBluetoothConfigPkg = pkgs.writeTextDir "wireplumber/bluetooth.lua.d/80-systemwide.lua" ''
         -- When running system-wide, logind-integration needs to be disabled.
         bluez_monitor.properties["with-logind"] = false
       '';
-    };
 
-    systemd.packages = [ cfg.package ];
+      configPackages = cfg.configPackages
+          ++ lib.optional (!pwUsedForAudio) pwNotForAudioConfigPkg
+          ++ lib.optionals config.services.pipewire.systemWide [ systemwideConfigPkg systemwideBluetoothConfigPkg ];
 
-    systemd.services.wireplumber.enable = config.services.pipewire.systemWide;
-    systemd.user.services.wireplumber.enable = !config.services.pipewire.systemWide;
+      configs = pkgs.buildEnv {
+        name = "wireplumber-configs";
+        paths = configPackages;
+        pathsToLink = [ "/share/wireplumber" ];
+      };
+
+      requiredLv2Packages = lib.flatten
+        (
+          lib.concatMap
+            (p:
+              lib.attrByPath ["passthru" "requiredLv2Packages"] [] p
+            )
+            configPackages
+        );
+
+      lv2Plugins = pkgs.buildEnv {
+        name = "wireplumber-lv2-plugins";
+        paths = cfg.extraLv2Packages ++ requiredLv2Packages;
+        pathsToLink = [ "/lib/lv2" ];
+      };
+    in
+    lib.mkIf cfg.enable {
+      assertions = [
+        {
+          assertion = !config.hardware.bluetooth.hsphfpd.enable;
+          message = "Using WirePlumber conflicts with hsphfpd, as it provides the same functionality. `hardware.bluetooth.hsphfpd.enable` needs be set to false";
+        }
+      ];
+
+      environment.systemPackages = [ cfg.package ];
+
+      environment.etc.wireplumber.source = "${configs}/share/wireplumber";
 
-    systemd.services.wireplumber.wantedBy = [ "pipewire.service" ];
-    systemd.user.services.wireplumber.wantedBy = [ "pipewire.service" ];
+      systemd.packages = [ cfg.package ];
 
-    systemd.services.wireplumber.environment = lib.mkIf config.services.pipewire.systemWide {
-      # Force wireplumber to use system dbus.
-      DBUS_SESSION_BUS_ADDRESS = "unix:path=/run/dbus/system_bus_socket";
+      systemd.services.wireplumber.enable = config.services.pipewire.systemWide;
+      systemd.user.services.wireplumber.enable = !config.services.pipewire.systemWide;
+
+      systemd.services.wireplumber.wantedBy = [ "pipewire.service" ];
+      systemd.user.services.wireplumber.wantedBy = [ "pipewire.service" ];
+
+      systemd.services.wireplumber.environment = lib.mkIf config.services.pipewire.systemWide {
+        # Force WirePlumber to use system dbus.
+        DBUS_SESSION_BUS_ADDRESS = "unix:path=/run/dbus/system_bus_socket";
+        LV2_PATH = "${lv2Plugins}/lib/lv2";
+      };
+
+      systemd.user.services.wireplumber.environment.LV2_PATH =
+        lib.mkIf (!config.services.pipewire.systemWide) "${lv2Plugins}/lib/lv2";
     };
-  };
 }