1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-27 06:52:50 -05:00

feat: add temperature widgets, separate ram/cpu widgets, update

calculations
- make CPU calculations per-process mirror gnome (of all CPUs)
This commit is contained in:
bbedward
2025-08-08 14:43:43 -04:00
parent 105353c2a4
commit 03276b7d9a
27 changed files with 794 additions and 254 deletions

View File

@@ -370,7 +370,6 @@ PanelWindow {
DankListView {
id: appList
mouseWheelSpeed: 20
property int itemHeight: 72
property int iconSize: 56

View File

@@ -41,7 +41,6 @@ Item {
clip: true
contentHeight: outputColumn.height
contentWidth: width
mouseWheelSpeed: 20
Column {
id: outputColumn
@@ -68,7 +67,6 @@ Item {
clip: true
contentHeight: inputColumn.height
contentWidth: width
mouseWheelSpeed: 20
Column {
id: inputColumn

View File

@@ -19,7 +19,6 @@ Item {
clip: true
contentHeight: mainColumn.height
contentWidth: width
mouseWheelSpeed: 20
Column {
id: mainColumn

View File

@@ -28,7 +28,6 @@ Item {
clip: true
contentHeight: mainColumn.height
contentWidth: width
mouseWheelSpeed: 20
Column {
id: mainColumn

View File

@@ -51,12 +51,44 @@ Row {
opacity: SysMonitorService.sortBy === "cpu" ? 1 : 0.8
}
StyledText {
text: SysMonitorService.totalCpuUsage.toFixed(1) + "%"
font.pixelSize: Theme.fontSizeLarge
font.family: SettingsData.monoFontFamily
font.weight: Font.Bold
color: Theme.surfaceText
Row {
spacing: Theme.spacingS
StyledText {
text: SysMonitorService.totalCpuUsage.toFixed(1) + "%"
font.pixelSize: Theme.fontSizeLarge
font.family: SettingsData.monoFontFamily
font.weight: Font.Bold
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
Rectangle {
width: 1
height: 20
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.3)
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: {
if (SysMonitorService.cpuTemperature === undefined || SysMonitorService.cpuTemperature === null || SysMonitorService.cpuTemperature < 0) {
return "--°";
}
return Math.round(SysMonitorService.cpuTemperature) + "°";
}
font.pixelSize: Theme.fontSizeMedium
font.family: SettingsData.monoFontFamily
font.weight: Font.Medium
color: {
if (SysMonitorService.cpuTemperature > 80)
return Theme.error;
if (SysMonitorService.cpuTemperature > 60)
return Theme.warning;
return Theme.surfaceText;
}
anchors.verticalCenter: parent.verticalCenter
}
}
StyledText {
@@ -123,16 +155,44 @@ Row {
opacity: SysMonitorService.sortBy === "memory" ? 1 : 0.8
}
StyledText {
text: SysMonitorService.formatSystemMemory(SysMonitorService.usedMemoryKB)
font.pixelSize: Theme.fontSizeLarge
font.family: SettingsData.monoFontFamily
font.weight: Font.Bold
color: Theme.surfaceText
Row {
spacing: Theme.spacingS
StyledText {
text: SysMonitorService.formatSystemMemory(SysMonitorService.usedMemoryKB)
font.pixelSize: Theme.fontSizeLarge
font.family: SettingsData.monoFontFamily
font.weight: Font.Bold
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
Rectangle {
width: 1
height: 20
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.3)
anchors.verticalCenter: parent.verticalCenter
visible: SysMonitorService.totalSwapKB > 0
}
StyledText {
text: SysMonitorService.totalSwapKB > 0 ? SysMonitorService.formatSystemMemory(SysMonitorService.usedSwapKB) : ""
font.pixelSize: Theme.fontSizeMedium
font.family: SettingsData.monoFontFamily
font.weight: Font.Medium
color: SysMonitorService.usedSwapKB > 0 ? Theme.warning : Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
visible: SysMonitorService.totalSwapKB > 0
}
}
StyledText {
text: "of " + SysMonitorService.formatSystemMemory(SysMonitorService.totalMemoryKB)
text: {
if (SysMonitorService.totalSwapKB > 0) {
return "of " + SysMonitorService.formatSystemMemory(SysMonitorService.totalMemoryKB) + " + swap";
}
return "of " + SysMonitorService.formatSystemMemory(SysMonitorService.totalMemoryKB);
}
font.pixelSize: Theme.fontSizeSmall
font.family: SettingsData.monoFontFamily
color: Theme.surfaceText
@@ -161,8 +221,8 @@ Row {
width: (parent.width - Theme.spacingM * 2) / 3
height: 80
radius: Theme.cornerRadiusLarge
color: SysMonitorService.totalSwapKB > 0 ? 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)
border.color: SysMonitorService.totalSwapKB > 0 ? 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)
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08)
border.color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.2)
border.width: 1
Column {
@@ -172,23 +232,74 @@ Row {
spacing: 2
StyledText {
text: "Swap"
text: "Graphics"
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: SysMonitorService.totalSwapKB > 0 ? Theme.warning : Theme.surfaceText
color: Theme.secondary
opacity: 0.8
}
StyledText {
text: SysMonitorService.totalSwapKB > 0 ? SysMonitorService.formatSystemMemory(SysMonitorService.usedSwapKB) : "None"
text: {
if (!SysMonitorService.availableGpus || SysMonitorService.availableGpus.length === 0) {
return "None";
}
if (SysMonitorService.availableGpus.length === 1) {
var gpu = SysMonitorService.availableGpus[0];
var temp = gpu.temperature;
var tempText = (temp === undefined || temp === null || temp === 0) ? "--°" : Math.round(temp) + "°";
return tempText;
}
// Multiple GPUs - show average temp
var totalTemp = 0;
var validTemps = 0;
for (var i = 0; i < SysMonitorService.availableGpus.length; i++) {
var temp = SysMonitorService.availableGpus[i].temperature;
if (temp !== undefined && temp !== null && temp > 0) {
totalTemp += temp;
validTemps++;
}
}
if (validTemps > 0) {
return Math.round(totalTemp / validTemps) + "°";
}
return "--°";
}
font.pixelSize: Theme.fontSizeLarge
font.family: SettingsData.monoFontFamily
font.weight: Font.Bold
color: Theme.surfaceText
color: {
if (!SysMonitorService.availableGpus || SysMonitorService.availableGpus.length === 0) {
return Theme.surfaceText;
}
if (SysMonitorService.availableGpus.length === 1) {
var temp = SysMonitorService.availableGpus[0].temperature || 0;
if (temp > 80) return Theme.tempDanger;
if (temp > 60) return Theme.tempWarning;
return Theme.surfaceText;
}
// Multiple GPUs - get max temp for coloring
var maxTemp = 0;
for (var i = 0; i < SysMonitorService.availableGpus.length; i++) {
var temp = SysMonitorService.availableGpus[i].temperature || 0;
if (temp > maxTemp) maxTemp = temp;
}
if (maxTemp > 80) return Theme.tempDanger;
if (maxTemp > 60) return Theme.tempWarning;
return Theme.surfaceText;
}
}
StyledText {
text: SysMonitorService.totalSwapKB > 0 ? "of " + SysMonitorService.formatSystemMemory(SysMonitorService.totalSwapKB) : "No swap configured"
text: {
if (!SysMonitorService.availableGpus || SysMonitorService.availableGpus.length === 0) {
return "No GPUs detected";
}
if (SysMonitorService.availableGpus.length === 1) {
return SysMonitorService.availableGpus[0].driver.toUpperCase();
}
return SysMonitorService.availableGpus.length + " GPUs detected";
}
font.pixelSize: Theme.fontSizeSmall
font.family: SettingsData.monoFontFamily
color: Theme.surfaceText

View File

@@ -15,7 +15,6 @@ Item {
clip: true
contentHeight: mainColumn.height
contentWidth: width
mouseWheelSpeed: 20
Column {
id: mainColumn

View File

@@ -14,7 +14,6 @@ Item {
clip: true
contentHeight: mainColumn.height
contentWidth: width
mouseWheelSpeed: 20
Column {
id: mainColumn

View File

@@ -20,7 +20,6 @@ Item {
clip: true
contentHeight: mainColumn.height
contentWidth: width
mouseWheelSpeed: 20
Column {
id: mainColumn

View File

@@ -13,7 +13,6 @@ Item {
clip: true
contentHeight: mainColumn.height
contentWidth: width
mouseWheelSpeed: 20
Column {
id: mainColumn

View File

@@ -49,11 +49,29 @@ Item {
"icon": "content_paste",
"enabled": true
}, {
"id": "systemResources",
"text": "System Resources",
"description": "CPU and memory usage indicators",
"id": "cpuUsage",
"text": "CPU Usage",
"description": "CPU usage indicator",
"icon": "memory",
"enabled": true
}, {
"id": "memUsage",
"text": "Memory Usage",
"description": "Memory usage indicator",
"icon": "storage",
"enabled": true
}, {
"id": "cpuTemp",
"text": "CPU Temperature",
"description": "CPU temperature display",
"icon": "device_thermostat",
"enabled": true
}, {
"id": "gpuTemp",
"text": "GPU Temperature",
"description": "GPU temperature display",
"icon": "auto_awesome_mosaic",
"enabled": true
}, {
"id": "systemTray",
"text": "System Tray",
@@ -127,7 +145,10 @@ Item {
"id": "clipboard",
"enabled": true
}, {
"id": "systemResources",
"id": "cpuUsage",
"enabled": true
}, {
"id": "memUsage",
"enabled": true
}, {
"id": "notificationButton",
@@ -147,6 +168,8 @@ Item {
};
if (widgetId === "spacer")
widgetObj.size = 20;
if (widgetId === "gpuTemp")
widgetObj.selectedGpuIndex = 0;
var widgets = [];
if (targetSection === "left") {
@@ -164,28 +187,25 @@ Item {
}
}
function removeWidgetFromSection(sectionId, itemId) {
function removeWidgetFromSection(sectionId, widgetIndex) {
var widgets = [];
if (sectionId === "left") {
widgets = SettingsData.topBarLeftWidgets.slice();
widgets = widgets.filter((widget) => {
var widgetId = typeof widget === "string" ? widget : widget.id;
return widgetId !== itemId;
});
if (widgetIndex >= 0 && widgetIndex < widgets.length) {
widgets.splice(widgetIndex, 1);
}
SettingsData.setTopBarLeftWidgets(widgets);
} else if (sectionId === "center") {
widgets = SettingsData.topBarCenterWidgets.slice();
widgets = widgets.filter((widget) => {
var widgetId = typeof widget === "string" ? widget : widget.id;
return widgetId !== itemId;
});
if (widgetIndex >= 0 && widgetIndex < widgets.length) {
widgets.splice(widgetIndex, 1);
}
SettingsData.setTopBarCenterWidgets(widgets);
} else if (sectionId === "right") {
widgets = SettingsData.topBarRightWidgets.slice();
widgets = widgets.filter((widget) => {
var widgetId = typeof widget === "string" ? widget : widget.id;
return widgetId !== itemId;
});
if (widgetIndex >= 0 && widgetIndex < widgets.length) {
widgets.splice(widgetIndex, 1);
}
SettingsData.setTopBarRightWidgets(widgets);
}
}
@@ -208,7 +228,8 @@ Item {
} : {
"id": widget.id,
"enabled": enabled,
"size": widget.size
"size": widget.size,
"selectedGpuIndex": widget.selectedGpuIndex
};
break;
}
@@ -249,7 +270,8 @@ Item {
} : {
"id": widget.id,
"enabled": widget.enabled,
"size": newSize
"size": newSize,
"selectedGpuIndex": widget.selectedGpuIndex
};
break;
}
@@ -262,6 +284,37 @@ Item {
SettingsData.setTopBarRightWidgets(widgets);
}
function handleGpuSelectionChanged(sectionId, widgetIndex, selectedGpuIndex) {
var widgets = [];
if (sectionId === "left")
widgets = SettingsData.topBarLeftWidgets.slice();
else if (sectionId === "center")
widgets = SettingsData.topBarCenterWidgets.slice();
else if (sectionId === "right")
widgets = SettingsData.topBarRightWidgets.slice();
if (widgetIndex >= 0 && widgetIndex < widgets.length) {
var widget = widgets[widgetIndex];
widgets[widgetIndex] = typeof widget === "string" ? {
"id": widget,
"enabled": true,
"selectedGpuIndex": selectedGpuIndex
} : {
"id": widget.id,
"enabled": widget.enabled,
"size": widget.size,
"selectedGpuIndex": selectedGpuIndex
};
}
if (sectionId === "left")
SettingsData.setTopBarLeftWidgets(widgets);
else if (sectionId === "center")
SettingsData.setTopBarCenterWidgets(widgets);
else if (sectionId === "right")
SettingsData.setTopBarRightWidgets(widgets);
}
function getItemsForSection(sectionId) {
var widgets = [];
var widgetData = [];
@@ -275,6 +328,7 @@ Item {
var widgetId = typeof widget === "string" ? widget : widget.id;
var widgetEnabled = typeof widget === "string" ? true : widget.enabled;
var widgetSize = typeof widget === "string" ? undefined : widget.size;
var widgetSelectedGpuIndex = typeof widget === "string" ? undefined : widget.selectedGpuIndex;
var widgetDef = baseWidgetDefinitions.find((w) => {
return w.id === widgetId;
});
@@ -284,6 +338,8 @@ Item {
item.enabled = widgetEnabled;
if (widgetSize !== undefined)
item.size = widgetSize;
if (widgetSelectedGpuIndex !== undefined)
item.selectedGpuIndex = widgetSelectedGpuIndex;
widgets.push(item);
}
@@ -338,7 +394,6 @@ Item {
clip: true
contentHeight: mainColumn.height
contentWidth: width
mouseWheelSpeed: 20
Column {
id: mainColumn
@@ -487,7 +542,7 @@ Item {
width: parent.width
spacing: Theme.spacingL
DankSections {
WidgetsTabSection {
width: parent.width
title: "Left Section"
titleIcon: "format_align_left"
@@ -505,8 +560,8 @@ Item {
widgetSelectionPopup.targetSection = sectionId;
widgetSelectionPopup.safeOpen();
}
onRemoveWidget: (sectionId, itemId) => {
widgetsTab.removeWidgetFromSection(sectionId, itemId);
onRemoveWidget: (sectionId, widgetIndex) => {
widgetsTab.removeWidgetFromSection(sectionId, widgetIndex);
}
onSpacerSizeChanged: (sectionId, itemId, newSize) => {
widgetsTab.handleSpacerSizeChanged(sectionId, itemId, newSize);
@@ -518,9 +573,12 @@ Item {
SettingsData.setMediaCompactMode(enabled);
}
}
onGpuSelectionChanged: (sectionId, widgetIndex, selectedIndex) => {
widgetsTab.handleGpuSelectionChanged(sectionId, widgetIndex, selectedIndex);
}
}
DankSections {
WidgetsTabSection {
width: parent.width
title: "Center Section"
titleIcon: "format_align_center"
@@ -538,8 +596,8 @@ Item {
widgetSelectionPopup.targetSection = sectionId;
widgetSelectionPopup.safeOpen();
}
onRemoveWidget: (sectionId, itemId) => {
widgetsTab.removeWidgetFromSection(sectionId, itemId);
onRemoveWidget: (sectionId, widgetIndex) => {
widgetsTab.removeWidgetFromSection(sectionId, widgetIndex);
}
onSpacerSizeChanged: (sectionId, itemId, newSize) => {
widgetsTab.handleSpacerSizeChanged(sectionId, itemId, newSize);
@@ -551,9 +609,12 @@ Item {
SettingsData.setMediaCompactMode(enabled);
}
}
onGpuSelectionChanged: (sectionId, widgetIndex, selectedIndex) => {
widgetsTab.handleGpuSelectionChanged(sectionId, widgetIndex, selectedIndex);
}
}
DankSections {
WidgetsTabSection {
width: parent.width
title: "Right Section"
titleIcon: "format_align_right"
@@ -571,8 +632,8 @@ Item {
widgetSelectionPopup.targetSection = sectionId;
widgetSelectionPopup.safeOpen();
}
onRemoveWidget: (sectionId, itemId) => {
widgetsTab.removeWidgetFromSection(sectionId, itemId);
onRemoveWidget: (sectionId, widgetIndex) => {
widgetsTab.removeWidgetFromSection(sectionId, widgetIndex);
}
onSpacerSizeChanged: (sectionId, itemId, newSize) => {
widgetsTab.handleSpacerSizeChanged(sectionId, itemId, newSize);
@@ -584,6 +645,9 @@ Item {
SettingsData.setMediaCompactMode(enabled);
}
}
onGpuSelectionChanged: (sectionId, widgetIndex, selectedIndex) => {
widgetsTab.handleGpuSelectionChanged(sectionId, widgetIndex, selectedIndex);
}
}
}
}

View File

@@ -0,0 +1,384 @@
import QtQuick
import QtQuick.Controls
import qs.Common
import qs.Widgets
import qs.Services
Column {
id: root
property var items: []
property var allWidgets: []
property string title: ""
property string titleIcon: "widgets"
property string sectionId: ""
signal itemEnabledChanged(string sectionId, string itemId, bool enabled)
signal itemOrderChanged(var newOrder)
signal addWidget(string sectionId)
signal removeWidget(string sectionId, int widgetIndex)
signal spacerSizeChanged(string sectionId, string itemId, int newSize)
signal compactModeChanged(string widgetId, bool enabled)
signal gpuSelectionChanged(string sectionId, int widgetIndex, int selectedIndex)
width: parent.width
height: implicitHeight
spacing: Theme.spacingM
Row {
width: parent.width
spacing: Theme.spacingM
DankIcon {
name: root.titleIcon
size: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: root.title
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
Item {
width: parent.width - 60
height: 1
}
}
Column {
id: itemsList
width: parent.width
spacing: Theme.spacingS
Repeater {
model: root.items
delegate: Item {
id: delegateItem
property bool held: dragArea.pressed
property real originalY: y
width: itemsList.width
height: 70
z: held ? 2 : 1
Rectangle {
id: itemBackground
anchors.fill: parent
anchors.margins: 2
radius: Theme.cornerRadius
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.8)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 1
DankIcon {
name: "drag_indicator"
size: Theme.iconSize - 4
color: Theme.outline
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM + 8
anchors.verticalCenter: parent.verticalCenter
opacity: 0.8
}
DankIcon {
name: modelData.icon
size: Theme.iconSize
color: modelData.enabled ? Theme.primary : Theme.outline
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM * 2 + 40
anchors.verticalCenter: parent.verticalCenter
}
Column {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM * 3 + 40 + Theme.iconSize
anchors.right: actionButtons.left
anchors.rightMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
spacing: 2
StyledText {
text: modelData.text
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: modelData.enabled ? Theme.surfaceText : Theme.outline
elide: Text.ElideRight
width: parent.width
}
StyledText {
text: modelData.description
font.pixelSize: Theme.fontSizeSmall
color: modelData.enabled ? Theme.outline : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.6)
elide: Text.ElideRight
width: parent.width
wrapMode: Text.WordWrap
}
}
Row {
id: actionButtons
anchors.right: parent.right
anchors.rightMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingXS
Item {
width: 120
height: 32
visible: modelData.id === "gpuTemp"
DankDropdown {
id: gpuDropdown
anchors.fill: parent
currentValue: {
var selectedIndex = modelData.selectedGpuIndex !== undefined ? modelData.selectedGpuIndex : 0;
if (SysMonitorService.availableGpus && SysMonitorService.availableGpus.length > selectedIndex && selectedIndex >= 0) {
var gpu = SysMonitorService.availableGpus[selectedIndex];
return gpu.driver.toUpperCase() + " (" + Math.round(gpu.temperature || 0) + "°C)";
}
return SysMonitorService.availableGpus && SysMonitorService.availableGpus.length > 0 ? SysMonitorService.availableGpus[0].driver.toUpperCase() + " (" + Math.round(SysMonitorService.availableGpus[0].temperature || 0) + "°C)" : "";
}
options: {
var gpuOptions = [];
if (SysMonitorService.availableGpus && SysMonitorService.availableGpus.length > 0) {
for (var i = 0; i < SysMonitorService.availableGpus.length; i++) {
var gpu = SysMonitorService.availableGpus[i];
gpuOptions.push(gpu.driver.toUpperCase() + " (" + Math.round(gpu.temperature || 0) + "°C)");
}
}
return gpuOptions;
}
onValueChanged: (value) => {
var gpuIndex = options.indexOf(value);
if (gpuIndex >= 0) {
root.gpuSelectionChanged(root.sectionId, index, gpuIndex);
}
}
}
}
Item {
width: 32
height: 32
visible: modelData.id === "clock" || modelData.id === "music"
DankActionButton {
id: compactModeButton
anchors.fill: parent
buttonSize: 32
iconName: (modelData.id === "clock" && SettingsData.clockCompactMode) || (modelData.id === "music" && SettingsData.mediaCompactMode) ? "zoom_out" : "zoom_in"
iconSize: 18
iconColor: ((modelData.id === "clock" && SettingsData.clockCompactMode) || (modelData.id === "music" && SettingsData.mediaCompactMode)) ? Theme.primary : Theme.outline
onClicked: {
if (modelData.id === "clock") {
root.compactModeChanged("clock", !SettingsData.clockCompactMode);
} else if (modelData.id === "music") {
root.compactModeChanged("music", !SettingsData.mediaCompactMode);
}
}
}
Rectangle {
id: compactModeTooltip
width: tooltipText.contentWidth + Theme.spacingM * 2
height: tooltipText.contentHeight + Theme.spacingS * 2
radius: Theme.cornerRadius
color: Theme.surfaceContainer
border.color: Theme.outline
border.width: 1
visible: compactModeButton.children[1] && compactModeButton.children[1].containsMouse
opacity: visible ? 1 : 0
x: -width - Theme.spacingS
y: (parent.height - height) / 2
z: 100
StyledText {
id: tooltipText
anchors.centerIn: parent
text: "Compact Mode"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
}
Behavior on opacity {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
}
DankActionButton {
visible: modelData.id !== "spacer"
buttonSize: 32
iconName: modelData.enabled ? "visibility" : "visibility_off"
iconSize: 18
iconColor: modelData.enabled ? Theme.primary : Theme.outline
onClicked: {
root.itemEnabledChanged(root.sectionId, modelData.id, !modelData.enabled);
}
}
Row {
visible: modelData.id === "spacer"
spacing: Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
DankActionButton {
buttonSize: 24
iconName: "remove"
iconSize: 14
iconColor: Theme.outline
onClicked: {
var currentSize = modelData.size || 20;
var newSize = Math.max(5, currentSize - 5);
root.spacerSizeChanged(root.sectionId, modelData.id, newSize);
}
}
StyledText {
text: (modelData.size || 20).toString()
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
DankActionButton {
buttonSize: 24
iconName: "add"
iconSize: 14
iconColor: Theme.outline
onClicked: {
var currentSize = modelData.size || 20;
var newSize = Math.min(5000, currentSize + 5);
root.spacerSizeChanged(root.sectionId, modelData.id, newSize);
}
}
}
DankActionButton {
buttonSize: 32
iconName: "close"
iconSize: 18
iconColor: Theme.error
onClicked: {
root.removeWidget(root.sectionId, index);
}
}
}
MouseArea {
id: dragArea
anchors.left: parent.left
anchors.top: parent.top
anchors.bottom: parent.bottom
width: 60
hoverEnabled: true
cursorShape: Qt.SizeVerCursor
drag.target: held ? delegateItem : undefined
drag.axis: Drag.YAxis
drag.minimumY: -delegateItem.height
drag.maximumY: itemsList.height
preventStealing: true
onPressed: {
delegateItem.z = 2;
delegateItem.originalY = delegateItem.y;
}
onReleased: {
delegateItem.z = 1;
if (drag.active) {
var newIndex = Math.round(delegateItem.y / (delegateItem.height + itemsList.spacing));
newIndex = Math.max(0, Math.min(newIndex, root.items.length - 1));
if (newIndex !== index) {
var newItems = root.items.slice();
var draggedItem = newItems.splice(index, 1)[0];
newItems.splice(newIndex, 0, draggedItem);
root.itemOrderChanged(newItems.map((item) => {
return ({
"id": item.id,
"enabled": item.enabled,
"size": item.size
});
}));
}
}
delegateItem.x = 0;
delegateItem.y = delegateItem.originalY;
}
}
Behavior on y {
enabled: !dragArea.held && !dragArea.drag.active
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
}
}
}
Rectangle {
width: 200
height: 40
radius: Theme.cornerRadius
color: addButtonArea.containsMouse ? Theme.primaryContainer : Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 1
anchors.horizontalCenter: parent.horizontalCenter
StyledText {
text: "Add Widget"
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
anchors.centerIn: parent
}
MouseArea {
id: addButtonArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
root.addWidget(root.sectionId);
}
}
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
}

View File

@@ -57,10 +57,10 @@ Rectangle {
size: Theme.iconSize - 8
color: {
if (SysMonitorService.cpuUsage > 80)
return Theme.error;
return Theme.tempDanger;
if (SysMonitorService.cpuUsage > 60)
return Theme.warning;
return Theme.tempWarning;
return Theme.surfaceText;
}
@@ -68,7 +68,12 @@ Rectangle {
}
StyledText {
text: (SysMonitorService.cpuUsage || 0).toFixed(0) + "%"
text: {
if (SysMonitorService.cpuUsage === undefined || SysMonitorService.cpuUsage === null || SysMonitorService.cpuUsage === 0) {
return "--%";
}
return SysMonitorService.cpuUsage.toFixed(0) + "%";
}
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: Theme.surfaceText

View File

@@ -0,0 +1,91 @@
import QtQuick
import QtQuick.Controls
import qs.Common
import qs.Services
import qs.Widgets
Rectangle {
id: root
property bool showPercentage: true
property bool showIcon: true
property var toggleProcessList
property string section: "right"
property var popupTarget: null
property var parentScreen: null
width: 55
height: 30
radius: Theme.cornerRadius
color: {
const baseColor = cpuTempArea.containsMouse ? Theme.primaryPressed : Theme.secondaryHover;
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
}
Component.onCompleted: {
SysMonitorService.addRef();
}
Component.onDestruction: {
SysMonitorService.removeRef();
}
MouseArea {
id: cpuTempArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (popupTarget && popupTarget.setTriggerPosition) {
var globalPos = mapToGlobal(0, 0);
var currentScreen = parentScreen || Screen;
var screenX = currentScreen.x || 0;
var relativeX = globalPos.x - screenX;
popupTarget.setTriggerPosition(relativeX, Theme.barHeight + Theme.spacingXS, width, section, currentScreen);
}
SysMonitorService.setSortBy("cpu");
if (root.toggleProcessList)
root.toggleProcessList();
}
}
Row {
anchors.centerIn: parent
spacing: 3
DankIcon {
name: "memory"
size: Theme.iconSize - 8
color: {
if (SysMonitorService.cpuTemperature > 85)
return Theme.tempDanger;
if (SysMonitorService.cpuTemperature > 69)
return Theme.tempWarning;
return Theme.surfaceText;
}
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: {
if (SysMonitorService.cpuTemperature === undefined || SysMonitorService.cpuTemperature === null || SysMonitorService.cpuTemperature < 0) {
return "--°";
}
return Math.round(SysMonitorService.cpuTemperature) + "°";
}
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}

View File

@@ -0,0 +1,111 @@
import QtQuick
import QtQuick.Controls
import qs.Common
import qs.Services
import qs.Widgets
Rectangle {
id: root
property bool showPercentage: true
property bool showIcon: true
property var toggleProcessList
property string section: "right"
property var popupTarget: null
property var parentScreen: null
property var widgetData: null
property int selectedGpuIndex: (widgetData && widgetData.selectedGpuIndex !== undefined) ? widgetData.selectedGpuIndex : 0
Connections {
target: SettingsData
function onWidgetDataChanged() {
// Force property re-evaluation by triggering change detection
root.selectedGpuIndex = Qt.binding(() => {
return (root.widgetData && root.widgetData.selectedGpuIndex !== undefined) ? root.widgetData.selectedGpuIndex : 0;
});
}
}
width: 55
height: 30
radius: Theme.cornerRadius
color: {
const baseColor = gpuArea.containsMouse ? Theme.primaryPressed : Theme.secondaryHover;
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
}
Component.onCompleted: {
SysMonitorService.addRef();
}
Component.onDestruction: {
SysMonitorService.removeRef();
}
property real displayTemp: {
if (!SysMonitorService.availableGpus || SysMonitorService.availableGpus.length === 0) return 0;
if (selectedGpuIndex >= 0 && selectedGpuIndex < SysMonitorService.availableGpus.length) {
return SysMonitorService.availableGpus[selectedGpuIndex].temperature || 0;
}
return 0;
}
MouseArea {
id: gpuArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (popupTarget && popupTarget.setTriggerPosition) {
var globalPos = mapToGlobal(0, 0);
var currentScreen = parentScreen || Screen;
var screenX = currentScreen.x || 0;
var relativeX = globalPos.x - screenX;
popupTarget.setTriggerPosition(relativeX, Theme.barHeight + Theme.spacingXS, width, section, currentScreen);
}
SysMonitorService.setSortBy("cpu");
if (root.toggleProcessList)
root.toggleProcessList();
}
}
Row {
anchors.centerIn: parent
spacing: 3
DankIcon {
name: "auto_awesome_mosaic"
size: Theme.iconSize - 8
color: {
if (root.displayTemp > 80)
return Theme.tempDanger;
if (root.displayTemp > 65)
return Theme.tempWarning;
return Theme.surfaceText;
}
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: {
if (root.displayTemp === undefined || root.displayTemp === null || root.displayTemp === 0) {
return "--°";
}
return Math.round(root.displayTemp) + "°";
}
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}

View File

@@ -57,10 +57,10 @@ Rectangle {
size: Theme.iconSize - 8
color: {
if (SysMonitorService.memoryUsage > 90)
return Theme.error;
return Theme.tempDanger;
if (SysMonitorService.memoryUsage > 75)
return Theme.warning;
return Theme.tempWarning;
return Theme.surfaceText;
}
@@ -68,7 +68,12 @@ Rectangle {
}
StyledText {
text: (SysMonitorService.memoryUsage || 0).toFixed(0) + "%"
text: {
if (SysMonitorService.memoryUsage === undefined || SysMonitorService.memoryUsage === null || SysMonitorService.memoryUsage === 0) {
return "--%";
}
return SysMonitorService.memoryUsage.toFixed(0) + "%";
}
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: Theme.surfaceText

View File

@@ -180,7 +180,13 @@ PanelWindow {
return true;
case "clipboard":
return true;
case "systemResources":
case "cpuUsage":
return true;
case "memUsage":
return true;
case "cpuTemp":
return true;
case "gpuTemp":
return true;
case "notificationButton":
return true;
@@ -217,8 +223,14 @@ PanelWindow {
return privacyIndicatorComponent;
case "clipboard":
return clipboardComponent;
case "systemResources":
return systemResourcesComponent;
case "cpuUsage":
return cpuUsageComponent;
case "memUsage":
return memUsageComponent;
case "cpuTemp":
return cpuTempComponent;
case "gpuTemp":
return gpuTempComponent;
case "notificationButton":
return notificationButtonComponent;
case "battery":
@@ -606,39 +618,78 @@ PanelWindow {
}
Component {
id: systemResourcesComponent
id: cpuUsageComponent
Row {
spacing: Theme.spacingXS
CpuMonitor {
section: {
if (parent && parent.parent && parent.parent.parent === leftSection) return "left";
if (parent && parent.parent && parent.parent.parent === rightSection) return "right";
if (parent && parent.parent && parent.parent.parent === centerSection) return "center";
return "right";
}
popupTarget: processListPopout
parentScreen: root.screen
toggleProcessList: () => {
return processListPopout.toggle();
}
CpuMonitor {
section: {
if (parent && parent.parent === leftSection) return "left";
if (parent && parent.parent === rightSection) return "right";
if (parent && parent.parent === centerSection) return "center";
return "right";
}
RamMonitor {
section: {
if (parent && parent.parent && parent.parent.parent === leftSection) return "left";
if (parent && parent.parent && parent.parent.parent === rightSection) return "right";
if (parent && parent.parent && parent.parent.parent === centerSection) return "center";
return "right";
}
popupTarget: processListPopout
parentScreen: root.screen
toggleProcessList: () => {
return processListPopout.toggle();
}
popupTarget: processListPopout
parentScreen: root.screen
toggleProcessList: () => {
return processListPopout.toggle();
}
}
}
Component {
id: memUsageComponent
RamMonitor {
section: {
if (parent && parent.parent === leftSection) return "left";
if (parent && parent.parent === rightSection) return "right";
if (parent && parent.parent === centerSection) return "center";
return "right";
}
popupTarget: processListPopout
parentScreen: root.screen
toggleProcessList: () => {
return processListPopout.toggle();
}
}
}
Component {
id: cpuTempComponent
CpuTemperature {
section: {
if (parent && parent.parent === leftSection) return "left";
if (parent && parent.parent === rightSection) return "right";
if (parent && parent.parent === centerSection) return "center";
return "right";
}
popupTarget: processListPopout
parentScreen: root.screen
toggleProcessList: () => {
return processListPopout.toggle();
}
}
}
Component {
id: gpuTempComponent
GpuTemperature {
section: {
if (parent && parent.parent === leftSection) return "left";
if (parent && parent.parent === rightSection) return "right";
if (parent && parent.parent === centerSection) return "center";
return "right";
}
popupTarget: processListPopout
parentScreen: root.screen
widgetData: parent.widgetData
toggleProcessList: () => {
return processListPopout.toggle();
}
}
}

View File

@@ -39,7 +39,13 @@ Rectangle {
}
StyledText {
text: (SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp) + "°" + (SettingsData.useFahrenheit ? "F" : "C")
text: {
var temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp;
if (temp === undefined || temp === null || temp === 0) {
return "--°" + (SettingsData.useFahrenheit ? "F" : "C");
}
return temp + "°" + (SettingsData.useFahrenheit ? "F" : "C");
}
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter