feat(ags-v3): desktop adaptation — ultrawide scaling, brain power panel, system stats
- Scaling 16px base pour ultrawide 3440x1440 - Bar: CPU/RAM/GPU visible, media single player (skip playerctld), network tooltip LAN/WAN IPv4 - Volume: class module pour sizing cohérent - Battery: désactivé (PC fixe) - Clock: tooltip calendrier + uptime - BrainPower: panel enrichi (focus, session, intentions, todos, repos git, derniers commits) - App: BrainPower sur moniteur principal uniquement - Heartbeat: Layer.TOP pour compatibilité COSMIC
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import GLib from "gi://GLib"
|
||||
import { createPoll } from "ags/time"
|
||||
import { exec } from "ags/process"
|
||||
|
||||
function readProc(path: string): string | null {
|
||||
try {
|
||||
@@ -16,9 +17,9 @@ function getCpuUsage(): string {
|
||||
const content = readProc("/proc/stat")
|
||||
if (!content) return "?"
|
||||
|
||||
const line = content.split("\n")[0] // "cpu user nice system idle ..."
|
||||
const line = content.split("\n")[0]
|
||||
const parts = line.split(/\s+/).slice(1).map(Number)
|
||||
const idle = parts[3] + parts[4] // idle + iowait
|
||||
const idle = parts[3] + parts[4]
|
||||
const total = parts.reduce((a, b) => a + b, 0)
|
||||
|
||||
const dIdle = idle - prevIdle
|
||||
@@ -30,31 +31,59 @@ function getCpuUsage(): string {
|
||||
return `${Math.round(((dTotal - dIdle) / dTotal) * 100)}`
|
||||
}
|
||||
|
||||
function getRamUsage(): string {
|
||||
function getRamUsage(): { pct: string; used: string; total: string } {
|
||||
const content = readProc("/proc/meminfo")
|
||||
if (!content) return "?"
|
||||
if (!content) return { pct: "?", used: "?", total: "?" }
|
||||
|
||||
const lines = content.split("\n")
|
||||
let total = 0, available = 0
|
||||
let totalKb = 0, availableKb = 0
|
||||
|
||||
for (const line of lines) {
|
||||
if (line.startsWith("MemTotal:")) total = parseInt(line.split(/\s+/)[1])
|
||||
if (line.startsWith("MemAvailable:")) available = parseInt(line.split(/\s+/)[1])
|
||||
if (total && available) break
|
||||
if (line.startsWith("MemTotal:")) totalKb = parseInt(line.split(/\s+/)[1])
|
||||
if (line.startsWith("MemAvailable:")) availableKb = parseInt(line.split(/\s+/)[1])
|
||||
if (totalKb && availableKb) break
|
||||
}
|
||||
|
||||
if (!total) return "?"
|
||||
return `${Math.round(((total - available) / total) * 100)}`
|
||||
if (!totalKb) return { pct: "?", used: "?", total: "?" }
|
||||
const usedGb = ((totalKb - availableKb) / 1048576).toFixed(1)
|
||||
const totalGb = (totalKb / 1048576).toFixed(0)
|
||||
const pct = `${Math.round(((totalKb - availableKb) / totalKb) * 100)}`
|
||||
return { pct, used: usedGb, total: totalGb }
|
||||
}
|
||||
|
||||
function getGpuInfo(): string {
|
||||
try {
|
||||
const out = exec("bash -c \"nvidia-smi --query-gpu=utilization.gpu,temperature.gpu --format=csv,noheader,nounits 2>/dev/null\"")
|
||||
const [usage, temp] = out.trim().split(", ")
|
||||
return `GPU ${usage}% · ${temp}°C`
|
||||
} catch {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
export default function SystemStats() {
|
||||
const cpu = createPoll("0", 3000, () => getCpuUsage())
|
||||
const ram = createPoll("0", 5000, () => getRamUsage())
|
||||
const ram = createPoll("", 5000, () => {
|
||||
const r = getRamUsage()
|
||||
return JSON.stringify(r)
|
||||
})
|
||||
|
||||
const ramLabel = ram((v: string) => {
|
||||
try {
|
||||
const r = JSON.parse(v)
|
||||
return `RAM ${r.used}/${r.total}G`
|
||||
} catch { return "RAM ?" }
|
||||
})
|
||||
|
||||
const gpu = createPoll("", 5000, () => getGpuInfo())
|
||||
|
||||
return (
|
||||
<box>
|
||||
<label class="cpu module" label={cpu((v: string) => ` ${v}%`)} />
|
||||
<label class="ram module" label={ram((v: string) => ` ${v}%`)} />
|
||||
<label class="cpu module" label={cpu((v: string) => `CPU ${v}%`)} />
|
||||
<label class="separator" label="│" />
|
||||
<label class="ram module" label={ramLabel} />
|
||||
<label class="separator" label="│" />
|
||||
<label class="gpu module" label={gpu((v: string) => v || "GPU ?")} />
|
||||
</box>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user