mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-17 00:34:01 -04:00
settings: re-org launcehr tab built-in plugins, make desktop widgets
sub-pages to match the pattern of bar widgets
This commit is contained in:
@@ -200,7 +200,19 @@ Singleton {
|
||||
"text": I18n.tr("Desktop widgets"),
|
||||
"icon": "widgets",
|
||||
"tabIndex": 27,
|
||||
"hint": I18n.tr("Clocks, system monitors, plugins")
|
||||
"hubHeader": "DesktopWidgetsTab",
|
||||
"hint": I18n.tr("Clocks, system monitors, plugins"),
|
||||
"children": [
|
||||
{
|
||||
"id": "desktop_widget",
|
||||
"hidden": true,
|
||||
"titleFrom": "selectedWidgetTitle",
|
||||
"text": I18n.tr("Widget settings"),
|
||||
"icon": "tune",
|
||||
"tabIndex": 63,
|
||||
"hint": I18n.tr("Options of one widget instance")
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "separator_2",
|
||||
|
||||
@@ -14,6 +14,7 @@ Singleton {
|
||||
// Set only while the widget settings page is showing a dock-hosted widget; empty means bar-hosted.
|
||||
property string selectedDockId: ""
|
||||
property string selectedDockWidgetId: ""
|
||||
property string selectedDesktopWidgetId: ""
|
||||
property string selectedWidgetSection: ""
|
||||
property int selectedWidgetIndex: -1
|
||||
property string selectedWidgetTitle: ""
|
||||
|
||||
@@ -218,6 +218,7 @@ FocusScope {
|
||||
"power_sleep": "PowerSleepTab.qml",
|
||||
"clipboard": "ClipboardTab.qml",
|
||||
"desktop_widgets": "DesktopWidgetsTab.qml",
|
||||
"desktop_widget": "DesktopWidgetTab.qml",
|
||||
"audio": "AudioTab.qml",
|
||||
"locale": "LocaleTab.qml",
|
||||
"multiplexers": "MuxTab.qml",
|
||||
|
||||
@@ -16,14 +16,13 @@ Column {
|
||||
property bool showHeader: true
|
||||
property bool collapsed: false
|
||||
property var instances: []
|
||||
property var expandedStates: ({})
|
||||
|
||||
readonly property string sectionKey: groupId ? groupId : ""
|
||||
readonly property bool dragActive: reorderGroup.active
|
||||
readonly property bool isDropTarget: dragActive && reorderGroup.target === cardsList
|
||||
|
||||
signal collapseToggled(string key)
|
||||
signal expandedToggled(string instanceId, bool expanded)
|
||||
signal configureRequested(string instanceId, string title)
|
||||
signal duplicateRequested(string instanceId)
|
||||
signal deleteRequested(string instanceId)
|
||||
|
||||
@@ -74,10 +73,9 @@ Column {
|
||||
|
||||
reorderList: cardsList
|
||||
instanceData: modelData
|
||||
isExpanded: section.expandedStates[instanceId] ?? false
|
||||
opacity: dragging && cardsList.crossSectionActive ? 0 : 1
|
||||
|
||||
onExpandedToggled: expanded => section.expandedToggled(instanceId, expanded)
|
||||
onConfigureRequested: section.configureRequested(instanceId, widgetName)
|
||||
onDuplicateRequested: section.duplicateRequested(instanceId)
|
||||
onDeleteRequested: section.deleteRequested(instanceId)
|
||||
}
|
||||
|
||||
@@ -2,18 +2,15 @@ pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import Quickshell
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
import qs.Modules.Settings.Widgets
|
||||
import qs.Modules.Settings.DesktopWidgetSettings as DWS
|
||||
|
||||
SettingsReorderRow {
|
||||
id: root
|
||||
|
||||
required property var instanceData
|
||||
property bool isExpanded: false
|
||||
property bool confirmingDelete: false
|
||||
|
||||
readonly property string instanceId: instanceData?.id ?? ""
|
||||
@@ -21,34 +18,29 @@ SettingsReorderRow {
|
||||
readonly property var widgetDef: DesktopWidgetRegistry.getWidget(widgetType)
|
||||
readonly property string widgetName: instanceData?.name ?? widgetDef?.name ?? widgetType
|
||||
|
||||
signal expandedToggled(bool expanded)
|
||||
signal configureRequested
|
||||
signal deleteRequested
|
||||
signal duplicateRequested
|
||||
|
||||
property Component clockSettingsComponent: Component {
|
||||
DWS.ClockSettings {}
|
||||
}
|
||||
|
||||
property Component systemMonitorSettingsComponent: Component {
|
||||
DWS.SystemMonitorSettings {}
|
||||
}
|
||||
|
||||
property Component pluginSettingsComponent: Component {
|
||||
DWS.PluginDesktopWidgetSettings {
|
||||
instanceId: root.instanceId
|
||||
instanceData: root.instanceData
|
||||
widgetType: root.widgetType
|
||||
widgetDef: root.widgetDef
|
||||
}
|
||||
}
|
||||
|
||||
width: parent?.width ?? 400
|
||||
iconName: widgetDef?.icon ?? "widgets"
|
||||
title: widgetName
|
||||
clickable: true
|
||||
onClicked: expandedToggled(!isExpanded)
|
||||
onClicked: configureRequested()
|
||||
|
||||
trailing: [
|
||||
DankIcon {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
name: "chevron_right"
|
||||
size: Theme.iconSize
|
||||
color: Theme.onSurfaceVariant
|
||||
rotation: I18n.isRtl ? 180 : 0
|
||||
},
|
||||
Rectangle {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: Theme.dividerWidth
|
||||
height: SettingsMetrics.splitDividerHeight
|
||||
color: Theme.outlineVariant
|
||||
},
|
||||
DankToggle {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
hideText: true
|
||||
@@ -173,215 +165,6 @@ SettingsReorderRow {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
DankIcon {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
name: root.isExpanded ? "expand_less" : "expand_more"
|
||||
size: Theme.iconSize
|
||||
color: Theme.onSurfaceVariant
|
||||
}
|
||||
]
|
||||
|
||||
body: Column {
|
||||
width: parent.width
|
||||
visible: root.isExpanded
|
||||
height: root.isExpanded ? implicitHeight : 0
|
||||
spacing: 0
|
||||
|
||||
SettingsTextFieldRow {
|
||||
leftIconName: "badge"
|
||||
text: I18n.tr("Name")
|
||||
value: root.widgetName
|
||||
onEditingFinished: value => SettingsData.updateDesktopWidgetInstance(root.instanceId, {
|
||||
name: value
|
||||
})
|
||||
}
|
||||
|
||||
SettingsDivider {}
|
||||
|
||||
SettingsDropdownRow {
|
||||
readonly property var groupsData: {
|
||||
const items = [
|
||||
{
|
||||
value: "",
|
||||
label: I18n.tr("None")
|
||||
}
|
||||
];
|
||||
for (const g of SettingsData.desktopWidgetGroups || []) {
|
||||
items.push({
|
||||
value: g.id,
|
||||
label: g.name
|
||||
});
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
visible: (SettingsData.desktopWidgetGroups || []).length > 0
|
||||
text: I18n.tr("Group", "noun, dropdown label for a desktop widget group")
|
||||
options: groupsData.map(g => g.label)
|
||||
currentValue: groupsData.find(g => g.value === (root.instanceData?.group ?? ""))?.label ?? I18n.tr("None")
|
||||
onValueChanged: value => SettingsData.updateDesktopWidgetInstance(root.instanceId, {
|
||||
group: groupsData.find(g => g.label === value)?.value || null
|
||||
})
|
||||
}
|
||||
|
||||
SettingsDivider {
|
||||
visible: (SettingsData.desktopWidgetGroups || []).length > 0
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("Show on overlay")
|
||||
checked: instanceData?.config?.showOnOverlay ?? false
|
||||
onToggled: isChecked => {
|
||||
SettingsData.updateDesktopWidgetInstanceConfig(root.instanceId, {
|
||||
showOnOverlay: isChecked
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
SettingsDivider {
|
||||
visible: CompositorService.isNiri
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
visible: CompositorService.isNiri
|
||||
text: I18n.tr("Show on overview")
|
||||
checked: instanceData?.config?.showOnOverview ?? false
|
||||
onToggled: isChecked => {
|
||||
SettingsData.updateDesktopWidgetInstanceConfig(root.instanceId, {
|
||||
showOnOverview: isChecked
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
SettingsDivider {
|
||||
visible: CompositorService.isNiri
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
visible: CompositorService.isNiri
|
||||
text: I18n.tr("Show on overview only")
|
||||
checked: instanceData?.config?.showOnOverviewOnly ?? false
|
||||
onToggled: isChecked => {
|
||||
SettingsData.updateDesktopWidgetInstanceConfig(root.instanceId, {
|
||||
showOnOverviewOnly: isChecked
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
SettingsDivider {}
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("Click through")
|
||||
checked: instanceData?.config?.clickThrough ?? false
|
||||
onToggled: isChecked => {
|
||||
SettingsData.updateDesktopWidgetInstanceConfig(root.instanceId, {
|
||||
clickThrough: isChecked
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
SettingsDivider {}
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("Sync position across displays")
|
||||
checked: instanceData?.config?.syncPositionAcrossScreens ?? false
|
||||
onToggled: isChecked => {
|
||||
if (isChecked)
|
||||
SessionData.syncDesktopWidgetPositionToAllScreens(root.instanceId);
|
||||
SettingsData.updateDesktopWidgetInstanceConfig(root.instanceId, {
|
||||
syncPositionAcrossScreens: isChecked
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
SettingsDivider {}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: ipcColumn.height + Theme.spacingM * 2
|
||||
|
||||
Column {
|
||||
id: ipcColumn
|
||||
x: Theme.spacingM
|
||||
width: parent.width - Theme.spacingM * 2
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingXS
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Command")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceText
|
||||
width: parent.width
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: ipcText.height + Theme.spacingS * 2
|
||||
radius: Theme.cornerRadiusS
|
||||
color: Theme.chipSurface
|
||||
|
||||
Row {
|
||||
x: Theme.spacingS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingS
|
||||
width: parent.width - Theme.spacingS * 2
|
||||
|
||||
StyledText {
|
||||
id: ipcText
|
||||
text: "dms ipc call desktopWidget toggleOverlay " + root.instanceId
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.family: Theme.monoFontFamily
|
||||
color: Theme.surfaceVariantText
|
||||
width: parent.width - copyBtn.width - Theme.spacingS
|
||||
elide: Text.ElideMiddle
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
DankButton {
|
||||
id: copyBtn
|
||||
iconName: "content_copy"
|
||||
Accessible.name: I18n.tr("Copy")
|
||||
backgroundColor: "transparent"
|
||||
textColor: Theme.surfaceText
|
||||
buttonHeight: 28
|
||||
horizontalPadding: 4
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
onClicked: {
|
||||
Quickshell.execDetached(["dms", "cl", "copy", "dms ipc call desktopWidget toggleOverlay " + root.instanceId]);
|
||||
ToastService.showInfo(I18n.tr("Copied to clipboard"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsDivider {}
|
||||
|
||||
Loader {
|
||||
id: settingsLoader
|
||||
width: parent.width
|
||||
active: root.isExpanded && root.widgetType !== ""
|
||||
|
||||
sourceComponent: {
|
||||
switch (root.widgetType) {
|
||||
case "desktopClock":
|
||||
return clockSettingsComponent;
|
||||
case "systemMonitor":
|
||||
return systemMonitorSettingsComponent;
|
||||
default:
|
||||
return pluginSettingsComponent;
|
||||
}
|
||||
}
|
||||
|
||||
onLoaded: {
|
||||
if (!item)
|
||||
return;
|
||||
item.instanceId = root.instanceId;
|
||||
item.instanceData = Qt.binding(() => root.instanceData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,10 +34,6 @@ DesktopWidgetInstanceSettings {
|
||||
}
|
||||
}
|
||||
|
||||
SettingsDivider {
|
||||
visible: root.analog
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
visible: root.analog
|
||||
text: I18n.tr("Show hour numbers")
|
||||
@@ -45,10 +41,6 @@ DesktopWidgetInstanceSettings {
|
||||
onToggled: checked => root.updateConfig("showAnalogNumbers", checked)
|
||||
}
|
||||
|
||||
SettingsDivider {
|
||||
visible: root.analog
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
visible: root.analog
|
||||
text: I18n.tr("Show seconds")
|
||||
@@ -56,10 +48,6 @@ DesktopWidgetInstanceSettings {
|
||||
onToggled: checked => root.updateConfig("showAnalogSeconds", checked)
|
||||
}
|
||||
|
||||
SettingsDivider {
|
||||
visible: !root.analog
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
visible: !root.analog
|
||||
text: I18n.tr("Show seconds")
|
||||
@@ -67,8 +55,6 @@ DesktopWidgetInstanceSettings {
|
||||
onToggled: checked => root.updateConfig("showDigitalSeconds", checked)
|
||||
}
|
||||
|
||||
SettingsDivider {}
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("Show date")
|
||||
checked: root.cfg.showDate ?? true
|
||||
|
||||
+39
-64
@@ -1,6 +1,5 @@
|
||||
import QtQuick
|
||||
import qs.Common
|
||||
import qs.Widgets
|
||||
import qs.Modules.Settings.Widgets
|
||||
|
||||
Column {
|
||||
@@ -11,7 +10,7 @@ Column {
|
||||
property bool showAppearance: true
|
||||
property bool showPlacement: true
|
||||
readonly property var cfg: instanceData?.config ?? {}
|
||||
default property alias rows: rowsColumn.data
|
||||
default property alias rows: optionsCard.content
|
||||
|
||||
function updateConfig(key, value) {
|
||||
const updates = {};
|
||||
@@ -19,78 +18,54 @@ Column {
|
||||
SettingsData.updateDesktopWidgetInstanceConfig(instanceId, updates);
|
||||
}
|
||||
|
||||
width: parent?.width ?? 400
|
||||
spacing: 0
|
||||
width: parent?.width ?? 0
|
||||
spacing: Theme.spacingL
|
||||
|
||||
Column {
|
||||
id: rowsColumn
|
||||
width: parent.width
|
||||
spacing: 0
|
||||
SettingsCard {
|
||||
id: optionsCard
|
||||
}
|
||||
|
||||
SettingsDivider {
|
||||
SettingsCard {
|
||||
title: I18n.tr("Appearance")
|
||||
visible: root.showAppearance
|
||||
|
||||
SettingsSliderRow {
|
||||
text: I18n.tr("Opacity")
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
value: Math.round((root.cfg.transparency ?? 0.8) * 100)
|
||||
onSliderValueChanged: newValue => root.updateConfig("transparency", newValue / 100)
|
||||
}
|
||||
|
||||
SettingsColorPicker {
|
||||
colorMode: root.cfg.colorMode ?? "primary"
|
||||
customColor: root.cfg.customColor ?? "#ffffff"
|
||||
onColorModeSelected: mode => root.updateConfig("colorMode", mode)
|
||||
onCustomColorSelected: selectedColor => root.updateConfig("customColor", selectedColor.toString())
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
visible: root.showAppearance
|
||||
text: I18n.tr("Opacity")
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
value: Math.round((root.cfg.transparency ?? 0.8) * 100)
|
||||
onSliderValueChanged: newValue => root.updateConfig("transparency", newValue / 100)
|
||||
}
|
||||
|
||||
SettingsDivider {
|
||||
visible: root.showAppearance
|
||||
}
|
||||
|
||||
SettingsColorPicker {
|
||||
visible: root.showAppearance
|
||||
colorMode: root.cfg.colorMode ?? "primary"
|
||||
customColor: root.cfg.customColor ?? "#ffffff"
|
||||
onColorModeSelected: mode => root.updateConfig("colorMode", mode)
|
||||
onCustomColorSelected: selectedColor => root.updateConfig("customColor", selectedColor.toString())
|
||||
}
|
||||
|
||||
SettingsDivider {
|
||||
visible: root.showAppearance && root.showPlacement
|
||||
}
|
||||
|
||||
SettingsDisplayPicker {
|
||||
SettingsCard {
|
||||
title: I18n.tr("Displays")
|
||||
visible: root.showPlacement
|
||||
displayPreferences: root.cfg.displayPreferences ?? ["all"]
|
||||
onPreferencesChanged: prefs => root.updateConfig("displayPreferences", prefs)
|
||||
}
|
||||
|
||||
SettingsDivider {
|
||||
visible: root.showPlacement
|
||||
}
|
||||
SettingsDisplayPicker {
|
||||
displayPreferences: root.cfg.displayPreferences ?? ["all"]
|
||||
onPreferencesChanged: prefs => root.updateConfig("displayPreferences", prefs)
|
||||
}
|
||||
|
||||
Item {
|
||||
visible: root.showPlacement
|
||||
width: parent.width
|
||||
height: resetRow.height + Theme.spacingM * 2
|
||||
SettingsRow {
|
||||
iconName: "drag_pan"
|
||||
title: I18n.tr("Reset Position")
|
||||
clickable: true
|
||||
onClicked: SessionData.resetDesktopWidgetInstanceGeometry(root.instanceId, ["x", "y"])
|
||||
}
|
||||
|
||||
Row {
|
||||
id: resetRow
|
||||
x: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankButton {
|
||||
text: I18n.tr("Reset Position")
|
||||
backgroundColor: Theme.chipSurface
|
||||
textColor: Theme.surfaceText
|
||||
onClicked: SessionData.resetDesktopWidgetInstanceGeometry(root.instanceId, ["x", "y"])
|
||||
}
|
||||
|
||||
DankButton {
|
||||
text: I18n.tr("Reset Size")
|
||||
backgroundColor: Theme.chipSurface
|
||||
textColor: Theme.surfaceText
|
||||
onClicked: SessionData.resetDesktopWidgetInstanceGeometry(root.instanceId, ["width", "height"])
|
||||
}
|
||||
SettingsRow {
|
||||
iconName: "open_in_full"
|
||||
title: I18n.tr("Reset Size")
|
||||
clickable: true
|
||||
onClicked: SessionData.resetDesktopWidgetInstanceGeometry(root.instanceId, ["width", "height"])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,20 +3,20 @@ pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
import qs.Modules.Settings.Widgets
|
||||
|
||||
DesktopWidgetInstanceSettings {
|
||||
id: root
|
||||
|
||||
readonly property var gpus: DgopService.availableGpus ?? []
|
||||
readonly property var gpuLabels: gpus.map(gpu => (gpu.driver ? gpu.driver.toUpperCase() + " " : "") + (gpu.displayName ?? ""))
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("Show header")
|
||||
checked: root.cfg.showHeader ?? true
|
||||
onToggled: checked => root.updateConfig("showHeader", checked)
|
||||
}
|
||||
|
||||
SettingsDivider {}
|
||||
|
||||
SettingsButtonGroupRow {
|
||||
readonly property var intervals: [60, 300, 600, 1800]
|
||||
text: I18n.tr("Graph time range")
|
||||
@@ -30,18 +30,12 @@ DesktopWidgetInstanceSettings {
|
||||
}
|
||||
}
|
||||
|
||||
SettingsDivider {}
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("CPU")
|
||||
checked: root.cfg.showCpu ?? true
|
||||
onToggled: checked => root.updateConfig("showCpu", checked)
|
||||
}
|
||||
|
||||
SettingsDivider {
|
||||
visible: root.cfg.showCpu ?? true
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
enabled: root.cfg.showCpu ?? true
|
||||
text: I18n.tr("CPU graph")
|
||||
@@ -49,10 +43,6 @@ DesktopWidgetInstanceSettings {
|
||||
onToggled: checked => root.updateConfig("showCpuGraph", checked)
|
||||
}
|
||||
|
||||
SettingsDivider {
|
||||
visible: root.cfg.showCpu ?? true
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
enabled: root.cfg.showCpu ?? true
|
||||
text: I18n.tr("CPU temperature")
|
||||
@@ -60,112 +50,32 @@ DesktopWidgetInstanceSettings {
|
||||
onToggled: checked => root.updateConfig("showCpuTemp", checked)
|
||||
}
|
||||
|
||||
SettingsDivider {}
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("GPU temperature")
|
||||
checked: root.cfg.showGpuTemp ?? false
|
||||
onToggled: checked => root.updateConfig("showGpuTemp", checked)
|
||||
}
|
||||
|
||||
SettingsDivider {
|
||||
visible: (root.cfg.showGpuTemp ?? false) && DgopService.availableGpus.length > 0
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: gpuSelectColumn.height + Theme.spacingM * 2
|
||||
visible: (root.cfg.showGpuTemp ?? false) && DgopService.availableGpus.length > 0
|
||||
|
||||
Column {
|
||||
id: gpuSelectColumn
|
||||
width: parent.width - Theme.spacingM * 2
|
||||
x: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingS
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("GPU", "graphics processor label in system monitor")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingXS
|
||||
|
||||
Repeater {
|
||||
model: DgopService.availableGpus
|
||||
|
||||
Rectangle {
|
||||
required property var modelData
|
||||
|
||||
readonly property bool isSelected: (root.cfg.gpuPciId ?? "") === modelData.pciId
|
||||
|
||||
width: parent.width
|
||||
height: 44
|
||||
radius: Theme.cornerRadius
|
||||
color: isSelected ? Theme.primarySelected : Theme.chipSurface
|
||||
border.color: isSelected ? Theme.primary : Theme.withAlpha(Theme.primary, 0)
|
||||
border.width: Theme.outlineWidthFocused
|
||||
|
||||
Row {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.spacingS
|
||||
spacing: Theme.spacingS
|
||||
|
||||
DankIcon {
|
||||
name: "videocam"
|
||||
size: Theme.iconSizeSmall
|
||||
color: isSelected ? Theme.primary : Theme.surfaceVariantText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width - Theme.iconSizeSmall - Theme.spacingS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: 0
|
||||
|
||||
StyledText {
|
||||
text: modelData.displayName || "Unknown GPU"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: modelData.driver || ""
|
||||
font.pixelSize: Theme.fontSizeSmall - 2
|
||||
color: Theme.surfaceVariantText
|
||||
visible: text !== ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: root.updateConfig("gpuPciId", modelData.pciId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SettingsDropdownRow {
|
||||
visible: root.cfg.showGpuTemp ?? false
|
||||
text: I18n.tr("GPU")
|
||||
options: root.gpuLabels
|
||||
emptyText: I18n.tr("No GPU detected", "empty state when no graphics card is found")
|
||||
currentValue: root.gpuLabels[root.gpus.findIndex(gpu => gpu.pciId === root.cfg.gpuPciId)] ?? ""
|
||||
onValueChanged: value => {
|
||||
const index = root.gpuLabels.indexOf(value);
|
||||
if (index < 0)
|
||||
return;
|
||||
root.updateConfig("gpuPciId", root.gpus[index].pciId);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsDivider {}
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("Memory")
|
||||
checked: root.cfg.showMemory ?? true
|
||||
onToggled: checked => root.updateConfig("showMemory", checked)
|
||||
}
|
||||
|
||||
SettingsDivider {
|
||||
visible: root.cfg.showMemory ?? true
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
enabled: root.cfg.showMemory ?? true
|
||||
text: I18n.tr("Memory graph")
|
||||
@@ -173,18 +83,12 @@ DesktopWidgetInstanceSettings {
|
||||
onToggled: checked => root.updateConfig("showMemoryGraph", checked)
|
||||
}
|
||||
|
||||
SettingsDivider {}
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("Network")
|
||||
checked: root.cfg.showNetwork ?? true
|
||||
onToggled: checked => root.updateConfig("showNetwork", checked)
|
||||
}
|
||||
|
||||
SettingsDivider {
|
||||
visible: root.cfg.showNetwork ?? true
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
enabled: root.cfg.showNetwork ?? true
|
||||
text: I18n.tr("Network graph")
|
||||
@@ -192,26 +96,18 @@ DesktopWidgetInstanceSettings {
|
||||
onToggled: checked => root.updateConfig("showNetworkGraph", checked)
|
||||
}
|
||||
|
||||
SettingsDivider {}
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("Disk")
|
||||
checked: root.cfg.showDisk ?? true
|
||||
onToggled: checked => root.updateConfig("showDisk", checked)
|
||||
}
|
||||
|
||||
SettingsDivider {}
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("Top processes")
|
||||
checked: root.cfg.showTopProcesses ?? false
|
||||
onToggled: checked => root.updateConfig("showTopProcesses", checked)
|
||||
}
|
||||
|
||||
SettingsDivider {
|
||||
visible: root.cfg.showTopProcesses ?? false
|
||||
}
|
||||
|
||||
SettingsButtonGroupRow {
|
||||
readonly property var counts: [3, 5, 10]
|
||||
visible: root.cfg.showTopProcesses ?? false
|
||||
@@ -226,10 +122,6 @@ DesktopWidgetInstanceSettings {
|
||||
}
|
||||
}
|
||||
|
||||
SettingsDivider {
|
||||
visible: root.cfg.showTopProcesses ?? false
|
||||
}
|
||||
|
||||
SettingsButtonGroupRow {
|
||||
visible: root.cfg.showTopProcesses ?? false
|
||||
text: I18n.tr("Sort by")
|
||||
@@ -243,8 +135,6 @@ DesktopWidgetInstanceSettings {
|
||||
}
|
||||
}
|
||||
|
||||
SettingsDivider {}
|
||||
|
||||
SettingsDropdownRow {
|
||||
text: I18n.tr("Layout")
|
||||
options: [I18n.tr("Auto"), I18n.tr("Grid"), I18n.tr("List")]
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
import qs.Modules.Settings.Widgets
|
||||
import qs.Modules.Settings.DesktopWidgetSettings as DWS
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
readonly property string instanceId: SettingsUiState.selectedDesktopWidgetId
|
||||
readonly property var instanceData: (SettingsData.desktopWidgetInstances || []).find(instance => instance.id === instanceId) ?? null
|
||||
readonly property string widgetType: instanceData?.widgetType ?? ""
|
||||
readonly property var widgetDef: DesktopWidgetRegistry.getWidget(widgetType)
|
||||
readonly property string widgetName: instanceData?.name ?? widgetDef?.name ?? widgetType
|
||||
readonly property var cfg: instanceData?.config ?? {}
|
||||
readonly property string overlayCommand: "dms ipc call desktopWidget toggleOverlay " + instanceId
|
||||
readonly property var groupOptions: [
|
||||
{
|
||||
"value": "",
|
||||
"label": I18n.tr("None")
|
||||
}
|
||||
].concat((SettingsData.desktopWidgetGroups || []).map(group => ({
|
||||
"value": group.id,
|
||||
"label": group.name
|
||||
})))
|
||||
|
||||
function updateConfig(key, value) {
|
||||
const updates = {};
|
||||
updates[key] = value;
|
||||
SettingsData.updateDesktopWidgetInstanceConfig(instanceId, updates);
|
||||
}
|
||||
|
||||
onWidgetNameChanged: SettingsUiState.selectedWidgetTitle = widgetName
|
||||
|
||||
Component {
|
||||
id: clockSettings
|
||||
|
||||
DWS.ClockSettings {
|
||||
instanceId: root.instanceId
|
||||
instanceData: root.instanceData
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: systemMonitorSettings
|
||||
|
||||
DWS.SystemMonitorSettings {
|
||||
instanceId: root.instanceId
|
||||
instanceData: root.instanceData
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: pluginSettings
|
||||
|
||||
DWS.PluginDesktopWidgetSettings {
|
||||
instanceId: root.instanceId
|
||||
instanceData: root.instanceData
|
||||
widgetType: root.widgetType
|
||||
widgetDef: root.widgetDef
|
||||
}
|
||||
}
|
||||
|
||||
SettingsPage {
|
||||
visible: root.instanceData !== null
|
||||
|
||||
SettingsCard {
|
||||
SettingsToggleRow {
|
||||
iconName: root.widgetDef?.icon ?? "widgets"
|
||||
text: root.widgetDef?.name ?? root.widgetType
|
||||
description: root.widgetDef?.description ?? ""
|
||||
checked: root.instanceData?.enabled ?? true
|
||||
onToggled: checked => SettingsData.updateDesktopWidgetInstance(root.instanceId, {
|
||||
"enabled": checked
|
||||
})
|
||||
}
|
||||
|
||||
SettingsTextFieldRow {
|
||||
leftIconName: "badge"
|
||||
text: I18n.tr("Name")
|
||||
value: root.widgetName
|
||||
onEditingFinished: value => SettingsData.updateDesktopWidgetInstance(root.instanceId, {
|
||||
"name": value
|
||||
})
|
||||
}
|
||||
|
||||
SettingsDropdownRow {
|
||||
visible: root.groupOptions.length > 1
|
||||
text: I18n.tr("Group", "noun, dropdown label for a desktop widget group")
|
||||
options: root.groupOptions.map(group => group.label)
|
||||
currentValue: root.groupOptions.find(group => group.value === (root.instanceData?.group ?? ""))?.label ?? I18n.tr("None")
|
||||
onValueChanged: value => SettingsData.updateDesktopWidgetInstance(root.instanceId, {
|
||||
"group": root.groupOptions.find(group => group.label === value)?.value || null
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
width: parent.width
|
||||
active: root.instanceData !== null
|
||||
sourceComponent: {
|
||||
switch (root.widgetType) {
|
||||
case "desktopClock":
|
||||
return clockSettings;
|
||||
case "systemMonitor":
|
||||
return systemMonitorSettings;
|
||||
default:
|
||||
return pluginSettings;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
title: I18n.tr("Behavior")
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("Show on overlay")
|
||||
checked: root.cfg.showOnOverlay ?? false
|
||||
onToggled: checked => root.updateConfig("showOnOverlay", checked)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
visible: CompositorService.isNiri
|
||||
text: I18n.tr("Show on overview")
|
||||
checked: root.cfg.showOnOverview ?? false
|
||||
onToggled: checked => root.updateConfig("showOnOverview", checked)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
visible: CompositorService.isNiri
|
||||
text: I18n.tr("Show on overview only")
|
||||
checked: root.cfg.showOnOverviewOnly ?? false
|
||||
onToggled: checked => root.updateConfig("showOnOverviewOnly", checked)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("Click through")
|
||||
checked: root.cfg.clickThrough ?? false
|
||||
onToggled: checked => root.updateConfig("clickThrough", checked)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("Sync position across displays")
|
||||
checked: root.cfg.syncPositionAcrossScreens ?? false
|
||||
onToggled: checked => {
|
||||
if (checked)
|
||||
SessionData.syncDesktopWidgetPositionToAllScreens(root.instanceId);
|
||||
root.updateConfig("syncPositionAcrossScreens", checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
title: I18n.tr("Command")
|
||||
|
||||
SettingsRow {
|
||||
body: Row {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
|
||||
StyledText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: parent.width - copyButton.width - parent.spacing
|
||||
text: root.overlayCommand
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.family: Theme.monoFontFamily
|
||||
color: Theme.surfaceVariantText
|
||||
elide: Text.ElideMiddle
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
id: copyButton
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
iconName: "content_copy"
|
||||
Accessible.name: I18n.tr("Copy")
|
||||
onClicked: {
|
||||
Quickshell.execDetached(["dms", "cl", "copy", root.overlayCommand]);
|
||||
ToastService.showInfo(I18n.tr("Copied to clipboard"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@ Item {
|
||||
LayoutMirroring.enabled: I18n.isRtl
|
||||
LayoutMirroring.childrenInherit: true
|
||||
|
||||
property var expandedStates: ({})
|
||||
property var groupCollapsedStates: ({})
|
||||
property var parentModal: null
|
||||
property string editingGroupId: ""
|
||||
@@ -43,12 +42,10 @@ Item {
|
||||
groupCollapsedStates = states;
|
||||
}
|
||||
|
||||
function setExpanded(instanceId, expanded) {
|
||||
if (expanded === (expandedStates[instanceId] ?? false))
|
||||
return;
|
||||
var states = Object.assign({}, expandedStates);
|
||||
states[instanceId] = expanded;
|
||||
expandedStates = states;
|
||||
function configureWidget(instanceId, title) {
|
||||
SettingsUiState.selectedDesktopWidgetId = instanceId;
|
||||
SettingsUiState.selectedWidgetTitle = title;
|
||||
parentModal?.navigateTo("desktop_widget");
|
||||
}
|
||||
|
||||
function showWidgetBrowser() {
|
||||
@@ -283,11 +280,10 @@ Item {
|
||||
showHeader: true
|
||||
collapsed: root.groupCollapsedStates[modelData.id] ?? false
|
||||
instances: root.allInstances.filter(inst => inst.group === modelData.id)
|
||||
expandedStates: root.expandedStates
|
||||
visible: instances.length > 0 || root.dragActive
|
||||
|
||||
onCollapseToggled: key => root.toggleCollapsed(key)
|
||||
onExpandedToggled: (instanceId, expanded) => root.setExpanded(instanceId, expanded)
|
||||
onConfigureRequested: (instanceId, title) => root.configureWidget(instanceId, title)
|
||||
onDuplicateRequested: instanceId => SettingsData.duplicateDesktopWidgetInstance(instanceId)
|
||||
onDeleteRequested: instanceId => {
|
||||
SettingsData.removeDesktopWidgetInstance(instanceId);
|
||||
@@ -313,11 +309,10 @@ Item {
|
||||
showHeader: root.allGroups.length > 0
|
||||
collapsed: root.groupCollapsedStates["_ungrouped"] ?? false
|
||||
instances: ungroupedInstances
|
||||
expandedStates: root.expandedStates
|
||||
visible: ungroupedInstances.length > 0 || root.dragActive
|
||||
|
||||
onCollapseToggled: key => root.toggleCollapsed(key)
|
||||
onExpandedToggled: (instanceId, expanded) => root.setExpanded(instanceId, expanded)
|
||||
onConfigureRequested: (instanceId, title) => root.configureWidget(instanceId, title)
|
||||
onDuplicateRequested: instanceId => SettingsData.duplicateDesktopWidgetInstance(instanceId)
|
||||
onDeleteRequested: instanceId => {
|
||||
SettingsData.removeDesktopWidgetInstance(instanceId);
|
||||
|
||||
@@ -14,6 +14,7 @@ Item {
|
||||
readonly property bool keybindsAvailable: KeybindsService.available
|
||||
readonly property string defaultLauncherKeybindSearch: "spotlight toggle"
|
||||
readonly property string spotlightBarKeybindSearch: "spotlight-bar"
|
||||
readonly property var builtInPluginIds: ["dms_settings", "dms_notepad", "dms_sysmon", "dms_colorpicker", "dms_settings_search", "dms_clipboard_search", "dms_power", "dms_vpn", "dms_qr_generator"]
|
||||
|
||||
function openKeybindsSearch(query) {
|
||||
if (!root.parentModal)
|
||||
@@ -35,6 +36,25 @@ Item {
|
||||
return keys.join(", ");
|
||||
}
|
||||
|
||||
function lastLaunchedText(lastUsed) {
|
||||
if (!lastUsed)
|
||||
return I18n.tr("Never used");
|
||||
const date = new Date(lastUsed);
|
||||
const diffMs = Date.now() - date.getTime();
|
||||
const diffMins = Math.floor(diffMs / (1000 * 60));
|
||||
const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
|
||||
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
||||
if (diffMins < 1)
|
||||
return I18n.tr("Last launched just now");
|
||||
if (diffMins < 60)
|
||||
return diffMins === 1 ? I18n.tr("Last launched %1 minute ago", "singular, app usage list in launcher settings, %1 is 1").arg(diffMins) : I18n.tr("Last launched %1 minutes ago", "plural, app usage list in launcher settings, %1 is a count").arg(diffMins);
|
||||
if (diffHours < 24)
|
||||
return diffHours === 1 ? I18n.tr("Last launched %1 hour ago", "singular, app usage list in launcher settings, %1 is 1").arg(diffHours) : I18n.tr("Last launched %1 hours ago", "plural, app usage list in launcher settings, %1 is a count").arg(diffHours);
|
||||
if (diffDays < 7)
|
||||
return diffDays === 1 ? I18n.tr("Last launched %1 day ago", "singular, app usage list in launcher settings, %1 is 1").arg(diffDays) : I18n.tr("Last launched %1 days ago", "plural, app usage list in launcher settings, %1 is a count").arg(diffDays);
|
||||
return I18n.tr("Last launched %1", "app usage list in launcher settings, %1 is a localized date").arg(date.toLocaleDateString());
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (KeybindsService.available)
|
||||
KeybindsService.loadBinds(false);
|
||||
@@ -320,78 +340,41 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: hiddenAppsCard.hiddenAppsModel
|
||||
|
||||
SettingsRow {
|
||||
id: hiddenAppRow
|
||||
|
||||
required property var modelData
|
||||
|
||||
title: modelData.name
|
||||
subtitle: modelData.comment || modelData.id
|
||||
leading: AppIconRenderer {
|
||||
width: Theme.iconSize
|
||||
height: Theme.iconSize
|
||||
iconValue: hiddenAppRow.modelData.icon || "application-x-executable"
|
||||
iconSize: Theme.iconSize
|
||||
fallbackText: (hiddenAppRow.modelData.name || "?").charAt(0).toUpperCase()
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
iconName: "visibility"
|
||||
Accessible.name: I18n.tr("Show")
|
||||
iconColor: Theme.primary
|
||||
onClicked: SessionData.showApp(hiddenAppRow.modelData.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsRow {
|
||||
body: Column {
|
||||
id: hiddenAppsList
|
||||
visible: hiddenAppsCard.hiddenAppsModel.length === 0
|
||||
body: StyledText {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
|
||||
Repeater {
|
||||
model: hiddenAppsCard.hiddenAppsModel
|
||||
|
||||
delegate: Rectangle {
|
||||
width: hiddenAppsList.width
|
||||
height: 48
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.floatingWindowFieldColor
|
||||
border.width: 0
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
AppIconRenderer {
|
||||
width: 24
|
||||
height: 24
|
||||
iconValue: modelData.icon || "application-x-executable"
|
||||
iconSize: 24
|
||||
fallbackText: (modelData.name || "?").charAt(0).toUpperCase()
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingXXS
|
||||
|
||||
StyledText {
|
||||
text: modelData.name
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Theme.fontWeightMedium
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: modelData.comment || modelData.id
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
visible: text.length > 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
iconName: "visibility"
|
||||
Accessible.name: I18n.tr("Show")
|
||||
iconSize: 18
|
||||
iconColor: Theme.primary
|
||||
onClicked: SessionData.showApp(modelData.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: I18n.tr("No hidden apps.")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceVariantText
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
visible: hiddenAppsCard.hiddenAppsModel.length === 0
|
||||
}
|
||||
text: I18n.tr("No hidden apps.")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceVariantText
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -431,77 +414,63 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: appOverridesCard.overridesModel
|
||||
|
||||
SettingsRow {
|
||||
id: overrideRow
|
||||
|
||||
required property var modelData
|
||||
|
||||
title: modelData.name
|
||||
subtitle: modelData.originalName !== modelData.name ? modelData.originalName : modelData.id
|
||||
leading: AppIconRenderer {
|
||||
width: Theme.iconSize
|
||||
height: Theme.iconSize
|
||||
iconValue: overrideRow.modelData.icon || "application-x-executable"
|
||||
iconSize: Theme.iconSize
|
||||
fallbackText: (overrideRow.modelData.name || "?").charAt(0).toUpperCase()
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
iconName: "delete"
|
||||
tooltipText: I18n.tr("Reset to default")
|
||||
iconColor: Theme.error
|
||||
onClicked: SessionData.clearAppOverride(overrideRow.modelData.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsRow {
|
||||
body: Column {
|
||||
id: overridesList
|
||||
visible: appOverridesCard.overridesModel.length === 0
|
||||
body: StyledText {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
text: I18n.tr("No app customizations.")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceVariantText
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: appOverridesCard.overridesModel
|
||||
SettingsCard {
|
||||
width: parent.width
|
||||
iconName: "apps"
|
||||
title: I18n.tr("Built-in apps", "launcher settings card, DMS tools listed with the installed apps")
|
||||
settingKey: "launcherBuiltInApps"
|
||||
tags: ["launcher", "apps", "builtin", "settings", "notepad", "system monitor", "color picker"]
|
||||
|
||||
delegate: Rectangle {
|
||||
width: overridesList.width
|
||||
height: 48
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.floatingWindowFieldColor
|
||||
border.width: 0
|
||||
Repeater {
|
||||
model: root.builtInPluginIds.filter(id => AppSearchService.builtInPlugins[id]?.isLauncher !== true)
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
SettingsToggleRow {
|
||||
required property string modelData
|
||||
readonly property var plugin: AppSearchService.builtInPlugins[modelData]
|
||||
|
||||
AppIconRenderer {
|
||||
width: 24
|
||||
height: 24
|
||||
iconValue: modelData.icon || "application-x-executable"
|
||||
iconSize: 24
|
||||
fallbackText: (modelData.name || "?").charAt(0).toUpperCase()
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingXXS
|
||||
|
||||
StyledText {
|
||||
text: modelData.name
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Theme.fontWeightMedium
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: modelData.originalName !== modelData.name ? modelData.originalName : modelData.id
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
iconName: "delete"
|
||||
tooltipText: I18n.tr("Reset to default")
|
||||
iconSize: 18
|
||||
iconColor: Theme.error
|
||||
onClicked: SessionData.clearAppOverride(modelData.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: I18n.tr("No app customizations.")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceVariantText
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
visible: appOverridesCard.overridesModel.length === 0
|
||||
}
|
||||
iconName: plugin?.cornerIcon ?? "extension"
|
||||
text: plugin?.name ?? modelData
|
||||
checked: SettingsData.getBuiltInPluginSetting(modelData, "enabled", true)
|
||||
onToggled: checked => SettingsData.setBuiltInPluginSetting(modelData, "enabled", checked)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -596,10 +565,18 @@ Item {
|
||||
title: modelData.name
|
||||
subtitle: modelData.trigger ? I18n.tr("Trigger: %1", "launcher plugin subtitle, %1 is the trigger prefix text").arg(modelData.trigger) : I18n.tr("No trigger")
|
||||
iconName: modelData.iconType !== "unicode" ? modelData.icon : ""
|
||||
trailingBadge: modelData.isBuiltIn ? "DMS" : ""
|
||||
textIcon: modelData.iconType === "unicode" ? modelData.icon : ""
|
||||
|
||||
DankBadge {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: pluginRow.modelData.isBuiltIn
|
||||
text: I18n.tr("Built-in", "badge on launcher plugins that ship with DMS")
|
||||
color: Theme.primaryHover
|
||||
textColor: Theme.primary
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
hideText: true
|
||||
checked: {
|
||||
switch (pluginRow.modelData.id) {
|
||||
@@ -644,10 +621,10 @@ Item {
|
||||
iconName: "extension"
|
||||
title: I18n.tr("Built-in plugins")
|
||||
settingKey: "launcherBuiltInPlugins"
|
||||
tags: ["launcher", "plugins", "trigger", "builtin", "settings", "notepad", "calculator", "clipboard", "power"]
|
||||
tags: ["launcher", "plugins", "trigger", "builtin", "power", "vpn", "qr", "clipboard", "search"]
|
||||
|
||||
Repeater {
|
||||
model: ["dms_settings", "dms_notepad", "dms_sysmon", "dms_settings_search", "dms_clipboard_search", "dms_power", "dms_vpn", "dms_colorpicker", "dms_qr_generator"]
|
||||
model: root.builtInPluginIds.filter(id => AppSearchService.builtInPlugins[id]?.isLauncher === true)
|
||||
|
||||
SettingsRow {
|
||||
id: builtInRow
|
||||
@@ -657,14 +634,12 @@ Item {
|
||||
|
||||
iconName: plugin?.cornerIcon ?? "extension"
|
||||
title: plugin?.name ?? modelData
|
||||
subtitle: plugin?.comment ?? ""
|
||||
|
||||
DankTextField {
|
||||
outlined: true
|
||||
leftIconName: "keyboard"
|
||||
labelText: I18n.tr("Trigger", "noun, launcher plugin trigger prefix text field label")
|
||||
width: Theme.fontSizeMedium * 6 + Theme.iconButtonSize
|
||||
visible: builtInRow.plugin?.isLauncher === true
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
onTextEdited: SettingsData.setBuiltInPluginSetting(builtInRow.modelData, "trigger", text)
|
||||
Component.onCompleted: text = SettingsData.getBuiltInPluginSetting(builtInRow.modelData, "trigger", builtInRow.plugin?.defaultTrigger ?? "")
|
||||
@@ -790,110 +765,58 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
SettingsRow {
|
||||
body: Column {
|
||||
id: rankedAppsList
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
Repeater {
|
||||
model: recentAppsCard.rankedAppsModel
|
||||
|
||||
Repeater {
|
||||
model: recentAppsCard.rankedAppsModel
|
||||
SettingsRow {
|
||||
id: rankedAppRow
|
||||
|
||||
delegate: Rectangle {
|
||||
width: rankedAppsList.width
|
||||
height: 48
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.floatingWindowFieldColor
|
||||
border.width: 0
|
||||
required property var modelData
|
||||
required property int index
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
title: modelData.name || I18n.tr("Unknown App")
|
||||
subtitle: root.lastLaunchedText(modelData.lastUsed)
|
||||
leading: [
|
||||
StyledText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: Theme.iconSize
|
||||
text: (rankedAppRow.index + 1).toString()
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Theme.fontWeightMedium
|
||||
color: Theme.primary
|
||||
},
|
||||
AppIconRenderer {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: Theme.iconSize
|
||||
height: Theme.iconSize
|
||||
iconValue: rankedAppRow.modelData.icon || "application-x-executable"
|
||||
iconSize: Theme.iconSize
|
||||
fallbackText: (rankedAppRow.modelData.name || "?").charAt(0).toUpperCase()
|
||||
}
|
||||
]
|
||||
|
||||
StyledText {
|
||||
text: (index + 1).toString()
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Theme.fontWeightMedium
|
||||
color: Theme.primary
|
||||
width: 20
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
AppIconRenderer {
|
||||
width: 24
|
||||
height: 24
|
||||
iconValue: modelData.icon || "application-x-executable"
|
||||
iconSize: 24
|
||||
fallbackText: (modelData.name || "?").charAt(0).toUpperCase()
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingXXS
|
||||
|
||||
StyledText {
|
||||
text: modelData.name || I18n.tr("Unknown App")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
font.weight: Theme.fontWeightMedium
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: {
|
||||
if (!modelData.lastUsed)
|
||||
return I18n.tr("Never used");
|
||||
var date = new Date(modelData.lastUsed);
|
||||
var now = new Date();
|
||||
var diffMs = now - date;
|
||||
var diffMins = Math.floor(diffMs / (1000 * 60));
|
||||
var diffHours = Math.floor(diffMs / (1000 * 60 * 60));
|
||||
var diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
||||
if (diffMins < 1)
|
||||
return I18n.tr("Last launched just now");
|
||||
if (diffMins < 60)
|
||||
return diffMins === 1 ? I18n.tr("Last launched %1 minute ago", "singular, app usage list in launcher settings, %1 is 1").arg(diffMins) : I18n.tr("Last launched %1 minutes ago", "plural, app usage list in launcher settings, %1 is a count").arg(diffMins);
|
||||
if (diffHours < 24)
|
||||
return diffHours === 1 ? I18n.tr("Last launched %1 hour ago", "singular, app usage list in launcher settings, %1 is 1").arg(diffHours) : I18n.tr("Last launched %1 hours ago", "plural, app usage list in launcher settings, %1 is a count").arg(diffHours);
|
||||
if (diffDays < 7)
|
||||
return diffDays === 1 ? I18n.tr("Last launched %1 day ago", "singular, app usage list in launcher settings, %1 is 1").arg(diffDays) : I18n.tr("Last launched %1 days ago", "plural, app usage list in launcher settings, %1 is a count").arg(diffDays);
|
||||
return I18n.tr("Last launched %1", "app usage list in launcher settings, %1 is a localized date").arg(date.toLocaleDateString());
|
||||
}
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
circular: true
|
||||
iconName: "close"
|
||||
Accessible.name: I18n.tr("Remove")
|
||||
iconSize: 16
|
||||
iconColor: Theme.error
|
||||
onClicked: {
|
||||
var currentRanking = Object.assign({}, AppUsageHistoryData.appUsageRanking || {});
|
||||
delete currentRanking[modelData.id];
|
||||
AppUsageHistoryData.appUsageRanking = currentRanking;
|
||||
AppUsageHistoryData.saveSettings();
|
||||
}
|
||||
}
|
||||
DankActionButton {
|
||||
iconName: "close"
|
||||
Accessible.name: I18n.tr("Remove")
|
||||
iconColor: Theme.error
|
||||
onClicked: {
|
||||
const currentRanking = Object.assign({}, AppUsageHistoryData.appUsageRanking || {});
|
||||
delete currentRanking[rankedAppRow.modelData.id];
|
||||
AppUsageHistoryData.appUsageRanking = currentRanking;
|
||||
AppUsageHistoryData.saveSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: I18n.tr("No apps have been launched yet.")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceVariantText
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
visible: recentAppsCard.rankedAppsModel.length === 0
|
||||
}
|
||||
SettingsRow {
|
||||
visible: recentAppsCard.rankedAppsModel.length === 0
|
||||
body: StyledText {
|
||||
width: parent.width
|
||||
text: I18n.tr("No apps have been launched yet.")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceVariantText
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
@@ -225,80 +224,66 @@ FocusScope {
|
||||
}
|
||||
}
|
||||
|
||||
DankCollapsibleSection {
|
||||
id: pluginDetails
|
||||
width: parent.width
|
||||
SettingsCard {
|
||||
title: I18n.tr("Plugin details", "plugin metadata and maintenance")
|
||||
settingKey: "pluginDetails"
|
||||
visible: root.pluginData !== null
|
||||
collapsible: true
|
||||
expanded: false
|
||||
|
||||
SettingsCard {
|
||||
Layout.fillWidth: true
|
||||
visible: pluginDetails.expanded
|
||||
settingKey: "pluginDetails"
|
||||
SettingsRow {
|
||||
title: [root.pluginData?.version, root.pluginData?.author].filter(Boolean).join(" · ")
|
||||
}
|
||||
SettingsRow {
|
||||
subtitle: root.pluginData?.description || ""
|
||||
visible: subtitle !== ""
|
||||
}
|
||||
|
||||
SettingsRow {
|
||||
title: [root.pluginData?.version, root.pluginData?.author].filter(Boolean).join(" · ")
|
||||
}
|
||||
SettingsRow {
|
||||
subtitle: root.pluginData?.description || ""
|
||||
visible: subtitle !== ""
|
||||
}
|
||||
SettingsRow {
|
||||
visible: root.permissions.length > 0
|
||||
body: Flow {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingXS
|
||||
|
||||
SettingsRow {
|
||||
visible: root.permissions.length > 0
|
||||
body: Flow {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingXS
|
||||
Repeater {
|
||||
model: root.permissions
|
||||
|
||||
Repeater {
|
||||
model: root.permissions
|
||||
DankBadge {
|
||||
required property string modelData
|
||||
|
||||
Rectangle {
|
||||
required property string modelData
|
||||
|
||||
height: Theme.iconSizeMedium
|
||||
width: permissionText.implicitWidth + Theme.spacingS * 2
|
||||
radius: Theme.fullRadius(width, height)
|
||||
color: Theme.withAlpha(Theme.primary, Theme.tonalTintAlpha)
|
||||
|
||||
StyledText {
|
||||
id: permissionText
|
||||
anchors.centerIn: parent
|
||||
text: parent.modelData
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.primary
|
||||
}
|
||||
}
|
||||
text: modelData
|
||||
color: Theme.primaryHover
|
||||
textColor: Theme.primary
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsRow {
|
||||
iconName: "download"
|
||||
title: I18n.tr("Update plugin")
|
||||
clickable: true
|
||||
visible: DMSService.dmsAvailable && root.isLoaded && root.hasUpdate && !root.isSystemPlugin
|
||||
enabled: !root.operationPending
|
||||
onClicked: root.requestUpdate()
|
||||
}
|
||||
SettingsRow {
|
||||
iconName: "download"
|
||||
title: I18n.tr("Update plugin")
|
||||
clickable: true
|
||||
visible: DMSService.dmsAvailable && root.isLoaded && root.hasUpdate && !root.isSystemPlugin
|
||||
enabled: !root.operationPending
|
||||
onClicked: root.requestUpdate()
|
||||
}
|
||||
|
||||
SettingsRow {
|
||||
iconName: "refresh"
|
||||
title: I18n.tr("Reload plugin")
|
||||
clickable: true
|
||||
visible: root.isLoaded
|
||||
enabled: !root.isReloading && !root.operationPending
|
||||
onClicked: root.reload()
|
||||
}
|
||||
SettingsRow {
|
||||
iconName: "refresh"
|
||||
title: I18n.tr("Reload plugin")
|
||||
clickable: true
|
||||
visible: root.isLoaded
|
||||
enabled: !root.isReloading && !root.operationPending
|
||||
onClicked: root.reload()
|
||||
}
|
||||
|
||||
SettingsRow {
|
||||
iconName: "delete"
|
||||
title: I18n.tr("Uninstall plugin")
|
||||
clickable: true
|
||||
visible: DMSService.dmsAvailable && !root.isSystemPlugin
|
||||
enabled: !root.operationPending
|
||||
onClicked: root.requestUninstall()
|
||||
}
|
||||
SettingsRow {
|
||||
iconName: "delete"
|
||||
title: I18n.tr("Uninstall plugin")
|
||||
clickable: true
|
||||
visible: DMSService.dmsAvailable && !root.isSystemPlugin
|
||||
enabled: !root.operationPending
|
||||
onClicked: root.requestUninstall()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
Item {
|
||||
SettingsRow {
|
||||
id: root
|
||||
|
||||
property string colorMode: "primary"
|
||||
@@ -15,99 +15,84 @@ Item {
|
||||
signal colorModeSelected(string mode)
|
||||
signal customColorSelected(color selectedColor)
|
||||
|
||||
width: parent?.width ?? 0
|
||||
height: colorColumn.height + Theme.spacingM * 2
|
||||
title: I18n.tr("Color")
|
||||
|
||||
Column {
|
||||
id: colorColumn
|
||||
width: parent.width - Theme.spacingM * 2
|
||||
x: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
body: Row {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Color")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
Repeater {
|
||||
model: [
|
||||
{
|
||||
id: "primary",
|
||||
label: I18n.tr("Primary"),
|
||||
color: Theme.primary
|
||||
},
|
||||
{
|
||||
id: "secondary",
|
||||
label: I18n.tr("Secondary"),
|
||||
color: Theme.secondary
|
||||
},
|
||||
{
|
||||
id: "custom",
|
||||
label: I18n.tr("Custom"),
|
||||
color: root.customColor
|
||||
}
|
||||
]
|
||||
|
||||
Row {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
Rectangle {
|
||||
required property var modelData
|
||||
required property int index
|
||||
|
||||
Repeater {
|
||||
model: [
|
||||
{
|
||||
id: "primary",
|
||||
label: I18n.tr("Primary"),
|
||||
color: Theme.primary
|
||||
},
|
||||
{
|
||||
id: "secondary",
|
||||
label: I18n.tr("Secondary"),
|
||||
color: Theme.secondary
|
||||
},
|
||||
{
|
||||
id: "custom",
|
||||
label: I18n.tr("Custom"),
|
||||
color: root.customColor
|
||||
}
|
||||
]
|
||||
width: (parent.width - Theme.spacingS * 2) / 3
|
||||
height: Theme.listItemHeight + Theme.spacingXS
|
||||
radius: Theme.cornerRadius
|
||||
color: root.colorMode === modelData.id ? Theme.primarySelected : Theme.chipSurface
|
||||
border.color: root.colorMode === modelData.id ? Theme.primary : Theme.withAlpha(Theme.primary, 0)
|
||||
border.width: Theme.outlineWidthFocused
|
||||
|
||||
Rectangle {
|
||||
required property var modelData
|
||||
required property int index
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
spacing: Theme.spacingXS
|
||||
|
||||
width: (parent.width - Theme.spacingS * 2) / 3
|
||||
height: Theme.listItemHeight + Theme.spacingXS
|
||||
radius: Theme.cornerRadius
|
||||
color: root.colorMode === modelData.id ? Theme.primarySelected : Theme.chipSurface
|
||||
border.color: root.colorMode === modelData.id ? Theme.primary : Theme.withAlpha(Theme.primary, 0)
|
||||
border.width: Theme.outlineWidthFocused
|
||||
DankColorSwatch {
|
||||
width: Theme.iconSize
|
||||
height: Theme.iconSize
|
||||
swatchColor: modelData.color
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
spacing: Theme.spacingXS
|
||||
|
||||
DankColorSwatch {
|
||||
width: Theme.iconSize
|
||||
height: Theme.iconSize
|
||||
swatchColor: modelData.color
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
DankIcon {
|
||||
visible: modelData.id === "custom"
|
||||
anchors.centerIn: parent
|
||||
name: "colorize"
|
||||
size: Theme.iconSizeSmall
|
||||
color: Theme.background
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: modelData.label
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
DankIcon {
|
||||
visible: modelData.id === "custom"
|
||||
anchors.centerIn: parent
|
||||
name: "colorize"
|
||||
size: Theme.iconSizeSmall
|
||||
color: Theme.background
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
if (modelData.id !== "custom") {
|
||||
root.colorModeSelected(modelData.id);
|
||||
return;
|
||||
}
|
||||
PopoutService.colorPickerModal.selectedColor = root.customColor;
|
||||
PopoutService.colorPickerModal.pickerTitle = root.pickerTitle;
|
||||
PopoutService.colorPickerModal.onColorSelectedCallback = function (selectedColor) {
|
||||
root.customColorSelected(selectedColor);
|
||||
root.colorModeSelected("custom");
|
||||
};
|
||||
PopoutService.colorPickerModal.show();
|
||||
StyledText {
|
||||
text: modelData.label
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
if (modelData.id !== "custom") {
|
||||
root.colorModeSelected(modelData.id);
|
||||
return;
|
||||
}
|
||||
PopoutService.colorPickerModal.selectedColor = root.customColor;
|
||||
PopoutService.colorPickerModal.pickerTitle = root.pickerTitle;
|
||||
PopoutService.colorPickerModal.onColorSelectedCallback = function (selectedColor) {
|
||||
root.customColorSelected(selectedColor);
|
||||
root.colorModeSelected("custom");
|
||||
};
|
||||
PopoutService.colorPickerModal.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,5 +7,7 @@ DankReorderList {
|
||||
|
||||
readonly property bool isSettingsRow: true
|
||||
readonly property bool transparentSlot: true
|
||||
readonly property bool firstInGroup: parent?.isSettingsGroupHost ? parent.isEdge(root, true) : true
|
||||
readonly property bool lastInGroup: parent?.isSettingsGroupHost ? parent.isEdge(root, false) : true
|
||||
Component.onCompleted: flickable = QmlUtils.findParentFlickable(root.parent)
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@ SettingsRow {
|
||||
|
||||
paintBackground: true
|
||||
rowColor: dragging ? Theme.blend(SettingsMetrics.rowColor, Theme.onSurface, Theme.stateLayerDrag) : SettingsMetrics.rowColor
|
||||
topRadius: dragging || position === 0 ? Theme.groupedListOuterRadius : Theme.groupedListInnerRadius
|
||||
bottomRadius: dragging || position === reorderList.count - 1 ? Theme.groupedListOuterRadius : Theme.groupedListInnerRadius
|
||||
topRadius: dragging || (position === 0 && reorderList.firstInGroup) ? Theme.groupedListOuterRadius : Theme.groupedListInnerRadius
|
||||
bottomRadius: dragging || (position === reorderList.count - 1 && reorderList.lastInGroup) ? Theme.groupedListOuterRadius : Theme.groupedListInnerRadius
|
||||
z: dragging ? 100 : 0
|
||||
|
||||
function focusHandle(reason) {
|
||||
|
||||
@@ -86,8 +86,16 @@ T.Control {
|
||||
}
|
||||
|
||||
function _edge(first) {
|
||||
if (groupItem.parent?.isSettingsGroupHost)
|
||||
return groupItem.parent.isEdge(groupItem, first);
|
||||
const container = groupItem.parent;
|
||||
if (container?.isSettingsGroupHost)
|
||||
return container.isEdge(groupItem, first);
|
||||
if (!_edgeInContainer(first))
|
||||
return false;
|
||||
const host = container?.parent;
|
||||
return host?.isSettingsGroupHost ? host.isEdge(container, first) : true;
|
||||
}
|
||||
|
||||
function _edgeInContainer(first) {
|
||||
const siblings = groupItem.parent?.visibleChildren;
|
||||
if (!siblings)
|
||||
return true;
|
||||
|
||||
@@ -136,6 +136,7 @@ TAB_INDEX_MAP = {
|
||||
"GammaControlTab.qml": 25,
|
||||
"DisplayWidgetsTab.qml": 26,
|
||||
"DesktopWidgetsTab.qml": 27,
|
||||
"DesktopWidgetTab.qml": 63,
|
||||
"AudioTab.qml": 29,
|
||||
"LocaleTab.qml": 30,
|
||||
"GreeterTab.qml": 31,
|
||||
|
||||
@@ -4443,6 +4443,30 @@
|
||||
],
|
||||
"icon": "border_style"
|
||||
},
|
||||
{
|
||||
"section": "launcherBuiltInApps",
|
||||
"label": "Built-in apps",
|
||||
"tabIndex": 9,
|
||||
"category": "Launcher",
|
||||
"keywords": [
|
||||
"app drawer",
|
||||
"app menu",
|
||||
"applications",
|
||||
"apps",
|
||||
"built",
|
||||
"builtin",
|
||||
"color picker",
|
||||
"drawer",
|
||||
"launcher",
|
||||
"menu",
|
||||
"notepad",
|
||||
"settings",
|
||||
"start",
|
||||
"start menu",
|
||||
"system monitor"
|
||||
],
|
||||
"icon": "apps"
|
||||
},
|
||||
{
|
||||
"section": "launcherBuiltInPlugins",
|
||||
"label": "Built-in plugins",
|
||||
@@ -4455,19 +4479,19 @@
|
||||
"applications",
|
||||
"built",
|
||||
"builtin",
|
||||
"calculator",
|
||||
"clipboard",
|
||||
"drawer",
|
||||
"extensions",
|
||||
"launcher",
|
||||
"menu",
|
||||
"notepad",
|
||||
"plugins",
|
||||
"power",
|
||||
"settings",
|
||||
"qr",
|
||||
"search",
|
||||
"start",
|
||||
"start menu",
|
||||
"trigger",
|
||||
"vpn",
|
||||
"widgets"
|
||||
],
|
||||
"icon": "extension"
|
||||
@@ -9490,6 +9514,32 @@
|
||||
],
|
||||
"icon": "add"
|
||||
},
|
||||
{
|
||||
"section": "_hub_desktop_widgets",
|
||||
"label": "Desktop widgets",
|
||||
"tabIndex": 27,
|
||||
"page": "desktop_widgets",
|
||||
"category": "Desktop widgets",
|
||||
"keywords": [
|
||||
"addons",
|
||||
"clocks",
|
||||
"components",
|
||||
"conky",
|
||||
"desktop",
|
||||
"desktop clock",
|
||||
"extensions",
|
||||
"modules",
|
||||
"monitors",
|
||||
"plugins",
|
||||
"settings",
|
||||
"system",
|
||||
"time",
|
||||
"watch",
|
||||
"widget",
|
||||
"widgets"
|
||||
],
|
||||
"icon": "widgets"
|
||||
},
|
||||
{
|
||||
"section": "_tab_27",
|
||||
"label": "Desktop widgets",
|
||||
@@ -14858,6 +14908,29 @@
|
||||
],
|
||||
"parentLabel": "Interface style"
|
||||
},
|
||||
{
|
||||
"section": "_tab_54",
|
||||
"label": "Bar widgets: Widget settings",
|
||||
"tabIndex": 54,
|
||||
"category": "Widget settings",
|
||||
"keywords": [
|
||||
"bar",
|
||||
"components",
|
||||
"instance",
|
||||
"modules",
|
||||
"options",
|
||||
"panel",
|
||||
"settings",
|
||||
"statusbar",
|
||||
"taskbar",
|
||||
"topbar",
|
||||
"widget",
|
||||
"widgets"
|
||||
],
|
||||
"icon": "tune",
|
||||
"parentLabel": "Bar widgets",
|
||||
"description": "Options of one widget instance"
|
||||
},
|
||||
{
|
||||
"section": "barWidgetGeneral",
|
||||
"label": "Show in dock",
|
||||
@@ -14880,29 +14953,6 @@
|
||||
"parentLabel": "Bar widgets",
|
||||
"icon": "SettingsUiState.selectedWidgetIcon"
|
||||
},
|
||||
{
|
||||
"section": "_tab_54",
|
||||
"label": "Widget settings",
|
||||
"tabIndex": 54,
|
||||
"category": "Widget settings",
|
||||
"keywords": [
|
||||
"bar",
|
||||
"components",
|
||||
"instance",
|
||||
"modules",
|
||||
"options",
|
||||
"panel",
|
||||
"settings",
|
||||
"statusbar",
|
||||
"taskbar",
|
||||
"topbar",
|
||||
"widget",
|
||||
"widgets"
|
||||
],
|
||||
"icon": "tune",
|
||||
"parentLabel": "Bar widgets",
|
||||
"description": "Options of one widget instance"
|
||||
},
|
||||
{
|
||||
"section": "mutedApps",
|
||||
"label": "Muted apps",
|
||||
@@ -15593,5 +15643,26 @@
|
||||
"parentLabel": "Security",
|
||||
"description": "DMS removes its managed block from /etc/pam.d/greetd and stops write services",
|
||||
"conditionKey": "greeterAvailable"
|
||||
},
|
||||
{
|
||||
"section": "_tab_63",
|
||||
"label": "Desktop widgets: Widget settings",
|
||||
"tabIndex": 63,
|
||||
"category": "Widget settings",
|
||||
"keywords": [
|
||||
"components",
|
||||
"conky",
|
||||
"desktop",
|
||||
"desktop clock",
|
||||
"instance",
|
||||
"modules",
|
||||
"options",
|
||||
"settings",
|
||||
"widget",
|
||||
"widgets"
|
||||
],
|
||||
"icon": "tune",
|
||||
"parentLabel": "Desktop widgets",
|
||||
"description": "Options of one widget instance"
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user