diff --git a/quickshell/Common/SettingsData.qml b/quickshell/Common/SettingsData.qml index 9f69a4c2..59b3facf 100644 --- a/quickshell/Common/SettingsData.qml +++ b/quickshell/Common/SettingsData.qml @@ -108,6 +108,7 @@ Singleton { } property bool clipboardEnterToPaste: false + property var clipboardVisibleEntryActions: ["pin", "edit", "delete"] property var launcherPluginVisibility: ({}) diff --git a/quickshell/Common/settings/SettingsSpec.js b/quickshell/Common/settings/SettingsSpec.js index 40a437bc..693154fa 100644 --- a/quickshell/Common/settings/SettingsSpec.js +++ b/quickshell/Common/settings/SettingsSpec.js @@ -572,6 +572,7 @@ var SPEC = { builtInPluginSettings: { def: {} }, clipboardEnterToPaste: { def: false }, + clipboardVisibleEntryActions: { def: ["pin", "edit", "delete"] }, launcherPluginVisibility: { def: {} }, launcherPluginOrder: { def: [] }, diff --git a/quickshell/Modals/Clipboard/ClipboardEntry.qml b/quickshell/Modals/Clipboard/ClipboardEntry.qml index 8cd7811a..439cdf8c 100644 --- a/quickshell/Modals/Clipboard/ClipboardEntry.qml +++ b/quickshell/Modals/Clipboard/ClipboardEntry.qml @@ -22,7 +22,14 @@ Rectangle { readonly property string entryType: modal ? modal.getEntryType(entry) : "text" readonly property string entryPreview: modal ? modal.getEntryPreview(entry) : "" readonly property var pinnedDuplicateEntry: !entry.pinned ? ClipboardService.getPinnedEntryByHash(entry.hash) : null - readonly property bool effectivePinned: entry.pinned || pinnedDuplicateEntry !== null + readonly property bool hasPinnedDuplicate: pinnedDuplicateEntry !== null + readonly property bool effectivePinned: entry.pinned || hasPinnedDuplicate + readonly property var visibleEntryActions: SettingsData.clipboardVisibleEntryActions || ["pin", "edit", "delete"] + readonly property bool showPinAction: visibleEntryActions.includes("pin") + readonly property bool showEditAction: visibleEntryActions.includes("edit") + readonly property bool showDeleteAction: visibleEntryActions.includes("delete") + readonly property bool showPinnedIndicator: !showPinAction && effectivePinned + readonly property bool showAnyAction: showPinAction || showEditAction || showDeleteAction || showPinnedIndicator radius: Theme.cornerRadius color: { @@ -63,12 +70,31 @@ Rectangle { anchors.rightMargin: Theme.spacingS anchors.verticalCenter: parent.verticalCenter spacing: Theme.spacingXS + visible: root.showAnyAction DankActionButton { iconName: "push_pin" iconSize: Theme.iconSize - 6 - iconColor: effectivePinned ? Theme.primary : Theme.surfaceText - backgroundColor: effectivePinned ? Theme.primarySelected : "transparent" + iconColor: Theme.primary + backgroundColor: Theme.primarySelected + visible: root.showPinnedIndicator + onClicked: { + if (entry.pinned) { + unpinRequested(entry); + return; + } + if (pinnedDuplicateEntry) { + unpinRequested(pinnedDuplicateEntry); + } + } + } + + DankActionButton { + iconName: "push_pin" + iconSize: Theme.iconSize - 6 + iconColor: (entry.pinned || hasPinnedDuplicate) ? Theme.primary : Theme.surfaceText + backgroundColor: (entry.pinned || hasPinnedDuplicate) ? Theme.primarySelected : "transparent" + visible: root.showPinAction onClicked: { if (entry.pinned) { unpinRequested(entry); @@ -86,6 +112,7 @@ Rectangle { iconName: "edit" iconSize: Theme.iconSize - 6 iconColor: Theme.surfaceText + visible: root.showEditAction onClicked: { if (entryType === "image") { @@ -99,6 +126,7 @@ Rectangle { iconName: "close" iconSize: Theme.iconSize - 6 iconColor: Theme.surfaceText + visible: root.showDeleteAction onClicked: deleteRequested() } } @@ -106,8 +134,8 @@ Rectangle { Item { anchors.left: indexBadge.right anchors.leftMargin: Theme.spacingM - anchors.right: actionButtons.left - anchors.rightMargin: Theme.spacingM + anchors.right: root.showAnyAction ? actionButtons.left : parent.right + anchors.rightMargin: root.showAnyAction ? Theme.spacingM : Theme.spacingS anchors.verticalCenter: parent.verticalCenter // height: contentColumn.implicitHeight height: ClipboardConstants.itemHeight @@ -168,8 +196,8 @@ Rectangle { MouseArea { id: mouseArea anchors.left: parent.left - anchors.right: actionButtons.left - anchors.rightMargin: Theme.spacingS + anchors.right: root.showAnyAction ? actionButtons.left : parent.right + anchors.rightMargin: root.showAnyAction ? Theme.spacingS : 0 anchors.top: parent.top anchors.bottom: parent.bottom hoverEnabled: true diff --git a/quickshell/Modules/Settings/ClipboardTab.qml b/quickshell/Modules/Settings/ClipboardTab.qml index d477bb9c..ab842b0c 100644 --- a/quickshell/Modules/Settings/ClipboardTab.qml +++ b/quickshell/Modules/Settings/ClipboardTab.qml @@ -152,6 +152,9 @@ Item { } ] + readonly property var entryActionKeys: ["pin", "edit", "delete"] + readonly property var entryActionLabels: [I18n.tr("Pin"), I18n.tr("Edit"), I18n.tr("Delete")] + function getMaxHistoryText(value) { if (value <= 0) return "∞"; @@ -187,6 +190,29 @@ Item { return value.toString(); } + function visibleEntryActionKeys() { + return SettingsData.clipboardVisibleEntryActions || ["pin", "edit", "delete"]; + } + + function visibleEntryActionLabels() { + const visibleKeys = visibleEntryActionKeys(); + return entryActionKeys.map((key, index) => visibleKeys.includes(key) ? entryActionLabels[index] : null).filter(label => label !== null); + } + + function setVisibleEntryAction(index, selected) { + const actionKey = entryActionKeys[index]; + if (!actionKey) + return; + + let actions = visibleEntryActionKeys().slice(); + if (selected && !actions.includes(actionKey)) { + actions.push(actionKey); + } else if (!selected && actions.includes(actionKey)) { + actions = actions.filter(action => action !== actionKey); + } + SettingsData.set("clipboardVisibleEntryActions", actions); + } + function loadConfig() { configLoaded = false; configError = false; @@ -437,6 +463,24 @@ Item { checked: SettingsData.clipboardEnterToPaste onToggled: checked => SettingsData.set("clipboardEnterToPaste", checked) } + + SettingsButtonGroupRow { + tab: "clipboard" + tags: ["clipboard", "actions", "buttons", "hide", "density", "pin", "edit", "delete"] + settingKey: "clipboardVisibleEntryActions" + text: I18n.tr("Visible Entry Actions") + description: I18n.tr("Choose which action buttons appear on clipboard entries") + selectionMode: "multi" + model: root.entryActionLabels + currentSelection: root.visibleEntryActionLabels() + checkEnabled: false + buttonHeight: 28 + minButtonWidth: 56 + buttonPadding: Theme.spacingS + textSize: Theme.fontSizeSmall + spacing: 1 + onSelectionChanged: (index, selected) => root.setVisibleEntryAction(index, selected) + } } SettingsCard { diff --git a/quickshell/Modules/Settings/Widgets/SettingsButtonGroupRow.qml b/quickshell/Modules/Settings/Widgets/SettingsButtonGroupRow.qml index 4e82545d..e8c475cd 100644 --- a/quickshell/Modules/Settings/Widgets/SettingsButtonGroupRow.qml +++ b/quickshell/Modules/Settings/Widgets/SettingsButtonGroupRow.qml @@ -64,6 +64,8 @@ Item { property alias model: buttonGroup.model property alias currentIndex: buttonGroup.currentIndex + property alias initialSelection: buttonGroup.initialSelection + property alias currentSelection: buttonGroup.currentSelection property alias selectionMode: buttonGroup.selectionMode property alias buttonHeight: buttonGroup.buttonHeight property alias minButtonWidth: buttonGroup.minButtonWidth