From 3a6f42e79a04343a27ab050d70cb6dfb98914cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alice=20=E2=9C=A8=F0=9F=8C=99=20Luna?= Date: Fri, 13 Feb 2026 01:51:28 +0100 Subject: [PATCH] SystemMonitor: Add option to pad the text This option is only shown if compact mode is off and a monospace font is enabled. If the bar is vertical the setting will be ignored. Everything should not shift and the width is calculated from the maximum value (which can be system dependent). --- Assets/Translations/de.json | 6 ++- Assets/Translations/en.json | 6 ++- Assets/settings-widgets-default.json | 1 + Modules/Bar/Widgets/SystemMonitor.qml | 34 +++++++++----- .../WidgetSettings/SystemMonitorSettings.qml | 17 +++++++ Services/System/SystemStatService.qml | 45 +++++++++++++++++-- Services/UI/BarWidgetRegistry.qml | 1 + 7 files changed, 94 insertions(+), 16 deletions(-) diff --git a/Assets/Translations/de.json b/Assets/Translations/de.json index 36a3442aa..42f27e50e 100644 --- a/Assets/Translations/de.json +++ b/Assets/Translations/de.json @@ -224,7 +224,11 @@ "swap-usage-description": "Swap-Speichernutzung anzeigen.", "swap-usage-label": "Swap-Auslastung", "use-monospace-font-description": "Verwende eine Monospace-Schriftart für eine konsistente Zeichenbreite.", - "use-monospace-font-label": "Schriftart mit fester Breite" + "use-monospace-font-label": "Schriftart mit fester Breite", + "use-padding-description": "Füllt die Textwerte mit Leerzeichen auf. Verhindert Layoutverschiebungen.", + "use-padding-description-disabled-monospace-font": "Eine Monospace-Schriftart ist notwendig, um dieses Option wählen zu können.", + "use-padding-description-disabled-vertical": "Vertikale Taskleiste unterstützt keine Titelanzeige.", + "use-padding-label": "Text mit führenden Leerzeichen auffüllen" }, "taskbar": { "colorize-icons-description": "Themenfarben auf Taskbar-Symbole anwenden.", diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json index d461003d0..dc216102b 100644 --- a/Assets/Translations/en.json +++ b/Assets/Translations/en.json @@ -224,7 +224,11 @@ "swap-usage-description": "Show swap memory usage.", "swap-usage-label": "Swap usage", "use-monospace-font-description": "Use monospace font for consistent character width.", - "use-monospace-font-label": "Monospace font" + "use-monospace-font-label": "Monospace font", + "use-padding-description": "Pads the text values with leading spaces to prevent layout shifting.", + "use-padding-description-disabled-monospace-font": "A monospace font is needed for this feature.", + "use-padding-description-disabled-vertical": "Vertical taskbar does not support padding text.", + "use-padding-label": "Pad text" }, "taskbar": { "colorize-icons-description": "Apply theme colors to taskbar icons.", diff --git a/Assets/settings-widgets-default.json b/Assets/settings-widgets-default.json index 967d1e2f5..acc0b7908 100644 --- a/Assets/settings-widgets-default.json +++ b/Assets/settings-widgets-default.json @@ -146,6 +146,7 @@ "iconColor": "none", "textColor": "none", "useMonospaceFont": true, + "usePadding": false, "showCpuUsage": true, "showCpuFreq": false, "showCpuTemp": true, diff --git a/Modules/Bar/Widgets/SystemMonitor.qml b/Modules/Bar/Widgets/SystemMonitor.qml index 8cbfbf88d..136f6bcab 100644 --- a/Modules/Bar/Widgets/SystemMonitor.qml +++ b/Modules/Bar/Widgets/SystemMonitor.qml @@ -44,6 +44,7 @@ Item { readonly property string textColorKey: widgetSettings.textColor !== undefined ? widgetSettings.textColor : widgetMetadata.textColor readonly property bool useMonospaceFont: widgetSettings.useMonospaceFont !== undefined ? widgetSettings.useMonospaceFont : widgetMetadata.useMonospaceFont + readonly property bool usePadding: !compactMode && !isVertical && useMonospaceFont && (widgetSettings.usePadding !== undefined) ? widgetSettings.usePadding : widgetMetadata.usePadding readonly property bool showCpuUsage: (widgetSettings.showCpuUsage !== undefined) ? widgetSettings.showCpuUsage : widgetMetadata.showCpuUsage readonly property bool showCpuFreq: (widgetSettings.showCpuFreq !== undefined) ? widgetSettings.showCpuFreq : widgetMetadata.showCpuFreq readonly property bool showCpuTemp: (widgetSettings.showCpuTemp !== undefined) ? widgetSettings.showCpuTemp : widgetMetadata.showCpuTemp @@ -59,6 +60,11 @@ Item { readonly property string diskPath: (widgetSettings.diskPath !== undefined) ? widgetSettings.diskPath : widgetMetadata.diskPath readonly property string fontFamily: useMonospaceFont ? Settings.data.ui.fontFixed : Settings.data.ui.fontDefault + readonly property int paddingPercent: usePadding ? String("100%").length : 0 + readonly property int paddingTemp: usePadding ? String("999°").length : 0 + readonly property int paddingCpuFreq: usePadding ? String("9.9GHz").length : 0 + readonly property int paddingSpeed: usePadding ? String("9999G").length : 0 + readonly property real iconSize: Style.toOdd(capsuleHeight * 0.48) readonly property real miniGaugeWidth: Math.max(3, Style.toOdd(root.iconSize * 0.25)) @@ -259,7 +265,7 @@ Item { // Text mode NText { visible: !compactMode - text: `${Math.round(SystemStatService.cpuUsage)}%` + text: `${Math.round(SystemStatService.cpuUsage)}%`.padStart(paddingPercent, " ") family: fontFamily pointSize: barFontSize applyUiScale: false @@ -327,7 +333,7 @@ Item { // Text mode NText { visible: !compactMode - text: SystemStatService.cpuFreq.replace(" ", "") + text: SystemStatService.cpuFreq.replace(" ", "").padStart(paddingCpuFreq, " ") family: fontFamily pointSize: barFontSize applyUiScale: false @@ -395,7 +401,7 @@ Item { // Text mode NText { visible: !compactMode - text: `${Math.round(SystemStatService.cpuTemp)}°` + text: `${Math.round(SystemStatService.cpuTemp)}°`.padStart(paddingTemp, " ") family: fontFamily pointSize: barFontSize applyUiScale: false @@ -463,7 +469,7 @@ Item { // Text mode NText { visible: !compactMode - text: `${Math.round(SystemStatService.gpuTemp)}°` + text: `${Math.round(SystemStatService.gpuTemp)}°`.padStart(paddingTemp, " ") family: fontFamily pointSize: barFontSize applyUiScale: false @@ -531,7 +537,7 @@ Item { // Text mode NText { visible: !compactMode - text: SystemStatService.loadAvg1.toFixed(1) + text: `${SystemStatService.loadAvg1.toFixed(1)}`.padStart(usePadding ? `${SystemStatService.nproc.toFixed(1)}`.length : 0, " ") family: fontFamily pointSize: barFontSize applyUiScale: false @@ -599,7 +605,10 @@ Item { // Text mode NText { visible: !compactMode - text: showMemoryAsPercent ? `${Math.round(SystemStatService.memPercent)}%` : SystemStatService.formatGigabytes(SystemStatService.memGb) + text: SystemStatService.formatRamDisplay({ + percent: showMemoryAsPercent, + padding: usePadding + }) family: fontFamily pointSize: barFontSize applyUiScale: false @@ -667,7 +676,11 @@ Item { // Text mode NText { visible: !compactMode - text: `${Math.round(SystemStatService.swapPercent)}%` + text: SystemStatService.formatRamDisplay({ + swap: true, + percent: true, + padding: usePadding + }) family: fontFamily pointSize: barFontSize applyUiScale: false @@ -734,7 +747,7 @@ Item { // Text mode NText { visible: !compactMode - text: isVertical ? SystemStatService.formatCompactSpeed(SystemStatService.rxSpeed) : SystemStatService.formatSpeed(SystemStatService.rxSpeed) + text: isVertical ? SystemStatService.formatCompactSpeed(SystemStatService.rxSpeed) : SystemStatService.formatSpeed(SystemStatService.rxSpeed).padStart(paddingSpeed, " ") family: fontFamily pointSize: barFontSize applyUiScale: false @@ -800,7 +813,7 @@ Item { // Text mode NText { visible: !compactMode - text: isVertical ? SystemStatService.formatCompactSpeed(SystemStatService.txSpeed) : SystemStatService.formatSpeed(SystemStatService.txSpeed) + text: isVertical ? SystemStatService.formatCompactSpeed(SystemStatService.txSpeed) : SystemStatService.formatSpeed(SystemStatService.txSpeed).padStart(paddingSpeed, " ") family: fontFamily pointSize: barFontSize applyUiScale: false @@ -869,7 +882,8 @@ Item { visible: !compactMode text: SystemStatService.formatDiskDisplay(diskPath, { percent: showDiskUsageAsPercent, - available: showDiskAvailable + available: showDiskAvailable, + padding: usePadding }) family: fontFamily pointSize: barFontSize diff --git a/Modules/Panels/Settings/Bar/WidgetSettings/SystemMonitorSettings.qml b/Modules/Panels/Settings/Bar/WidgetSettings/SystemMonitorSettings.qml index b04a0ccc6..5342e3520 100644 --- a/Modules/Panels/Settings/Bar/WidgetSettings/SystemMonitorSettings.qml +++ b/Modules/Panels/Settings/Bar/WidgetSettings/SystemMonitorSettings.qml @@ -15,11 +15,14 @@ ColumnLayout { signal settingsChanged(var settings) + readonly property bool isVerticalBar: Settings.data.bar.position === "left" || Settings.data.bar.position === "right" + // Local, editable state for checkboxes property bool valueCompactMode: widgetData.compactMode !== undefined ? widgetData.compactMode : widgetMetadata.compactMode property string valueIconColor: widgetData.iconColor !== undefined ? widgetData.iconColor : widgetMetadata.iconColor property string valueTextColor: widgetData.textColor !== undefined ? widgetData.textColor : widgetMetadata.textColor property bool valueUseMonospaceFont: widgetData.useMonospaceFont !== undefined ? widgetData.useMonospaceFont : widgetMetadata.useMonospaceFont + property bool valueUsePadding: isVerticalBar ? false : widgetData.usePadding !== undefined ? widgetData.usePadding : widgetMetadata.usePadding property bool valueShowCpuUsage: widgetData.showCpuUsage !== undefined ? widgetData.showCpuUsage : widgetMetadata.showCpuUsage property bool valueShowCpuFreq: widgetData.showCpuFreq !== undefined ? widgetData.showCpuFreq : widgetMetadata.showCpuFreq property bool valueShowCpuTemp: widgetData.showCpuTemp !== undefined ? widgetData.showCpuTemp : widgetMetadata.showCpuTemp @@ -40,6 +43,7 @@ ColumnLayout { settings.iconColor = valueIconColor; settings.textColor = valueTextColor; settings.useMonospaceFont = valueUseMonospaceFont; + settings.usePadding = valueUsePadding; settings.showCpuUsage = valueShowCpuUsage; settings.showCpuFreq = valueShowCpuFreq; settings.showCpuTemp = valueShowCpuTemp; @@ -105,6 +109,19 @@ ColumnLayout { visible: !valueCompactMode } + NToggle { + Layout.fillWidth: true + label: I18n.tr("bar.system-monitor.use-padding-label") + description: isVerticalBar ? I18n.tr("bar.system-monitor.use-padding-description-disabled-vertical") : !valueUseMonospaceFont ? I18n.tr("bar.system-monitor.use-padding-description-disabled-monospace-font") : I18n.tr("bar.system-monitor.use-padding-description") + checked: valueUsePadding + onToggled: checked => { + valueUsePadding = checked; + settingsChanged(saveSettings()); + } + visible: !valueCompactMode + enabled: !isVerticalBar && valueUseMonospaceFont + } + NToggle { id: showCpuUsage Layout.fillWidth: true diff --git a/Services/System/SystemStatService.qml b/Services/System/SystemStatService.qml index 9ee97bebe..ce3931d6a 100644 --- a/Services/System/SystemStatService.qml +++ b/Services/System/SystemStatService.qml @@ -28,6 +28,7 @@ Singleton { property string gpuType: "" // "amd", "intel", "nvidia" property real memGb: 0 property real memPercent: 0 + property real memTotalGb: 0 property real swapGb: 0 property real swapPercent: 0 property real swapTotalGb: 0 @@ -1034,6 +1035,7 @@ Singleton { } root.memGb = (usageKb / 1048576).toFixed(1); // 1024*1024 = 1048576 root.memPercent = Math.round((usageKb / memTotal) * 100); + root.memTotalGb = (memTotal / 1048576).toFixed(1); root.pushMemHistory(); } @@ -1230,19 +1232,54 @@ Singleton { return Math.round(value) + "G"; // "10G" to "999G" } + // ------------------------------------------------------- + // Formatting gigabytes with optional padding + function formatGigabytesDisplay(memGb, maxGb = null) { + const value = formatGigabytes(memGb === null ? 0 : memGb); + if (maxGb !== null) { + const padding = Math.max(4, formatGigabytes(maxGb).length); + return value.padStart(padding, " "); + } + return value; + } + + // ------------------------------------------------------- + // Formatting percentage with optional padding + function formatPercentageDisplay(value, padding = false) { + return `${Math.round(value === null ? 0 : value)}%`.padStart(padding ? 4 : 0, " "); + } + // ------------------------------------------------------- // Formatting disk usage function formatDiskDisplay(diskPath, { percent = false, - available = false + available = false, + padding = false } = {}) { if (percent) { const raw = available ? root.diskAvailPercents[diskPath] : root.diskPercents[diskPath]; - const value = (raw === null) ? 0 : raw; - return `${value}%`; + return formatPercentageDisplay(raw, padding); } else { const rawGb = available ? root.diskAvailableGb[diskPath] : root.diskUsedGb[diskPath]; - return formatGigabytes(rawGb === null ? 0 : rawGb); + const maxGb = padding ? root.diskSizeGb[diskPath] : null; + return formatGigabytesDisplay(rawGb, maxGb); + } + } + + // ------------------------------------------------------- + // Formatting ram usage + function formatRamDisplay({ + swap = false, + percent = false, + padding = false +} = {}) { + if (percent) { + const raw = swap ? swapPercent : memPercent; + return formatPercentageDisplay(raw, padding); + } else { + const rawGb = swap ? swapGb : memGb; + const maxGb = padding ? (swap ? swapTotalGb : memTotalGb) : null; + return formatGigabytesDisplay(rawGb, maxGb); } } diff --git a/Services/UI/BarWidgetRegistry.qml b/Services/UI/BarWidgetRegistry.qml index ca7c18d3f..7df98beae 100644 --- a/Services/UI/BarWidgetRegistry.qml +++ b/Services/UI/BarWidgetRegistry.qml @@ -222,6 +222,7 @@ Singleton { "iconColor": "none", "textColor": "none", "useMonospaceFont": true, + "usePadding": false, "showCpuUsage": true, "showCpuFreq": false, "showCpuTemp": true,