import QtQuick import Quickshell import Quickshell.Io import Quickshell.Services.Mpris import "." as M import "../services" as S import "../applets" as C M.BarModule { id: root spacing: S.Theme.moduleSpacing active: S.Modules.mpris.enable && S.MprisService.player !== null tooltip: S.MprisService.player ? (S.MprisService.player.trackTitle || S.MprisService.player.identity || "Media") + (S.MprisService.playing ? " (playing)" : " (paused)") : "Media" panelNamespace: "nova-mpris" panelTitle: "Now Playing" panelContentWidth: 280 panelComponent: Component { C.MprisApplet { width: parent.width accentColor: root.accentColor cavaBars: root._cavaBars } } // Cava visualizer - 16 bars, raw output mode property var _cavaBars: Array(16).fill(0) property bool _cavaActive: false on_ShowPanelChanged: { if (_showPanel) { _cavaKillTimer.stop(); _cavaActive = true; } else { _cavaKillTimer.restart(); } } Timer { id: _cavaKillTimer interval: 30000 onTriggered: root._cavaActive = false } Process { id: cavaProc running: S.MprisService.playing && root._cavaActive command: ["sh", "-c", "cfg=$(mktemp /tmp/nova-cava-XXXXXX.conf);" + "cat > \"$cfg\" << 'CAVAEOF'\n" + "[general]\nbars=16\nframerate=30\n[output]\nmethod=raw\nraw_target=/dev/stdout\ndata_format=ascii\nascii_max_range=100\n" + "CAVAEOF\n" + "trap 'rm -f \"$cfg\"' EXIT;" + "exec cava -p \"$cfg\""] stdout: SplitParser { splitMarker: "\n" onRead: line => { const vals = line.split(";").filter(s => s).map(Number); if (vals.length >= 16) root._cavaBars = vals.map(v => v / 100); } } } required property var bar M.BarIcon { icon: S.MprisService.playing ? "\uF04B" : (S.MprisService.player?.playbackState === MprisPlaybackState.Paused ? "\uDB80\uDFE4" : "\uDB81\uDCDB") anchors.verticalCenter: parent.verticalCenter } M.BarLabel { label: S.MprisService.player?.trackTitle || S.MprisService.player?.identity || "" elide: Text.ElideRight width: Math.min(implicitWidth, 200) anchors.verticalCenter: parent.verticalCenter } }