diff --git a/quickshell/Modules/DankBar/Widgets/ClipboardButton.qml b/quickshell/Modules/DankBar/Widgets/ClipboardButton.qml index 5790f5ac6..0b60a25e8 100644 --- a/quickshell/Modules/DankBar/Widgets/ClipboardButton.qml +++ b/quickshell/Modules/DankBar/Widgets/ClipboardButton.qml @@ -11,6 +11,7 @@ BasePill { property bool isActive: false property bool isAutoHideBar: false + property bool dropConfirmed: false signal clipboardClicked signal showSavedItemsRequested @@ -33,6 +34,52 @@ BasePill { return Math.max(minValue, Math.min(maxValue, value)); } + function handleDrop(drop) { + if (!ClipboardService.clipboardAvailable) + return; + + if (drop.hasUrls && drop.urls.length > 0) { + const fileUrls = drop.urls.map(url => url.toString()).filter(url => url.startsWith("file://")); + if (fileUrls.length > 0) { + DMSService.sendRequest("clipboard.store", { + "data": fileUrls.join("\r\n"), + "mimeType": "text/uri-list" + }, response => { + if (response.error) { + ToastService.showError(I18n.tr("Failed to save dropped file")); + return; + } + root.showDropConfirmation(); + }); + return; + } + } + + if (drop.hasText && drop.text.length > 0) { + DMSService.sendRequest("clipboard.store", { + "data": drop.text, + "mimeType": "text/plain;charset=utf-8" + }, response => { + if (response.error) { + ToastService.showError(I18n.tr("Failed to save dropped text")); + return; + } + root.showDropConfirmation(); + }); + } + } + + function showDropConfirmation() { + dropConfirmed = true; + dropConfirmationTimer.restart(); + } + + Timer { + id: dropConfirmationTimer + interval: 1200 + onTriggered: root.dropConfirmed = false + } + function openContextMenu() { const screen = root.parentScreen || Screen; const screenX = screen.x || 0; @@ -84,12 +131,34 @@ BasePill { implicitWidth: icon.width implicitHeight: root.widgetThickness - root.horizontalPadding * 2 + property bool draggingOver: false + + DropArea { + anchors.fill: parent + anchors.margins: -root.horizontalPadding + onEntered: draggingOver = true + onExited: draggingOver = false + onDropped: drop => { + draggingOver = false; + drop.accept(Qt.CopyAction); + root.handleDrop(drop); + } + } + DankIcon { id: icon anchors.centerIn: parent - name: "content_paste" + name: root.dropConfirmed ? "check" : "content_paste" size: Theme.barIconSize(root.barThickness, -4, root.barConfig?.maximizeWidgetIcons, root.barConfig?.iconScale) - color: Theme.widgetIconColor + color: root.dropConfirmed || draggingOver ? Theme.primary : Theme.widgetIconColor + scale: draggingOver ? 1.2 : 1.0 + + Behavior on color { + ColorAnimation { duration: 150 } + } + Behavior on scale { + NumberAnimation { duration: 200; easing.type: Easing.OutBack } + } } } }