Compare commits

..

No commits in common. "c96b023fbe1507abfdc4fa73b6e5145cfdd086ce" and "8fdd9692e610d81a2c1c15004193166295356f2a" have entirely different histories.

8 changed files with 39 additions and 71 deletions

View file

@ -54,7 +54,6 @@ PanelWindow {
text: ":" text: ":"
color: colon._colors[colon._colorIdx % colon._colors.length] color: colon._colors[colon._colorIdx % colon._colors.length]
Behavior on color { Behavior on color {
enabled: !M.Theme.reducedMotion
ColorAnimation { ColorAnimation {
duration: 800 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] 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] color: _colors[_colorIdx % _colors.length]
Behavior on color { Behavior on color {
enabled: !M.Theme.reducedMotion
ColorAnimation { ColorAnimation {
duration: 800 duration: 800
} }
@ -119,7 +117,7 @@ PanelWindow {
SequentialAnimation { SequentialAnimation {
loops: Animation.Infinite loops: Animation.Infinite
running: !M.Theme.reducedMotion running: true
NumberAnimation { NumberAnimation {
target: colon target: colon
property: "opacity" property: "opacity"
@ -189,7 +187,6 @@ PanelWindow {
height: parent.height height: parent.height
color: colon._colors[colon._colorIdx % colon._colors.length] color: colon._colors[colon._colorIdx % colon._colors.length]
Behavior on color { Behavior on color {
enabled: !M.Theme.reducedMotion
ColorAnimation { ColorAnimation {
duration: 800 duration: 800
} }
@ -198,7 +195,6 @@ PanelWindow {
opacity: 0.6 opacity: 0.6
Behavior on width { Behavior on width {
enabled: !M.Theme.reducedMotion
NumberAnimation { NumberAnimation {
duration: 300 duration: 300
} }

View file

@ -8,7 +8,6 @@ M.BarSection {
property int usage: M.SystemStats.cpuUsage property int usage: M.SystemStats.cpuUsage
Behavior on usage { Behavior on usage {
enabled: root._showPanel
NumberAnimation { NumberAnimation {
duration: 400 duration: 400
easing.type: Easing.OutCubic easing.type: Easing.OutCubic
@ -17,14 +16,15 @@ M.BarSection {
property real freqGhz: M.SystemStats.cpuFreqGhz property real freqGhz: M.SystemStats.cpuFreqGhz
Behavior on freqGhz { Behavior on freqGhz {
enabled: root._showPanel
NumberAnimation { NumberAnimation {
duration: 400 duration: 400
easing.type: Easing.OutCubic 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 _coreMaxFreq: M.SystemStats.cpuCoreMaxFreq
readonly property var _coreTypes: M.SystemStats.cpuCoreTypes readonly property var _coreTypes: M.SystemStats.cpuCoreTypes
@ -114,14 +114,14 @@ M.BarSection {
// Per-core rows // Per-core rows
Repeater { Repeater {
model: root._cores.length model: root._coreUsage.length
delegate: Item { delegate: Item {
required property int index required property int index
width: hoverPanel.contentWidth width: hoverPanel.contentWidth
readonly property int _u: root._cores[index]?.usage ?? 0 readonly property int _u: root._coreUsage[index] ?? 0
readonly property real _f: root._cores[index]?.freq_ghz ?? 0 readonly property real _f: root._coreFreq[index] ?? 0
readonly property color _barColor: root._loadColor(_u) readonly property color _barColor: root._loadColor(_u)
readonly property bool _throttled: { readonly property bool _throttled: {
const maxF = root._coreMaxFreq[index] ?? 0; const maxF = root._coreMaxFreq[index] ?? 0;
@ -204,7 +204,7 @@ M.BarSection {
width: 32 width: 32
height: 10 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 property color _col: parent.parent._barColor
on_HistChanged: if (root._showPanel) on_HistChanged: if (root._showPanel)

View file

@ -89,9 +89,6 @@ QtObject {
property var overviewBackdrop: ({ property var overviewBackdrop: ({
enable: true enable: true
}) })
property var statsDaemon: ({
interval: -1
})
property FileView _file: FileView { property FileView _file: FileView {
path: (Quickshell.env("XDG_CONFIG_HOME") || (Quickshell.env("HOME") + "/.config")) + "/nova-shell/modules.json" path: (Quickshell.env("XDG_CONFIG_HOME") || (Quickshell.env("HOME") + "/.config")) + "/nova-shell/modules.json"

View file

@ -48,7 +48,7 @@ PanelWindow {
// Wave animation: 6s sweep + 8s pause, only while overview is open // Wave animation: 6s sweep + 8s pause, only while overview is open
SequentialAnimation on uWavePhase { SequentialAnimation on uWavePhase {
loops: Animation.Infinite loops: Animation.Infinite
running: M.NiriIpc.overviewOpen && !M.Theme.reducedMotion running: M.NiriIpc.overviewOpen
NumberAnimation { NumberAnimation {
from: -200 from: -200
to: fx.width + 200 to: fx.width + 200

View file

@ -10,7 +10,9 @@ QtObject {
// CPU // CPU
property int cpuUsage: 0 property int cpuUsage: 0
property real cpuFreqGhz: 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 cpuCoreMaxFreq: []
property var cpuCoreTypes: [] property var cpuCoreTypes: []
@ -29,10 +31,7 @@ QtObject {
// nova-stats stream (cpu + mem) // nova-stats stream (cpu + mem)
property var _statsProc: Process { property var _statsProc: Process {
running: true running: true
command: { command: ["nova-stats"]
const ms = M.Modules.statsDaemon.interval;
return ms > 0 ? ["nova-stats", "--interval", ms.toString()] : ["nova-stats"];
}
stdout: SplitParser { stdout: SplitParser {
splitMarker: "\n" splitMarker: "\n"
onRead: line => { onRead: line => {
@ -41,17 +40,17 @@ QtObject {
if (ev.type === "cpu") { if (ev.type === "cpu") {
root.cpuUsage = ev.usage; root.cpuUsage = ev.usage;
root.cpuFreqGhz = ev.freq_ghz; root.cpuFreqGhz = ev.freq_ghz;
root.cpuCoreUsage = ev.core_usage;
root.cpuCoreFreq = ev.core_freq_ghz;
const histLen = 16; const histLen = 16;
const prev = root.cpuCores; const oldH = root.cpuCoreHistory;
root.cpuCores = ev.cores.map((c, i) => { const newH = [];
const oldHist = prev[i]?.history ?? []; for (let i = 0; i < ev.core_usage.length; i++) {
const hist = oldHist.concat([c.usage]); const prev = i < oldH.length ? oldH[i] : [];
return { const next = prev.concat([ev.core_usage[i]]);
usage: c.usage, newH.push(next.length > histLen ? next.slice(next.length - histLen) : next);
freq_ghz: c.freq_ghz, }
history: hist.length > histLen ? hist.slice(hist.length - histLen) : hist root.cpuCoreHistory = newH;
};
});
} else if (ev.type === "mem") { } else if (ev.type === "mem") {
root.memPercent = ev.percent; root.memPercent = ev.percent;
root.memUsedGb = ev.used_gb; root.memUsedGb = ev.used_gb;

View file

@ -35,7 +35,6 @@ QtObject {
property int groupSpacing: 6 property int groupSpacing: 6
property int radius: 4 property int radius: 4
property int screenRadius: 15 property int screenRadius: 15
property bool reducedMotion: false
property FileView _themeFile: FileView { property FileView _themeFile: FileView {
path: (Quickshell.env("XDG_CONFIG_HOME") || (Quickshell.env("HOME") + "/.config")) + "/nova-shell/theme.json" path: (Quickshell.env("XDG_CONFIG_HOME") || (Quickshell.env("HOME") + "/.config")) + "/nova-shell/theme.json"
@ -76,7 +75,5 @@ QtObject {
root.radius = data.radius; root.radius = data.radius;
if (data.screenRadius !== undefined) if (data.screenRadius !== undefined)
root.screenRadius = data.screenRadius; root.screenRadius = data.screenRadius;
if (data.reducedMotion !== undefined)
root.reducedMotion = data.reducedMotion;
} }
} }

View file

@ -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 { theme = lib.mkOption {

View file

@ -132,18 +132,22 @@ fn emit_cpu(out: &mut impl Write, prev: &[Sample], curr: &[Sample], freqs: &[f64
freqs.iter().sum::<f64>() / freqs.len() as f64 freqs.iter().sum::<f64>() / freqs.len() as f64
}; };
let n = core_usage.len().max(freqs.len());
let _ = write!( let _ = write!(
out, 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 { if i > 0 {
let _ = write!(out, ","); let _ = write!(out, ",");
} }
let u = core_usage.get(i).copied().unwrap_or(0); let _ = write!(out, "{u}");
let f = freqs.get(i).copied().unwrap_or(0.0); }
let _ = write!(out, "{{\"usage\":{u},\"freq_ghz\":{f:.3}}}"); 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, "]}}"); let _ = writeln!(out, "]}}");
} }
@ -159,22 +163,7 @@ fn emit_mem(out: &mut impl Write) {
} }
} }
fn parse_interval_ms() -> u64 {
let args: Vec<String> = 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() { fn main() {
let interval = Duration::from_millis(parse_interval_ms());
let stdout = io::stdout(); let stdout = io::stdout();
let mut out = io::BufWriter::new(stdout.lock()); let mut out = io::BufWriter::new(stdout.lock());
let mut prev: Vec<Sample> = vec![]; let mut prev: Vec<Sample> = vec![];
@ -196,8 +185,8 @@ fn main() {
tick += 1; tick += 1;
let elapsed = t0.elapsed(); let elapsed = t0.elapsed();
if elapsed < interval { if elapsed < Duration::from_secs(1) {
thread::sleep(interval - elapsed); thread::sleep(Duration::from_secs(1) - elapsed);
} }
} }
} }
@ -371,7 +360,8 @@ SwapFree: 8192000 kB";
assert!(s.contains("\"type\":\"cpu\"")); assert!(s.contains("\"type\":\"cpu\""));
assert!(s.contains("\"usage\":")); assert!(s.contains("\"usage\":"));
assert!(s.contains("\"freq_ghz\":")); 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('}')); assert!(s.trim().ends_with('}'));
} }
@ -409,8 +399,8 @@ SwapFree: 8192000 kB";
let mut buf = Vec::new(); let mut buf = Vec::new();
emit_cpu(&mut buf, &curr, &curr, &freqs); emit_cpu(&mut buf, &curr, &curr, &freqs);
let s = String::from_utf8(buf).unwrap(); let s = String::from_utf8(buf).unwrap();
assert!(s.contains("\"freq_ghz\":3.200"), "got: {s}"); assert!(s.contains("3.200"), "got: {s}");
assert!(s.contains("\"freq_ghz\":2.900"), "got: {s}"); assert!(s.contains("2.900"), "got: {s}");
} }
// ── emit_mem (via parse_meminfo) ───────────────────────────────────── // ── emit_mem (via parse_meminfo) ─────────────────────────────────────