1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-07 14:05:38 -05:00

processmonitor: add system info tab

This commit is contained in:
bbedward
2025-07-15 16:08:57 -04:00
parent 90999e8ac1
commit 3df92697e0
2 changed files with 793 additions and 23 deletions

View File

@@ -24,9 +24,25 @@ Singleton {
property real cpuTemperature: 0.0 property real cpuTemperature: 0.0
property string kernelVersion: ""
property string distribution: ""
property string hostname: ""
property string uptime: ""
property string scheduler: ""
property string architecture: ""
property string loadAverage: ""
property int processCount: 0
property int threadCount: 0
property string bootTime: ""
property string motherboard: ""
property string biosVersion: ""
property var diskMounts: []
property string diskUsage: ""
property int cpuUpdateInterval: 3000 property int cpuUpdateInterval: 3000
property int memoryUpdateInterval: 5000 property int memoryUpdateInterval: 5000
property int temperatureUpdateInterval: 10000 property int temperatureUpdateInterval: 10000
property int systemInfoUpdateInterval: 30000
property bool enabledForTopBar: true property bool enabledForTopBar: true
property bool enabledForDetailedView: false property bool enabledForDetailedView: false
@@ -35,6 +51,7 @@ Singleton {
console.log("SystemMonitorService: Starting initialization...") console.log("SystemMonitorService: Starting initialization...")
getCpuInfo() getCpuInfo()
updateSystemStats() updateSystemStats()
updateSystemInfo()
console.log("SystemMonitorService: Initialization complete") console.log("SystemMonitorService: Initialization complete")
} }
@@ -162,6 +179,282 @@ Singleton {
} }
} }
Process {
id: kernelInfoProcess
command: ["bash", "-c", "uname -r"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
root.kernelVersion = text.trim()
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("Kernel info check failed with exit code:", exitCode)
}
}
}
Process {
id: distributionProcess
command: ["bash", "-c", "grep PRETTY_NAME /etc/os-release 2>/dev/null | cut -d'=' -f2 | tr -d '\"' || echo 'Unknown'"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
root.distribution = text.trim()
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("Distribution check failed with exit code:", exitCode)
}
}
}
Process {
id: hostnameProcess
command: ["bash", "-c", "hostname"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
root.hostname = text.trim()
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("Hostname check failed with exit code:", exitCode)
}
}
}
Process {
id: uptimeProcess
command: ["bash", "-c", "uptime -p | sed 's/up //'"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
root.uptime = text.trim()
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("Uptime check failed with exit code:", exitCode)
}
}
}
Process {
id: schedulerProcess
command: ["bash", "-c", "cat /sys/block/sda/queue/scheduler 2>/dev/null | grep -o '\\[.*\\]' | tr -d '[]' || echo 'Unknown'"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
root.scheduler = text.trim()
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("Scheduler check failed with exit code:", exitCode)
}
}
}
Process {
id: architectureProcess
command: ["bash", "-c", "uname -m"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
root.architecture = text.trim()
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("Architecture check failed with exit code:", exitCode)
}
}
}
Process {
id: loadAverageProcess
command: ["bash", "-c", "cat /proc/loadavg | cut -d' ' -f1,2,3"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
root.loadAverage = text.trim()
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("Load average check failed with exit code:", exitCode)
}
}
}
Process {
id: processCountProcess
command: ["bash", "-c", "ps aux | wc -l"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
root.processCount = parseInt(text.trim()) - 1
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("Process count check failed with exit code:", exitCode)
}
}
}
Process {
id: threadCountProcess
command: ["bash", "-c", "cat /proc/stat | grep processes | awk '{print $2}'"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
root.threadCount = parseInt(text.trim())
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("Thread count check failed with exit code:", exitCode)
}
}
}
Process {
id: bootTimeProcess
command: ["bash", "-c", "who -b | awk '{print $3, $4}' || stat -c %w /proc/1 2>/dev/null | cut -d' ' -f1,2 || echo 'Unknown'"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
root.bootTime = text.trim()
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("Boot time check failed with exit code:", exitCode)
}
}
}
Process {
id: motherboardProcess
command: ["bash", "-c", "if [ -r /sys/devices/virtual/dmi/id/board_vendor ] && [ -r /sys/devices/virtual/dmi/id/board_name ]; then echo \"$(cat /sys/devices/virtual/dmi/id/board_vendor 2>/dev/null) $(cat /sys/devices/virtual/dmi/id/board_name 2>/dev/null)\"; else echo 'Unknown'; fi"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
root.motherboard = text.trim()
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("Motherboard check failed with exit code:", exitCode)
}
}
}
Process {
id: biosProcess
command: ["bash", "-c", "if [ -r /sys/devices/virtual/dmi/id/bios_version ] && [ -r /sys/devices/virtual/dmi/id/bios_date ]; then echo \"$(cat /sys/devices/virtual/dmi/id/bios_version 2>/dev/null) $(cat /sys/devices/virtual/dmi/id/bios_date 2>/dev/null)\"; else echo 'Unknown'; fi"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
root.biosVersion = text.trim()
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("BIOS check failed with exit code:", exitCode)
}
}
}
Process {
id: diskMountsProcess
command: ["bash", "-c", "df -h --output=source,target,fstype,size,used,avail,pcent | tail -n +2 | grep -v tmpfs | grep -v devtmpfs | head -10"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (text.trim()) {
let mounts = []
const lines = text.trim().split('\n')
for (const line of lines) {
const parts = line.split(/\s+/)
if (parts.length >= 7) {
mounts.push({
device: parts[0],
mount: parts[1],
fstype: parts[2],
size: parts[3],
used: parts[4],
avail: parts[5],
percent: parts[6]
})
}
}
root.diskMounts = mounts
}
}
}
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("Disk mounts check failed with exit code:", exitCode)
}
}
}
Timer { Timer {
id: cpuTimer id: cpuTimer
interval: root.cpuUpdateInterval interval: root.cpuUpdateInterval
@@ -202,6 +495,19 @@ Singleton {
} }
} }
Timer {
id: systemInfoTimer
interval: root.systemInfoUpdateInterval
running: root.enabledForDetailedView
repeat: true
onTriggered: {
if (root.enabledForDetailedView) {
updateSystemInfo()
}
}
}
function getCpuInfo() { function getCpuInfo() {
cpuInfoProcess.running = true cpuInfoProcess.running = true
} }
@@ -217,6 +523,22 @@ Singleton {
} }
} }
function updateSystemInfo() {
kernelInfoProcess.running = true
distributionProcess.running = true
hostnameProcess.running = true
uptimeProcess.running = true
schedulerProcess.running = true
architectureProcess.running = true
loadAverageProcess.running = true
processCountProcess.running = true
threadCountProcess.running = true
bootTimeProcess.running = true
motherboardProcess.running = true
biosProcess.running = true
diskMountsProcess.running = true
}
function enableTopBarMonitoring(enabled) { function enableTopBarMonitoring(enabled) {
root.enabledForTopBar = enabled root.enabledForTopBar = enabled
} }

View File

@@ -1115,36 +1115,481 @@ PanelWindow {
Component { Component {
id: systemTabComponent id: systemTabComponent
Rectangle {
color: "transparent" ScrollView {
anchors.fill: parent
clip: true
ScrollBar.vertical.policy: ScrollBar.AsNeeded
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
Column { Column {
anchors.centerIn: parent width: parent.width
spacing: Theme.spacingL spacing: Theme.spacingM
Text { Row {
text: "settings" width: parent.width
font.family: Theme.iconFont height: 140
font.pixelSize: 48 spacing: Theme.spacingM
color: Theme.primary
opacity: 0.6 Rectangle {
anchors.horizontalCenter: parent.horizontalCenter width: (parent.width - Theme.spacingM) / 2
height: 140
radius: Theme.cornerRadiusLarge
color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08)
border.color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.16)
border.width: 1
Column {
anchors.fill: parent
anchors.margins: Theme.spacingM
anchors.bottomMargin: Theme.spacingM + 4
spacing: Theme.spacingXS
Row {
width: parent.width
spacing: Theme.spacingS
Text {
text: "computer"
font.family: Theme.iconFont
font.pixelSize: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: "System"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Bold
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
Text {
text: "Host: " + SystemMonitorService.hostname
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width
elide: Text.ElideRight
}
Text {
text: "OS: " + SystemMonitorService.distribution
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width
elide: Text.ElideRight
}
Text {
text: "Arch: " + SystemMonitorService.architecture
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width
elide: Text.ElideRight
}
Text {
text: "Kernel: " + SystemMonitorService.kernelVersion
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width
elide: Text.ElideRight
}
}
}
Rectangle {
width: (parent.width - Theme.spacingM) / 2
height: 140
radius: Theme.cornerRadiusLarge
color: Qt.rgba(Theme.secondary.r, Theme.secondary.g, Theme.secondary.b, 0.08)
border.color: Qt.rgba(Theme.secondary.r, Theme.secondary.g, Theme.secondary.b, 0.16)
border.width: 1
Column {
anchors.fill: parent
anchors.margins: Theme.spacingM
anchors.bottomMargin: Theme.spacingM + 4
spacing: Theme.spacingXS
Row {
width: parent.width
spacing: Theme.spacingS
Text {
text: "developer_board"
font.family: Theme.iconFont
font.pixelSize: Theme.iconSize
color: Theme.secondary
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: "Hardware"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Bold
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
Text {
text: "CPU: " + SystemMonitorService.cpuModel
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width
elide: Text.ElideRight
}
Text {
text: "Motherboard: " + SystemMonitorService.motherboard
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width
elide: Text.ElideRight
}
Text {
text: "BIOS: " + SystemMonitorService.biosVersion
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width
elide: Text.ElideRight
}
Text {
text: "Memory: " + SystemMonitorService.formatMemory(SystemMonitorService.totalMemory)
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width
elide: Text.ElideRight
}
}
}
} }
Text { Row {
text: "System Information" width: parent.width
font.pixelSize: Theme.fontSizeLarge + 2 height: 120
font.weight: Font.Bold spacing: Theme.spacingM
color: Theme.surfaceText
anchors.horizontalCenter: parent.horizontalCenter Rectangle {
width: (parent.width - Theme.spacingM) / 2
height: 120
radius: Theme.cornerRadiusLarge
color: Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.08)
border.color: Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.16)
border.width: 1
Column {
anchors.fill: parent
anchors.margins: Theme.spacingM
anchors.bottomMargin: Theme.spacingM + 4
spacing: Theme.spacingXS
Row {
width: parent.width
spacing: Theme.spacingS
Text {
text: "timer"
font.family: Theme.iconFont
font.pixelSize: Theme.iconSize
color: Theme.warning
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: "Uptime"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Bold
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
Text {
text: SystemMonitorService.uptime
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Bold
color: Theme.surfaceText
width: parent.width
elide: Text.ElideRight
}
Text {
text: "Boot: " + SystemMonitorService.bootTime
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width
elide: Text.ElideRight
}
Text {
text: "Load: " + SystemMonitorService.loadAverage
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width
elide: Text.ElideRight
}
}
}
Rectangle {
width: (parent.width - Theme.spacingM) / 2
height: 120
radius: Theme.cornerRadiusLarge
color: Qt.rgba(Theme.info.r, Theme.info.g, Theme.info.b, 0.08)
border.color: Qt.rgba(Theme.info.r, Theme.info.g, Theme.info.b, 0.16)
border.width: 1
Column {
anchors.fill: parent
anchors.margins: Theme.spacingM
anchors.bottomMargin: Theme.spacingM + 4
spacing: Theme.spacingXS
Row {
width: parent.width
spacing: Theme.spacingS
Text {
text: "list_alt"
font.family: Theme.iconFont
font.pixelSize: Theme.iconSize
color: Theme.info
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: "Processes"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Bold
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
Text {
text: SystemMonitorService.processCount + " Running"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width
elide: Text.ElideRight
}
Text {
text: SystemMonitorService.threadCount + " Total Created"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width
elide: Text.ElideRight
}
}
}
} }
Text { Rectangle {
text: "Kernel information, schedulers,\nand system details will be shown here" width: parent.width
font.pixelSize: Theme.fontSizeMedium height: Math.max(200, diskMountRepeater.count * 28 + 60)
color: Theme.surfaceVariantText radius: Theme.cornerRadiusLarge
horizontalAlignment: Text.AlignHCenter color: Qt.rgba(Theme.success.r, Theme.success.g, Theme.success.b, 0.08)
anchors.horizontalCenter: parent.horizontalCenter border.color: Qt.rgba(Theme.success.r, Theme.success.g, Theme.success.b, 0.16)
border.width: 1
Column {
anchors.fill: parent
anchors.margins: Theme.spacingM
spacing: Theme.spacingS
Row {
width: parent.width
spacing: Theme.spacingS
Text {
text: "storage"
font.family: Theme.iconFont
font.pixelSize: Theme.iconSize
color: Theme.success
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: "Storage & Disks"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Bold
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
Text {
text: "I/O Scheduler: " + SystemMonitorService.scheduler
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width
elide: Text.ElideRight
}
ScrollView {
width: parent.width
height: parent.height - 60
clip: true
ScrollBar.vertical.policy: ScrollBar.AsNeeded
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
Column {
width: parent.width
spacing: 2
Row {
width: parent.width
height: 24
spacing: Theme.spacingS
Text {
text: "Device"
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Bold
color: Theme.surfaceText
width: parent.width * 0.25
elide: Text.ElideRight
}
Text {
text: "Mount"
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Bold
color: Theme.surfaceText
width: parent.width * 0.2
elide: Text.ElideRight
}
Text {
text: "Size"
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Bold
color: Theme.surfaceText
width: parent.width * 0.15
elide: Text.ElideRight
}
Text {
text: "Used"
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Bold
color: Theme.surfaceText
width: parent.width * 0.15
elide: Text.ElideRight
}
Text {
text: "Available"
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Bold
color: Theme.surfaceText
width: parent.width * 0.15
elide: Text.ElideRight
}
Text {
text: "Use%"
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Bold
color: Theme.surfaceText
width: parent.width * 0.1
elide: Text.ElideRight
}
}
Repeater {
id: diskMountRepeater
model: SystemMonitorService.diskMounts
Rectangle {
width: parent.width
height: 24
radius: Theme.cornerRadiusSmall
color: diskMouseArea.containsMouse ?
Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.04) :
"transparent"
MouseArea {
id: diskMouseArea
anchors.fill: parent
hoverEnabled: true
}
Row {
anchors.fill: parent
spacing: Theme.spacingS
Text {
text: modelData.device
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width * 0.25
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: modelData.mount
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width * 0.2
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: modelData.size
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width * 0.15
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: modelData.used
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width * 0.15
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: modelData.avail
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
width: parent.width * 0.15
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: modelData.percent
font.pixelSize: Theme.fontSizeSmall
color: {
const percent = parseInt(modelData.percent)
if (percent > 90) return Theme.error
if (percent > 75) return Theme.warning
return Theme.surfaceText
}
width: parent.width * 0.1
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
}
}
}
}
}
}
} }
} }
} }
@@ -1484,10 +1929,13 @@ PanelWindow {
processListWidget.isVisible = true processListWidget.isVisible = true
ProcessMonitorService.updateSystemInfo() ProcessMonitorService.updateSystemInfo()
ProcessMonitorService.updateProcessList() ProcessMonitorService.updateProcessList()
SystemMonitorService.enableDetailedMonitoring(true)
SystemMonitorService.updateSystemInfo()
} }
function hide() { function hide() {
processListWidget.isVisible = false processListWidget.isVisible = false
SystemMonitorService.enableDetailedMonitoring(false)
} }
function toggle() { function toggle() {