Add network stats to SystemMonitor, fix ActiveWindow text display
SystemMonitor: add network up/down stats (also added setting to disable it in BarTab) ActiveWindow: add elide if not hovered
This commit is contained in:
parent
724e55c37d
commit
2ebdc74f15
8 changed files with 135 additions and 10 deletions
|
|
@ -24,6 +24,11 @@ fi
|
||||||
TEMP_SENSOR_PATH=""
|
TEMP_SENSOR_PATH=""
|
||||||
TEMP_SENSOR_TYPE=""
|
TEMP_SENSOR_TYPE=""
|
||||||
|
|
||||||
|
# Network speed monitoring variables
|
||||||
|
PREV_RX_BYTES=0
|
||||||
|
PREV_TX_BYTES=0
|
||||||
|
PREV_TIME=0
|
||||||
|
|
||||||
# --- Data Collection Functions ---
|
# --- Data Collection Functions ---
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
@ -194,6 +199,8 @@ get_cpu_temp() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# --- Main Loop ---
|
# --- Main Loop ---
|
||||||
# This loop runs indefinitely, gathering and printing stats.
|
# This loop runs indefinitely, gathering and printing stats.
|
||||||
while true; do
|
while true; do
|
||||||
|
|
@ -205,14 +212,58 @@ while true; do
|
||||||
disk_per=$(get_disk_usage)
|
disk_per=$(get_disk_usage)
|
||||||
cpu_usage=$(get_cpu_usage)
|
cpu_usage=$(get_cpu_usage)
|
||||||
cpu_temp=$(get_cpu_temp)
|
cpu_temp=$(get_cpu_temp)
|
||||||
|
|
||||||
|
# Get network speeds
|
||||||
|
current_time=$(date +%s.%N)
|
||||||
|
total_rx=0
|
||||||
|
total_tx=0
|
||||||
|
|
||||||
|
# Read total bytes from /proc/net/dev for all interfaces
|
||||||
|
while IFS=: read -r interface stats; do
|
||||||
|
# Skip only loopback interface, allow other interfaces
|
||||||
|
if [[ "$interface" =~ ^lo[[:space:]]*$ ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract rx and tx bytes (fields 1 and 9 in the stats part)
|
||||||
|
rx_bytes=$(echo "$stats" | awk '{print $1}')
|
||||||
|
tx_bytes=$(echo "$stats" | awk '{print $9}')
|
||||||
|
|
||||||
|
# Add to totals if they are valid numbers
|
||||||
|
if [[ "$rx_bytes" =~ ^[0-9]+$ ]] && [[ "$tx_bytes" =~ ^[0-9]+$ ]]; then
|
||||||
|
total_rx=$((total_rx + rx_bytes))
|
||||||
|
total_tx=$((total_tx + tx_bytes))
|
||||||
|
fi
|
||||||
|
done < <(tail -n +3 /proc/net/dev)
|
||||||
|
|
||||||
|
# Calculate speeds if we have previous data
|
||||||
|
rx_speed=0
|
||||||
|
tx_speed=0
|
||||||
|
|
||||||
|
if [[ "$PREV_TIME" != "0" ]]; then
|
||||||
|
time_diff=$(awk -v current="$current_time" -v prev="$PREV_TIME" 'BEGIN { printf "%.3f", current - prev }')
|
||||||
|
rx_diff=$((total_rx - PREV_RX_BYTES))
|
||||||
|
tx_diff=$((total_tx - PREV_TX_BYTES))
|
||||||
|
|
||||||
|
# Calculate speeds in bytes per second using awk
|
||||||
|
rx_speed=$(awk -v rx="$rx_diff" -v time="$time_diff" 'BEGIN { printf "%.0f", rx / time }')
|
||||||
|
tx_speed=$(awk -v tx="$tx_diff" -v time="$time_diff" 'BEGIN { printf "%.0f", tx / time }')
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update previous values for next iteration
|
||||||
|
PREV_RX_BYTES=$total_rx
|
||||||
|
PREV_TX_BYTES=$total_tx
|
||||||
|
PREV_TIME=$current_time
|
||||||
|
|
||||||
# Use printf to format the final JSON output string, adding the mem_mb key.
|
# Use printf to format the final JSON output string, adding the mem_mb key.
|
||||||
printf '{"cpu": "%s", "cputemp": "%s", "memgb":"%s", "memper": "%s", "diskper": "%s"}\n' \
|
printf '{"cpu": "%s", "cputemp": "%s", "memgb":"%s", "memper": "%s", "diskper": "%s", "rx_speed": "%s", "tx_speed": "%s"}\n' \
|
||||||
"$cpu_usage" \
|
"$cpu_usage" \
|
||||||
"$cpu_temp" \
|
"$cpu_temp" \
|
||||||
"$mem_gb" \
|
"$mem_gb" \
|
||||||
"$mem_per" \
|
"$mem_per" \
|
||||||
"$disk_per"
|
"$disk_per" \
|
||||||
|
"$rx_speed" \
|
||||||
|
"$tx_speed"
|
||||||
|
|
||||||
# Wait for the specified duration before the next update.
|
# Wait for the specified duration before the next update.
|
||||||
sleep "$SLEEP_DURATION"
|
sleep "$SLEEP_DURATION"
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,7 @@ Singleton {
|
||||||
property string position: "top" // Possible values: "top", "bottom"
|
property string position: "top" // Possible values: "top", "bottom"
|
||||||
property bool showActiveWindowIcon: true
|
property bool showActiveWindowIcon: true
|
||||||
property bool alwaysShowBatteryPercentage: false
|
property bool alwaysShowBatteryPercentage: false
|
||||||
|
property bool showNetworkStats: true
|
||||||
property real backgroundOpacity: 1.0
|
property real backgroundOpacity: 1.0
|
||||||
property string showWorkspaceLabel: "none"
|
property string showWorkspaceLabel: "none"
|
||||||
property list<string> monitors: []
|
property list<string> monitors: []
|
||||||
|
|
|
||||||
|
|
@ -141,10 +141,12 @@ NPanel {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
color: (modelData?.enabled
|
color: (modelData?.enabled
|
||||||
?? true) ? (mouseArea.containsMouse ? Color.mOnTertiary : Color.mOnSurface) : Color.mOnSurfaceVariant
|
?? true) ? (mouseArea.containsMouse ? Color.mOnTertiary : Color.mOnSurface) : Color.mOnSurfaceVariant
|
||||||
text: modelData?.text !== "" ? modelData?.text.replace(/[\n\r]+/g, ' ') : "..."
|
text: modelData?.text !== "" ? modelData?.text.replace(/[\n\r]+/g, ' ').replace(/\s+/g,
|
||||||
|
' ').trim() : "..."
|
||||||
font.pointSize: Style.fontSizeS * scaling
|
font.pointSize: Style.fontSizeS * scaling
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.NoWrap
|
||||||
|
elide: Text.ElideRight
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
|
|
|
||||||
|
|
@ -86,18 +86,18 @@ Row {
|
||||||
NText {
|
NText {
|
||||||
id: titleText
|
id: titleText
|
||||||
|
|
||||||
// Fix collapsed width to 120px to avoid layout shifts with neighbors
|
// Collapsed width when not hovered, expand on hover
|
||||||
// Expand up to 400px on hover
|
width: mouseArea.containsMouse ? Math.min(fullTitleMetrics.contentWidth + (Style.marginS * scaling),
|
||||||
width: mouseArea.containsMouse ? Math.min(Math.max(minWidth * scaling, fullTitleMetrics.contentWidth),
|
400 * scaling) : (minWidth * scaling)
|
||||||
400 * scaling) : minWidth * scaling
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
text: getTitle()
|
text: getTitle()
|
||||||
font.pointSize: Style.fontSizeS * scaling
|
font.pointSize: Style.fontSizeS * scaling
|
||||||
font.weight: Style.fontWeightMedium
|
font.weight: Style.fontWeightMedium
|
||||||
elide: Text.ElideRight
|
elide: mouseArea.containsMouse ? Text.ElideNone : Text.ElideRight
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
color: Color.mSecondary
|
color: Color.mSecondary
|
||||||
|
clip: true
|
||||||
|
|
||||||
Behavior on width {
|
Behavior on width {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,50 @@ Row {
|
||||||
color: Color.mPrimary
|
color: Color.mPrimary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Network Download Speed Component
|
||||||
|
Row {
|
||||||
|
id: networkDownloadLayout
|
||||||
|
spacing: Style.marginXS * scaling
|
||||||
|
visible: Settings.data.bar.showNetworkStats
|
||||||
|
|
||||||
|
NIcon {
|
||||||
|
text: "download"
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
NText {
|
||||||
|
text: SystemStatService.formatSpeed(SystemStatService.rxSpeed)
|
||||||
|
font.family: Settings.data.ui.fontFixed
|
||||||
|
font.pointSize: Style.fontSizeS * scaling
|
||||||
|
font.weight: Style.fontWeightMedium
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
color: Color.mPrimary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Network Upload Speed Component
|
||||||
|
Row {
|
||||||
|
id: networkUploadLayout
|
||||||
|
spacing: Style.marginXS * scaling
|
||||||
|
visible: Settings.data.bar.showNetworkStats
|
||||||
|
|
||||||
|
NIcon {
|
||||||
|
text: "upload"
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
NText {
|
||||||
|
text: SystemStatService.formatSpeed(SystemStatService.txSpeed)
|
||||||
|
font.family: Settings.data.ui.fontFixed
|
||||||
|
font.pointSize: Style.fontSizeS * scaling
|
||||||
|
font.weight: Style.fontWeightMedium
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
color: Color.mPrimary
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -309,7 +309,8 @@ NPanel {
|
||||||
return Color.mOnSurfaceVariant
|
return Color.mOnSurfaceVariant
|
||||||
}
|
}
|
||||||
opacity: Style.opacityHeavy
|
opacity: Style.opacityHeavy
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.NoWrap
|
||||||
|
elide: Text.ElideRight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,15 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NToggle {
|
||||||
|
label: "Show Network Statistics"
|
||||||
|
description: "Display network upload and download speeds in the system monitor."
|
||||||
|
checked: Settings.data.bar.showNetworkStats
|
||||||
|
onToggled: checked => {
|
||||||
|
Settings.data.bar.showNetworkStats = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NComboBox {
|
NComboBox {
|
||||||
label: "Show Workspaces Labels"
|
label: "Show Workspaces Labels"
|
||||||
description: "Display the workspace name or index in the workspace indicator"
|
description: "Display the workspace name or index in the workspace indicator"
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,21 @@ Singleton {
|
||||||
property real memoryUsageGb: 0
|
property real memoryUsageGb: 0
|
||||||
property real memoryUsagePer: 0
|
property real memoryUsagePer: 0
|
||||||
property real diskUsage: 0
|
property real diskUsage: 0
|
||||||
|
property real rxSpeed: 0
|
||||||
|
property real txSpeed: 0
|
||||||
|
|
||||||
|
// Helper function to format network speeds
|
||||||
|
function formatSpeed(bytesPerSecond) {
|
||||||
|
if (bytesPerSecond < 1024) {
|
||||||
|
return bytesPerSecond.toFixed(0) + " B/s"
|
||||||
|
} else if (bytesPerSecond < 1024 * 1024) {
|
||||||
|
return (bytesPerSecond / 1024).toFixed(1) + " KB/s"
|
||||||
|
} else if (bytesPerSecond < 1024 * 1024 * 1024) {
|
||||||
|
return (bytesPerSecond / (1024 * 1024)).toFixed(1) + " MB/s"
|
||||||
|
} else {
|
||||||
|
return (bytesPerSecond / (1024 * 1024 * 1024)).toFixed(1) + " GB/s"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Background process emitting one JSON line per sample
|
// Background process emitting one JSON line per sample
|
||||||
Process {
|
Process {
|
||||||
|
|
@ -29,6 +44,8 @@ Singleton {
|
||||||
root.memoryUsageGb = data.memgb
|
root.memoryUsageGb = data.memgb
|
||||||
root.memoryUsagePer = data.memper
|
root.memoryUsagePer = data.memper
|
||||||
root.diskUsage = data.diskper
|
root.diskUsage = data.diskper
|
||||||
|
root.rxSpeed = parseFloat(data.rx_speed) || 0
|
||||||
|
root.txSpeed = parseFloat(data.tx_speed) || 0
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
||||||
// ignore malformed lines
|
// ignore malformed lines
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue