From 3a365f68078b8dfea123ac0b6e2f8d51084aa072 Mon Sep 17 00:00:00 2001 From: bbedward Date: Tue, 25 Nov 2025 10:33:32 -0500 Subject: [PATCH] settings: make plugin browser and widget browser floating --- quickshell/Modules/Settings/DankBarTab.qml | 602 +++++----- .../Modules/Settings/PersonalizationTab.qml | 5 +- quickshell/Modules/Settings/PluginBrowser.qml | 1030 ++++++++--------- quickshell/Modules/Settings/PluginsTab.qml | 15 +- .../Modules/Settings/WidgetSelectionPopup.qml | 444 +++---- .../Modules/Settings/WidgetTweaksTab.qml | 2 +- 6 files changed, 1040 insertions(+), 1058 deletions(-) diff --git a/quickshell/Modules/Settings/DankBarTab.qml b/quickshell/Modules/Settings/DankBarTab.qml index bc916ae3..4acafc16 100644 --- a/quickshell/Modules/Settings/DankBarTab.qml +++ b/quickshell/Modules/Settings/DankBarTab.qml @@ -194,9 +194,9 @@ Item { // ! Hacky workaround because we want to re-register any vertical bars after changing a hBar // ! That allows them to re-make with the right exclusiveZone function notifyHorizontalBarChange() { - if (!selectedBarIsVertical) { - horizontalBarChangeDebounce.restart(); - } + if (selectedBarIsVertical) + return; + horizontalBarChangeDebounce.restart(); } function createNewBar() { @@ -290,38 +290,44 @@ Item { } function getWidgetsForSection(sectionId) { - if (sectionId === "left") + switch (sectionId) { + case "left": return selectedBarConfig?.leftWidgets || []; - if (sectionId === "center") + case "center": return selectedBarConfig?.centerWidgets || []; - if (sectionId === "right") + case "right": return selectedBarConfig?.rightWidgets || []; - return []; + default: + return []; + } } function setWidgetsForSection(sectionId, widgets) { - if (sectionId === "left") + switch (sectionId) { + case "left": SettingsData.updateBarConfig(selectedBarId, { leftWidgets: widgets }); - else if (sectionId === "center") + break; + case "center": SettingsData.updateBarConfig(selectedBarId, { centerWidgets: widgets }); - else if (sectionId === "right") + break; + case "right": SettingsData.updateBarConfig(selectedBarId, { rightWidgets: widgets }); + break; + } } function getWidgetsForPopup() { return baseWidgetDefinitions.filter(widget => { - if (widget.warning && widget.warning.includes("Plugin is disabled")) { + if (widget.warning && widget.warning.includes("Plugin is disabled")) return false; - } - if (widget.enabled === false) { + if (widget.enabled === false) return false; - } return true; }); } @@ -646,36 +652,38 @@ Item { for (var i = 0; i < widgets.length; i++) { var widget = widgets[i]; var widgetId = typeof widget === "string" ? widget : widget.id; - if (widgetId === itemId) { - if (typeof widget === "string") { - widgets[i] = { - "id": widget, - "enabled": enabled - }; - } else { - var newWidget = { - "id": widget.id, - "enabled": enabled - }; - if (widget.size !== undefined) - newWidget.size = widget.size; - if (widget.selectedGpuIndex !== undefined) - newWidget.selectedGpuIndex = widget.selectedGpuIndex; - else if (widget.id === "gpuTemp") - newWidget.selectedGpuIndex = 0; - if (widget.pciId !== undefined) - newWidget.pciId = widget.pciId; - else if (widget.id === "gpuTemp") - newWidget.pciId = ""; - 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[i] = newWidget; - } + if (widgetId !== itemId) + continue; + + if (typeof widget === "string") { + widgets[i] = { + "id": widget, + "enabled": enabled + }; break; } + + var newWidget = { + "id": widget.id, + "enabled": enabled + }; + if (widget.size !== undefined) + newWidget.size = widget.size; + if (widget.selectedGpuIndex !== undefined) + newWidget.selectedGpuIndex = widget.selectedGpuIndex; + else if (widget.id === "gpuTemp") + newWidget.selectedGpuIndex = 0; + if (widget.pciId !== undefined) + newWidget.pciId = widget.pciId; + else if (widget.id === "gpuTemp") + newWidget.pciId = ""; + if (widget.id === "controlCenterButton") { + newWidget.showNetworkIcon = widget.showNetworkIcon ?? true; + newWidget.showBluetoothIcon = widget.showBluetoothIcon ?? true; + newWidget.showAudioIcon = widget.showAudioIcon ?? true; + } + widgets[i] = newWidget; + break; } setWidgetsForSection(sectionId, widgets); } @@ -686,227 +694,251 @@ Item { function handleSpacerSizeChanged(sectionId, widgetIndex, newSize) { var widgets = getWidgetsForSection(sectionId).slice(); - - if (widgetIndex >= 0 && widgetIndex < widgets.length) { - var widget = widgets[widgetIndex]; - var widgetId = typeof widget === "string" ? widget : widget.id; - if (widgetId === "spacer") { - if (typeof widget === "string") { - widgets[widgetIndex] = { - "id": widget, - "enabled": true, - "size": newSize - }; - } else { - var newWidget = { - "id": widget.id, - "enabled": widget.enabled, - "size": newSize - }; - if (widget.selectedGpuIndex !== undefined) - newWidget.selectedGpuIndex = widget.selectedGpuIndex; - if (widget.pciId !== undefined) - newWidget.pciId = widget.pciId; - 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 (widgetIndex < 0 || widgetIndex >= widgets.length) { + setWidgetsForSection(sectionId, widgets); + return; } + var widget = widgets[widgetIndex]; + var widgetId = typeof widget === "string" ? widget : widget.id; + if (widgetId !== "spacer") { + setWidgetsForSection(sectionId, widgets); + return; + } + + if (typeof widget === "string") { + widgets[widgetIndex] = { + "id": widget, + "enabled": true, + "size": newSize + }; + setWidgetsForSection(sectionId, widgets); + return; + } + + var newWidget = { + "id": widget.id, + "enabled": widget.enabled, + "size": newSize + }; + if (widget.selectedGpuIndex !== undefined) + newWidget.selectedGpuIndex = widget.selectedGpuIndex; + if (widget.pciId !== undefined) + newWidget.pciId = widget.pciId; + if (widget.id === "controlCenterButton") { + newWidget.showNetworkIcon = widget.showNetworkIcon ?? true; + newWidget.showBluetoothIcon = widget.showBluetoothIcon ?? true; + newWidget.showAudioIcon = widget.showAudioIcon ?? true; + } + widgets[widgetIndex] = newWidget; setWidgetsForSection(sectionId, widgets); } function handleGpuSelectionChanged(sectionId, widgetIndex, selectedGpuIndex) { var widgets = getWidgetsForSection(sectionId).slice(); - - if (widgetIndex >= 0 && widgetIndex < widgets.length) { - var widget = widgets[widgetIndex]; - if (typeof widget === "string") { - widgets[widgetIndex] = { - "id": widget, - "enabled": true, - "selectedGpuIndex": selectedGpuIndex, - "pciId": DgopService.availableGpus && DgopService.availableGpus.length > selectedGpuIndex ? DgopService.availableGpus[selectedGpuIndex].pciId : "" - }; - } else { - var newWidget = { - "id": widget.id, - "enabled": widget.enabled, - "selectedGpuIndex": selectedGpuIndex, - "pciId": DgopService.availableGpus && DgopService.availableGpus.length > selectedGpuIndex ? DgopService.availableGpus[selectedGpuIndex].pciId : "" - }; - if (widget.size !== undefined) - newWidget.size = widget.size; - widgets[widgetIndex] = newWidget; - } + if (widgetIndex < 0 || widgetIndex >= widgets.length) { + setWidgetsForSection(sectionId, widgets); + return; } + var pciId = DgopService.availableGpus && DgopService.availableGpus.length > selectedGpuIndex ? DgopService.availableGpus[selectedGpuIndex].pciId : ""; + var widget = widgets[widgetIndex]; + if (typeof widget === "string") { + widgets[widgetIndex] = { + "id": widget, + "enabled": true, + "selectedGpuIndex": selectedGpuIndex, + "pciId": pciId + }; + setWidgetsForSection(sectionId, widgets); + return; + } + + var newWidget = { + "id": widget.id, + "enabled": widget.enabled, + "selectedGpuIndex": selectedGpuIndex, + "pciId": pciId + }; + if (widget.size !== undefined) + newWidget.size = widget.size; + widgets[widgetIndex] = newWidget; setWidgetsForSection(sectionId, widgets); } function handleDiskMountSelectionChanged(sectionId, widgetIndex, mountPath) { var widgets = getWidgetsForSection(sectionId).slice(); - - if (widgetIndex >= 0 && widgetIndex < widgets.length) { - var widget = widgets[widgetIndex]; - if (typeof widget === "string") { - widgets[widgetIndex] = { - "id": widget, - "enabled": true, - "mountPath": mountPath - }; - } else { - var newWidget = { - "id": widget.id, - "enabled": widget.enabled, - "mountPath": mountPath - }; - 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.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 (widgetIndex < 0 || widgetIndex >= widgets.length) { + setWidgetsForSection(sectionId, widgets); + return; } + var widget = widgets[widgetIndex]; + if (typeof widget === "string") { + widgets[widgetIndex] = { + "id": widget, + "enabled": true, + "mountPath": mountPath + }; + setWidgetsForSection(sectionId, widgets); + return; + } + + var newWidget = { + "id": widget.id, + "enabled": widget.enabled, + "mountPath": mountPath + }; + 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.id === "controlCenterButton") { + newWidget.showNetworkIcon = widget.showNetworkIcon ?? true; + newWidget.showBluetoothIcon = widget.showBluetoothIcon ?? true; + newWidget.showAudioIcon = widget.showAudioIcon ?? true; + } + widgets[widgetIndex] = newWidget; + setWidgetsForSection(sectionId, widgets); } function handleControlCenterSettingChanged(sectionId, widgetIndex, settingName, value) { switch (settingName) { case "showNetworkIcon": - SettingsData.set("controlCenterShowNetworkIcon", value) - break + SettingsData.set("controlCenterShowNetworkIcon", value); + break; case "showBluetoothIcon": - SettingsData.set("controlCenterShowBluetoothIcon", value) - break + SettingsData.set("controlCenterShowBluetoothIcon", value); + break; case "showAudioIcon": - SettingsData.set("controlCenterShowAudioIcon", value) - break + SettingsData.set("controlCenterShowAudioIcon", value); + break; case "showVpnIcon": - SettingsData.set("controlCenterShowVpnIcon", value) - break + SettingsData.set("controlCenterShowVpnIcon", value); + break; case "showBrightnessIcon": - SettingsData.set("controlCenterShowBrightnessIcon", value) - break + SettingsData.set("controlCenterShowBrightnessIcon", value); + break; case "showMicIcon": - SettingsData.set("controlCenterShowMicIcon", value) - break + SettingsData.set("controlCenterShowMicIcon", value); + break; case "showBatteryIcon": - SettingsData.set("controlCenterShowBatteryIcon", value) - break + SettingsData.set("controlCenterShowBatteryIcon", value); + break; case "showPrinterIcon": - SettingsData.set("controlCenterShowPrinterIcon", value) - break + SettingsData.set("controlCenterShowPrinterIcon", value); + break; } } function handlePrivacySettingChanged(sectionId, widgetIndex, settingName, value) { - if (settingName === "showMicIcon") { + switch (settingName) { + case "showMicIcon": SettingsData.set("privacyShowMicIcon", value); - } else if (settingName === "showCameraIcon") { + break; + case "showCameraIcon": SettingsData.set("privacyShowCameraIcon", value); - } else if (settingName === "showScreenSharingIcon") { + break; + case "showScreenSharingIcon": SettingsData.set("privacyShowScreenShareIcon", value); + break; } } function handleMinimumWidthChanged(sectionId, widgetIndex, enabled) { var widgets = getWidgetsForSection(sectionId).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.showSwap !== undefined) - newWidget.showSwap = widget.showSwap; - 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 (widgetIndex < 0 || widgetIndex >= widgets.length) { + setWidgetsForSection(sectionId, widgets); + return; } + var widget = widgets[widgetIndex]; + if (typeof widget === "string") { + widgets[widgetIndex] = { + "id": widget, + "enabled": true, + "minimumWidth": enabled + }; + setWidgetsForSection(sectionId, widgets); + return; + } + + 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.showSwap !== undefined) + newWidget.showSwap = widget.showSwap; + if (widget.id === "controlCenterButton") { + newWidget.showNetworkIcon = widget.showNetworkIcon ?? true; + newWidget.showBluetoothIcon = widget.showBluetoothIcon ?? true; + newWidget.showAudioIcon = widget.showAudioIcon ?? true; + } + widgets[widgetIndex] = newWidget; setWidgetsForSection(sectionId, widgets); } function handleShowSwapChanged(sectionId, widgetIndex, enabled) { var widgets = getWidgetsForSection(sectionId).slice(); - - if (widgetIndex >= 0 && widgetIndex < widgets.length) { - var widget = widgets[widgetIndex]; - if (typeof widget === "string") { - widgets[widgetIndex] = { - "id": widget, - "enabled": true, - "showSwap": enabled - }; - } else { - var newWidget = { - "id": widget.id, - "enabled": widget.enabled, - "showSwap": 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.minimumWidth !== undefined) - newWidget.minimumWidth = widget.minimumWidth; - if (widget.mediaSize !== undefined) - newWidget.mediaSize = widget.mediaSize; - if (widget.clockCompactMode !== undefined) - newWidget.clockCompactMode = widget.clockCompactMode; - if (widget.focusedWindowCompactMode !== undefined) - newWidget.focusedWindowCompactMode = widget.focusedWindowCompactMode; - if (widget.runningAppsCompactMode !== undefined) - newWidget.runningAppsCompactMode = widget.runningAppsCompactMode; - if (widget.keyboardLayoutNameCompactMode !== undefined) - newWidget.keyboardLayoutNameCompactMode = widget.keyboardLayoutNameCompactMode; - 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 (widgetIndex < 0 || widgetIndex >= widgets.length) { + setWidgetsForSection(sectionId, widgets); + return; } + var widget = widgets[widgetIndex]; + if (typeof widget === "string") { + widgets[widgetIndex] = { + "id": widget, + "enabled": true, + "showSwap": enabled + }; + setWidgetsForSection(sectionId, widgets); + return; + } + + var newWidget = { + "id": widget.id, + "enabled": widget.enabled, + "showSwap": 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.minimumWidth !== undefined) + newWidget.minimumWidth = widget.minimumWidth; + if (widget.mediaSize !== undefined) + newWidget.mediaSize = widget.mediaSize; + if (widget.clockCompactMode !== undefined) + newWidget.clockCompactMode = widget.clockCompactMode; + if (widget.focusedWindowCompactMode !== undefined) + newWidget.focusedWindowCompactMode = widget.focusedWindowCompactMode; + if (widget.runningAppsCompactMode !== undefined) + newWidget.runningAppsCompactMode = widget.runningAppsCompactMode; + if (widget.keyboardLayoutNameCompactMode !== undefined) + newWidget.keyboardLayoutNameCompactMode = widget.keyboardLayoutNameCompactMode; + if (widget.id === "controlCenterButton") { + newWidget.showNetworkIcon = widget.showNetworkIcon ?? true; + newWidget.showBluetoothIcon = widget.showBluetoothIcon ?? true; + newWidget.showAudioIcon = widget.showAudioIcon ?? true; + } + widgets[widgetIndex] = newWidget; setWidgetsForSection(sectionId, widgets); } @@ -932,7 +964,6 @@ Item { "id": widget.id, "enabled": widget.enabled }; - if (widget.size !== undefined) newWidget.size = widget.size; if (widget.selectedGpuIndex !== undefined) @@ -956,11 +987,10 @@ Item { if (widget.keyboardLayoutNameCompactMode !== undefined) newWidget.keyboardLayoutNameCompactMode = widget.keyboardLayoutNameCompactMode; 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; + newWidget.showNetworkIcon = widget.showNetworkIcon ?? true; + newWidget.showBluetoothIcon = widget.showBluetoothIcon ?? true; + newWidget.showAudioIcon = widget.showAudioIcon ?? true; } - widgets[i] = newWidget; widget = newWidget; } @@ -993,59 +1023,45 @@ Item { var widgets = []; var widgetData = getWidgetsForSection(sectionId); widgetData.forEach(widget => { - 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 widgetPciId = typeof widget === "string" ? undefined : widget.pciId; - var widgetMountPath = typeof widget === "string" ? undefined : widget.mountPath; - 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 widgetShowSwap = typeof widget === "string" ? undefined : widget.showSwap; - var widgetMediaSize = typeof widget === "string" ? undefined : widget.mediaSize; - var widgetClockCompactMode = typeof widget === "string" ? undefined : widget.clockCompactMode; - var widgetFocusedWindowCompactMode = typeof widget === "string" ? undefined : widget.focusedWindowCompactMode; - var widgetRunningAppsCompactMode = typeof widget === "string" ? undefined : widget.runningAppsCompactMode; - var widgetKeyboardLayoutNameCompactMode = typeof widget === "string" ? undefined : widget.keyboardLayoutNameCompactMode; - var widgetDef = baseWidgetDefinitions.find(w => { - return w.id === widgetId; - }); - if (widgetDef) { - var item = Object.assign({}, widgetDef); - item.enabled = widgetEnabled; - if (widgetSize !== undefined) - item.size = widgetSize; - if (widgetSelectedGpuIndex !== undefined) - item.selectedGpuIndex = widgetSelectedGpuIndex; - if (widgetPciId !== undefined) - item.pciId = widgetPciId; - if (widgetMountPath !== undefined) - item.mountPath = widgetMountPath; - if (widgetShowNetworkIcon !== undefined) - item.showNetworkIcon = widgetShowNetworkIcon; - if (widgetShowBluetoothIcon !== undefined) - item.showBluetoothIcon = widgetShowBluetoothIcon; - if (widgetShowAudioIcon !== undefined) - item.showAudioIcon = widgetShowAudioIcon; - if (widgetMinimumWidth !== undefined) - item.minimumWidth = widgetMinimumWidth; - if (widgetShowSwap !== undefined) - item.showSwap = widgetShowSwap; - if (widgetMediaSize !== undefined) - item.mediaSize = widgetMediaSize; - if (widgetClockCompactMode !== undefined) - item.clockCompactMode = widgetClockCompactMode; - if (widgetFocusedWindowCompactMode !== undefined) - item.focusedWindowCompactMode = widgetFocusedWindowCompactMode; - if (widgetRunningAppsCompactMode !== undefined) - item.runningAppsCompactMode = widgetRunningAppsCompactMode; - if (widgetKeyboardLayoutNameCompactMode !== undefined) - item.keyboardLayoutNameCompactMode = widgetKeyboardLayoutNameCompactMode; + var isString = typeof widget === "string"; + var widgetId = isString ? widget : widget.id; + var widgetDef = baseWidgetDefinitions.find(w => w.id === widgetId); + if (!widgetDef) + return; - widgets.push(item); + var item = Object.assign({}, widgetDef); + item.enabled = isString ? true : widget.enabled; + if (!isString) { + if (widget.size !== undefined) + item.size = widget.size; + if (widget.selectedGpuIndex !== undefined) + item.selectedGpuIndex = widget.selectedGpuIndex; + if (widget.pciId !== undefined) + item.pciId = widget.pciId; + if (widget.mountPath !== undefined) + item.mountPath = widget.mountPath; + if (widget.showNetworkIcon !== undefined) + item.showNetworkIcon = widget.showNetworkIcon; + if (widget.showBluetoothIcon !== undefined) + item.showBluetoothIcon = widget.showBluetoothIcon; + if (widget.showAudioIcon !== undefined) + item.showAudioIcon = widget.showAudioIcon; + if (widget.minimumWidth !== undefined) + item.minimumWidth = widget.minimumWidth; + if (widget.showSwap !== undefined) + item.showSwap = widget.showSwap; + if (widget.mediaSize !== undefined) + item.mediaSize = widget.mediaSize; + if (widget.clockCompactMode !== undefined) + item.clockCompactMode = widget.clockCompactMode; + if (widget.focusedWindowCompactMode !== undefined) + item.focusedWindowCompactMode = widget.focusedWindowCompactMode; + if (widget.runningAppsCompactMode !== undefined) + item.runningAppsCompactMode = widget.runningAppsCompactMode; + if (widget.keyboardLayoutNameCompactMode !== undefined) + item.keyboardLayoutNameCompactMode = widget.keyboardLayoutNameCompactMode; } + widgets.push(item); }); return widgets; } @@ -1139,49 +1155,13 @@ Item { implicitHeight: 1 } - Rectangle { - id: addBarBtn - width: 100 - height: 32 - radius: Theme.cornerRadius - color: addBarArea.containsMouse ? Theme.primaryPressed : Theme.primary + DankButton { + text: I18n.tr("Add Bar") + iconName: "add" + buttonHeight: 32 visible: SettingsData.barConfigs.length < 4 Layout.alignment: Qt.AlignVCenter - - Row { - anchors.centerIn: parent - spacing: Theme.spacingXS - - DankIcon { - name: "add" - size: 14 - color: Theme.onPrimary - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: I18n.tr("Add Bar") - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.Medium - color: Theme.onPrimary - anchors.verticalCenter: parent.verticalCenter - } - } - - MouseArea { - id: addBarArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: dankBarTab.createNewBar() - } - - Behavior on color { - ColorAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } + onClicked: dankBarTab.createNewBar() } } @@ -3284,7 +3264,6 @@ Item { } } - // Center/Middle Section StyledRect { width: parent.width height: centerSection.implicitHeight + Theme.spacingL * 2 @@ -3343,7 +3322,6 @@ Item { } } - // Right/Bottom Section StyledRect { width: parent.width height: rightSection.implicitHeight + Theme.spacingL * 2 diff --git a/quickshell/Modules/Settings/PersonalizationTab.qml b/quickshell/Modules/Settings/PersonalizationTab.qml index 1cbdd178..c1571bb4 100644 --- a/quickshell/Modules/Settings/PersonalizationTab.qml +++ b/quickshell/Modules/Settings/PersonalizationTab.qml @@ -1,10 +1,7 @@ -import QtCore import QtQuick -import QtQuick.Controls import QtQuick.Effects import Quickshell import qs.Common -import qs.Modals import qs.Modals.FileBrowser import qs.Services import qs.Widgets @@ -1542,7 +1539,7 @@ Item { anchors.verticalCenter: parent.verticalCenter checked: SessionData.isLightMode - onToggleCompleted: checked => { + onToggled: checked => { Theme.screenTransition(); Theme.setLightMode(checked); } diff --git a/quickshell/Modules/Settings/PluginBrowser.qml b/quickshell/Modules/Settings/PluginBrowser.qml index 698b62d4..cdad73df 100644 --- a/quickshell/Modules/Settings/PluginBrowser.qml +++ b/quickshell/Modules/Settings/PluginBrowser.qml @@ -2,11 +2,10 @@ import QtQuick import QtQuick.Controls import Quickshell import qs.Common -import qs.Modals.Common import qs.Services import qs.Widgets -DankModal { +FloatingWindow { id: root property var allPlugins: [] @@ -17,12 +16,6 @@ DankModal { property bool isLoading: false property var parentModal: null - modalWidth: 600 - modalHeight: 650 - allowStacking: true - backgroundOpacity: 0 - closeOnEscapeKey: false - function updateFilteredPlugins() { var filtered = []; var query = searchQuery ? searchQuery.toLowerCase() : ""; @@ -31,21 +24,20 @@ DankModal { var plugin = allPlugins[i]; var isFirstParty = plugin.firstParty || false; - if (!SessionData.showThirdPartyPlugins && !isFirstParty) { + if (!SessionData.showThirdPartyPlugins && !isFirstParty) + continue; + + if (query.length === 0) { + filtered.push(plugin); continue; } - if (query.length > 0) { - var name = plugin.name ? plugin.name.toLowerCase() : ""; - var description = plugin.description ? plugin.description.toLowerCase() : ""; - var author = plugin.author ? plugin.author.toLowerCase() : ""; + var name = plugin.name ? plugin.name.toLowerCase() : ""; + var description = plugin.description ? plugin.description.toLowerCase() : ""; + var author = plugin.author ? plugin.author.toLowerCase() : ""; - if (name.indexOf(query) !== -1 || description.indexOf(query) !== -1 || author.indexOf(query) !== -1) { - filtered.push(plugin); - } - } else { + if (name.indexOf(query) !== -1 || description.indexOf(query) !== -1 || author.indexOf(query) !== -1) filtered.push(plugin); - } } filteredPlugins = filtered; @@ -65,9 +57,8 @@ DankModal { return; keyboardNavigationActive = true; selectedIndex = Math.max(selectedIndex - 1, -1); - if (selectedIndex === -1) { + if (selectedIndex === -1) keyboardNavigationActive = false; - } } function installPlugin(pluginName) { @@ -75,64 +66,56 @@ DankModal { DMSService.install(pluginName, response => { if (response.error) { ToastService.showError("Install failed: " + response.error); - } else { - ToastService.showInfo("Plugin installed: " + pluginName); - PluginService.scanPlugins(); - refreshPlugins(); + return; } + ToastService.showInfo("Plugin installed: " + pluginName); + PluginService.scanPlugins(); + refreshPlugins(); }); } function refreshPlugins() { isLoading = true; DMSService.listPlugins(); - if (DMSService.apiVersion >= 8) { + if (DMSService.apiVersion >= 8) DMSService.listInstalled(); - } } function show() { - if (parentModal) { + if (parentModal) parentModal.shouldHaveFocus = false; - } - open(); + visible = true; Qt.callLater(() => { - if (contentLoader.item && contentLoader.item.searchField) { - contentLoader.item.searchField.forceActiveFocus(); - } + browserSearchField.forceActiveFocus(); }); } function hide() { - close(); - if (parentModal) { - parentModal.shouldHaveFocus = Qt.binding(() => { - return parentModal.shouldBeVisible; - }); + visible = false; + if (!parentModal) + return; + parentModal.shouldHaveFocus = Qt.binding(() => parentModal.shouldBeVisible); + Qt.callLater(() => { + if (parentModal.modalFocusScope) + parentModal.modalFocusScope.forceActiveFocus(); + }); + } + + objectName: "pluginBrowser" + title: I18n.tr("Browse Plugins") + implicitWidth: 600 + implicitHeight: 650 + color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) + visible: false + + onVisibleChanged: { + if (visible) { + refreshPlugins(); Qt.callLater(() => { - if (parentModal.modalFocusScope) { - parentModal.modalFocusScope.forceActiveFocus(); - } + browserSearchField.forceActiveFocus(); }); + return; } - } - - onOpened: { - refreshPlugins(); - } - - Connections { - target: contentLoader - function onLoaded() { - Qt.callLater(() => { - if (contentLoader.item && contentLoader.item.searchField) { - contentLoader.item.searchField.forceActiveFocus(); - } - }); - } - } - - onDialogClosed: () => { allPlugins = []; searchQuery = ""; filteredPlugins = []; @@ -141,519 +124,524 @@ DankModal { isLoading = false; } - onBackgroundClicked: () => { - hide(); - } + FocusScope { + id: browserKeyHandler - content: Component { - FocusScope { - id: browserKeyHandler - property alias searchField: browserSearchField + anchors.fill: parent + focus: true + Keys.onPressed: event => { + switch (event.key) { + case Qt.Key_Escape: + root.hide(); + event.accepted = true; + return; + case Qt.Key_Down: + root.selectNext(); + event.accepted = true; + return; + case Qt.Key_Up: + root.selectPrevious(); + event.accepted = true; + return; + } + } + + Item { + id: browserContent anchors.fill: parent - focus: true + anchors.margins: Theme.spacingL - Component.onCompleted: { - browserSearchField.forceActiveFocus(); + Item { + id: headerArea + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + height: Math.max(headerIcon.height, headerText.height, refreshButton.height, closeButton.height) + + DankIcon { + id: headerIcon + name: "store" + size: Theme.iconSize + color: Theme.primary + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + id: headerText + text: I18n.tr("Browse Plugins") + font.pixelSize: Theme.fontSizeLarge + font.weight: Font.Medium + color: Theme.surfaceText + anchors.left: headerIcon.right + anchors.leftMargin: Theme.spacingM + anchors.verticalCenter: parent.verticalCenter + } + + Row { + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingXS + + DankButton { + id: thirdPartyButton + text: SessionData.showThirdPartyPlugins ? "Hide 3rd Party" : "Show 3rd Party" + iconName: SessionData.showThirdPartyPlugins ? "visibility_off" : "visibility" + height: 28 + onClicked: { + if (SessionData.showThirdPartyPlugins) { + SessionData.setShowThirdPartyPlugins(false); + root.updateFilteredPlugins(); + return; + } + thirdPartyConfirmModal.visible = true; + } + } + + DankActionButton { + id: refreshButton + iconName: "refresh" + iconSize: 18 + iconColor: Theme.primary + visible: !root.isLoading + onClicked: root.refreshPlugins() + } + + DankActionButton { + id: closeButton + iconName: "close" + iconSize: Theme.iconSize - 2 + iconColor: Theme.outline + onClicked: root.hide() + } + } } - Keys.onPressed: event => { - if (event.key === Qt.Key_Escape) { - root.close(); - event.accepted = true; - } else if (event.key === Qt.Key_Down) { - root.selectNext(); - event.accepted = true; - } else if (event.key === Qt.Key_Up) { - root.selectPrevious(); - event.accepted = true; + StyledText { + id: descriptionText + anchors.left: parent.left + anchors.right: parent.right + anchors.top: headerArea.bottom + anchors.topMargin: Theme.spacingM + text: I18n.tr("Install plugins from the DMS plugin registry") + font.pixelSize: Theme.fontSizeSmall + color: Theme.outline + wrapMode: Text.WordWrap + } + + DankTextField { + id: browserSearchField + anchors.left: parent.left + anchors.right: parent.right + anchors.top: descriptionText.bottom + anchors.topMargin: Theme.spacingM + height: 48 + cornerRadius: Theme.cornerRadius + backgroundColor: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) + normalBorderColor: Theme.outlineMedium + focusedBorderColor: Theme.primary + leftIconName: "search" + leftIconSize: Theme.iconSize + leftIconColor: Theme.surfaceVariantText + leftIconFocusedColor: Theme.primary + showClearButton: true + textColor: Theme.surfaceText + font.pixelSize: Theme.fontSizeMedium + placeholderText: I18n.tr("Search plugins...") + text: root.searchQuery + focus: true + ignoreLeftRightKeys: true + keyForwardTargets: [browserKeyHandler] + onTextEdited: { + root.searchQuery = text; + root.updateFilteredPlugins(); } } Item { - id: browserContent - anchors.fill: parent - anchors.margins: Theme.spacingL + id: listArea + anchors.left: parent.left + anchors.right: parent.right + anchors.top: browserSearchField.bottom + anchors.topMargin: Theme.spacingM + anchors.bottom: parent.bottom + anchors.bottomMargin: Theme.spacingM Item { - id: headerArea - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: Math.max(headerIcon.height, headerText.height, refreshButton.height, closeButton.height) + anchors.fill: parent + visible: root.isLoading - DankIcon { - id: headerIcon - name: "store" - size: Theme.iconSize - color: Theme.primary - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - } + Column { + anchors.centerIn: parent + spacing: Theme.spacingM - StyledText { - id: headerText - text: I18n.tr("Browse Plugins") - font.pixelSize: Theme.fontSizeLarge - font.weight: Font.Medium - color: Theme.surfaceText - anchors.left: headerIcon.right - anchors.leftMargin: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - } + DankIcon { + name: "sync" + size: 48 + color: Theme.primary + anchors.horizontalCenter: parent.horizontalCenter - Row { - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingXS - - DankButton { - id: thirdPartyButton - text: SessionData.showThirdPartyPlugins ? "Hide 3rd Party" : "Show 3rd Party" - iconName: SessionData.showThirdPartyPlugins ? "visibility_off" : "visibility" - height: 28 - onClicked: { - if (SessionData.showThirdPartyPlugins) { - SessionData.setShowThirdPartyPlugins(false); - root.updateFilteredPlugins(); - } else { - thirdPartyConfirmModal.open(); - } + RotationAnimator on rotation { + from: 0 + to: 360 + duration: 1000 + loops: Animation.Infinite + running: root.isLoading } } - DankActionButton { - id: refreshButton - iconName: "refresh" - iconSize: 18 - iconColor: Theme.primary - visible: !root.isLoading - onClicked: root.refreshPlugins() + StyledText { + text: I18n.tr("Loading plugins...") + font.pixelSize: Theme.fontSizeMedium + color: Theme.surfaceVariantText + anchors.horizontalCenter: parent.horizontalCenter } + } + } - DankActionButton { - id: closeButton - iconName: "close" - iconSize: Theme.iconSize - 2 - iconColor: Theme.outline - onClicked: root.close() + DankListView { + id: pluginBrowserList + + anchors.fill: parent + anchors.leftMargin: Theme.spacingM + anchors.rightMargin: Theme.spacingM + anchors.topMargin: Theme.spacingS + anchors.bottomMargin: Theme.spacingS + spacing: Theme.spacingS + model: ScriptModel { + values: root.filteredPlugins + } + clip: true + visible: !root.isLoading + + ScrollBar.vertical: DankScrollbar { + id: browserScrollbar + } + + delegate: Rectangle { + width: pluginBrowserList.width + height: pluginDelegateColumn.implicitHeight + Theme.spacingM * 2 + radius: Theme.cornerRadius + property bool isSelected: root.keyboardNavigationActive && index === root.selectedIndex + property bool isInstalled: modelData.installed || false + property bool isFirstParty: modelData.firstParty || false + color: isSelected ? Theme.primarySelected : Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3) + border.color: isSelected ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2) + border.width: isSelected ? 2 : 1 + + Column { + id: pluginDelegateColumn + anchors.fill: parent + anchors.margins: Theme.spacingM + spacing: Theme.spacingXS + + Row { + width: parent.width + spacing: Theme.spacingM + + DankIcon { + name: modelData.icon || "extension" + size: Theme.iconSize + color: Theme.primary + anchors.verticalCenter: parent.verticalCenter + } + + Column { + width: parent.width - Theme.iconSize - Theme.spacingM - installButton.width - Theme.spacingM + spacing: 2 + + Row { + spacing: Theme.spacingXS + + StyledText { + text: modelData.name + font.pixelSize: Theme.fontSizeMedium + font.weight: Font.Medium + color: Theme.surfaceText + elide: Text.ElideRight + anchors.verticalCenter: parent.verticalCenter + } + + Rectangle { + height: 16 + width: firstPartyText.implicitWidth + Theme.spacingXS * 2 + radius: 8 + color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.15) + border.color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.4) + border.width: 1 + visible: isFirstParty + anchors.verticalCenter: parent.verticalCenter + + StyledText { + id: firstPartyText + anchors.centerIn: parent + text: I18n.tr("official") + font.pixelSize: Theme.fontSizeSmall - 2 + color: Theme.primary + font.weight: Font.Medium + } + } + + Rectangle { + height: 16 + width: thirdPartyText.implicitWidth + Theme.spacingXS * 2 + radius: 8 + color: Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.15) + border.color: Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.4) + border.width: 1 + visible: !isFirstParty + anchors.verticalCenter: parent.verticalCenter + + StyledText { + id: thirdPartyText + anchors.centerIn: parent + text: I18n.tr("3rd party") + font.pixelSize: Theme.fontSizeSmall - 2 + color: Theme.warning + font.weight: Font.Medium + } + } + } + + StyledText { + text: { + const author = "by " + (modelData.author || "Unknown"); + const source = modelData.repo ? ` • source` : ""; + return author + source; + } + font.pixelSize: Theme.fontSizeSmall + color: Theme.outline + linkColor: Theme.primary + textFormat: Text.RichText + elide: Text.ElideRight + width: parent.width + onLinkActivated: url => Qt.openUrlExternally(url) + + MouseArea { + anchors.fill: parent + cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor + acceptedButtons: Qt.NoButton + propagateComposedEvents: true + } + } + } + + Rectangle { + id: installButton + width: 80 + height: 32 + radius: Theme.cornerRadius + anchors.verticalCenter: parent.verticalCenter + color: isInstalled ? Theme.surfaceVariant : Theme.primary + opacity: isInstalled ? 1 : (installMouseArea.containsMouse ? 0.9 : 1) + border.width: isInstalled ? 1 : 0 + border.color: Theme.outline + + Behavior on opacity { + NumberAnimation { + duration: Theme.shortDuration + easing.type: Theme.standardEasing + } + } + + Row { + anchors.centerIn: parent + spacing: Theme.spacingXS + + DankIcon { + name: isInstalled ? "check" : "download" + size: 14 + color: isInstalled ? Theme.surfaceText : Theme.surface + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: isInstalled ? "Installed" : "Install" + font.pixelSize: Theme.fontSizeSmall + font.weight: Font.Medium + color: isInstalled ? Theme.surfaceText : Theme.surface + anchors.verticalCenter: parent.verticalCenter + } + } + + MouseArea { + id: installMouseArea + anchors.fill: parent + hoverEnabled: true + cursorShape: isInstalled ? Qt.ArrowCursor : Qt.PointingHandCursor + enabled: !isInstalled + onClicked: { + if (!isInstalled) + root.installPlugin(modelData.name); + } + } + } + } + + StyledText { + text: modelData.description || "" + font.pixelSize: Theme.fontSizeSmall + color: Theme.outline + width: parent.width + wrapMode: Text.WordWrap + visible: modelData.description && modelData.description.length > 0 + } + + Flow { + width: parent.width + spacing: Theme.spacingXS + visible: modelData.capabilities && modelData.capabilities.length > 0 + + Repeater { + model: modelData.capabilities || [] + + Rectangle { + height: 18 + width: capabilityText.implicitWidth + Theme.spacingXS * 2 + radius: 9 + color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1) + border.color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3) + border.width: 1 + + StyledText { + id: capabilityText + anchors.centerIn: parent + text: modelData + font.pixelSize: Theme.fontSizeSmall - 2 + color: Theme.primary + } + } + } + } } } } StyledText { - id: descriptionText - anchors.left: parent.left - anchors.right: parent.right - anchors.top: headerArea.bottom - anchors.topMargin: Theme.spacingM - text: I18n.tr("Install plugins from the DMS plugin registry") - font.pixelSize: Theme.fontSizeSmall - color: Theme.outline - wrapMode: Text.WordWrap - } - - DankTextField { - id: browserSearchField - anchors.left: parent.left - anchors.right: parent.right - anchors.top: descriptionText.bottom - anchors.topMargin: Theme.spacingM - height: 48 - cornerRadius: Theme.cornerRadius - backgroundColor: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - normalBorderColor: Theme.outlineMedium - focusedBorderColor: Theme.primary - leftIconName: "search" - leftIconSize: Theme.iconSize - leftIconColor: Theme.surfaceVariantText - leftIconFocusedColor: Theme.primary - showClearButton: true - textColor: Theme.surfaceText + anchors.centerIn: listArea + text: I18n.tr("No plugins found") font.pixelSize: Theme.fontSizeMedium - placeholderText: I18n.tr("Search plugins...") - text: root.searchQuery - focus: true - ignoreLeftRightKeys: true - keyForwardTargets: [browserKeyHandler] - onTextEdited: { - root.searchQuery = text; - root.updateFilteredPlugins(); - } - } - - Item { - id: listArea - anchors.left: parent.left - anchors.right: parent.right - anchors.top: browserSearchField.bottom - anchors.topMargin: Theme.spacingM - anchors.bottom: parent.bottom - anchors.bottomMargin: Theme.spacingM - - Item { - anchors.fill: parent - visible: root.isLoading - - Column { - anchors.centerIn: parent - spacing: Theme.spacingM - - DankIcon { - name: "sync" - size: 48 - color: Theme.primary - anchors.horizontalCenter: parent.horizontalCenter - - RotationAnimator on rotation { - from: 0 - to: 360 - duration: 1000 - loops: Animation.Infinite - running: root.isLoading - } - } - - StyledText { - text: I18n.tr("Loading plugins...") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceVariantText - anchors.horizontalCenter: parent.horizontalCenter - } - } - } - - DankListView { - id: pluginBrowserList - - anchors.fill: parent - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - anchors.topMargin: Theme.spacingS - anchors.bottomMargin: Theme.spacingS - spacing: Theme.spacingS - model: ScriptModel { - values: root.filteredPlugins - } - clip: true - visible: !root.isLoading - - ScrollBar.vertical: DankScrollbar { - id: browserScrollbar - } - - delegate: Rectangle { - width: pluginBrowserList.width - height: pluginDelegateColumn.implicitHeight + Theme.spacingM * 2 - radius: Theme.cornerRadius - property bool isSelected: root.keyboardNavigationActive && index === root.selectedIndex - property bool isInstalled: modelData.installed || false - property bool isFirstParty: modelData.firstParty || false - color: isSelected ? Theme.primarySelected : Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3) - border.color: isSelected ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2) - border.width: isSelected ? 2 : 1 - - Column { - id: pluginDelegateColumn - anchors.fill: parent - anchors.margins: Theme.spacingM - spacing: Theme.spacingXS - - Row { - width: parent.width - spacing: Theme.spacingM - - DankIcon { - name: modelData.icon || "extension" - size: Theme.iconSize - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - Column { - width: parent.width - Theme.iconSize - Theme.spacingM - installButton.width - Theme.spacingM - spacing: 2 - - Row { - spacing: Theme.spacingXS - - StyledText { - text: modelData.name - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - color: Theme.surfaceText - elide: Text.ElideRight - anchors.verticalCenter: parent.verticalCenter - } - - Rectangle { - height: 16 - width: firstPartyText.implicitWidth + Theme.spacingXS * 2 - radius: 8 - color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.15) - border.color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.4) - border.width: 1 - visible: isFirstParty - anchors.verticalCenter: parent.verticalCenter - - StyledText { - id: firstPartyText - anchors.centerIn: parent - text: I18n.tr("official") - font.pixelSize: Theme.fontSizeSmall - 2 - color: Theme.primary - font.weight: Font.Medium - } - } - - Rectangle { - height: 16 - width: thirdPartyText.implicitWidth + Theme.spacingXS * 2 - radius: 8 - color: Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.15) - border.color: Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.4) - border.width: 1 - visible: !isFirstParty - anchors.verticalCenter: parent.verticalCenter - - StyledText { - id: thirdPartyText - anchors.centerIn: parent - text: I18n.tr("3rd party") - font.pixelSize: Theme.fontSizeSmall - 2 - color: Theme.warning - font.weight: Font.Medium - } - } - } - - StyledText { - text: { - const author = "by " + (modelData.author || "Unknown"); - const source = modelData.repo ? ` • source` : ""; - return author + source; - } - font.pixelSize: Theme.fontSizeSmall - color: Theme.outline - linkColor: Theme.primary - textFormat: Text.RichText - elide: Text.ElideRight - width: parent.width - onLinkActivated: url => Qt.openUrlExternally(url) - - MouseArea { - anchors.fill: parent - cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor - acceptedButtons: Qt.NoButton - propagateComposedEvents: true - } - } - } - - Rectangle { - id: installButton - width: 80 - height: 32 - radius: Theme.cornerRadius - anchors.verticalCenter: parent.verticalCenter - color: isInstalled ? Theme.surfaceVariant : Theme.primary - opacity: isInstalled ? 1 : (installMouseArea.containsMouse ? 0.9 : 1) - border.width: isInstalled ? 1 : 0 - border.color: Theme.outline - - Behavior on opacity { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - - Row { - anchors.centerIn: parent - spacing: Theme.spacingXS - - DankIcon { - name: isInstalled ? "check" : "download" - size: 14 - color: isInstalled ? Theme.surfaceText : Theme.surface - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: isInstalled ? "Installed" : "Install" - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.Medium - color: isInstalled ? Theme.surfaceText : Theme.surface - anchors.verticalCenter: parent.verticalCenter - } - } - - MouseArea { - id: installMouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: isInstalled ? Qt.ArrowCursor : Qt.PointingHandCursor - enabled: !isInstalled - onClicked: { - if (!isInstalled) { - root.installPlugin(modelData.name); - } - } - } - } - } - - StyledText { - text: modelData.description || "" - font.pixelSize: Theme.fontSizeSmall - color: Theme.outline - width: parent.width - wrapMode: Text.WordWrap - visible: modelData.description && modelData.description.length > 0 - } - - Flow { - width: parent.width - spacing: Theme.spacingXS - visible: modelData.capabilities && modelData.capabilities.length > 0 - - Repeater { - model: modelData.capabilities || [] - - Rectangle { - height: 18 - width: capabilityText.implicitWidth + Theme.spacingXS * 2 - radius: 9 - color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1) - border.color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3) - border.width: 1 - - StyledText { - id: capabilityText - anchors.centerIn: parent - text: modelData - font.pixelSize: Theme.fontSizeSmall - 2 - color: Theme.primary - } - } - } - } - } - } - } - - StyledText { - anchors.centerIn: listArea - text: I18n.tr("No plugins found") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceVariantText - visible: !root.isLoading && root.filteredPlugins.length === 0 - } + color: Theme.surfaceVariantText + visible: !root.isLoading && root.filteredPlugins.length === 0 } } } } - DankModal { + FloatingWindow { id: thirdPartyConfirmModal - modalWidth: 500 - modalHeight: 300 - allowStacking: true - backgroundOpacity: 0.4 - closeOnEscapeKey: true + objectName: "thirdPartyConfirm" + title: I18n.tr("Third-Party Plugin Warning") + implicitWidth: 500 + implicitHeight: 350 + color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) + visible: false - content: Component { - FocusScope { - anchors.fill: parent - focus: true + FocusScope { + anchors.fill: parent + focus: true - Keys.onPressed: event => { - if (event.key === Qt.Key_Escape) { - thirdPartyConfirmModal.close(); - event.accepted = true; - } + Keys.onPressed: event => { + if (event.key === Qt.Key_Escape) { + thirdPartyConfirmModal.visible = false; + event.accepted = true; } + } - Column { - anchors.fill: parent - anchors.margins: Theme.spacingL - spacing: Theme.spacingL + Column { + anchors.fill: parent + anchors.margins: Theme.spacingL + spacing: Theme.spacingL - Row { - width: parent.width - spacing: Theme.spacingM + Row { + width: parent.width + spacing: Theme.spacingM - DankIcon { - name: "warning" - size: Theme.iconSize - color: Theme.warning - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: I18n.tr("Third-Party Plugin Warning") - font.pixelSize: Theme.fontSizeLarge - font.weight: Font.Medium - color: Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } + DankIcon { + name: "warning" + size: Theme.iconSize + color: Theme.warning + anchors.verticalCenter: parent.verticalCenter } StyledText { - width: parent.width - text: I18n.tr("Third-party plugins are created by the community and are not officially supported by DankMaterialShell.\n\nThese plugins may pose security and privacy risks - install at your own risk.") - font.pixelSize: Theme.fontSizeMedium + text: I18n.tr("Third-Party Plugin Warning") + font.pixelSize: Theme.fontSizeLarge + font.weight: Font.Medium color: Theme.surfaceText - wrapMode: Text.WordWrap - } - - Column { - width: parent.width - spacing: Theme.spacingS - - StyledText { - text: I18n.tr("• Plugins may contain bugs or security issues") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - } - - StyledText { - text: I18n.tr("• Review code before installation when possible") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - } - - StyledText { - text: I18n.tr("• Install only from trusted sources") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - } + anchors.verticalCenter: parent.verticalCenter } Item { - width: parent.width - height: parent.height - parent.spacing * 3 - y + width: parent.width - parent.spacing * 2 - Theme.iconSize - parent.children[1].implicitWidth - closeConfirmBtn.width + height: 1 } - Row { - anchors.right: parent.right - spacing: Theme.spacingM + DankActionButton { + id: closeConfirmBtn + iconName: "close" + iconSize: Theme.iconSize - 2 + iconColor: Theme.outline + anchors.verticalCenter: parent.verticalCenter + onClicked: thirdPartyConfirmModal.visible = false + } + } - DankButton { - text: I18n.tr("Cancel") - iconName: "close" - onClicked: thirdPartyConfirmModal.close() - } + StyledText { + width: parent.width + text: I18n.tr("Third-party plugins are created by the community and are not officially supported by DankMaterialShell.\n\nThese plugins may pose security and privacy risks - install at your own risk.") + font.pixelSize: Theme.fontSizeMedium + color: Theme.surfaceText + wrapMode: Text.WordWrap + } - DankButton { - text: I18n.tr("I Understand") - iconName: "check" - onClicked: { - SessionData.setShowThirdPartyPlugins(true); - root.updateFilteredPlugins(); - thirdPartyConfirmModal.close(); - } + Column { + width: parent.width + spacing: Theme.spacingS + + StyledText { + text: I18n.tr("• Plugins may contain bugs or security issues") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceVariantText + } + + StyledText { + text: I18n.tr("• Review code before installation when possible") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceVariantText + } + + StyledText { + text: I18n.tr("• Install only from trusted sources") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceVariantText + } + } + + Item { + width: parent.width + height: parent.height - parent.spacing * 3 - y + } + + Row { + anchors.right: parent.right + spacing: Theme.spacingM + + DankButton { + text: I18n.tr("Cancel") + iconName: "close" + onClicked: thirdPartyConfirmModal.visible = false + } + + DankButton { + text: I18n.tr("I Understand") + iconName: "check" + onClicked: { + SessionData.setShowThirdPartyPlugins(true); + root.updateFilteredPlugins(); + thirdPartyConfirmModal.visible = false; } } } diff --git a/quickshell/Modules/Settings/PluginsTab.qml b/quickshell/Modules/Settings/PluginsTab.qml index c5f1f2c4..086e9566 100644 --- a/quickshell/Modules/Settings/PluginsTab.qml +++ b/quickshell/Modules/Settings/PluginsTab.qml @@ -124,7 +124,7 @@ FocusScope { iconName: "store" enabled: DMSService.dmsAvailable onClicked: { - pluginBrowserModal.show(); + pluginBrowser.show(); } } @@ -286,9 +286,9 @@ FocusScope { Connections { target: DMSService function onPluginsListReceived(plugins) { - pluginBrowserModal.isLoading = false; - pluginBrowserModal.allPlugins = plugins; - pluginBrowserModal.updateFilteredPlugins(); + pluginBrowser.isLoading = false; + pluginBrowser.allPlugins = plugins; + pluginBrowser.updateFilteredPlugins(); } function onInstalledPluginsReceived(plugins) { var pluginMap = {}; @@ -314,13 +314,12 @@ FocusScope { } Component.onCompleted: { - pluginBrowserModal.parentModal = pluginsTab.parentModal; - if (DMSService.dmsAvailable && DMSService.apiVersion >= 8) { + pluginBrowser.parentModal = pluginsTab.parentModal; + if (DMSService.dmsAvailable && DMSService.apiVersion >= 8) DMSService.listInstalled(); - } } PluginBrowser { - id: pluginBrowserModal + id: pluginBrowser } } diff --git a/quickshell/Modules/Settings/WidgetSelectionPopup.qml b/quickshell/Modules/Settings/WidgetSelectionPopup.qml index b6c80622..750cbfdf 100644 --- a/quickshell/Modules/Settings/WidgetSelectionPopup.qml +++ b/quickshell/Modules/Settings/WidgetSelectionPopup.qml @@ -1,9 +1,9 @@ import QtQuick +import Quickshell import qs.Common -import qs.Modals.Common import qs.Widgets -DankModal { +FloatingWindow { id: root property var allWidgets: [] @@ -12,7 +12,6 @@ DankModal { property var filteredWidgets: [] property int selectedIndex: -1 property bool keyboardNavigationActive: false - property Component widgetSelectionContent property var parentModal: null signal widgetSelected(string widgetId, string targetSection) @@ -32,9 +31,8 @@ DankModal { var description = widget.description ? widget.description.toLowerCase() : ""; var id = widget.id ? widget.id.toLowerCase() : ""; - if (text.indexOf(query) !== -1 || description.indexOf(query) !== -1 || id.indexOf(query) !== -1) { + if (text.indexOf(query) !== -1 || description.indexOf(query) !== -1 || id.indexOf(query) !== -1) filtered.push(widget); - } } filteredWidgets = filtered; @@ -58,136 +56,134 @@ DankModal { return; keyboardNavigationActive = true; selectedIndex = Math.max(selectedIndex - 1, -1); - if (selectedIndex === -1) { + if (selectedIndex === -1) keyboardNavigationActive = false; - } } function selectWidget() { - if (selectedIndex >= 0 && selectedIndex < filteredWidgets.length) { - var widget = filteredWidgets[selectedIndex]; - root.widgetSelected(widget.id, root.targetSection); - root.close(); - } + if (selectedIndex < 0 || selectedIndex >= filteredWidgets.length) + return; + var widget = filteredWidgets[selectedIndex]; + root.widgetSelected(widget.id, root.targetSection); + root.hide(); } function show() { - if (parentModal) { + if (parentModal) parentModal.shouldHaveFocus = false; - } - open(); + visible = true; Qt.callLater(() => { - if (contentLoader.item && contentLoader.item.searchField) { - contentLoader.item.searchField.forceActiveFocus(); - } + searchField.forceActiveFocus(); }); } function hide() { - close(); - if (parentModal) { - parentModal.shouldHaveFocus = Qt.binding(() => { - return parentModal.shouldBeVisible; - }); - Qt.callLater(() => { - if (parentModal && parentModal.modalFocusScope) { - parentModal.modalFocusScope.forceActiveFocus(); - } - }); - } + visible = false; + if (!parentModal) + return; + parentModal.shouldHaveFocus = Qt.binding(() => parentModal.shouldBeVisible); + Qt.callLater(() => { + if (parentModal && parentModal.modalFocusScope) + parentModal.modalFocusScope.forceActiveFocus(); + }); } - modalWidth: 500 - modalHeight: 550 - allowStacking: true - backgroundOpacity: 0 - closeOnEscapeKey: false - onDialogClosed: () => { + objectName: "widgetSelectionPopup" + title: I18n.tr("Add Widget") + implicitWidth: 500 + implicitHeight: 550 + color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) + visible: false + + onVisibleChanged: { + if (visible) { + Qt.callLater(() => { + searchField.forceActiveFocus(); + }); + return; + } allWidgets = []; targetSection = ""; searchQuery = ""; filteredWidgets = []; selectedIndex = -1; keyboardNavigationActive = false; - if (parentModal) { - parentModal.shouldHaveFocus = Qt.binding(() => { - return parentModal.shouldBeVisible; - }); - Qt.callLater(() => { - if (parentModal && parentModal.modalFocusScope) { - parentModal.modalFocusScope.forceActiveFocus(); + if (!parentModal) + return; + parentModal.shouldHaveFocus = Qt.binding(() => parentModal.shouldBeVisible); + Qt.callLater(() => { + if (parentModal && parentModal.modalFocusScope) + parentModal.modalFocusScope.forceActiveFocus(); + }); + } + + FocusScope { + id: widgetKeyHandler + + anchors.fill: parent + focus: true + + Keys.onPressed: event => { + switch (event.key) { + case Qt.Key_Escape: + root.hide(); + event.accepted = true; + return; + case Qt.Key_Down: + root.selectNext(); + event.accepted = true; + return; + case Qt.Key_Up: + root.selectPrevious(); + event.accepted = true; + return; + case Qt.Key_Return: + case Qt.Key_Enter: + if (root.keyboardNavigationActive) { + root.selectWidget(); + } else if (root.filteredWidgets.length > 0) { + var firstWidget = root.filteredWidgets[0]; + root.widgetSelected(firstWidget.id, root.targetSection); + root.hide(); } - }); + event.accepted = true; + return; + } + if (event.modifiers & Qt.ControlModifier) { + switch (event.key) { + case Qt.Key_N: + case Qt.Key_J: + root.selectNext(); + event.accepted = true; + return; + case Qt.Key_P: + case Qt.Key_K: + root.selectPrevious(); + event.accepted = true; + return; + } + } } - } - onBackgroundClicked: () => { - return hide(); - } - content: widgetSelectionContent - - widgetSelectionContent: Component { - FocusScope { - id: widgetKeyHandler - property alias searchField: searchField + Column { anchors.fill: parent - focus: true + spacing: 0 - Keys.onPressed: event => { - if (event.key === Qt.Key_Escape) { - root.close(); - event.accepted = true; - } else if (event.key === Qt.Key_Down) { - root.selectNext(); - event.accepted = true; - } else if (event.key === Qt.Key_Up) { - root.selectPrevious(); - event.accepted = true; - } else if (event.key === Qt.Key_N && event.modifiers & Qt.ControlModifier) { - root.selectNext(); - event.accepted = true; - } else if (event.key === Qt.Key_P && event.modifiers & Qt.ControlModifier) { - root.selectPrevious(); - event.accepted = true; - } else if (event.key === Qt.Key_J && event.modifiers & Qt.ControlModifier) { - root.selectNext(); - event.accepted = true; - } else if (event.key === Qt.Key_K && event.modifiers & Qt.ControlModifier) { - root.selectPrevious(); - event.accepted = true; - } else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) { - if (root.keyboardNavigationActive) { - root.selectWidget(); - } else if (root.filteredWidgets.length > 0) { - var firstWidget = root.filteredWidgets[0]; - root.widgetSelected(firstWidget.id, root.targetSection); - root.close(); - } - event.accepted = true; + Item { + id: titleBar + width: parent.width + height: 48 + + Rectangle { + anchors.fill: parent + color: Theme.surfaceContainer + opacity: 0.5 } - } - - DankActionButton { - iconName: "close" - iconSize: Theme.iconSize - 2 - iconColor: Theme.outline - anchors.top: parent.top - anchors.topMargin: Theme.spacingM - anchors.right: parent.right - anchors.rightMargin: Theme.spacingM - onClicked: root.close() - } - - Column { - id: contentColumn - - spacing: Theme.spacingM - anchors.fill: parent - anchors.margins: Theme.spacingL - anchors.topMargin: Theme.spacingL + 30 // Space for close button Row { - width: parent.width + anchors.left: parent.left + anchors.leftMargin: Theme.spacingL + anchors.verticalCenter: parent.verticalCenter spacing: Theme.spacingM DankIcon { @@ -198,134 +194,158 @@ DankModal { } StyledText { - text: I18n.tr("Add Widget to ") + root.targetSection + " Section" - font.pixelSize: Theme.fontSizeLarge - font.weight: Font.Medium + text: I18n.tr("Add Widget to %1 Section").arg(root.targetSection) + font.pixelSize: Theme.fontSizeXLarge color: Theme.surfaceText + font.weight: Font.Medium anchors.verticalCenter: parent.verticalCenter } } - StyledText { - text: I18n.tr("Select a widget to add to the ") + root.targetSection.toLowerCase() + " section of the top bar. You can add multiple instances of the same widget if needed." - font.pixelSize: Theme.fontSizeSmall - color: Theme.outline - width: parent.width - wrapMode: Text.WordWrap + DankActionButton { + circular: false + iconName: "close" + iconSize: Theme.iconSize - 4 + iconColor: Theme.surfaceText + anchors.right: parent.right + anchors.rightMargin: Theme.spacingM + anchors.verticalCenter: parent.verticalCenter + onClicked: root.hide() } + } - DankTextField { - id: searchField - width: parent.width - height: 48 - cornerRadius: Theme.cornerRadius - backgroundColor: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - normalBorderColor: Theme.outlineMedium - focusedBorderColor: Theme.primary - leftIconName: "search" - leftIconSize: Theme.iconSize - leftIconColor: Theme.surfaceVariantText - leftIconFocusedColor: Theme.primary - showClearButton: true - textColor: Theme.surfaceText - font.pixelSize: Theme.fontSizeMedium - placeholderText: "" - text: root.searchQuery - focus: true - ignoreLeftRightKeys: true - keyForwardTargets: [widgetKeyHandler] - onTextEdited: { - root.searchQuery = text; - updateFilteredWidgets(); + Item { + width: parent.width + height: parent.height - titleBar.height + + Column { + id: contentColumn + anchors.fill: parent + anchors.margins: Theme.spacingL + spacing: Theme.spacingM + + StyledText { + text: I18n.tr("Select a widget to add. You can add multiple instances of the same widget if needed.") + font.pixelSize: Theme.fontSizeSmall + color: Theme.outline + width: parent.width + wrapMode: Text.WordWrap } - Keys.onPressed: event => { - if (event.key === Qt.Key_Escape) { - root.close(); - event.accepted = true; - } else if (event.key === Qt.Key_Down || event.key === Qt.Key_Up || ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && text.length === 0)) { - event.accepted = false; + + DankTextField { + id: searchField + width: parent.width + height: 48 + cornerRadius: Theme.cornerRadius + backgroundColor: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) + normalBorderColor: Theme.outlineMedium + focusedBorderColor: Theme.primary + leftIconName: "search" + leftIconSize: Theme.iconSize + leftIconColor: Theme.surfaceVariantText + leftIconFocusedColor: Theme.primary + showClearButton: true + textColor: Theme.surfaceText + font.pixelSize: Theme.fontSizeMedium + placeholderText: I18n.tr("Search widgets...") + text: root.searchQuery + focus: true + ignoreLeftRightKeys: true + keyForwardTargets: [widgetKeyHandler] + onTextEdited: { + root.searchQuery = text; + updateFilteredWidgets(); + } + Keys.onPressed: event => { + if (event.key === Qt.Key_Escape) { + root.hide(); + event.accepted = true; + return; + } + if (event.key === Qt.Key_Down || event.key === Qt.Key_Up || ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && text.length === 0)) + event.accepted = false; } } - } - DankListView { - id: widgetList + DankListView { + id: widgetList - width: parent.width - height: parent.height - y - spacing: Theme.spacingS - model: root.filteredWidgets - clip: true + width: parent.width + height: parent.height - y + spacing: Theme.spacingS + model: root.filteredWidgets + clip: true - delegate: Rectangle { - width: widgetList.width - height: 60 - radius: Theme.cornerRadius - property bool isSelected: root.keyboardNavigationActive && index === root.selectedIndex - color: isSelected ? Theme.primarySelected : widgetArea.containsMouse ? Theme.primaryHover : Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3) - border.color: isSelected ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2) - border.width: isSelected ? 2 : 1 + delegate: Rectangle { + width: widgetList.width + height: 60 + radius: Theme.cornerRadius + property bool isSelected: root.keyboardNavigationActive && index === root.selectedIndex + color: isSelected ? Theme.primarySelected : widgetArea.containsMouse ? Theme.primaryHover : Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3) + border.color: isSelected ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2) + border.width: isSelected ? 2 : 1 - Row { - anchors.fill: parent - anchors.margins: Theme.spacingM - spacing: Theme.spacingM + Row { + anchors.fill: parent + anchors.margins: Theme.spacingM + spacing: Theme.spacingM - DankIcon { - name: modelData.icon - size: Theme.iconSize - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - Column { - anchors.verticalCenter: parent.verticalCenter - spacing: 2 - width: parent.width - Theme.iconSize - Theme.spacingM * 3 - - StyledText { - text: modelData.text - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - color: Theme.surfaceText - elide: Text.ElideRight - width: parent.width + DankIcon { + name: modelData.icon + size: Theme.iconSize + color: Theme.primary + anchors.verticalCenter: parent.verticalCenter } - StyledText { - text: modelData.description - font.pixelSize: Theme.fontSizeSmall - color: Theme.outline - elide: Text.ElideRight - width: parent.width - wrapMode: Text.WordWrap + Column { + anchors.verticalCenter: parent.verticalCenter + spacing: 2 + width: parent.width - Theme.iconSize - Theme.spacingM * 3 + + StyledText { + text: modelData.text + font.pixelSize: Theme.fontSizeMedium + font.weight: Font.Medium + color: Theme.surfaceText + elide: Text.ElideRight + width: parent.width + } + + StyledText { + text: modelData.description + font.pixelSize: Theme.fontSizeSmall + color: Theme.outline + elide: Text.ElideRight + width: parent.width + wrapMode: Text.WordWrap + } + } + + DankIcon { + name: "add" + size: Theme.iconSize - 4 + color: Theme.primary + anchors.verticalCenter: parent.verticalCenter } } - DankIcon { - name: "add" - size: Theme.iconSize - 4 - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter + MouseArea { + id: widgetArea + + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + root.widgetSelected(modelData.id, root.targetSection); + root.hide(); + } } - } - MouseArea { - id: widgetArea - - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - root.widgetSelected(modelData.id, root.targetSection); - root.close(); - } - } - - Behavior on color { - ColorAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing + Behavior on color { + ColorAnimation { + duration: Theme.shortDuration + easing.type: Theme.standardEasing + } } } } diff --git a/quickshell/Modules/Settings/WidgetTweaksTab.qml b/quickshell/Modules/Settings/WidgetTweaksTab.qml index 308f4315..c226395e 100644 --- a/quickshell/Modules/Settings/WidgetTweaksTab.qml +++ b/quickshell/Modules/Settings/WidgetTweaksTab.qml @@ -682,7 +682,7 @@ Item { anchors.verticalCenter: parent.verticalCenter checked: SettingsData.osdAlwaysShowValue - onToggleCompleted: checked => { + onToggled: checked => { SettingsData.set("osdAlwaysShowValue", checked); } }