1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-06 21:45:38 -05:00
Files
DankMaterialShell/Services/SystemMonitorService.qml
2025-07-14 14:36:08 -04:00

269 lines
8.3 KiB
QML

import QtQuick
import Quickshell
import Quickshell.Io
pragma Singleton
pragma ComponentBehavior: Bound
Singleton {
id: root
// CPU properties
property real cpuUsage: 0.0
property int cpuCores: 1
property string cpuModel: ""
property real cpuFrequency: 0.0
// Previous CPU stats for accurate calculation
property var prevCpuStats: [0, 0, 0, 0, 0, 0, 0, 0]
// Memory properties
property real memoryUsage: 0.0
property real totalMemory: 0.0
property real usedMemory: 0.0
property real freeMemory: 0.0
property real availableMemory: 0.0
property real bufferMemory: 0.0
property real cacheMemory: 0.0
// Temperature properties
property real cpuTemperature: 0.0
property int cpuUpdateInterval: 3000
property int memoryUpdateInterval: 5000
property int temperatureUpdateInterval: 10000
// Performance control
property bool enabledForTopBar: true
property bool enabledForDetailedView: false
Component.onCompleted: {
console.log("SystemMonitorService: Starting initialization...")
getCpuInfo()
updateSystemStats()
console.log("SystemMonitorService: Initialization complete")
}
// Get CPU information (static)
Process {
id: cpuInfoProcess
command: ["bash", "-c", "lscpu | grep -E 'Model name|CPU\\(s\\):' | head -2"]
running: false
stdout: StdioCollector {
onStreamFinished: {
const lines = text.trim().split('\n')
for (const line of lines) {
if (line.includes("Model name")) {
root.cpuModel = line.split(":")[1].trim()
} else if (line.includes("CPU(s):")) {
root.cpuCores = parseInt(line.split(":")[1].trim())
}
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("CPU info check failed with exit code:", exitCode)
}
}
}
// CPU usage monitoring with accurate calculation
Process {
id: cpuUsageProcess
command: ["bash", "-c", "head -1 /proc/stat | awk '{print $2,$3,$4,$5,$6,$7,$8,$9}'"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
const stats = text.trim().split(" ").map(x => parseInt(x))
if (root.prevCpuStats[0] > 0) {
// Calculate differences
let diffs = []
for (let i = 0; i < 8; i++) {
diffs[i] = stats[i] - root.prevCpuStats[i]
}
// Calculate total and idle time
const totalTime = diffs.reduce((a, b) => a + b, 0)
const idleTime = diffs[3] + diffs[4] // idle + iowait
// CPU usage percentage
if (totalTime > 0) {
root.cpuUsage = Math.max(0, Math.min(100, ((totalTime - idleTime) / totalTime) * 100))
}
}
root.prevCpuStats = stats
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("CPU usage check failed with exit code:", exitCode)
}
}
}
// Memory usage monitoring
Process {
id: memoryUsageProcess
command: ["bash", "-c", "free -m | awk 'NR==2{printf \"%.1f %.1f %.1f %.1f\", $3*100/$2, $2, $3, $7}'"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
const parts = text.trim().split(" ")
root.memoryUsage = parseFloat(parts[0])
root.totalMemory = parseFloat(parts[1])
root.usedMemory = parseFloat(parts[2])
root.availableMemory = parseFloat(parts[3])
root.freeMemory = root.totalMemory - root.usedMemory
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("Memory usage check failed with exit code:", exitCode)
}
}
}
// CPU frequency monitoring
Process {
id: cpuFrequencyProcess
command: ["bash", "-c", "cat /proc/cpuinfo | grep 'cpu MHz' | head -1 | awk '{print $4}'"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
root.cpuFrequency = parseFloat(text.trim())
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("CPU frequency check failed with exit code:", exitCode)
}
}
}
// CPU temperature monitoring
Process {
id: temperatureProcess
command: ["bash", "-c", "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then cat /sys/class/thermal/thermal_zone0/temp | awk '{print $1/1000}'; else sensors 2>/dev/null | grep 'Core 0' | awk '{print $3}' | sed 's/+//g;s/°C//g' | head -1; fi"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
root.cpuTemperature = parseFloat(text.trim())
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("CPU temperature check failed with exit code:", exitCode)
}
}
}
// CPU monitoring timer
Timer {
id: cpuTimer
interval: root.cpuUpdateInterval
running: root.enabledForTopBar || root.enabledForDetailedView
repeat: true
onTriggered: {
if (root.enabledForTopBar || root.enabledForDetailedView) {
cpuUsageProcess.running = true
cpuFrequencyProcess.running = true
}
}
}
// Memory monitoring timer
Timer {
id: memoryTimer
interval: root.memoryUpdateInterval
running: root.enabledForTopBar || root.enabledForDetailedView
repeat: true
onTriggered: {
if (root.enabledForTopBar || root.enabledForDetailedView) {
memoryUsageProcess.running = true
}
}
}
// Temperature monitoring timer
Timer {
id: temperatureTimer
interval: root.temperatureUpdateInterval
running: root.enabledForDetailedView
repeat: true
onTriggered: {
if (root.enabledForDetailedView) {
temperatureProcess.running = true
}
}
}
// Public functions
function getCpuInfo() {
cpuInfoProcess.running = true
}
function updateSystemStats() {
if (root.enabledForTopBar || root.enabledForDetailedView) {
cpuUsageProcess.running = true
memoryUsageProcess.running = true
cpuFrequencyProcess.running = true
if (root.enabledForDetailedView) {
temperatureProcess.running = true
}
}
}
function enableTopBarMonitoring(enabled) {
root.enabledForTopBar = enabled
}
function enableDetailedMonitoring(enabled) {
root.enabledForDetailedView = enabled
}
function getCpuUsageColor() {
if (cpuUsage > 80) return "#e74c3c" // Red
if (cpuUsage > 60) return "#f39c12" // Orange
return "#27ae60" // Green
}
function getMemoryUsageColor() {
if (memoryUsage > 90) return "#e74c3c" // Red
if (memoryUsage > 75) return "#f39c12" // Orange
return "#3498db" // Blue
}
function formatMemory(mb) {
if (mb >= 1024) {
return (mb / 1024).toFixed(1) + " GB"
}
return mb.toFixed(0) + " MB"
}
function getTemperatureColor() {
if (cpuTemperature > 80) return "#e74c3c" // Red
if (cpuTemperature > 65) return "#f39c12" // Orange
return "#27ae60" // Green
}
}