mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-07 14:05:38 -05:00
Add Performance tab under Process monitor
This commit is contained in:
@@ -10,7 +10,7 @@ Singleton {
|
|||||||
// Process list properties
|
// Process list properties
|
||||||
property var processes: []
|
property var processes: []
|
||||||
property bool isUpdating: false
|
property bool isUpdating: false
|
||||||
property int processUpdateInterval: 1500
|
property int processUpdateInterval: 3000
|
||||||
|
|
||||||
// Performance control - only run when process monitor is actually visible
|
// Performance control - only run when process monitor is actually visible
|
||||||
property bool monitoringEnabled: false
|
property bool monitoringEnabled: false
|
||||||
@@ -24,6 +24,26 @@ Singleton {
|
|||||||
property real totalCpuUsage: 0.0
|
property real totalCpuUsage: 0.0
|
||||||
property bool systemInfoAvailable: false
|
property bool systemInfoAvailable: false
|
||||||
|
|
||||||
|
// Performance history for charts
|
||||||
|
property var cpuHistory: []
|
||||||
|
property var memoryHistory: []
|
||||||
|
property var networkHistory: ({rx: [], tx: []})
|
||||||
|
property var diskHistory: ({read: [], write: []})
|
||||||
|
property int historySize: 60 // Keep 60 data points
|
||||||
|
|
||||||
|
// Per-core CPU usage
|
||||||
|
property var perCoreCpuUsage: []
|
||||||
|
|
||||||
|
// Network stats
|
||||||
|
property real networkRxRate: 0 // bytes/sec
|
||||||
|
property real networkTxRate: 0 // bytes/sec
|
||||||
|
property var lastNetworkStats: null
|
||||||
|
|
||||||
|
// Disk I/O stats
|
||||||
|
property real diskReadRate: 0 // bytes/sec
|
||||||
|
property real diskWriteRate: 0 // bytes/sec
|
||||||
|
property var lastDiskStats: null
|
||||||
|
|
||||||
// Sorting options
|
// Sorting options
|
||||||
property string sortBy: "cpu" // "cpu", "memory", "name", "pid"
|
property string sortBy: "cpu" // "cpu", "memory", "name", "pid"
|
||||||
property bool sortDescending: true
|
property bool sortDescending: true
|
||||||
@@ -33,12 +53,39 @@ Singleton {
|
|||||||
console.log("ProcessMonitorService: Starting initialization...")
|
console.log("ProcessMonitorService: Starting initialization...")
|
||||||
updateProcessList()
|
updateProcessList()
|
||||||
console.log("ProcessMonitorService: Initialization complete")
|
console.log("ProcessMonitorService: Initialization complete")
|
||||||
|
|
||||||
|
// Test monitoring disabled - only monitor when explicitly enabled
|
||||||
|
// testTimer.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: testTimer
|
||||||
|
interval: 3000
|
||||||
|
running: false
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
console.log("ProcessMonitorService: Starting test monitoring...")
|
||||||
|
enableMonitoring(true)
|
||||||
|
// Stop after 8 seconds
|
||||||
|
stopTestTimer.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: stopTestTimer
|
||||||
|
interval: 8000
|
||||||
|
running: false
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
console.log("ProcessMonitorService: Stopping test monitoring...")
|
||||||
|
enableMonitoring(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// System information monitoring
|
// System information monitoring
|
||||||
Process {
|
Process {
|
||||||
id: systemInfoProcess
|
id: systemInfoProcess
|
||||||
command: ["bash", "-c", "cat /proc/meminfo; echo '---CPU---'; nproc; echo '---CPUSTAT---'; grep '^cpu ' /proc/stat"]
|
command: ["bash", "-c", "cat /proc/meminfo; echo '---CPU---'; nproc; echo '---CPUSTAT---'; grep '^cpu' /proc/stat | head -" + (root.cpuCount + 1)]
|
||||||
running: false
|
running: false
|
||||||
|
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
@@ -57,6 +104,36 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Network monitoring process
|
||||||
|
Process {
|
||||||
|
id: networkStatsProcess
|
||||||
|
command: ["bash", "-c", "cat /proc/net/dev | grep -E '(wlan|eth|enp|wlp|ens|eno)' | awk '{print $1,$2,$10}' | sed 's/:/ /'"]
|
||||||
|
running: false
|
||||||
|
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
if (text.trim()) {
|
||||||
|
parseNetworkStats(text.trim())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disk I/O monitoring process
|
||||||
|
Process {
|
||||||
|
id: diskStatsProcess
|
||||||
|
command: ["bash", "-c", "cat /proc/diskstats | grep -E ' (sd[a-z]+|nvme[0-9]+n[0-9]+|vd[a-z]+) ' | grep -v 'p[0-9]' | awk '{print $3,$6,$10}'"]
|
||||||
|
running: false
|
||||||
|
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
if (text.trim()) {
|
||||||
|
parseDiskStats(text.trim())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Process monitoring with ps command
|
// Process monitoring with ps command
|
||||||
Process {
|
Process {
|
||||||
id: processListProcess
|
id: processListProcess
|
||||||
@@ -123,6 +200,8 @@ Singleton {
|
|||||||
if (root.monitoringEnabled) {
|
if (root.monitoringEnabled) {
|
||||||
updateSystemInfo()
|
updateSystemInfo()
|
||||||
updateProcessList()
|
updateProcessList()
|
||||||
|
updateNetworkStats()
|
||||||
|
updateDiskStats()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -139,9 +218,29 @@ Singleton {
|
|||||||
console.log("ProcessMonitorService: Monitoring", enabled ? "enabled" : "disabled")
|
console.log("ProcessMonitorService: Monitoring", enabled ? "enabled" : "disabled")
|
||||||
root.monitoringEnabled = enabled
|
root.monitoringEnabled = enabled
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
|
// Clear history when starting
|
||||||
|
root.cpuHistory = []
|
||||||
|
root.memoryHistory = []
|
||||||
|
root.networkHistory = ({rx: [], tx: []})
|
||||||
|
root.diskHistory = ({read: [], write: []})
|
||||||
// Immediately update when enabled
|
// Immediately update when enabled
|
||||||
updateSystemInfo()
|
updateSystemInfo()
|
||||||
updateProcessList()
|
updateProcessList()
|
||||||
|
updateNetworkStats()
|
||||||
|
updateDiskStats()
|
||||||
|
// console.log("ProcessMonitorService: Initial data collection started")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateNetworkStats() {
|
||||||
|
if (!networkStatsProcess.running && root.monitoringEnabled) {
|
||||||
|
networkStatsProcess.running = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateDiskStats() {
|
||||||
|
if (!diskStatsProcess.running && root.monitoringEnabled) {
|
||||||
|
diskStatsProcess.running = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,6 +343,7 @@ Singleton {
|
|||||||
function parseSystemInfo(text) {
|
function parseSystemInfo(text) {
|
||||||
const lines = text.split('\n')
|
const lines = text.split('\n')
|
||||||
let section = 'memory'
|
let section = 'memory'
|
||||||
|
const coreUsages = []
|
||||||
|
|
||||||
for (let i = 0; i < lines.length; i++) {
|
for (let i = 0; i < lines.length; i++) {
|
||||||
const line = lines[i].trim()
|
const line = lines[i].trim()
|
||||||
@@ -289,10 +389,103 @@ Singleton {
|
|||||||
const used = total - idle - iowait
|
const used = total - idle - iowait
|
||||||
root.totalCpuUsage = total > 0 ? (used / total) * 100 : 0
|
root.totalCpuUsage = total > 0 ? (used / total) * 100 : 0
|
||||||
}
|
}
|
||||||
|
} else if (line.match(/^cpu\d+/)) {
|
||||||
|
const parts = line.split(/\s+/)
|
||||||
|
if (parts.length >= 8) {
|
||||||
|
const user = parseInt(parts[1])
|
||||||
|
const nice = parseInt(parts[2])
|
||||||
|
const system = parseInt(parts[3])
|
||||||
|
const idle = parseInt(parts[4])
|
||||||
|
const iowait = parseInt(parts[5])
|
||||||
|
const irq = parseInt(parts[6])
|
||||||
|
const softirq = parseInt(parts[7])
|
||||||
|
|
||||||
|
const total = user + nice + system + idle + iowait + irq + softirq
|
||||||
|
const used = total - idle - iowait
|
||||||
|
const usage = total > 0 ? (used / total) * 100 : 0
|
||||||
|
coreUsages.push(usage)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update per-core usage
|
||||||
|
root.perCoreCpuUsage = coreUsages
|
||||||
|
|
||||||
|
// Update history
|
||||||
|
addToHistory(root.cpuHistory, root.totalCpuUsage)
|
||||||
|
const memoryPercent = root.totalMemoryKB > 0 ? (root.usedMemoryKB / root.totalMemoryKB) * 100 : 0
|
||||||
|
addToHistory(root.memoryHistory, memoryPercent)
|
||||||
|
|
||||||
|
// console.log("ProcessMonitorService: Updated - CPU:", root.totalCpuUsage.toFixed(1) + "%", "Memory:", memoryPercent.toFixed(1) + "%", "History length:", root.cpuHistory.length)
|
||||||
|
|
||||||
root.systemInfoAvailable = true
|
root.systemInfoAvailable = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseNetworkStats(text) {
|
||||||
|
const lines = text.split('\n')
|
||||||
|
let totalRx = 0
|
||||||
|
let totalTx = 0
|
||||||
|
|
||||||
|
for (const line of lines) {
|
||||||
|
const parts = line.trim().split(/\s+/)
|
||||||
|
if (parts.length >= 3) {
|
||||||
|
const rx = parseInt(parts[1])
|
||||||
|
const tx = parseInt(parts[2])
|
||||||
|
if (!isNaN(rx) && !isNaN(tx)) {
|
||||||
|
totalRx += rx
|
||||||
|
totalTx += tx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (root.lastNetworkStats) {
|
||||||
|
const timeDiff = root.processUpdateInterval / 1000
|
||||||
|
root.networkRxRate = Math.max(0, (totalRx - root.lastNetworkStats.rx) / timeDiff)
|
||||||
|
root.networkTxRate = Math.max(0, (totalTx - root.lastNetworkStats.tx) / timeDiff)
|
||||||
|
|
||||||
|
// Convert to KB/s for history
|
||||||
|
addToHistory(root.networkHistory.rx, root.networkRxRate / 1024)
|
||||||
|
addToHistory(root.networkHistory.tx, root.networkTxRate / 1024)
|
||||||
|
}
|
||||||
|
|
||||||
|
root.lastNetworkStats = { rx: totalRx, tx: totalTx }
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseDiskStats(text) {
|
||||||
|
const lines = text.split('\n')
|
||||||
|
let totalRead = 0
|
||||||
|
let totalWrite = 0
|
||||||
|
|
||||||
|
for (const line of lines) {
|
||||||
|
const parts = line.trim().split(/\s+/)
|
||||||
|
if (parts.length >= 3) {
|
||||||
|
const readSectors = parseInt(parts[1])
|
||||||
|
const writeSectors = parseInt(parts[2])
|
||||||
|
if (!isNaN(readSectors) && !isNaN(writeSectors)) {
|
||||||
|
totalRead += readSectors * 512 // Convert sectors to bytes
|
||||||
|
totalWrite += writeSectors * 512
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (root.lastDiskStats) {
|
||||||
|
const timeDiff = root.processUpdateInterval / 1000
|
||||||
|
root.diskReadRate = Math.max(0, (totalRead - root.lastDiskStats.read) / timeDiff)
|
||||||
|
root.diskWriteRate = Math.max(0, (totalWrite - root.lastDiskStats.write) / timeDiff)
|
||||||
|
|
||||||
|
// Convert to MB/s for history
|
||||||
|
addToHistory(root.diskHistory.read, root.diskReadRate / (1024 * 1024))
|
||||||
|
addToHistory(root.diskHistory.write, root.diskWriteRate / (1024 * 1024))
|
||||||
|
}
|
||||||
|
|
||||||
|
root.lastDiskStats = { read: totalRead, write: totalWrite }
|
||||||
|
}
|
||||||
|
|
||||||
|
function addToHistory(array, value) {
|
||||||
|
array.push(value)
|
||||||
|
if (array.length > root.historySize) {
|
||||||
|
array.shift()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -281,10 +281,10 @@ PanelWindow {
|
|||||||
height: 80
|
height: 80
|
||||||
radius: Theme.cornerRadiusLarge
|
radius: Theme.cornerRadiusLarge
|
||||||
color: ProcessMonitorService.totalSwapKB > 0 ?
|
color: ProcessMonitorService.totalSwapKB > 0 ?
|
||||||
Qt.rgba(Theme.tertiary.r, Theme.tertiary.g, Theme.tertiary.b, 0.08) :
|
Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.08) :
|
||||||
Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.04)
|
Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.04)
|
||||||
border.color: ProcessMonitorService.totalSwapKB > 0 ?
|
border.color: ProcessMonitorService.totalSwapKB > 0 ?
|
||||||
Qt.rgba(Theme.tertiary.r, Theme.tertiary.g, Theme.tertiary.b, 0.2) :
|
Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.2) :
|
||||||
Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.12)
|
Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.12)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
@@ -298,7 +298,7 @@ PanelWindow {
|
|||||||
text: "Swap"
|
text: "Swap"
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
color: ProcessMonitorService.totalSwapKB > 0 ? Theme.tertiary : Theme.surfaceText
|
color: ProcessMonitorService.totalSwapKB > 0 ? Theme.warning : Theme.surfaceText
|
||||||
opacity: 0.8
|
opacity: 0.8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -443,10 +443,10 @@ PanelWindow {
|
|||||||
height: 80
|
height: 80
|
||||||
radius: Theme.cornerRadiusLarge
|
radius: Theme.cornerRadiusLarge
|
||||||
color: ProcessMonitorService.totalSwapKB > 0 ?
|
color: ProcessMonitorService.totalSwapKB > 0 ?
|
||||||
Qt.rgba(Theme.tertiary.r, Theme.tertiary.g, Theme.tertiary.b, 0.08) :
|
Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.08) :
|
||||||
Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.04)
|
Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.04)
|
||||||
border.color: ProcessMonitorService.totalSwapKB > 0 ?
|
border.color: ProcessMonitorService.totalSwapKB > 0 ?
|
||||||
Qt.rgba(Theme.tertiary.r, Theme.tertiary.g, Theme.tertiary.b, 0.2) :
|
Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.2) :
|
||||||
Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.12)
|
Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.12)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
@@ -460,7 +460,7 @@ PanelWindow {
|
|||||||
text: "Swap"
|
text: "Swap"
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
color: ProcessMonitorService.totalSwapKB > 0 ? Theme.tertiary : Theme.surfaceText
|
color: ProcessMonitorService.totalSwapKB > 0 ? Theme.warning : Theme.surfaceText
|
||||||
opacity: 0.8
|
opacity: 0.8
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -749,36 +749,365 @@ PanelWindow {
|
|||||||
// Define inline components for tabs
|
// Define inline components for tabs
|
||||||
Component {
|
Component {
|
||||||
id: performanceTabComponent
|
id: performanceTabComponent
|
||||||
Rectangle {
|
|
||||||
color: "transparent"
|
Column {
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
Column {
|
// CPU Section - Compact with per-core bars
|
||||||
anchors.centerIn: parent
|
Rectangle {
|
||||||
spacing: Theme.spacingL
|
width: parent.width
|
||||||
|
height: 200
|
||||||
|
radius: Theme.cornerRadiusLarge
|
||||||
|
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.04)
|
||||||
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.06)
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
Text {
|
Column {
|
||||||
text: "analytics"
|
anchors.fill: parent
|
||||||
font.family: Theme.iconFont
|
anchors.margins: Theme.spacingM
|
||||||
font.pixelSize: 48
|
spacing: Theme.spacingS
|
||||||
color: Theme.primary
|
|
||||||
opacity: 0.6
|
// CPU Header with overall usage
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
Row {
|
||||||
|
width: parent.width
|
||||||
|
height: 32
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "CPU"
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
font.weight: Font.Bold
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 80
|
||||||
|
height: 24
|
||||||
|
radius: Theme.cornerRadiusSmall
|
||||||
|
color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12)
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: ProcessMonitorService.totalCpuUsage.toFixed(1) + "%"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
font.weight: Font.Bold
|
||||||
|
color: Theme.primary
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { width: parent.width - 280; height: 1 }
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: ProcessMonitorService.cpuCount + " cores"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Per-core CPU bars - Scrollable
|
||||||
|
ScrollView {
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height - 40
|
||||||
|
clip: true
|
||||||
|
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
||||||
|
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: parent.width
|
||||||
|
spacing: 6
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: ProcessMonitorService.perCoreCpuUsage.length
|
||||||
|
|
||||||
|
Row {
|
||||||
|
width: parent.width
|
||||||
|
height: 20
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
// Core label
|
||||||
|
Text {
|
||||||
|
text: "C" + index
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
width: 24
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
// Usage bar
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width - 80
|
||||||
|
height: 6
|
||||||
|
radius: 3
|
||||||
|
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width * Math.min(1.0, ProcessMonitorService.perCoreCpuUsage[index] / 100)
|
||||||
|
height: parent.height
|
||||||
|
radius: parent.radius
|
||||||
|
color: {
|
||||||
|
const usage = ProcessMonitorService.perCoreCpuUsage[index]
|
||||||
|
if (usage > 80) return Theme.error
|
||||||
|
if (usage > 60) return Theme.warning
|
||||||
|
return Theme.primary
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on width {
|
||||||
|
NumberAnimation { duration: Theme.shortDuration }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Usage percentage
|
||||||
|
Text {
|
||||||
|
text: ProcessMonitorService.perCoreCpuUsage[index] ?
|
||||||
|
ProcessMonitorService.perCoreCpuUsage[index].toFixed(0) + "%" : "0%"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
width: 32
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Memory Section - Simplified
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: 80
|
||||||
|
radius: Theme.cornerRadiusLarge
|
||||||
|
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.04)
|
||||||
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.06)
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.spacingM
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "Memory"
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
font.weight: Font.Bold
|
||||||
|
color: Theme.surfaceText
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: ProcessMonitorService.formatSystemMemory(ProcessMonitorService.usedMemoryKB) +
|
||||||
|
" / " + ProcessMonitorService.formatSystemMemory(ProcessMonitorService.totalMemoryKB)
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { width: Theme.spacingL; height: 1 }
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: 4
|
||||||
|
width: 200
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: 16
|
||||||
|
radius: 8
|
||||||
|
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: ProcessMonitorService.totalMemoryKB > 0 ?
|
||||||
|
parent.width * (ProcessMonitorService.usedMemoryKB / ProcessMonitorService.totalMemoryKB) : 0
|
||||||
|
height: parent.height
|
||||||
|
radius: parent.radius
|
||||||
|
color: {
|
||||||
|
const usage = ProcessMonitorService.totalMemoryKB > 0 ?
|
||||||
|
(ProcessMonitorService.usedMemoryKB / ProcessMonitorService.totalMemoryKB) : 0
|
||||||
|
if (usage > 0.9) return Theme.error
|
||||||
|
if (usage > 0.7) return Theme.warning
|
||||||
|
return Theme.secondary
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on width {
|
||||||
|
NumberAnimation { duration: Theme.mediumDuration }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: ProcessMonitorService.totalMemoryKB > 0 ?
|
||||||
|
((ProcessMonitorService.usedMemoryKB / ProcessMonitorService.totalMemoryKB) * 100).toFixed(1) + "% used" :
|
||||||
|
"No data"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
font.weight: Font.Bold
|
||||||
|
color: Theme.surfaceText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { width: parent.width - 300; height: 1 }
|
||||||
|
|
||||||
|
// Swap info - compact
|
||||||
|
Column {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: 4
|
||||||
|
visible: ProcessMonitorService.totalSwapKB > 0
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "Swap"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
font.weight: Font.Bold
|
||||||
|
color: Theme.warning
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: ProcessMonitorService.formatSystemMemory(ProcessMonitorService.usedSwapKB) +
|
||||||
|
" / " + ProcessMonitorService.formatSystemMemory(ProcessMonitorService.totalSwapKB)
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Network & Disk I/O - Combined compact view
|
||||||
|
Row {
|
||||||
|
width: parent.width
|
||||||
|
height: 80
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
// Network I/O
|
||||||
|
Rectangle {
|
||||||
|
width: (parent.width - Theme.spacingM) / 2
|
||||||
|
height: 80
|
||||||
|
radius: Theme.cornerRadiusLarge
|
||||||
|
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.04)
|
||||||
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.06)
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "Network"
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
font.weight: Font.Bold
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "↓"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.info
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: formatNetworkSpeed(ProcessMonitorService.networkRxRate)
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
font.weight: Font.Bold
|
||||||
|
color: Theme.surfaceText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "↑"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.error
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: formatNetworkSpeed(ProcessMonitorService.networkTxRate)
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
font.weight: Font.Bold
|
||||||
|
color: Theme.surfaceText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
// Disk I/O
|
||||||
text: "Performance Monitoring"
|
Rectangle {
|
||||||
font.pixelSize: Theme.fontSizeLarge + 2
|
width: (parent.width - Theme.spacingM) / 2
|
||||||
font.weight: Font.Bold
|
height: 80
|
||||||
color: Theme.surfaceText
|
radius: Theme.cornerRadiusLarge
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.04)
|
||||||
}
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.06)
|
||||||
|
border.width: 1
|
||||||
Text {
|
|
||||||
text: "Real-time system performance charts\nwill be displayed here"
|
Column {
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
anchors.centerIn: parent
|
||||||
color: Theme.surfaceVariantText
|
spacing: Theme.spacingXS
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
Text {
|
||||||
|
text: "Disk"
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
font.weight: Font.Bold
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "R"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.primary
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: formatDiskSpeed(ProcessMonitorService.diskReadRate)
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
font.weight: Font.Bold
|
||||||
|
color: Theme.surfaceText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "W"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.warning
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: formatDiskSpeed(ProcessMonitorService.diskWriteRate)
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
font.weight: Font.Bold
|
||||||
|
color: Theme.surfaceText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1168,4 +1497,27 @@ PanelWindow {
|
|||||||
show()
|
show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper functions for formatting
|
||||||
|
function formatNetworkSpeed(bytesPerSec) {
|
||||||
|
if (bytesPerSec < 1024) {
|
||||||
|
return bytesPerSec.toFixed(0) + " B/s"
|
||||||
|
} else if (bytesPerSec < 1024 * 1024) {
|
||||||
|
return (bytesPerSec / 1024).toFixed(1) + " KB/s"
|
||||||
|
} else if (bytesPerSec < 1024 * 1024 * 1024) {
|
||||||
|
return (bytesPerSec / (1024 * 1024)).toFixed(1) + " MB/s"
|
||||||
|
} else {
|
||||||
|
return (bytesPerSec / (1024 * 1024 * 1024)).toFixed(1) + " GB/s"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDiskSpeed(bytesPerSec) {
|
||||||
|
if (bytesPerSec < 1024 * 1024) {
|
||||||
|
return (bytesPerSec / 1024).toFixed(1) + " KB/s"
|
||||||
|
} else if (bytesPerSec < 1024 * 1024 * 1024) {
|
||||||
|
return (bytesPerSec / (1024 * 1024)).toFixed(1) + " MB/s"
|
||||||
|
} else {
|
||||||
|
return (bytesPerSec / (1024 * 1024 * 1024)).toFixed(1) + " GB/s"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user