about summary refs log tree commit diff
path: root/nixpkgs/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos')
-rw-r--r--nixpkgs/nixos/modules/hardware/video/switcheroo-control.nix17
-rw-r--r--nixpkgs/nixos/modules/services/desktops/pipewire/pipewire.nix84
-rw-r--r--nixpkgs/nixos/modules/services/desktops/pipewire/wireplumber.nix113
3 files changed, 164 insertions, 50 deletions
diff --git a/nixpkgs/nixos/modules/hardware/video/switcheroo-control.nix b/nixpkgs/nixos/modules/hardware/video/switcheroo-control.nix
index 982388f8e5f4..967120d6744a 100644
--- a/nixpkgs/nixos/modules/hardware/video/switcheroo-control.nix
+++ b/nixpkgs/nixos/modules/hardware/video/switcheroo-control.nix
@@ -1,18 +1,19 @@
 { config, pkgs, lib, ... }:
 
-with lib;
 let
-  pkg = [ pkgs.switcheroo-control ];
   cfg = config.services.switcherooControl;
 in {
   options.services.switcherooControl = {
-    enable = mkEnableOption (lib.mdDoc "switcheroo-control, a D-Bus service to check the availability of dual-GPU");
+    enable = lib.mkEnableOption "switcheroo-control, a D-Bus service to check the availability of dual-GPU";
+    package = lib.mkPackageOption pkgs "switcheroo-control" { };
   };
 
-  config = mkIf cfg.enable {
-    services.dbus.packages = pkg;
-    environment.systemPackages = pkg;
-    systemd.packages = pkg;
-    systemd.targets.multi-user.wants = [ "switcheroo-control.service" ];
+  config = lib.mkIf cfg.enable {
+    services.dbus.packages = [ cfg.package ];
+    environment.systemPackages = [ cfg.package ];
+    systemd = {
+      packages = [ cfg.package ];
+      targets.multi-user.wants = [ "switcheroo-control.service" ];
+    };
   };
 }
diff --git a/nixpkgs/nixos/modules/services/desktops/pipewire/pipewire.nix b/nixpkgs/nixos/modules/services/desktops/pipewire/pipewire.nix
index da409030b3a3..aa24c0842bab 100644
--- a/nixpkgs/nixos/modules/services/desktops/pipewire/pipewire.nix
+++ b/nixpkgs/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,48 @@ 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" ];
+  };
+
+  requiredLv2Packages = lib.flatten
+    (
+      lib.concatMap
+      (p:
+        lib.attrByPath ["passthru" "requiredLv2Packages"] [] p
+      )
+      configPackages
+    );
+
+  lv2Plugins = pkgs.buildEnv {
+    name = "pipewire-lv2-plugins";
+    paths = cfg.extraLv2Packages ++ requiredLv2Packages;
+    pathsToLink = [ "/lib/lv2" ];
+  };
 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 +72,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 +239,30 @@ 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.
+        '';
+      };
+
+      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 PipeWire for [filter chains][wiki-filter-chain].
+
+          Config packages have their required LV2 plugins added automatically,
+          so they don't need to be specified here.
+
+          [wiki-filter-chain]: https://docs.pipewire.org/page_module_filter_chain.html
+        '';
+      };
     };
   };
 
@@ -249,6 +312,9 @@ in {
     systemd.user.sockets.pipewire.enable = !cfg.systemWide;
     systemd.user.services.pipewire.enable = !cfg.systemWide;
 
+    systemd.services.pipewire.environment.LV2_PATH = lib.mkIf cfg.systemWide "${lv2Plugins}/lib/lv2";
+    systemd.user.services.pipewire.environment.LV2_PATH = lib.mkIf (!cfg.systemWide) "${lv2Plugins}/lib/lv2";
+
     # Mask pw-pulse if it's not wanted
     systemd.user.services.pipewire-pulse.enable = cfg.pulse.enable;
     systemd.user.sockets.pipewire-pulse.enable = cfg.pulse.enable;
@@ -283,12 +349,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 +363,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/nixpkgs/nixos/modules/services/desktops/pipewire/wireplumber.nix b/nixpkgs/nixos/modules/services/desktops/pipewire/wireplumber.nix
index 95a7ece26c5d..dc4d726d7632 100644
--- a/nixpkgs/nixos/modules/services/desktops/pipewire/wireplumber.nix
+++ b/nixpkgs/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";
     };
-  };
 }