From 94d64a91b84d85cb9d06bc93d3fcb26c029598f8 Mon Sep 17 00:00:00 2001 From: Ly-sec Date: Tue, 9 Sep 2025 13:08:48 +0200 Subject: [PATCH] Add toasts & tooltips to a lot of things, add Disk Usage --- Modules/Bar/Widgets/Battery.qml | 3 +- Modules/Bar/Widgets/SystemMonitor.qml | 33 +++++++++++++++++++ Modules/Bar/Widgets/Volume.qml | 2 +- Modules/LockScreen/LockScreen.qml | 30 +++++++++++++++++ .../WidgetSettings/SystemMonitorSettings.qml | 11 +++++++ Modules/SidePanel/Cards/PowerProfilesCard.qml | 3 ++ Services/AudioService.qml | 4 +++ Services/BarWidgetRegistry.qml | 3 +- Services/ColorSchemeService.qml | 5 +++ Services/NightLightService.qml | 3 ++ Services/ToastService.qml | 5 +++ Widgets/NPill.qml | 6 ++-- 12 files changed, 102 insertions(+), 6 deletions(-) diff --git a/Modules/Bar/Widgets/Battery.qml b/Modules/Bar/Widgets/Battery.qml index bd1be8d..e191c44 100644 --- a/Modules/Bar/Widgets/Battery.qml +++ b/Modules/Bar/Widgets/Battery.qml @@ -85,7 +85,8 @@ Item { id: pill rightOpen: BarWidgetRegistry.getNPillDirection(root) - icon: testMode ? BatteryService.getIcon(testPercent, testCharging, true) : BatteryService.getIcon(percent, charging, isReady) + icon: testMode ? BatteryService.getIcon(testPercent, testCharging, true) : BatteryService.getIcon(percent, + charging, isReady) text: (isReady || testMode) ? Math.round(percent) + "%" : "-" autoHide: false forceOpen: isReady && (testMode || battery.isLaptopBattery) && alwaysShowPercentage diff --git a/Modules/Bar/Widgets/SystemMonitor.qml b/Modules/Bar/Widgets/SystemMonitor.qml index 9641998..fbfaed1 100644 --- a/Modules/Bar/Widgets/SystemMonitor.qml +++ b/Modules/Bar/Widgets/SystemMonitor.qml @@ -38,6 +38,9 @@ RowLayout { !== undefined) ? widgetSettings.showMemoryAsPercent : widgetMetadata.showMemoryAsPercent readonly property bool showNetworkStats: (widgetSettings.showNetworkStats !== undefined) ? widgetSettings.showNetworkStats : widgetMetadata.showNetworkStats + readonly property bool showDiskUsage: (widgetSettings.showDiskUsage + !== undefined) ? widgetSettings.showDiskUsage : (widgetMetadata.showDiskUsage + || false) Layout.alignment: Qt.AlignVCenter spacing: Style.marginS * scaling @@ -206,6 +209,36 @@ RowLayout { } } } + + // Disk Usage Component (primary drive) + Item { + Layout.preferredWidth: diskUsageRow.implicitWidth + Layout.preferredHeight: Math.round(Style.capsuleHeight * scaling) + Layout.alignment: Qt.AlignVCenter + visible: showDiskUsage + + RowLayout { + id: diskUsageRow + anchors.centerIn: parent + spacing: Style.marginXS * scaling + + NIcon { + icon: "hdd" + font.pointSize: Style.fontSizeM * scaling + Layout.alignment: Qt.AlignVCenter + } + + NText { + text: `${SystemStatService.diskPercent}%` + font.family: Settings.data.ui.fontFixed + font.pointSize: Style.fontSizeS * scaling + font.weight: Style.fontWeightMedium + Layout.alignment: Qt.AlignVCenter + verticalAlignment: Text.AlignVCenter + color: Color.mPrimary + } + } + } } } } diff --git a/Modules/Bar/Widgets/Volume.qml b/Modules/Bar/Widgets/Volume.qml index ccc40f9..b61554c 100644 --- a/Modules/Bar/Widgets/Volume.qml +++ b/Modules/Bar/Widgets/Volume.qml @@ -45,7 +45,7 @@ Item { if (AudioService.muted) { return "volume-mute" } - return AudioService.volume <= 0.2? "volume-off" : (AudioService.volume < 0.6 ? "volume-down" : "volume-up") + return AudioService.volume <= 0.2 ? "volume-off" : (AudioService.volume < 0.6 ? "volume-down" : "volume-up") } // Connection used to open the pill when volume changes diff --git a/Modules/LockScreen/LockScreen.qml b/Modules/LockScreen/LockScreen.qml index 528736f..beeccc6 100644 --- a/Modules/LockScreen/LockScreen.qml +++ b/Modules/LockScreen/LockScreen.qml @@ -735,6 +735,14 @@ Loader { color: powerButtonArea.containsMouse ? Color.mOnError : Color.mError } + // Tooltip + NTooltip { + id: tooltipShutdown + target: parent + positionAbove: true + text: "Shut down" + } + MouseArea { id: powerButtonArea anchors.fill: parent @@ -742,6 +750,8 @@ Loader { onClicked: { CompositorService.shutdown() } + onEntered: tooltipShutdown.show() + onExited: tooltipShutdown.hide() } } @@ -762,6 +772,14 @@ Loader { color: restartButtonArea.containsMouse ? Color.mOnPrimary : Color.mPrimary } + // Tooltip + NTooltip { + id: tooltipRestart + target: parent + positionAbove: true + text: "Restart" + } + MouseArea { id: restartButtonArea anchors.fill: parent @@ -769,6 +787,8 @@ Loader { onClicked: { CompositorService.reboot() } + onEntered: tooltipRestart.show() + onExited: tooltipRestart.hide() } } @@ -789,6 +809,14 @@ Loader { color: suspendButtonArea.containsMouse ? Color.mOnSecondary : Color.mSecondary } + // Tooltip + NTooltip { + id: tooltipSuspend + target: parent + positionAbove: true + text: "Suspend" + } + MouseArea { id: suspendButtonArea anchors.fill: parent @@ -796,6 +824,8 @@ Loader { onClicked: { CompositorService.suspend() } + onEntered: tooltipSuspend.show() + onExited: tooltipSuspend.hide() } } } diff --git a/Modules/SettingsPanel/Bar/WidgetSettings/SystemMonitorSettings.qml b/Modules/SettingsPanel/Bar/WidgetSettings/SystemMonitorSettings.qml index 21d0d4c..4b2807b 100644 --- a/Modules/SettingsPanel/Bar/WidgetSettings/SystemMonitorSettings.qml +++ b/Modules/SettingsPanel/Bar/WidgetSettings/SystemMonitorSettings.qml @@ -21,6 +21,8 @@ ColumnLayout { !== undefined ? widgetData.showMemoryAsPercent : widgetMetadata.showMemoryAsPercent property bool valueShowNetworkStats: widgetData.showNetworkStats !== undefined ? widgetData.showNetworkStats : widgetMetadata.showNetworkStats + property bool valueShowDiskUsage: widgetData.showDiskUsage !== undefined ? widgetData.showDiskUsage : (widgetMetadata.showDiskUsage + || false) function saveSettings() { var settings = Object.assign({}, widgetData || {}) @@ -29,6 +31,7 @@ ColumnLayout { settings.showMemoryUsage = valueShowMemoryUsage settings.showMemoryAsPercent = valueShowMemoryAsPercent settings.showNetworkStats = valueShowNetworkStats + settings.showDiskUsage = valueShowDiskUsage return settings } @@ -71,4 +74,12 @@ ColumnLayout { checked: valueShowNetworkStats onToggled: checked => valueShowNetworkStats = checked } + + NToggle { + id: showDiskUsage + Layout.fillWidth: true + label: "Storage usage" + checked: valueShowDiskUsage + onToggled: checked => valueShowDiskUsage = checked + } } diff --git a/Modules/SidePanel/Cards/PowerProfilesCard.qml b/Modules/SidePanel/Cards/PowerProfilesCard.qml index 3892c7f..842d432 100644 --- a/Modules/SidePanel/Cards/PowerProfilesCard.qml +++ b/Modules/SidePanel/Cards/PowerProfilesCard.qml @@ -37,6 +37,7 @@ NBox { onClicked: { if (enabled) { powerProfiles.profile = PowerProfile.Performance + ToastService.showNotice("Power Profile", "Performance") } } } @@ -51,6 +52,7 @@ NBox { onClicked: { if (enabled) { powerProfiles.profile = PowerProfile.Balanced + ToastService.showNotice("Power Profile", "Balanced") } } } @@ -65,6 +67,7 @@ NBox { onClicked: { if (enabled) { powerProfiles.profile = PowerProfile.PowerSaver + ToastService.showNotice("Power Profile", "Power Saver") } } } diff --git a/Services/AudioService.qml b/Services/AudioService.qml index c6ec05c..9f526ea 100644 --- a/Services/AudioService.qml +++ b/Services/AudioService.qml @@ -62,6 +62,8 @@ Singleton { function onMutedChanged() { root._muted = (sink?.audio.muted ?? true) Logger.log("AudioService", "OnMuteChanged:", root._muted) + // Toast: audio output mute toggle + ToastService.showNotice("Audio Output", root._muted ? "Muted" : "Unmuted") } } @@ -79,6 +81,8 @@ Singleton { function onMutedChanged() { root._inputMuted = (source?.audio.muted ?? true) Logger.log("AudioService", "OnInputMuteChanged:", root._inputMuted) + // Toast: microphone mute toggle + ToastService.showNotice("Microphone", root._inputMuted ? "Muted" : "Unmuted") } } diff --git a/Services/BarWidgetRegistry.qml b/Services/BarWidgetRegistry.qml index b82a3e1..fc99a0e 100644 --- a/Services/BarWidgetRegistry.qml +++ b/Services/BarWidgetRegistry.qml @@ -84,7 +84,8 @@ Singleton { "showCpuTemp": true, "showMemoryUsage": true, "showMemoryAsPercent": false, - "showNetworkStats": false + "showNetworkStats": false, + "showDiskUsage": false }, "Workspace": { "allowUserSettings": true, diff --git a/Services/ColorSchemeService.qml b/Services/ColorSchemeService.qml index 096f8f9..ade585f 100644 --- a/Services/ColorSchemeService.qml +++ b/Services/ColorSchemeService.qml @@ -23,6 +23,11 @@ Singleton { // Re-apply current scheme to pick the right variant applyScheme(Settings.data.colorSchemes.predefinedScheme) } + // Toast: dark/light mode switched + const enabled = !!Settings.data.colorSchemes.darkMode + const label = enabled ? "Dark Mode" : "Light Mode" + const description = enabled ? "Enabled" : "Enabled" + ToastService.showNotice(label, description) } } diff --git a/Services/NightLightService.qml b/Services/NightLightService.qml index 3719a29..77084f2 100644 --- a/Services/NightLightService.qml +++ b/Services/NightLightService.qml @@ -50,6 +50,9 @@ Singleton { target: Settings.data.nightLight function onEnabledChanged() { apply() + // Toast: night light toggled + const enabled = !!Settings.data.nightLight.enabled + ToastService.showNotice("Night Light", enabled ? "Enabled" : "Disabled") } function onNightTempChanged() { apply() diff --git a/Services/ToastService.qml b/Services/ToastService.qml index edff04b..ee9fb24 100644 --- a/Services/ToastService.qml +++ b/Services/ToastService.qml @@ -185,6 +185,11 @@ Singleton { // Process the message queue function processQueue() { if (messageQueue.length === 0 || allToasts.length === 0) { + // Added this so we don't accidentally get duplicate toasts + // if it causes issues, remove it and we'll find a different solution + if (allToasts.length === 0 && messageQueue.length > 0) { + messageQueue = [] + } isShowingToast = false return } diff --git a/Widgets/NPill.qml b/Widgets/NPill.qml index 1d9bfba..7b57ad8 100644 --- a/Widgets/NPill.qml +++ b/Widgets/NPill.qml @@ -96,7 +96,7 @@ Item { width: iconSize height: iconSize radius: width * 0.5 - color: hovered && !forceOpen? Color.mPrimary : Color.mSurfaceVariant + color: hovered && !forceOpen ? Color.mPrimary : Color.mSurfaceVariant anchors.verticalCenter: parent.verticalCenter x: rightOpen ? 0 : (parent.width - width) @@ -111,8 +111,8 @@ Item { NIcon { icon: root.icon font.pointSize: Style.fontSizeM * scaling - color: hovered && !forceOpen? Color.mOnPrimary : Color.mOnSurface - // Center horizontally + color: hovered && !forceOpen ? Color.mOnPrimary : Color.mOnSurface + // Center horizontally x: (iconCircle.width - width) / 2 // Center vertically accounting for font metrics y: (iconCircle.height - height) / 2 + (height - contentHeight) / 2