diff --git a/modules/BackgroundOverlay.qml b/modules/BackgroundOverlay.qml index 1936770..bd028b6 100644 --- a/modules/BackgroundOverlay.qml +++ b/modules/BackgroundOverlay.qml @@ -54,7 +54,6 @@ PanelWindow { text: ":" color: colon._colors[colon._colorIdx % colon._colors.length] Behavior on color { - enabled: !M.Theme.reducedMotion ColorAnimation { duration: 800 } @@ -111,7 +110,6 @@ PanelWindow { readonly property var _colors: [M.Theme.base08, M.Theme.base09, M.Theme.base0A, M.Theme.base0B, M.Theme.base0C, M.Theme.base0D, M.Theme.base0E, M.Theme.base05] color: _colors[_colorIdx % _colors.length] Behavior on color { - enabled: !M.Theme.reducedMotion ColorAnimation { duration: 800 } @@ -119,7 +117,7 @@ PanelWindow { SequentialAnimation { loops: Animation.Infinite - running: !M.Theme.reducedMotion + running: true NumberAnimation { target: colon property: "opacity" @@ -189,7 +187,6 @@ PanelWindow { height: parent.height color: colon._colors[colon._colorIdx % colon._colors.length] Behavior on color { - enabled: !M.Theme.reducedMotion ColorAnimation { duration: 800 } @@ -198,7 +195,6 @@ PanelWindow { opacity: 0.6 Behavior on width { - enabled: !M.Theme.reducedMotion NumberAnimation { duration: 300 } diff --git a/modules/Cpu.qml b/modules/Cpu.qml index c0d7274..cfe49c1 100644 --- a/modules/Cpu.qml +++ b/modules/Cpu.qml @@ -8,7 +8,6 @@ M.BarSection { property int usage: M.SystemStats.cpuUsage Behavior on usage { - enabled: root._showPanel NumberAnimation { duration: 400 easing.type: Easing.OutCubic @@ -17,14 +16,15 @@ M.BarSection { property real freqGhz: M.SystemStats.cpuFreqGhz Behavior on freqGhz { - enabled: root._showPanel NumberAnimation { duration: 400 easing.type: Easing.OutCubic } } - readonly property var _cores: M.SystemStats.cpuCores + readonly property var _coreUsage: M.SystemStats.cpuCoreUsage + readonly property var _coreFreq: M.SystemStats.cpuCoreFreq + readonly property var _coreHistory: M.SystemStats.cpuCoreHistory readonly property var _coreMaxFreq: M.SystemStats.cpuCoreMaxFreq readonly property var _coreTypes: M.SystemStats.cpuCoreTypes @@ -114,14 +114,14 @@ M.BarSection { // Per-core rows Repeater { - model: root._cores.length + model: root._coreUsage.length delegate: Item { required property int index width: hoverPanel.contentWidth - readonly property int _u: root._cores[index]?.usage ?? 0 - readonly property real _f: root._cores[index]?.freq_ghz ?? 0 + readonly property int _u: root._coreUsage[index] ?? 0 + readonly property real _f: root._coreFreq[index] ?? 0 readonly property color _barColor: root._loadColor(_u) readonly property bool _throttled: { const maxF = root._coreMaxFreq[index] ?? 0; @@ -204,7 +204,7 @@ M.BarSection { width: 32 height: 10 - property var _hist: root._cores[parent.parent.index]?.history ?? [] + property var _hist: root._coreHistory[parent.parent.index] || [] property color _col: parent.parent._barColor on_HistChanged: if (root._showPanel) diff --git a/modules/Modules.qml b/modules/Modules.qml index 0a2b753..f1f07ed 100644 --- a/modules/Modules.qml +++ b/modules/Modules.qml @@ -89,9 +89,6 @@ QtObject { property var overviewBackdrop: ({ enable: true }) - property var statsDaemon: ({ - interval: -1 - }) property FileView _file: FileView { path: (Quickshell.env("XDG_CONFIG_HOME") || (Quickshell.env("HOME") + "/.config")) + "/nova-shell/modules.json" diff --git a/modules/OverviewBackdrop.qml b/modules/OverviewBackdrop.qml index ab17be2..c9652a6 100644 --- a/modules/OverviewBackdrop.qml +++ b/modules/OverviewBackdrop.qml @@ -48,7 +48,7 @@ PanelWindow { // Wave animation: 6s sweep + 8s pause, only while overview is open SequentialAnimation on uWavePhase { loops: Animation.Infinite - running: M.NiriIpc.overviewOpen && !M.Theme.reducedMotion + running: M.NiriIpc.overviewOpen NumberAnimation { from: -200 to: fx.width + 200 diff --git a/modules/SystemStats.qml b/modules/SystemStats.qml index cb7a0ad..fd0c20d 100644 --- a/modules/SystemStats.qml +++ b/modules/SystemStats.qml @@ -10,7 +10,9 @@ QtObject { // ── CPU ────────────────────────────────────────────────────────────── property int cpuUsage: 0 property real cpuFreqGhz: 0 - property var cpuCores: [] // [{usage, freq_ghz, history:[]}] + property var cpuCoreUsage: [] + property var cpuCoreFreq: [] + property var cpuCoreHistory: [] property var cpuCoreMaxFreq: [] property var cpuCoreTypes: [] @@ -29,10 +31,7 @@ QtObject { // nova-stats stream (cpu + mem) property var _statsProc: Process { running: true - command: { - const ms = M.Modules.statsDaemon.interval; - return ms > 0 ? ["nova-stats", "--interval", ms.toString()] : ["nova-stats"]; - } + command: ["nova-stats"] stdout: SplitParser { splitMarker: "\n" onRead: line => { @@ -41,17 +40,17 @@ QtObject { if (ev.type === "cpu") { root.cpuUsage = ev.usage; root.cpuFreqGhz = ev.freq_ghz; + root.cpuCoreUsage = ev.core_usage; + root.cpuCoreFreq = ev.core_freq_ghz; const histLen = 16; - const prev = root.cpuCores; - root.cpuCores = ev.cores.map((c, i) => { - const oldHist = prev[i]?.history ?? []; - const hist = oldHist.concat([c.usage]); - return { - usage: c.usage, - freq_ghz: c.freq_ghz, - history: hist.length > histLen ? hist.slice(hist.length - histLen) : hist - }; - }); + const oldH = root.cpuCoreHistory; + const newH = []; + for (let i = 0; i < ev.core_usage.length; i++) { + const prev = i < oldH.length ? oldH[i] : []; + const next = prev.concat([ev.core_usage[i]]); + newH.push(next.length > histLen ? next.slice(next.length - histLen) : next); + } + root.cpuCoreHistory = newH; } else if (ev.type === "mem") { root.memPercent = ev.percent; root.memUsedGb = ev.used_gb; diff --git a/modules/Theme.qml b/modules/Theme.qml index 13ac23c..f924df9 100644 --- a/modules/Theme.qml +++ b/modules/Theme.qml @@ -35,7 +35,6 @@ QtObject { property int groupSpacing: 6 property int radius: 4 property int screenRadius: 15 - property bool reducedMotion: false property FileView _themeFile: FileView { path: (Quickshell.env("XDG_CONFIG_HOME") || (Quickshell.env("HOME") + "/.config")) + "/nova-shell/theme.json" @@ -76,7 +75,5 @@ QtObject { root.radius = data.radius; if (data.screenRadius !== undefined) root.screenRadius = data.screenRadius; - if (data.reducedMotion !== undefined) - root.reducedMotion = data.reducedMotion; } } diff --git a/nix/hm-module.nix b/nix/hm-module.nix index aa71894..343af64 100644 --- a/nix/hm-module.nix +++ b/nix/hm-module.nix @@ -169,17 +169,6 @@ in }; } ); - statsDaemon = lib.mkOption { - default = { }; - description = "Configuration for the nova-stats daemon."; - type = lib.types.submodule { - options.interval = lib.mkOption { - type = lib.types.int; - default = -1; - description = "nova-stats polling interval in milliseconds (-1 = use binary default of 1s)."; - }; - }; - }; }; theme = lib.mkOption { diff --git a/stats-daemon/src/main.rs b/stats-daemon/src/main.rs index c66ab5a..1324530 100644 --- a/stats-daemon/src/main.rs +++ b/stats-daemon/src/main.rs @@ -132,18 +132,22 @@ fn emit_cpu(out: &mut impl Write, prev: &[Sample], curr: &[Sample], freqs: &[f64 freqs.iter().sum::() / freqs.len() as f64 }; - let n = core_usage.len().max(freqs.len()); let _ = write!( out, - "{{\"type\":\"cpu\",\"usage\":{usage},\"freq_ghz\":{avg_freq:.3},\"cores\":[" + "{{\"type\":\"cpu\",\"usage\":{usage},\"freq_ghz\":{avg_freq:.3},\"core_usage\":[" ); - for i in 0..n { + for (i, u) in core_usage.iter().enumerate() { if i > 0 { let _ = write!(out, ","); } - let u = core_usage.get(i).copied().unwrap_or(0); - let f = freqs.get(i).copied().unwrap_or(0.0); - let _ = write!(out, "{{\"usage\":{u},\"freq_ghz\":{f:.3}}}"); + let _ = write!(out, "{u}"); + } + let _ = write!(out, "],\"core_freq_ghz\":["); + for (i, f) in freqs.iter().enumerate() { + if i > 0 { + let _ = write!(out, ","); + } + let _ = write!(out, "{f:.3}"); } let _ = writeln!(out, "]}}"); } @@ -159,22 +163,7 @@ fn emit_mem(out: &mut impl Write) { } } -fn parse_interval_ms() -> u64 { - let args: Vec = std::env::args().collect(); - let mut i = 1; - while i < args.len() { - if args[i] == "--interval" { - if let Some(ms) = args.get(i + 1).and_then(|s| s.parse().ok()) { - return ms; - } - } - i += 1; - } - 1000 -} - fn main() { - let interval = Duration::from_millis(parse_interval_ms()); let stdout = io::stdout(); let mut out = io::BufWriter::new(stdout.lock()); let mut prev: Vec = vec![]; @@ -196,8 +185,8 @@ fn main() { tick += 1; let elapsed = t0.elapsed(); - if elapsed < interval { - thread::sleep(interval - elapsed); + if elapsed < Duration::from_secs(1) { + thread::sleep(Duration::from_secs(1) - elapsed); } } } @@ -371,7 +360,8 @@ SwapFree: 8192000 kB"; assert!(s.contains("\"type\":\"cpu\"")); assert!(s.contains("\"usage\":")); assert!(s.contains("\"freq_ghz\":")); - assert!(s.contains("\"cores\":")); + assert!(s.contains("\"core_usage\":")); + assert!(s.contains("\"core_freq_ghz\":")); assert!(s.trim().ends_with('}')); } @@ -409,8 +399,8 @@ SwapFree: 8192000 kB"; let mut buf = Vec::new(); emit_cpu(&mut buf, &curr, &curr, &freqs); let s = String::from_utf8(buf).unwrap(); - assert!(s.contains("\"freq_ghz\":3.200"), "got: {s}"); - assert!(s.contains("\"freq_ghz\":2.900"), "got: {s}"); + assert!(s.contains("3.200"), "got: {s}"); + assert!(s.contains("2.900"), "got: {s}"); } // ── emit_mem (via parse_meminfo) ─────────────────────────────────────