mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-22 03:04:01 -04:00
it doesnt interfere, with a setting to turn it off Some compositors like kwin/labwc/sway cannot have this without breaking some built in layering they do. niri can have this, but for focus follow mouse it may need to be disabled. fixes #3717
308 lines
10 KiB
QML
308 lines
10 KiB
QML
pragma ComponentBehavior: Bound
|
|
|
|
import QtQuick
|
|
import Quickshell
|
|
import qs.Common
|
|
import qs.Services
|
|
import qs.DCommon.Widgets
|
|
import qs.Modules.Settings.Widgets
|
|
|
|
Item {
|
|
id: root
|
|
|
|
LayoutMirroring.enabled: I18n.isRtl
|
|
LayoutMirroring.childrenInherit: true
|
|
|
|
property var groupCollapsedStates: ({})
|
|
property var parentModal: null
|
|
property string newGroupName: ""
|
|
property string renamingGroupId: ""
|
|
|
|
readonly property var allInstances: SettingsData.desktopWidgetInstances || []
|
|
readonly property var allGroups: SettingsData.desktopWidgetGroups || []
|
|
|
|
readonly property bool dragActive: dragGroup.active
|
|
property alias reorderGroup: dragGroup
|
|
|
|
SettingsReorderGroup {
|
|
id: dragGroup
|
|
|
|
coordinateItem: root
|
|
onTransferred: (source, sourceIndex, target, targetIndex) => SettingsData.moveDesktopWidgetInstanceToGroup(source.model[sourceIndex].id, target.groupKey || null, targetIndex)
|
|
}
|
|
|
|
function storageKeyFor(sectionKey) {
|
|
return sectionKey === "" ? "_ungrouped" : sectionKey;
|
|
}
|
|
|
|
function toggleCollapsed(sectionKey) {
|
|
const key = storageKeyFor(sectionKey);
|
|
var states = Object.assign({}, groupCollapsedStates);
|
|
states[key] = !(states[key] ?? false);
|
|
groupCollapsedStates = states;
|
|
}
|
|
|
|
function configureWidget(instanceId, title) {
|
|
SettingsUiState.selectedDesktopWidgetId = instanceId;
|
|
SettingsUiState.selectedWidgetTitle = title;
|
|
parentModal?.navigateTo("desktop_widget");
|
|
}
|
|
|
|
function openRenameDialog(group) {
|
|
renamingGroupId = group.id;
|
|
renameDialog.show(group.name);
|
|
}
|
|
|
|
function saveGroupName(name) {
|
|
SettingsData.updateDesktopWidgetGroup(renamingGroupId, {
|
|
name: name
|
|
});
|
|
renameDialog.hide();
|
|
}
|
|
|
|
function showWidgetBrowser() {
|
|
widgetBrowserLoader.active = true;
|
|
if (widgetBrowserLoader.item)
|
|
widgetBrowserLoader.item.show();
|
|
}
|
|
|
|
function showDesktopPluginBrowser() {
|
|
desktopPluginBrowserLoader.active = true;
|
|
if (desktopPluginBrowserLoader.item)
|
|
desktopPluginBrowserLoader.item.show();
|
|
}
|
|
|
|
LazyLoader {
|
|
id: widgetBrowserLoader
|
|
active: false
|
|
|
|
DesktopWidgetBrowser {
|
|
parentModal: root.parentModal
|
|
onWidgetAdded: widgetType => {
|
|
ToastService.showInfo(I18n.tr("Widget added"));
|
|
}
|
|
}
|
|
}
|
|
|
|
LazyLoader {
|
|
id: desktopPluginBrowserLoader
|
|
active: false
|
|
|
|
PluginBrowser {
|
|
parentModal: root.parentModal
|
|
typeFilter: "desktop-widget"
|
|
}
|
|
}
|
|
|
|
SettingsPage {
|
|
id: mainColumn
|
|
|
|
SettingsCard {
|
|
settingKey: "desktopGeneral"
|
|
tags: ["desktop", "context", "menu", "right click", "wallpaper"]
|
|
width: parent.width
|
|
iconName: "mouse"
|
|
title: I18n.tr("General")
|
|
|
|
SettingsDropdownRow {
|
|
settingKey: "desktopContextMenu"
|
|
text: I18n.tr("Right-click menu")
|
|
description: I18n.tr("Auto turns it off on compositors that use clicks on the empty desktop themselves", "desktop context menu dropdown description")
|
|
options: [I18n.tr("Auto"), I18n.tr("On"), I18n.tr("Off")]
|
|
readonly property var values: ["auto", "on", "off"]
|
|
currentValue: options[Math.max(0, values.indexOf(SettingsData.desktopContextMenu))]
|
|
onValueChanged: value => SettingsData.set("desktopContextMenu", values[options.indexOf(value)])
|
|
}
|
|
}
|
|
|
|
SettingsCard {
|
|
settingKey: "desktopWidgetGroups"
|
|
tags: ["groups", "profiles", "layouts"]
|
|
width: parent.width
|
|
iconName: "folder"
|
|
title: I18n.tr("Groups", "noun, card title for desktop widget groups")
|
|
collapsible: true
|
|
expanded: root.allGroups.length > 0
|
|
|
|
SettingsRow {
|
|
body: Row {
|
|
spacing: Theme.spacingS
|
|
width: parent.width
|
|
|
|
DTextField {
|
|
id: newGroupField
|
|
outlined: true
|
|
leftIconName: "folder"
|
|
labelText: I18n.tr("Name")
|
|
width: parent.width - addGroupBtn.width - Theme.spacingS
|
|
text: root.newGroupName
|
|
onTextChanged: root.newGroupName = text
|
|
onAccepted: {
|
|
if (!text.trim())
|
|
return;
|
|
SettingsData.createDesktopWidgetGroup(text.trim());
|
|
root.newGroupName = "";
|
|
text = "";
|
|
}
|
|
}
|
|
|
|
DButton {
|
|
id: addGroupBtn
|
|
iconName: "add"
|
|
text: I18n.tr("Add")
|
|
enabled: root.newGroupName.trim().length > 0
|
|
onClicked: {
|
|
SettingsData.createDesktopWidgetGroup(root.newGroupName.trim());
|
|
root.newGroupName = "";
|
|
newGroupField.text = "";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Repeater {
|
|
model: root.allGroups
|
|
|
|
delegate: SettingsRow {
|
|
id: groupRow
|
|
|
|
required property var modelData
|
|
|
|
iconName: "folder"
|
|
title: modelData.name
|
|
singleLineTitle: true
|
|
|
|
DActionButton {
|
|
iconName: "edit"
|
|
tooltipText: I18n.tr("Rename")
|
|
onClicked: root.openRenameDialog(groupRow.modelData)
|
|
}
|
|
|
|
DActionButton {
|
|
iconName: "delete"
|
|
iconColor: Theme.error
|
|
tooltipText: I18n.tr("Delete")
|
|
onClicked: {
|
|
SettingsData.removeDesktopWidgetGroup(groupRow.modelData.id);
|
|
ToastService.showInfo(I18n.tr("Group removed"));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Repeater {
|
|
id: groupsRepeater
|
|
model: root.allGroups
|
|
|
|
DesktopWidgetGroupSection {
|
|
required property var modelData
|
|
required property int index
|
|
|
|
width: mainColumn.columnWidth
|
|
reorderGroup: dragGroup
|
|
groupId: modelData.id
|
|
groupName: modelData.name
|
|
isUngrouped: false
|
|
showHeader: true
|
|
collapsed: root.groupCollapsedStates[modelData.id] ?? false
|
|
instances: root.allInstances.filter(inst => inst.group === modelData.id)
|
|
visible: instances.length > 0 || root.dragActive
|
|
|
|
onCollapseToggled: key => root.toggleCollapsed(key)
|
|
onConfigureRequested: (instanceId, title) => root.configureWidget(instanceId, title)
|
|
onDuplicateRequested: instanceId => SettingsData.duplicateDesktopWidgetInstance(instanceId)
|
|
onDeleteRequested: instanceId => {
|
|
SettingsData.removeDesktopWidgetInstance(instanceId);
|
|
ToastService.showInfo(I18n.tr("Widget removed"));
|
|
}
|
|
}
|
|
}
|
|
|
|
DesktopWidgetGroupSection {
|
|
id: ungroupedSection
|
|
|
|
readonly property var ungroupedInstances: root.allInstances.filter(inst => {
|
|
if (!inst.group)
|
|
return true;
|
|
return !root.allGroups.some(g => g.id === inst.group);
|
|
})
|
|
|
|
width: mainColumn.columnWidth
|
|
reorderGroup: dragGroup
|
|
groupId: null
|
|
groupName: I18n.tr("Ungrouped", "section header for desktop widgets without a group")
|
|
isUngrouped: true
|
|
showHeader: root.allGroups.length > 0
|
|
collapsed: root.groupCollapsedStates["_ungrouped"] ?? false
|
|
instances: ungroupedInstances
|
|
visible: ungroupedInstances.length > 0 || root.dragActive
|
|
|
|
onCollapseToggled: key => root.toggleCollapsed(key)
|
|
onConfigureRequested: (instanceId, title) => root.configureWidget(instanceId, title)
|
|
onDuplicateRequested: instanceId => SettingsData.duplicateDesktopWidgetInstance(instanceId)
|
|
onDeleteRequested: instanceId => {
|
|
SettingsData.removeDesktopWidgetInstance(instanceId);
|
|
ToastService.showInfo(I18n.tr("Widget removed"));
|
|
}
|
|
}
|
|
|
|
StyledText {
|
|
visible: root.allInstances.length === 0
|
|
text: I18n.tr("No widgets added. Click \"Add widget\" to get started.")
|
|
font.pixelSize: Theme.fontSizeMedium
|
|
color: Theme.surfaceVariantText
|
|
width: parent.width
|
|
wrapMode: Text.WordWrap
|
|
horizontalAlignment: Text.AlignLeft
|
|
}
|
|
|
|
SettingsCard {
|
|
width: parent.width
|
|
iconName: "info"
|
|
title: I18n.tr("Help", "noun, card title for desktop widget usage tips")
|
|
|
|
SettingsRow {
|
|
iconName: "drag_indicator"
|
|
iconBox: true
|
|
title: I18n.tr("Reorder & group")
|
|
subtitle: I18n.tr("Drag a widget by its handle here to reorder it or drop it into another group")
|
|
}
|
|
}
|
|
|
|
SettingsFabBar {
|
|
DFab {
|
|
text: I18n.tr("Browse plugins")
|
|
iconName: "store"
|
|
colorRole: "secondaryContainer"
|
|
onClicked: root.showDesktopPluginBrowser()
|
|
}
|
|
|
|
DFab {
|
|
text: I18n.tr("Edit widgets")
|
|
iconName: "edit"
|
|
colorRole: "secondaryContainer"
|
|
onClicked: DesktopWidgetRegistry.editing = true
|
|
}
|
|
|
|
DFab {
|
|
text: I18n.tr("Add widget")
|
|
iconName: "add"
|
|
onClicked: root.showWidgetBrowser()
|
|
}
|
|
}
|
|
}
|
|
|
|
SettingsReorderPreview {
|
|
group: dragGroup
|
|
}
|
|
|
|
SettingsRenameDialog {
|
|
id: renameDialog
|
|
parent: root.parentModal?.modalFocusScope ?? root
|
|
supportingText: root.allGroups.find(g => g.id === root.renamingGroupId)?.name ?? ""
|
|
leftIconName: "folder"
|
|
onAccepted: name => root.saveGroupName(name)
|
|
}
|
|
}
|