{ config, lib, pkgs, util, ... }: # PipeWire as the desktop audio server. let volumeKey = keys: command: { inherit keys; repeating = true; action = { kind = "exec"; command = "${lib.getExe' pkgs.swayosd "swayosd-client"} --output-volume ${command}"; }; }; mediaKey = keys: command: { inherit keys; locked = true; action = { kind = "exec"; command = "${lib.getExe pkgs.playerctl} ${command}"; }; }; in { options.modules.desktop.utilities.audio.enable = lib.mkEnableOption "the PipeWire audio server"; config = lib.mkIf config.modules.desktop.utilities.audio.enable { # Realtime scheduling for the audio threads, so playback survives load. security.rtkit.enable = true; services.pipewire = { enable = true; alsa.enable = true; pulse.enable = true; }; registry.keybind.${config.networking.hostName} = { volume-up = volumeKey "XF86AudioRaiseVolume" "raise --max-volume 100"; volume-down = volumeKey "XF86AudioLowerVolume" "lower"; mute = { keys = "XF86AudioMute"; locked = true; action = { kind = "exec"; command = "${lib.getExe' pkgs.swayosd "swayosd-client"} --output-volume mute-toggle"; }; }; media-play = mediaKey "XF86AudioPlay" "play-pause"; media-next = mediaKey "XF86AudioNext" "next"; media-previous = mediaKey "XF86AudioPrev" "previous"; }; registry.waybar.${config.networking.hostName} = { mpris = { order = 30; settings = { format = "${util.glyph "f001"} {title}"; format-paused = "${util.glyph "f04c"} {title}"; max-length = 40; on-click = "play-pause"; on-scroll-up = "next"; on-scroll-down = "previous"; }; }; wireplumber = { order = 40; settings = { format = "{icon} {volume}%"; format-muted = "${util.glyph "f026"} muted"; format-icons = [ (util.glyph "f026") (util.glyph "f027") (util.glyph "f028") ]; on-click = "${lib.getExe' pkgs.wireplumber "wpctl"} set-mute @DEFAULT_AUDIO_SINK@ toggle"; }; }; }; }; }