mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
widgets: add a way to show cpu intensive ones
This commit is contained in:
@@ -965,6 +965,7 @@
|
||||
"clock-style-label": "Clock style",
|
||||
"clock-style-minimal": "Minimal",
|
||||
"clock-width-description": "Width of the clock widget in pixels.",
|
||||
"cpu-intensive-note": "Widgets marked with ! use more CPU and should be enabled mindfully.",
|
||||
"edit-mode-button-label": "Enter edit mode",
|
||||
"edit-mode-controls-explanation": "Left-click & drag: Move or resize the widget.\nRight-click: Open the context menu options.",
|
||||
"edit-mode-description": "Enable edit mode to move and reposition desktop widgets. When enabled, widgets show a drag outline and can be repositioned.",
|
||||
|
||||
@@ -33,6 +33,7 @@ Singleton {
|
||||
"media-next": "player-skip-forward-filled",
|
||||
"download-speed": "download",
|
||||
"upload-speed": "upload",
|
||||
"cpu-intensive": "alert-octagon",
|
||||
"cpu-usage": "brand-speedtest",
|
||||
"cpu-temperature": "flame",
|
||||
"gpu-temperature": "device-desktop",
|
||||
|
||||
@@ -117,6 +117,7 @@ NBox {
|
||||
for (var i = 0; i < widgetIds.length; i++) {
|
||||
var id = widgetIds[i];
|
||||
var displayName = id;
|
||||
const badges = [];
|
||||
if (BarWidgetRegistry.isPluginWidget(id)) {
|
||||
var pluginId = id.replace("plugin:", "");
|
||||
var manifest = PluginRegistry.getPluginManifest(pluginId);
|
||||
@@ -125,10 +126,21 @@ NBox {
|
||||
} else {
|
||||
displayName = pluginId;
|
||||
}
|
||||
badges.push({
|
||||
"icon": "plugin",
|
||||
"color": Color.mSecondary
|
||||
});
|
||||
}
|
||||
if (BarWidgetRegistry.isCpuIntensive(id)) {
|
||||
badges.push({
|
||||
"icon": "cpu-intensive",
|
||||
"color": Color.mSecondary
|
||||
});
|
||||
}
|
||||
availableWidgetsModel.append({
|
||||
"key": id,
|
||||
"name": displayName
|
||||
"name": displayName,
|
||||
"badges": badges
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,29 +36,80 @@ ColumnLayout {
|
||||
onToggled: checked => Settings.data.desktopWidgets.enabled = checked
|
||||
}
|
||||
|
||||
NButton {
|
||||
ColumnLayout {
|
||||
enabled: Settings.data.desktopWidgets.enabled
|
||||
Layout.fillWidth: true
|
||||
text: DesktopWidgetRegistry.editMode ? I18n.tr("panels.desktop-widgets.edit-mode-exit-button") : I18n.tr("panels.desktop-widgets.edit-mode-button-label")
|
||||
icon: "edit"
|
||||
onClicked: {
|
||||
DesktopWidgetRegistry.editMode = !DesktopWidgetRegistry.editMode;
|
||||
if (DesktopWidgetRegistry.editMode && Settings.data.ui.settingsPanelMode !== "window") {
|
||||
var item = root.parent;
|
||||
while (item) {
|
||||
if (item.closeRequested !== undefined) {
|
||||
item.closeRequested();
|
||||
break;
|
||||
|
||||
NLabel {
|
||||
description: I18n.tr("panels.desktop-widgets.cpu-intensive-note")
|
||||
}
|
||||
|
||||
NButton {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginM
|
||||
Layout.bottomMargin: Style.marginM
|
||||
text: DesktopWidgetRegistry.editMode ? I18n.tr("panels.desktop-widgets.edit-mode-exit-button") : I18n.tr("panels.desktop-widgets.edit-mode-button-label")
|
||||
icon: "edit"
|
||||
onClicked: {
|
||||
DesktopWidgetRegistry.editMode = !DesktopWidgetRegistry.editMode;
|
||||
if (DesktopWidgetRegistry.editMode && Settings.data.ui.settingsPanelMode !== "window") {
|
||||
var item = root.parent;
|
||||
while (item) {
|
||||
if (item.closeRequested !== undefined) {
|
||||
item.closeRequested();
|
||||
break;
|
||||
}
|
||||
item = item.parent;
|
||||
}
|
||||
item = item.parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// One NSectionEditor per monitor
|
||||
Repeater {
|
||||
model: Quickshell.screens
|
||||
|
||||
NSectionEditor {
|
||||
required property var modelData
|
||||
|
||||
Layout.fillWidth: true
|
||||
sectionName: modelData.name
|
||||
sectionSubtitle: {
|
||||
var compositorScale = CompositorService.getDisplayScale(modelData.name);
|
||||
// Format scale to 2 decimal places to prevent overly long text
|
||||
var formattedScale = compositorScale.toFixed(2);
|
||||
return "(" + modelData.width + "x" + modelData.height + " @ " + formattedScale + "x)";
|
||||
}
|
||||
|
||||
sectionId: modelData.name
|
||||
screen: modelData
|
||||
settingsDialogComponent: Qt.resolvedUrl(Quickshell.shellDir + "/Modules/Panels/Settings/DesktopWidgets/DesktopWidgetSettingsDialog.qml")
|
||||
widgetRegistry: DesktopWidgetRegistry
|
||||
widgetModel: getWidgetsForMonitor(modelData.name)
|
||||
availableWidgets: root.availableWidgetsModel
|
||||
availableSections: root.getScreenNames()
|
||||
sectionLabels: root.getScreenLabels()
|
||||
sectionIcons: root.getScreenIcons()
|
||||
draggable: false // Desktop widgets are positioned by X,Y, not list order
|
||||
maxWidgets: -1
|
||||
onAddWidget: (widgetId, section) => _addWidgetToMonitor(modelData.name, widgetId)
|
||||
onRemoveWidget: (section, index) => _removeWidgetFromMonitor(modelData.name, index)
|
||||
onMoveWidget: (fromSection, index, toSection) => _moveWidgetToMonitor(fromSection, index, toSection)
|
||||
onUpdateWidgetSettings: (section, index, settings) => _updateWidgetSettingsForMonitor(modelData.name, index, settings)
|
||||
onOpenPluginSettingsRequested: manifest => pluginSettingsDialog.openPluginSettings(manifest)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
visible: Settings.data.desktopWidgets.enabled
|
||||
Layout.fillWidth: true
|
||||
// Shared Plugin Settings Popup
|
||||
NPluginSettingsPopup {
|
||||
id: pluginSettingsDialog
|
||||
parent: Overlay.overlay
|
||||
showToastOnSave: false
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
// Use Qt.callLater to ensure DesktopWidgetRegistry is ready
|
||||
Qt.callLater(updateAvailableWidgetsModel);
|
||||
}
|
||||
|
||||
// Helper to get screen names array
|
||||
@@ -89,54 +140,6 @@ ColumnLayout {
|
||||
return icons;
|
||||
}
|
||||
|
||||
// One NSectionEditor per monitor
|
||||
Repeater {
|
||||
model: Quickshell.screens
|
||||
|
||||
NSectionEditor {
|
||||
enabled: Settings.data.desktopWidgets.enabled
|
||||
required property var modelData
|
||||
|
||||
Layout.fillWidth: true
|
||||
sectionName: modelData.name
|
||||
sectionSubtitle: {
|
||||
var compositorScale = CompositorService.getDisplayScale(modelData.name);
|
||||
// Format scale to 2 decimal places to prevent overly long text
|
||||
var formattedScale = compositorScale.toFixed(2);
|
||||
return "(" + modelData.width + "x" + modelData.height + " @ " + formattedScale + "x)";
|
||||
}
|
||||
|
||||
sectionId: modelData.name
|
||||
screen: modelData
|
||||
settingsDialogComponent: Qt.resolvedUrl(Quickshell.shellDir + "/Modules/Panels/Settings/DesktopWidgets/DesktopWidgetSettingsDialog.qml")
|
||||
widgetRegistry: DesktopWidgetRegistry
|
||||
widgetModel: getWidgetsForMonitor(modelData.name)
|
||||
availableWidgets: root.availableWidgetsModel
|
||||
availableSections: root.getScreenNames()
|
||||
sectionLabels: root.getScreenLabels()
|
||||
sectionIcons: root.getScreenIcons()
|
||||
draggable: false // Desktop widgets are positioned by X,Y, not list order
|
||||
maxWidgets: -1
|
||||
onAddWidget: (widgetId, section) => _addWidgetToMonitor(modelData.name, widgetId)
|
||||
onRemoveWidget: (section, index) => _removeWidgetFromMonitor(modelData.name, index)
|
||||
onMoveWidget: (fromSection, index, toSection) => _moveWidgetToMonitor(fromSection, index, toSection)
|
||||
onUpdateWidgetSettings: (section, index, settings) => _updateWidgetSettingsForMonitor(modelData.name, index, settings)
|
||||
onOpenPluginSettingsRequested: manifest => pluginSettingsDialog.openPluginSettings(manifest)
|
||||
}
|
||||
}
|
||||
|
||||
// Shared Plugin Settings Popup
|
||||
NPluginSettingsPopup {
|
||||
id: pluginSettingsDialog
|
||||
parent: Overlay.overlay
|
||||
showToastOnSave: false
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
// Use Qt.callLater to ensure DesktopWidgetRegistry is ready
|
||||
Qt.callLater(updateAvailableWidgetsModel);
|
||||
}
|
||||
|
||||
function updateAvailableWidgetsModel() {
|
||||
availableWidgets.clear();
|
||||
try {
|
||||
@@ -179,6 +182,12 @@ ColumnLayout {
|
||||
"color": Color.mSecondary
|
||||
});
|
||||
}
|
||||
if (DesktopWidgetRegistry.isCpuIntensive(widgetId)) {
|
||||
badges.push({
|
||||
"icon": "cpu-intensive",
|
||||
"color": Color.mSecondary
|
||||
});
|
||||
}
|
||||
|
||||
availableWidgets.append({
|
||||
"key": widgetId,
|
||||
|
||||
@@ -475,6 +475,14 @@ Singleton {
|
||||
return id.startsWith("plugin:");
|
||||
}
|
||||
|
||||
property var cpuIntensiveWidgets: ["AudioVisualizer"]
|
||||
|
||||
function isCpuIntensive(id) {
|
||||
if (pluginWidgetMetadata[id]?.cpuIntensive)
|
||||
return true;
|
||||
return cpuIntensiveWidgets.indexOf(id) >= 0;
|
||||
}
|
||||
|
||||
// Get list of plugin widget IDs
|
||||
function getPluginWidgets() {
|
||||
return Object.keys(pluginWidgets);
|
||||
|
||||
@@ -37,6 +37,8 @@ Singleton {
|
||||
}
|
||||
})
|
||||
|
||||
property var cpuIntensiveWidgets: ["SystemStat"]
|
||||
|
||||
// Component definitions - these are loaded once at startup
|
||||
property Component airplaneModeComponent: Component {
|
||||
AirplaneMode {}
|
||||
@@ -152,4 +154,10 @@ Singleton {
|
||||
function getPluginWidgets() {
|
||||
return Object.keys(pluginWidgets);
|
||||
}
|
||||
|
||||
function isCpuIntensive(id) {
|
||||
if (pluginWidgetMetadata[id]?.cpuIntensive)
|
||||
return true;
|
||||
return cpuIntensiveWidgets.indexOf(id) >= 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,8 @@ Singleton {
|
||||
}
|
||||
})
|
||||
|
||||
property var cpuIntensiveWidgets: ["SystemStat"]
|
||||
|
||||
// Plugin widget storage (mirroring BarWidgetRegistry pattern)
|
||||
property var pluginWidgets: ({})
|
||||
property var pluginWidgetMetadata: ({})
|
||||
@@ -111,6 +113,12 @@ Singleton {
|
||||
return widgetMetadata[id] !== undefined;
|
||||
}
|
||||
|
||||
function isCpuIntensive(id) {
|
||||
if (pluginWidgetMetadata[id]?.cpuIntensive)
|
||||
return true;
|
||||
return cpuIntensiveWidgets.indexOf(id) >= 0;
|
||||
}
|
||||
|
||||
// Check if a widget is a plugin widget
|
||||
function isPluginWidget(id) {
|
||||
return id.startsWith("plugin:");
|
||||
|
||||
@@ -494,6 +494,16 @@ NBox {
|
||||
Layout.preferredHeight: Style.baseWidgetSize * 0.5
|
||||
}
|
||||
|
||||
// CPU-intensive indicator icon
|
||||
NIcon {
|
||||
visible: root.widgetRegistry && root.widgetRegistry.isCpuIntensive(modelData.id)
|
||||
icon: "cpu-intensive"
|
||||
pointSize: Style.fontSizeXXS
|
||||
color: root.getWidgetColor(modelData)[1]
|
||||
Layout.preferredWidth: visible ? Style.baseWidgetSize * 0.5 : 0
|
||||
Layout.preferredHeight: Style.baseWidgetSize * 0.5
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
Layout.preferredWidth: buttonsCount * buttonsWidth * Style.uiScaleRatio
|
||||
|
||||
Reference in New Issue
Block a user