{ config, lib, pkgs, util, ... }: # PipeWire as the desktop audio server. { options.modules.desktop.utilities.audio.enable = lib.mkEnableOption "the PipeWire audio server"; config = lib.mkIf config.modules.desktop.utilities.audio.enable { registry.keybind.${config.networking.hostName} = { media-play = { keys = "XF86AudioPlay"; locked = true; action = { kind = "exec"; command = "${lib.getExe pkgs.playerctl} play-pause"; }; }; media-next = { keys = "XF86AudioNext"; locked = true; action = { kind = "exec"; command = "${lib.getExe pkgs.playerctl} next"; }; }; media-previous = { keys = "XF86AudioPrev"; locked = true; action = { kind = "exec"; command = "${lib.getExe pkgs.playerctl} 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"; }; }; }; # Realtime scheduling for the audio threads, so playback survives load. security.rtkit.enable = true; services.pipewire = { enable = true; alsa.enable = true; pulse.enable = true; }; }; }