From 7b2d97cc2dde0224b6959f10778dcc8f6a44e4f5 Mon Sep 17 00:00:00 2001 From: talyz Date: Thu, 1 Apr 2021 12:03:18 +0200 Subject: [PATCH 1/2] pipewire: Add JSON parser patch --- pkgs/development/libraries/pipewire/default.nix | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkgs/development/libraries/pipewire/default.nix b/pkgs/development/libraries/pipewire/default.nix index 955a4d9da6e..d685bde35ed 100644 --- a/pkgs/development/libraries/pipewire/default.nix +++ b/pkgs/development/libraries/pipewire/default.nix @@ -75,6 +75,11 @@ let ./0070-installed-tests-path.patch # Add flag to specify configuration directory (different from the installation directory). ./0080-pipewire-config-dir.patch + # Fix JSON parser. + (fetchpatch { + url = "https://gitlab.freedesktop.org/pipewire/pipewire/-/commit/34800dc0191a4ee7a329eeb361a6f2ccf4a75176.diff"; + sha256 = "0dzxzr408qqzf0252nwg14709p1lb2k826i3kdzg6djq8w98d5aj"; + }) ]; nativeBuildInputs = [ From 2a3c276b5321e0499db5d825a6e0abc0ce096a29 Mon Sep 17 00:00:00 2001 From: talyz Date: Wed, 31 Mar 2021 17:27:50 +0200 Subject: [PATCH 2/2] nixos/pipewire: Use formats.json, stricter typing, line breaks The upstream pipewire config is written in an almost, but not quite JSON format. The parser accepts standard JSON, though, so we don't need to write our file in the same nonstandard version. The typing for all config options is changed from `types.attrs`, which behaves poorly when the option is set from multiple locations, to the formats.json-type. Also, rewrite some very long one-liners for improved readability. --- .../pipewire/pipewire-media-session.nix | 65 +++++++++++-------- .../services/desktops/pipewire/pipewire.nix | 56 ++++++++-------- 2 files changed, 65 insertions(+), 56 deletions(-) diff --git a/nixos/modules/services/desktops/pipewire/pipewire-media-session.nix b/nixos/modules/services/desktops/pipewire/pipewire-media-session.nix index 539a4cf4469..17a2d49bb1f 100644 --- a/nixos/modules/services/desktops/pipewire/pipewire-media-session.nix +++ b/nixos/modules/services/desktops/pipewire/pipewire-media-session.nix @@ -4,6 +4,7 @@ with lib; let + json = pkgs.formats.json {}; cfg = config.services.pipewire.media-session; enable32BitAlsaPlugins = cfg.alsa.support32Bit && pkgs.stdenv.isx86_64 @@ -17,24 +18,13 @@ let media-session = (builtins.fromJSON (builtins.readFile ./media-session.conf.json)); v4l2-monitor = (builtins.fromJSON (builtins.readFile ./v4l2-monitor.conf.json)); }; - # Helpers for generating the pipewire JSON config file - mkSPAValueString = v: - if builtins.isList v then "[${lib.concatMapStringsSep " " mkSPAValueString v}]" - else if lib.types.attrs.check v then - "{${lib.concatStringsSep " " (mkSPAKeyValue v)}}" - else if builtins.isString v then "\"${lib.generators.mkValueStringDefault { } v}\"" - else lib.generators.mkValueStringDefault { } v; - mkSPAKeyValue = attrs: map (def: def.content) ( - lib.sortProperties - ( - lib.mapAttrsToList - (k: v: lib.mkOrder (v._priority or 1000) "${lib.escape [ "=" ":" ] k} = ${mkSPAValueString (v._content or v)}") - attrs - ) - ); - - toSPAJSON = attrs: lib.concatStringsSep "\n" (mkSPAKeyValue attrs); + configs = { + alsa-monitor = recursiveUpdate defaults.alsa-monitor cfg.config.alsa-monitor; + bluez-monitor = recursiveUpdate defaults.bluez-monitor cfg.config.bluez-monitor; + media-session = recursiveUpdate defaults.media-session cfg.config.media-session; + v4l2-monitor = recursiveUpdate defaults.v4l2-monitor cfg.config.v4l2-monitor; + }; in { meta = { @@ -62,7 +52,7 @@ in { config = { media-session = mkOption { - type = types.attrs; + type = json.type; description = '' Configuration for the media session core. For details see https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/${cfg.package.version}/src/daemon/media-session.d/media-session.conf @@ -71,7 +61,7 @@ in { }; alsa-monitor = mkOption { - type = types.attrs; + type = json.type; description = '' Configuration for the alsa monitor. For details see https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/${cfg.package.version}/src/daemon/media-session.d/alsa-monitor.conf @@ -80,7 +70,7 @@ in { }; bluez-monitor = mkOption { - type = types.attrs; + type = json.type; description = '' Configuration for the bluez5 monitor. For details see https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/${cfg.package.version}/src/daemon/media-session.d/bluez-monitor.conf @@ -89,7 +79,7 @@ in { }; v4l2-monitor = mkOption { - type = types.attrs; + type = json.type; description = '' Configuration for the V4L2 monitor. For details see https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/${cfg.package.version}/src/daemon/media-session.d/v4l2-monitor.conf @@ -106,15 +96,34 @@ in { systemd.packages = [ cfg.package ]; systemd.user.services.pipewire-media-session.wantedBy = [ "pipewire.service" ]; - environment.etc."pipewire/media-session.d/media-session.conf" = { text = toSPAJSON (recursiveUpdate defaults.media-session cfg.config.media-session); }; - environment.etc."pipewire/media-session.d/v4l2-monitor.conf" = { text = toSPAJSON (recursiveUpdate defaults.v4l2-monitor cfg.config.v4l2-monitor); }; + environment.etc."pipewire/media-session.d/media-session.conf" = { + source = json.generate "media-session.conf" configs.media-session; + }; + environment.etc."pipewire/media-session.d/v4l2-monitor.conf" = { + source = json.generate "v4l2-monitor.conf" configs.v4l2-monitor; + }; - environment.etc."pipewire/media-session.d/with-alsa" = mkIf config.services.pipewire.alsa.enable { text = ""; }; - environment.etc."pipewire/media-session.d/alsa-monitor.conf" = mkIf config.services.pipewire.alsa.enable { text = toSPAJSON (recursiveUpdate defaults.alsa-monitor cfg.config.alsa-monitor); }; + environment.etc."pipewire/media-session.d/with-alsa" = + mkIf config.services.pipewire.alsa.enable { + text = ""; + }; + environment.etc."pipewire/media-session.d/alsa-monitor.conf" = + mkIf config.services.pipewire.alsa.enable { + source = json.generate "alsa-monitor.conf" configs.alsa-monitor; + }; - environment.etc."pipewire/media-session.d/with-pulseaudio" = mkIf config.services.pipewire.pulse.enable { text = ""; }; - environment.etc."pipewire/media-session.d/bluez-monitor.conf" = mkIf config.services.pipewire.pulse.enable { text = toSPAJSON (recursiveUpdate defaults.bluez-monitor cfg.config.bluez-monitor); }; + environment.etc."pipewire/media-session.d/with-pulseaudio" = + mkIf config.services.pipewire.pulse.enable { + text = ""; + }; + environment.etc."pipewire/media-session.d/bluez-monitor.conf" = + mkIf config.services.pipewire.pulse.enable { + source = json.generate "bluez-monitor.conf" configs.bluez-monitor; + }; - environment.etc."pipewire/media-session.d/with-jack" = mkIf config.services.pipewire.jack.enable { text = ""; }; + environment.etc."pipewire/media-session.d/with-jack" = + mkIf config.services.pipewire.jack.enable { + text = ""; + }; }; } diff --git a/nixos/modules/services/desktops/pipewire/pipewire.nix b/nixos/modules/services/desktops/pipewire/pipewire.nix index 7cf19706a63..dbd6c5d87e1 100644 --- a/nixos/modules/services/desktops/pipewire/pipewire.nix +++ b/nixos/modules/services/desktops/pipewire/pipewire.nix @@ -4,6 +4,7 @@ with lib; let + json = pkgs.formats.json {}; cfg = config.services.pipewire; enable32BitAlsaPlugins = cfg.alsa.support32Bit && pkgs.stdenv.isx86_64 @@ -29,24 +30,13 @@ let pipewire-pulse = builtins.fromJSON (builtins.readFile ./pipewire-pulse.conf.json); }; - # Helpers for generating the pipewire JSON config file - mkSPAValueString = v: - if builtins.isList v then "[${lib.concatMapStringsSep " " mkSPAValueString v}]" - else if lib.types.attrs.check v then - "{${lib.concatStringsSep " " (mkSPAKeyValue v)}}" - else if builtins.isString v then "\"${lib.generators.mkValueStringDefault { } v}\"" - else lib.generators.mkValueStringDefault { } v; - - mkSPAKeyValue = attrs: map (def: def.content) ( - lib.sortProperties - ( - lib.mapAttrsToList - (k: v: lib.mkOrder (v._priority or 1000) "${lib.escape [ "=" ] k} = ${mkSPAValueString (v._content or v)}") - attrs - ) - ); - - toSPAJSON = attrs: lib.concatStringsSep "\n" (mkSPAKeyValue attrs); + configs = { + client = recursiveUpdate defaults.client cfg.config.client; + client-rt = recursiveUpdate defaults.client-rt cfg.config.client-rt; + jack = recursiveUpdate defaults.jack cfg.config.jack; + pipewire = recursiveUpdate defaults.pipewire cfg.config.pipewire; + pipewire-pulse = recursiveUpdate defaults.pipewire-pulse cfg.config.pipewire-pulse; + }; in { meta = { @@ -78,7 +68,7 @@ in { config = { client = mkOption { - type = types.attrs; + type = json.type; default = {}; description = '' Configuration for pipewire clients. For details see @@ -87,7 +77,7 @@ in { }; client-rt = mkOption { - type = types.attrs; + type = json.type; default = {}; description = '' Configuration for realtime pipewire clients. For details see @@ -96,7 +86,7 @@ in { }; jack = mkOption { - type = types.attrs; + type = json.type; default = {}; description = '' Configuration for the pipewire daemon's jack module. For details see @@ -105,7 +95,7 @@ in { }; pipewire = mkOption { - type = types.attrs; + type = json.type; default = {}; description = '' Configuration for the pipewire daemon. For details see @@ -114,7 +104,7 @@ in { }; pipewire-pulse = mkOption { - type = types.attrs; + type = json.type; default = {}; description = '' Configuration for the pipewire-pulse daemon. For details see @@ -187,11 +177,21 @@ in { source = "${cfg.package}/share/alsa/alsa.conf.d/99-pipewire-default.conf"; }; - environment.etc."pipewire/client.conf" = { text = toSPAJSON (recursiveUpdate defaults.client cfg.config.client); }; - environment.etc."pipewire/client-rt.conf" = { text = toSPAJSON (recursiveUpdate defaults.client-rt cfg.config.client-rt); }; - environment.etc."pipewire/jack.conf" = { text = toSPAJSON (recursiveUpdate defaults.jack cfg.config.jack); }; - environment.etc."pipewire/pipewire.conf" = { text = toSPAJSON (recursiveUpdate defaults.pipewire cfg.config.pipewire); }; - environment.etc."pipewire/pipewire-pulse.conf" = { text = toSPAJSON (recursiveUpdate defaults.pipewire-pulse cfg.config.pipewire-pulse); }; + environment.etc."pipewire/client.conf" = { + source = json.generate "client.conf" configs.client; + }; + environment.etc."pipewire/client-rt.conf" = { + source = json.generate "client-rt.conf" configs.client-rt; + }; + environment.etc."pipewire/jack.conf" = { + source = json.generate "jack.conf" configs.jack; + }; + environment.etc."pipewire/pipewire.conf" = { + source = json.generate "pipewire.conf" configs.pipewire; + }; + environment.etc."pipewire/pipewire-pulse.conf" = { + source = json.generate "pipewire-pulse.conf" configs.pipewire-pulse; + }; environment.sessionVariables.LD_LIBRARY_PATH = lib.optional cfg.jack.enable "/run/current-system/sw/lib/pipewire";