Files
dotfiles/.config/quickshell/nucleus-shell/services/SystemDetails.qml

395 lines
9.3 KiB
QML

import QtQuick
import Quickshell
import Quickshell.Io
import qs.config
pragma Singleton
Singleton {
id: root
property string hostname: ""
property string username: ""
property string osIcon: ""
property string osName: ""
property string kernelVersion: ""
property string architecture: ""
property string uptime: ""
property string qsVersion: ""
property string swapUsage: "—"
property real swapPercent: 0
property string ipAddress: "—"
property int runningProcesses: 0
property int loggedInUsers: 0
property string ramUsage: "—"
property real ramPercent: 0
property string cpuLoad: "—"
property real cpuPercent: 0
property string diskUsage: "—"
property real diskPercent: 0
property string cpuTemp: "—"
property string keyboardLayout: "none"
property real cpuTempPercent: 0
property int prevIdle: -1
property int prevTotal: -1
readonly property var osIcons: ({
"almalinux": "",
"alpine": "",
"arch": "󰣇",
"archcraft": "",
"arcolinux": "",
"artix": "",
"centos": "",
"debian": "",
"devuan": "",
"elementary": "",
"endeavouros": "",
"fedora": "",
"freebsd": "",
"garuda": "",
"gentoo": "",
"hyperbola": "",
"kali": "",
"linuxmint": "󰣭",
"mageia": "",
"openmandriva": "",
"manjaro": "",
"neon": "",
"nixos": "",
"opensuse": "",
"suse": "",
"sles": "",
"sles_sap": "",
"opensuse-tumbleweed": "",
"parrot": "",
"pop": "",
"raspbian": "",
"rhel": "",
"rocky": "",
"slackware": "",
"solus": "",
"steamos": "",
"tails": "",
"trisquel": "",
"ubuntu": "",
"vanilla": "",
"void": "",
"zorin": "",
"opensuse": "",
})
FileView { id: cpuStat; path: "/proc/stat" }
FileView { id: memInfo; path: "/proc/meminfo" }
FileView { id: uptimeFile; path: "/proc/uptime" }
Timer {
interval: 1000
running: true
repeat: true
onTriggered: {
cpuStat.reload()
memInfo.reload()
uptimeFile.reload()
/* CPU */
const cpuLine = cpuStat.text().split("\n")[0].trim().split(/\s+/)
const cpuUser = parseInt(cpuLine[1])
const cpuNice = parseInt(cpuLine[2])
const cpuSystem = parseInt(cpuLine[3])
const cpuIdle = parseInt(cpuLine[4])
const cpuIowait = parseInt(cpuLine[5])
const cpuIrq = parseInt(cpuLine[6])
const cpuSoftirq = parseInt(cpuLine[7])
const cpuIdleAll = cpuIdle + cpuIowait
const cpuTotal =
cpuUser + cpuNice + cpuSystem + cpuIrq + cpuSoftirq + cpuIdleAll
if (root.prevTotal >= 0) {
const totalDiff = cpuTotal - root.prevTotal
const idleDiff = cpuIdleAll - root.prevIdle
if (totalDiff > 0)
root.cpuPercent = (totalDiff - idleDiff) / totalDiff
}
root.prevTotal = cpuTotal
root.prevIdle = cpuIdleAll
root.cpuLoad = Math.round(root.cpuPercent * 100) + "%"
/* RAM */
const memLines = memInfo.text().split("\n")
let memTotal = 0
let memAvailable = 0
for (let line of memLines) {
if (line.startsWith("MemTotal"))
memTotal = parseInt(line.match(/\d+/)[0])
if (line.startsWith("MemAvailable"))
memAvailable = parseInt(line.match(/\d+/)[0])
}
if (memTotal > 0) {
const memUsed = memTotal - memAvailable
root.ramPercent = memUsed / memTotal
root.ramUsage =
`${Math.round(memUsed/1024)}/${Math.round(memTotal/1024)} MB`
}
/* Uptime */
const uptimeSeconds =
parseFloat(uptimeFile.text().split(" ")[0])
const d = Math.floor(uptimeSeconds / 86400)
const h = Math.floor((uptimeSeconds % 86400) / 3600)
const m = Math.floor((uptimeSeconds % 3600) / 60)
let upString = "Up "
if (d > 0) upString += d + "d "
if (h > 0) upString += h + "h "
upString += m + "m"
root.uptime = upString
cpuTempProc.running = true
diskProc.running = true
ipProc.running = true
procCountProc.running = true
swapProc.running = true
keyboardLayoutProc.running = true
loggedUsersProc.running = true
}
}
/* CPU Temperature */
Process {
id: cpuTempProc
command: [
"sh","-c",
"for f in /sys/class/hwmon/hwmon*/temp*_input; do cat $f && exit; done"
]
stdout: StdioCollector {
onStreamFinished: {
const raw = parseInt(text.trim())
if (isNaN(raw)) return
const c = raw / 1000
root.cpuTemp = `${Math.round(c)}°C`
const min = 30
const max = 95
root.cpuTempPercent =
Math.max(0, Math.min(1,(c-min)/(max-min)))
}
}
}
/* Disk */
Process {
id: diskProc
command: ["df","-h","/"]
stdout: StdioCollector {
onStreamFinished: {
const lines = text.trim().split("\n")
if (lines.length < 2) return
const parts = lines[1].split(/\s+/)
const used = parts[2]
const total = parts[1]
const percent = parseInt(parts[4]) / 100
root.diskPercent = percent
root.diskUsage = `${used}/${total}`
}
}
}
/* Swap */
Process {
id: swapProc
command: ["sh","-c","free -m | grep Swap"]
stdout: StdioCollector {
onStreamFinished: {
const parts = text.trim().split(/\s+/)
if (parts.length < 3) return
const total = parseInt(parts[1])
const used = parseInt(parts[2])
root.swapPercent = used / total
root.swapUsage = `${used}/${total} MB`
}
}
}
/* IP */
Process {
id: ipProc
command: ["sh","-c","hostname -I | awk '{print $1}'"]
stdout: StdioCollector {
onStreamFinished: root.ipAddress = text.trim()
}
}
/* Process Count */
Process {
id: procCountProc
command: ["sh","-c","ps -e --no-headers | wc -l"]
stdout: StdioCollector {
onStreamFinished: root.runningProcesses = parseInt(text.trim())
}
}
/* Logged Users */
Process {
id: loggedUsersProc
command: ["who","-q"]
stdout: StdioCollector {
onStreamFinished: {
const lines = text.trim().split("\n")
if (lines.length > 0)
root.loggedInUsers =
parseInt(lines[lines.length-1].replace("# users=",""))
}
}
}
/* Keyboard Layout */
Process {
id: keyboardLayoutProc
command: [
"sh","-c",
"hyprctl devices -j | jq -r '.keyboards[] | .layout' | head -n1"
]
stdout: StdioCollector {
onStreamFinished: {
const layout = text.trim()
if (layout)
root.keyboardLayout = layout
}
}
}
/* OS Info */
Process {
running: true
command: [
"sh","-c",
"source /etc/os-release && echo \"$PRETTY_NAME|$ID\""
]
stdout: StdioCollector {
onStreamFinished: {
const parts = text.trim().split("|")
root.osName = parts[0]
root.osIcon = root.osIcons[parts[1]] || ""
}
}
}
/* Quickshell Version */
Process {
running: true
command: ["qs","--version"]
stdout: StdioCollector {
onStreamFinished: {
root.qsVersion =
text.trim().split(',')[0]
.replace("quickshell ","")
}
}
}
/* Static system info */
Process {
running: true
command: ["whoami"]
stdout: StdioCollector {
onStreamFinished: root.username = text.trim()
}
}
Process {
running: true
command: ["hostname"]
stdout: StdioCollector {
onStreamFinished: root.hostname = text.trim()
}
}
Process {
running: true
command: ["uname","-r"]
stdout: StdioCollector {
onStreamFinished: root.kernelVersion = text.trim()
}
}
Process {
running: true
command: ["uname","-m"]
stdout: StdioCollector {
onStreamFinished: root.architecture = text.trim()
}
}
}