From 58e8dd5456505969911ee57eb0458870ea50b2c1 Mon Sep 17 00:00:00 2001 From: null <33122401+TheSynt4x@users.noreply.github.com> Date: Wed, 25 Feb 2026 16:53:12 +0100 Subject: [PATCH] feat: add more disk usage viewing options (#1833) * feat: show memory widget in gb * cleanup * even more cleanup * fix * feat: add more disk usage viewing options --- .../Modules/DankBar/Widgets/DiskUsage.qml | 26 +++- quickshell/Modules/Settings/WidgetsTab.qml | 29 +++- .../Modules/Settings/WidgetsTabSection.qml | 146 +++++++++++++++++- 3 files changed, 195 insertions(+), 6 deletions(-) diff --git a/quickshell/Modules/DankBar/Widgets/DiskUsage.qml b/quickshell/Modules/DankBar/Widgets/DiskUsage.qml index e1f9f298..d6e6d1be 100644 --- a/quickshell/Modules/DankBar/Widgets/DiskUsage.qml +++ b/quickshell/Modules/DankBar/Widgets/DiskUsage.qml @@ -9,6 +9,7 @@ BasePill { property var widgetData: null property string mountPath: (widgetData && widgetData.mountPath !== undefined) ? widgetData.mountPath : "/" + property int diskUsageMode: (widgetData && widgetData.diskUsageMode !== undefined) ? widgetData.diskUsageMode : 0 property bool isHovered: mouseArea.containsMouse property bool isAutoHideBar: false @@ -130,7 +131,13 @@ BasePill { if (root.diskUsagePercent === undefined || root.diskUsagePercent === null || root.diskUsagePercent === 0) { return "--"; } - return root.diskUsagePercent.toFixed(0); + if (!root.selectedMount) return "--"; + switch (root.diskUsageMode) { + case 1: return root.selectedMount.size || "--"; + case 2: return root.selectedMount.avail || "--"; + case 3: return (root.selectedMount.avail || "--") + " / " + (root.selectedMount.size || "--"); + default: return root.diskUsagePercent.toFixed(0); + } } font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale, root.barConfig?.maximizeWidgetText) color: Theme.widgetTextColor @@ -178,7 +185,13 @@ BasePill { if (root.diskUsagePercent === undefined || root.diskUsagePercent === null || root.diskUsagePercent === 0) { return "--%"; } - return root.diskUsagePercent.toFixed(0) + "%"; + if (!root.selectedMount) return "--%"; + switch (root.diskUsageMode) { + case 1: return root.selectedMount.size || "--"; + case 2: return root.selectedMount.avail || "--"; + case 3: return (root.selectedMount.avail || "--") + " / " + (root.selectedMount.size || "--"); + default: return root.diskUsagePercent.toFixed(0) + "%"; + } } font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale, root.barConfig?.maximizeWidgetText) color: Theme.widgetTextColor @@ -189,7 +202,14 @@ BasePill { StyledTextMetrics { id: diskBaseline font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale, root.barConfig?.maximizeWidgetText) - text: "100%" + text: { + switch (root.diskUsageMode) { + case 3: return "888.8G / 888.8G"; + case 1: + case 2: return "888.8G"; + default: return "100%"; + } + } } width: Math.max(diskBaseline.width, paintedWidth) diff --git a/quickshell/Modules/Settings/WidgetsTab.qml b/quickshell/Modules/Settings/WidgetsTab.qml index acc6fa36..fd5eb580 100644 --- a/quickshell/Modules/Settings/WidgetsTab.qml +++ b/quickshell/Modules/Settings/WidgetsTab.qml @@ -398,8 +398,10 @@ Item { widgetObj.runningAppsCurrentWorkspace = SettingsData.runningAppsCurrentWorkspace; widgetObj.runningAppsCurrentMonitor = false; } - if (widgetId === "diskUsage") + if (widgetId === "diskUsage") { widgetObj.mountPath = "/"; + widgetObj.diskUsageMode = 0; + } if (widgetId === "cpuUsage" || widgetId === "memUsage" || widgetId === "cpuTemp" || widgetId === "gpuTemp") widgetObj.minimumWidth = true; if (widgetId === "memUsage") @@ -427,7 +429,7 @@ Item { "id": widget.id, "enabled": widget.enabled }; - var keys = ["size", "selectedGpuIndex", "pciId", "mountPath", "minimumWidth", "showSwap", "showInGb", "mediaSize", "clockCompactMode", "focusedWindowCompactMode", "runningAppsCompactMode", "keyboardLayoutNameCompactMode", "runningAppsGroupByApp", "runningAppsCurrentWorkspace", "runningAppsCurrentMonitor", "showNetworkIcon", "showBluetoothIcon", "showAudioIcon", "showAudioPercent", "showVpnIcon", "showBrightnessIcon", "showBrightnessPercent", "showMicIcon", "showMicPercent", "showBatteryIcon", "showPrinterIcon", "showScreenSharingIcon", "barMaxVisibleApps", "barMaxVisibleRunningApps", "barShowOverflowBadge"]; + var keys = ["size", "selectedGpuIndex", "pciId", "mountPath", "diskUsageMode", "minimumWidth", "showSwap", "showInGb", "mediaSize", "clockCompactMode", "focusedWindowCompactMode", "runningAppsCompactMode", "keyboardLayoutNameCompactMode", "runningAppsGroupByApp", "runningAppsCurrentWorkspace", "runningAppsCurrentMonitor", "showNetworkIcon", "showBluetoothIcon", "showAudioIcon", "showAudioPercent", "showVpnIcon", "showBrightnessIcon", "showBrightnessPercent", "showMicIcon", "showMicPercent", "showBatteryIcon", "showPrinterIcon", "showScreenSharingIcon", "barMaxVisibleApps", "barMaxVisibleRunningApps", "barShowOverflowBadge"]; for (var i = 0; i < keys.length; i++) { if (widget[keys[i]] !== undefined) result[keys[i]] = widget[keys[i]]; @@ -550,6 +552,18 @@ Item { setWidgetsForSection(sectionId, widgets); } + function handleDiskUsageModeChanged(sectionId, widgetIndex, mode) { + var widgets = getWidgetsForSection(sectionId).slice(); + if (widgetIndex < 0 || widgetIndex >= widgets.length) { + setWidgetsForSection(sectionId, widgets); + return; + } + var newWidget = cloneWidgetData(widgets[widgetIndex]); + newWidget.diskUsageMode = mode; + widgets[widgetIndex] = newWidget; + setWidgetsForSection(sectionId, widgets); + } + function handleOverflowSettingChanged(sectionId, widgetIndex, settingName, value) { var widgets = getWidgetsForSection(sectionId).slice(); if (widgetIndex < 0 || widgetIndex >= widgets.length) { @@ -615,6 +629,8 @@ Item { item.pciId = widget.pciId; if (widget.mountPath !== undefined) item.mountPath = widget.mountPath; + if (widget.diskUsageMode !== undefined) + item.diskUsageMode = widget.diskUsageMode; if (widget.showNetworkIcon !== undefined) item.showNetworkIcon = widget.showNetworkIcon; if (widget.showBluetoothIcon !== undefined) @@ -944,6 +960,9 @@ Item { onShowInGbChanged: (sectionId, index, enabled) => { widgetsTab.handleShowInGbChanged(sectionId, index, enabled); } + onDiskUsageModeChanged: (sectionId, widgetIndex, mode) => { + widgetsTab.handleDiskUsageModeChanged(sectionId, widgetIndex, mode); + } onCompactModeChanged: (widgetId, value) => { widgetsTab.handleCompactModeChanged(sectionId, widgetId, value); } @@ -1005,6 +1024,9 @@ Item { onShowInGbChanged: (sectionId, index, enabled) => { widgetsTab.handleShowInGbChanged(sectionId, index, enabled); } + onDiskUsageModeChanged: (sectionId, widgetIndex, mode) => { + widgetsTab.handleDiskUsageModeChanged(sectionId, widgetIndex, mode); + } onCompactModeChanged: (widgetId, value) => { widgetsTab.handleCompactModeChanged(sectionId, widgetId, value); } @@ -1066,6 +1088,9 @@ Item { onShowInGbChanged: (sectionId, index, enabled) => { widgetsTab.handleShowInGbChanged(sectionId, index, enabled); } + onDiskUsageModeChanged: (sectionId, widgetIndex, mode) => { + widgetsTab.handleDiskUsageModeChanged(sectionId, widgetIndex, mode); + } onCompactModeChanged: (widgetId, value) => { widgetsTab.handleCompactModeChanged(sectionId, widgetId, value); } diff --git a/quickshell/Modules/Settings/WidgetsTabSection.qml b/quickshell/Modules/Settings/WidgetsTabSection.qml index 4812258b..3d898da7 100644 --- a/quickshell/Modules/Settings/WidgetsTabSection.qml +++ b/quickshell/Modules/Settings/WidgetsTabSection.qml @@ -31,6 +31,7 @@ Column { signal minimumWidthChanged(string sectionId, int widgetIndex, bool enabled) signal showSwapChanged(string sectionId, int widgetIndex, bool enabled) signal showInGbChanged(string sectionId, int widgetIndex, bool enabled) + signal diskUsageModeChanged(string sectionId, int widgetIndex, int mode) signal overflowSettingChanged(string sectionId, int widgetIndex, string settingName, var value) function cloneWidgetData(widget) { @@ -38,7 +39,7 @@ Column { "id": widget.id, "enabled": widget.enabled }; - var keys = ["size", "selectedGpuIndex", "pciId", "mountPath", "minimumWidth", "showSwap", "showInGb", "mediaSize", "clockCompactMode", "focusedWindowCompactMode", "runningAppsCompactMode", "keyboardLayoutNameCompactMode", "runningAppsGroupByApp", "runningAppsCurrentWorkspace", "runningAppsCurrentMonitor", "showNetworkIcon", "showBluetoothIcon", "showAudioIcon", "showAudioPercent", "showVpnIcon", "showBrightnessIcon", "showBrightnessPercent", "showMicIcon", "showMicPercent", "showBatteryIcon", "showPrinterIcon", "showScreenSharingIcon", "barMaxVisibleApps", "barMaxVisibleRunningApps", "barShowOverflowBadge"]; + var keys = ["size", "selectedGpuIndex", "pciId", "mountPath", "diskUsageMode", "minimumWidth", "showSwap", "showInGb", "mediaSize", "clockCompactMode", "focusedWindowCompactMode", "runningAppsCompactMode", "keyboardLayoutNameCompactMode", "runningAppsGroupByApp", "runningAppsCurrentWorkspace", "runningAppsCurrentMonitor", "showNetworkIcon", "showBluetoothIcon", "showAudioIcon", "showAudioPercent", "showVpnIcon", "showBrightnessIcon", "showBrightnessPercent", "showMicIcon", "showMicPercent", "showBatteryIcon", "showPrinterIcon", "showScreenSharingIcon", "barMaxVisibleApps", "barMaxVisibleRunningApps", "barShowOverflowBadge"]; for (var i = 0; i < keys.length; i++) { if (widget[keys[i]] !== undefined) result[keys[i]] = widget[keys[i]]; @@ -230,6 +231,34 @@ Column { } } + DankActionButton { + id: diskMenuButton + visible: modelData.id === "diskUsage" + buttonSize: 32 + iconName: "more_vert" + iconSize: 18 + iconColor: Theme.outline + onClicked: { + diskUsageContextMenu.widgetData = modelData; + diskUsageContextMenu.sectionId = root.sectionId; + diskUsageContextMenu.widgetIndex = index; + + var buttonPos = diskMenuButton.mapToItem(root, 0, 0); + var xPos = buttonPos.x - diskUsageContextMenu.width - Theme.spacingS; + if (xPos < 0) + xPos = buttonPos.x + diskMenuButton.width + Theme.spacingS; + var yPos = buttonPos.y - diskUsageContextMenu.height / 2 + diskMenuButton.height / 2; + if (yPos < 0) + yPos = Theme.spacingS; + else if (yPos + diskUsageContextMenu.height > root.height) + yPos = root.height - diskUsageContextMenu.height - Theme.spacingS; + + diskUsageContextMenu.x = xPos; + diskUsageContextMenu.y = yPos; + diskUsageContextMenu.open(); + } + } + Item { width: 32 height: 32 @@ -903,6 +932,121 @@ Column { } } + Popup { + id: diskUsageContextMenu + + property var widgetData: null + property string sectionId: "" + property int widgetIndex: -1 + readonly property var currentWidgetData: (widgetIndex >= 0 && widgetIndex < root.items.length) ? root.items[widgetIndex] : widgetData + + width: 240 + height: diskMenuColumn.implicitHeight + Theme.spacingS * 2 + padding: 0 + modal: true + focus: true + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + + background: Rectangle { + color: Theme.surfaceContainer + radius: Theme.cornerRadius + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) + border.width: 0 + } + + contentItem: Item { + Column { + id: diskMenuColumn + anchors.fill: parent + anchors.margins: Theme.spacingS + spacing: 2 + + Rectangle { + width: parent.width + height: 32 + radius: Theme.cornerRadius + color: "transparent" + + StyledText { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + text: I18n.tr("Disk Usage Display") + font.pixelSize: Theme.fontSizeSmall + font.weight: Font.Medium + color: Theme.surfaceText + } + } + + Repeater { + model: [ + { label: I18n.tr("Percentage"), mode: 0, icon: "percent" }, + { label: I18n.tr("Total"), mode: 1, icon: "storage" }, + { label: I18n.tr("Remaining"), mode: 2, icon: "hourglass_empty" }, + { label: I18n.tr("Remaining / Total"), mode: 3, icon: "pie_chart" } + ] + + delegate: Rectangle { + required property var modelData + required property int index + + width: diskMenuColumn.width + height: 32 + radius: Theme.cornerRadius + color: diskOptionArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + function isSelected() { + return (diskUsageContextMenu.currentWidgetData?.diskUsageMode ?? 0) === modelData.mode; + } + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingS + + DankIcon { + name: modelData.icon + size: 16 + color: isSelected() ? Theme.primary : Theme.surfaceText + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: modelData.label + font.pixelSize: Theme.fontSizeSmall + color: isSelected() ? Theme.primary : Theme.surfaceText + font.weight: isSelected() ? Font.Medium : Font.Normal + anchors.verticalCenter: parent.verticalCenter + } + } + + DankIcon { + anchors.right: parent.right + anchors.rightMargin: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + name: "check" + size: 16 + color: Theme.primary + visible: isSelected() + } + + MouseArea { + id: diskOptionArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + root.diskUsageModeChanged(diskUsageContextMenu.sectionId, diskUsageContextMenu.widgetIndex, modelData.mode); + diskUsageContextMenu.close(); + } + } + } + } + } + } + } + Popup { id: controlCenterContextMenu