1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-05 21:15:38 -05:00

Allow removing force-padding on monitor widgets + plugin load fixes

This commit is contained in:
bbedward
2025-10-06 11:32:25 -04:00
parent e24ddb804d
commit 11a1af89f4
10 changed files with 209 additions and 44 deletions

View File

@@ -204,7 +204,8 @@ Singleton {
"size": 20,
"selectedGpuIndex": 0,
"pciId": "",
"mountPath": "/"
"mountPath": "/",
"minimumWidth": true
}
leftWidgetsModel.append(dummyItem)
centerWidgetsModel.append(dummyItem)
@@ -811,6 +812,7 @@ Singleton {
var selectedGpuIndex = typeof order[i] === "string" ? undefined : order[i].selectedGpuIndex
var pciId = typeof order[i] === "string" ? undefined : order[i].pciId
var mountPath = typeof order[i] === "string" ? undefined : order[i].mountPath
var minimumWidth = typeof order[i] === "string" ? undefined : order[i].minimumWidth
var item = {
"widgetId": widgetId,
"enabled": enabled
@@ -823,6 +825,8 @@ Singleton {
item.pciId = pciId
if (mountPath !== undefined)
item.mountPath = mountPath
if (minimumWidth !== undefined)
item.minimumWidth = minimumWidth
listModel.append(item)
}

View File

@@ -827,6 +827,7 @@ Item {
return processListPopoutLoader.item
}
parentScreen: barWindow.screen
widgetData: parent.widgetData
toggleProcessList: () => {
processListPopoutLoader.active = true
return processListPopoutLoader.item?.toggle()
@@ -846,6 +847,7 @@ Item {
return processListPopoutLoader.item
}
parentScreen: barWindow.screen
widgetData: parent.widgetData
toggleProcessList: () => {
processListPopoutLoader.active = true
return processListPopoutLoader.item?.toggle()
@@ -875,6 +877,7 @@ Item {
return processListPopoutLoader.item
}
parentScreen: barWindow.screen
widgetData: parent.widgetData
toggleProcessList: () => {
processListPopoutLoader.active = true
return processListPopoutLoader.item?.toggle()

View File

@@ -65,6 +65,14 @@ Loader {
restoreMode: Binding.RestoreNone
}
Binding {
target: root.item
when: root.item && "widgetData" in root.item
property: "widgetData"
value: root.widgetData
restoreMode: Binding.RestoreNone
}
onLoaded: {
if (item) {
contentItemReady(item)

View File

@@ -17,6 +17,8 @@ Rectangle {
property var parentScreen: null
property real barThickness: 48
property real widgetThickness: 30
property var widgetData: null
property bool minimumWidth: (widgetData && widgetData.minimumWidth !== undefined) ? widgetData.minimumWidth : true
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
width: isVertical ? widgetThickness : (cpuContent.implicitWidth + horizontalPadding * 2)
@@ -141,7 +143,7 @@ Rectangle {
text: "100%"
}
width: Math.max(cpuBaseline.width, paintedWidth)
width: root.minimumWidth ? Math.max(cpuBaseline.width, paintedWidth) : paintedWidth
Behavior on width {
NumberAnimation {

View File

@@ -17,6 +17,8 @@ Rectangle {
property var parentScreen: null
property real barThickness: 48
property real widgetThickness: 30
property var widgetData: null
property bool minimumWidth: (widgetData && widgetData.minimumWidth !== undefined) ? widgetData.minimumWidth : true
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
width: isVertical ? widgetThickness : (cpuTempContent.implicitWidth + horizontalPadding * 2)
@@ -141,7 +143,7 @@ Rectangle {
text: "100°"
}
width: Math.max(tempBaseline.width, paintedWidth)
width: root.minimumWidth ? Math.max(tempBaseline.width, paintedWidth) : paintedWidth
Behavior on width {
NumberAnimation {

View File

@@ -19,6 +19,7 @@ Rectangle {
property real barThickness: 48
property real widgetThickness: 30
property int selectedGpuIndex: (widgetData && widgetData.selectedGpuIndex !== undefined) ? widgetData.selectedGpuIndex : 0
property bool minimumWidth: (widgetData && widgetData.minimumWidth !== undefined) ? widgetData.minimumWidth : true
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
property real displayTemp: {
if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) {
@@ -209,7 +210,7 @@ Rectangle {
text: "100°"
}
width: Math.max(gpuTempBaseline.width, paintedWidth)
width: root.minimumWidth ? Math.max(gpuTempBaseline.width, paintedWidth) : paintedWidth
Behavior on width {
NumberAnimation {

View File

@@ -17,6 +17,8 @@ Rectangle {
property var parentScreen: null
property real barThickness: 48
property real widgetThickness: 30
property var widgetData: null
property bool minimumWidth: (widgetData && widgetData.minimumWidth !== undefined) ? widgetData.minimumWidth : true
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
width: isVertical ? widgetThickness : (ramContent.implicitWidth + horizontalPadding * 2)
@@ -30,6 +32,7 @@ Rectangle {
const baseColor = ramArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
}
Component.onCompleted: {
DgopService.addRef(["memory"]);
}
@@ -141,7 +144,7 @@ Rectangle {
text: "100%"
}
width: Math.max(ramBaseline.width, paintedWidth)
width: root.minimumWidth ? Math.max(ramBaseline.width, paintedWidth) : paintedWidth
Behavior on width {
NumberAnimation {

View File

@@ -263,6 +263,9 @@ Item {
if (widgetId === "diskUsage") {
widgetObj.mountPath = "/"
}
if (widgetId === "cpuUsage" || widgetId === "memUsage" || widgetId === "cpuTemp" || widgetId === "gpuTemp") {
widgetObj.minimumWidth = true
}
var widgets = []
if (targetSection === "left") {
@@ -509,6 +512,54 @@ Item {
}
}
function handleMinimumWidthChanged(sectionId, widgetIndex, enabled) {
var widgets = []
if (sectionId === "left")
widgets = SettingsData.dankBarLeftWidgets.slice()
else if (sectionId === "center")
widgets = SettingsData.dankBarCenterWidgets.slice()
else if (sectionId === "right")
widgets = SettingsData.dankBarRightWidgets.slice()
if (widgetIndex >= 0 && widgetIndex < widgets.length) {
var widget = widgets[widgetIndex]
if (typeof widget === "string") {
widgets[widgetIndex] = {
"id": widget,
"enabled": true,
"minimumWidth": enabled
}
} else {
var newWidget = {
"id": widget.id,
"enabled": widget.enabled,
"minimumWidth": enabled
}
if (widget.size !== undefined)
newWidget.size = widget.size
if (widget.selectedGpuIndex !== undefined)
newWidget.selectedGpuIndex = widget.selectedGpuIndex
if (widget.pciId !== undefined)
newWidget.pciId = widget.pciId
if (widget.mountPath !== undefined)
newWidget.mountPath = widget.mountPath
if (widget.id === "controlCenterButton") {
newWidget.showNetworkIcon = widget.showNetworkIcon !== undefined ? widget.showNetworkIcon : true
newWidget.showBluetoothIcon = widget.showBluetoothIcon !== undefined ? widget.showBluetoothIcon : true
newWidget.showAudioIcon = widget.showAudioIcon !== undefined ? widget.showAudioIcon : true
}
widgets[widgetIndex] = newWidget
}
}
if (sectionId === "left")
SettingsData.setDankBarLeftWidgets(widgets)
else if (sectionId === "center")
SettingsData.setDankBarCenterWidgets(widgets)
else if (sectionId === "right")
SettingsData.setDankBarRightWidgets(widgets)
}
function getItemsForSection(sectionId) {
var widgets = []
var widgetData = []
@@ -532,6 +583,7 @@ Item {
var widgetShowNetworkIcon = typeof widget === "string" ? undefined : widget.showNetworkIcon
var widgetShowBluetoothIcon = typeof widget === "string" ? undefined : widget.showBluetoothIcon
var widgetShowAudioIcon = typeof widget === "string" ? undefined : widget.showAudioIcon
var widgetMinimumWidth = typeof widget === "string" ? undefined : widget.minimumWidth
var widgetDef = baseWidgetDefinitions.find(w => {
return w.id === widgetId
})
@@ -552,6 +604,8 @@ Item {
item.showBluetoothIcon = widgetShowBluetoothIcon
if (widgetShowAudioIcon !== undefined)
item.showAudioIcon = widgetShowAudioIcon
if (widgetMinimumWidth !== undefined)
item.minimumWidth = widgetMinimumWidth
widgets.push(item)
}
@@ -1208,6 +1262,10 @@ Item {
dankBarTab.handleDiskMountSelectionChanged(
sectionId, widgetIndex, mountPath)
}
onMinimumWidthChanged: (sectionId, widgetIndex, enabled) => {
dankBarTab.handleMinimumWidthChanged(
sectionId, widgetIndex, enabled)
}
}
}
@@ -1280,6 +1338,10 @@ Item {
dankBarTab.handleDiskMountSelectionChanged(
sectionId, widgetIndex, mountPath)
}
onMinimumWidthChanged: (sectionId, widgetIndex, enabled) => {
dankBarTab.handleMinimumWidthChanged(
sectionId, widgetIndex, enabled)
}
}
}
@@ -1352,6 +1414,10 @@ Item {
dankBarTab.handleDiskMountSelectionChanged(
sectionId, widgetIndex, mountPath)
}
onMinimumWidthChanged: (sectionId, widgetIndex, enabled) => {
dankBarTab.handleMinimumWidthChanged(
sectionId, widgetIndex, enabled)
}
}
}
}

View File

@@ -22,6 +22,7 @@ Column {
signal gpuSelectionChanged(string sectionId, int widgetIndex, int selectedIndex)
signal diskMountSelectionChanged(string sectionId, int widgetIndex, string mountPath)
signal controlCenterSettingChanged(string sectionId, int widgetIndex, string settingName, bool value)
signal minimumWidthChanged(string sectionId, int widgetIndex, bool enabled)
width: parent.width
height: implicitHeight
@@ -283,6 +284,37 @@ Column {
}
}
DankActionButton {
id: minimumWidthButton
buttonSize: 28
visible: modelData.id === "cpuUsage"
|| modelData.id === "memUsage"
|| modelData.id === "cpuTemp"
|| modelData.id === "gpuTemp"
iconName: "straighten"
iconSize: 16
iconColor: (modelData.minimumWidth !== undefined ? modelData.minimumWidth : true) ? Theme.primary : Theme.outline
onClicked: {
var currentEnabled = modelData.minimumWidth !== undefined ? modelData.minimumWidth : true
root.minimumWidthChanged(root.sectionId, index, !currentEnabled)
}
onEntered: {
minimumWidthTooltipLoader.active = true
if (minimumWidthTooltipLoader.item) {
var currentEnabled = modelData.minimumWidth !== undefined ? modelData.minimumWidth : true
const tooltipText = currentEnabled ? "Force Padding" : "Dynamic Width"
const p = minimumWidthButton.mapToItem(null, minimumWidthButton.width / 2, 0)
minimumWidthTooltipLoader.item.show(tooltipText, p.x, p.y - 40, null)
}
}
onExited: {
if (minimumWidthTooltipLoader.item) {
minimumWidthTooltipLoader.item.hide()
}
minimumWidthTooltipLoader.active = false
}
}
Row {
spacing: Theme.spacingXS
visible: modelData.id === "clock"
@@ -892,4 +924,10 @@ Column {
active: false
sourceComponent: DankTooltip {}
}
Loader {
id: minimumWidthTooltipLoader
active: false
sourceComponent: DankTooltip {}
}
}

View File

@@ -41,6 +41,7 @@ Singleton {
property int currentScanIndex: 0
property var scanResults: []
property var foundPlugins: ({})
property var lsProcess: Process {
id: dirScanner
@@ -68,12 +69,14 @@ Singleton {
scanNextDirectory()
} else {
currentScanIndex = 0
cleanupRemovedPlugins()
}
}
}
function scanPlugins() {
currentScanIndex = 0
foundPlugins = {}
scanNextDirectory()
}
@@ -88,39 +91,57 @@ Singleton {
function loadPluginManifest(manifestPath) {
var readerId = "reader_" + Date.now() + "_" + Math.random()
var catProcess = Qt.createComponent("data:text/plain,import Quickshell.Io; Process { stdout: StdioCollector { } }")
if (catProcess.status === Component.Ready) {
var process = catProcess.createObject(root)
process.command = ["cat", manifestPath]
process.stdout.streamFinished.connect(function() {
try {
var manifest = JSON.parse(process.stdout.text.trim())
processManifest(manifest, manifestPath)
} catch (e) {
console.error("PluginService: Failed to parse manifest", manifestPath, ":", e.message)
}
process.destroy()
delete manifestReaders[readerId]
})
process.exited.connect(function(exitCode) {
var checkProcess = Qt.createComponent("data:text/plain,import Quickshell.Io; Process { stdout: StdioCollector { } }")
if (checkProcess.status === Component.Ready) {
var checker = checkProcess.createObject(root)
checker.command = ["test", "-f", manifestPath]
checker.exited.connect(function(exitCode) {
if (exitCode !== 0) {
console.error("PluginService: Failed to read manifest file:", manifestPath, "exit code:", exitCode)
process.destroy()
checker.destroy()
delete manifestReaders[readerId]
return
}
var catProcess = Qt.createComponent("data:text/plain,import Quickshell.Io; Process { stdout: StdioCollector { } }")
if (catProcess.status === Component.Ready) {
var process = catProcess.createObject(root)
process.command = ["cat", manifestPath]
process.stdout.streamFinished.connect(function() {
try {
var manifest = JSON.parse(process.stdout.text.trim())
processManifest(manifest, manifestPath)
} catch (e) {
console.error("PluginService: Failed to parse manifest", manifestPath, ":", e.message)
}
process.destroy()
delete manifestReaders[readerId]
})
process.exited.connect(function(exitCode) {
if (exitCode !== 0) {
console.error("PluginService: Failed to read manifest file:", manifestPath, "exit code:", exitCode)
process.destroy()
delete manifestReaders[readerId]
}
})
manifestReaders[readerId] = process
process.running = true
} else {
console.error("PluginService: Failed to create manifest reader process")
}
checker.destroy()
})
manifestReaders[readerId] = process
process.running = true
manifestReaders[readerId] = checker
checker.running = true
} else {
console.error("PluginService: Failed to create manifest reader process")
console.error("PluginService: Failed to create file check process")
}
}
function processManifest(manifest, manifestPath) {
registerPlugin(manifest, manifestPath)
// Auto-load plugin if it's enabled in settings (default to enabled)
var enabled = SettingsData.getPluginSetting(manifest.id, "enabled", true)
var enabled = SettingsData.getPluginSetting(manifest.id, "enabled", false)
if (enabled) {
loadPlugin(manifest.id)
}
@@ -156,7 +177,10 @@ Singleton {
pluginInfo.loaded = false
pluginInfo.type = manifest.type || "widget"
availablePlugins[manifest.id] = pluginInfo
var newPlugins = Object.assign({}, availablePlugins)
newPlugins[manifest.id] = pluginInfo
availablePlugins = newPlugins
foundPlugins[manifest.id] = true
}
function hasPermission(pluginId, permission) {
@@ -168,6 +192,27 @@ Singleton {
return permissions.indexOf(permission) !== -1
}
function cleanupRemovedPlugins() {
var pluginsToRemove = []
for (var pluginId in availablePlugins) {
if (!foundPlugins[pluginId]) {
pluginsToRemove.push(pluginId)
}
}
if (pluginsToRemove.length > 0) {
var newPlugins = Object.assign({}, availablePlugins)
for (var i = 0; i < pluginsToRemove.length; i++) {
var pluginId = pluginsToRemove[i]
if (isPluginLoaded(pluginId)) {
unloadPlugin(pluginId)
}
delete newPlugins[pluginId]
}
availablePlugins = newPlugins
}
}
function loadPlugin(pluginId) {
var plugin = availablePlugins[pluginId]
if (!plugin) {
@@ -184,14 +229,15 @@ Singleton {
var componentMap = isDaemon ? pluginDaemonComponents : pluginWidgetComponents
if (componentMap[pluginId]) {
var oldComponent = componentMap[pluginId]
if (oldComponent) {
oldComponent.destroy()
}
componentMap[pluginId]?.destroy()
if (isDaemon) {
delete pluginDaemonComponents[pluginId]
var newDaemons = Object.assign({}, pluginDaemonComponents)
delete newDaemons[pluginId]
pluginDaemonComponents = newDaemons
} else {
delete pluginWidgetComponents[pluginId]
var newComponents = Object.assign({}, pluginWidgetComponents)
delete newComponents[pluginId]
pluginWidgetComponents = newComponents
}
}
@@ -204,7 +250,6 @@ Singleton {
if (component.status === Component.Error) {
console.error("PluginService: Failed to create component for plugin:", pluginId, "Error:", component.errorString())
pluginLoadFailed(pluginId, component.errorString())
component.destroy()
}
})
}
@@ -212,7 +257,6 @@ Singleton {
if (component.status === Component.Error) {
console.error("PluginService: Failed to create component for plugin:", pluginId, "Error:", component.errorString())
pluginLoadFailed(pluginId, component.errorString())
component.destroy()
return false
}
@@ -250,18 +294,12 @@ Singleton {
var isDaemon = plugin.type === "daemon"
if (isDaemon && pluginDaemonComponents[pluginId]) {
var daemonComponent = pluginDaemonComponents[pluginId]
if (daemonComponent) {
daemonComponent.destroy()
}
pluginDaemonComponents[pluginId]?.destroy()
var newDaemons = Object.assign({}, pluginDaemonComponents)
delete newDaemons[pluginId]
pluginDaemonComponents = newDaemons
} else if (pluginWidgetComponents[pluginId]) {
var component = pluginWidgetComponents[pluginId]
if (component) {
component.destroy()
}
pluginWidgetComponents[pluginId]?.destroy()
var newComponents = Object.assign({}, pluginWidgetComponents)
delete newComponents[pluginId]
pluginWidgetComponents = newComponents