diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2025-08-05 17:25:30 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2025-08-05 17:25:30 +0800 |
| commit | f9efa56caeeb5289d6b2314e50041a1b7055a3c8 (patch) | |
| tree | 8a9e5b59f8690555ba8ad51f653db02d9483e2a7 /services/Clip.qml | |
| parent | f6b5ac3cfba03602fea9d8c30b13075514dbd131 (diff) | |
feat: add launcher support and image clipboard history utility
- Integrated a new Launcher component into the shell.qml for improved application launching.
- Implemented an IPC handler to toggle the launcher visibility.
- Added a new script (cliphist-img.sh) to manage image history from the clipboard.
- Removed the outdated fuzzysort.js utility to streamline the codebase.
- Refactored the Levenshtein distance algorithm for better performance and clarity.
Diffstat (limited to 'services/Clip.qml')
| -rw-r--r-- | services/Clip.qml | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/services/Clip.qml b/services/Clip.qml new file mode 100644 index 0000000..31ac2d4 --- /dev/null +++ b/services/Clip.qml @@ -0,0 +1,149 @@ +pragma Singleton + +import Quickshell +import Quickshell.Io +import QtQuick + +Singleton { + id: root + + property list<string> _clipHist: [] + property list<string> _clipImg: [] + property list<string> _clipImgIds: _clipImg.map(p => p.split("/").pop().split(".").shift()) + + property string toDecode: "" + property string toCopy: "" + property string decoded: "" + + property var clipHist: { + const arr = []; + if (!_clipHist?.length) + return arr; + + const imgMap = {}; + const nimg = Math.min(_clipImg.length, _clipImgIds.length); + for (let i = 0; i < nimg; i++) { + const id = _clipImgIds[i]; + if (id) + imgMap[id] = _clipImg[i]; + } + + for (let i = 0; i < _clipHist.length; i++) { + const raw = _clipHist[i]; + if (!raw) + continue; + const tab = raw.indexOf("\t"); + let idNum = -1; + let payload = raw; + if (tab > 0) { + const n = parseInt(raw.slice(0, tab), 10); + if (!Number.isNaN(n)) { + idNum = n; + payload = raw.slice(tab + 1); // strip "ID<TAB>" + } + } + + const idStr = idNum >= 0 ? "" + idNum : ""; + const imgPath = idStr ? imgMap[idStr] || "" : ""; + const isImg = !!imgPath; + + arr.push({ + index: idNum, + isImage: isImg, + data: isImg ? imgPath : payload, + raw: raw + }); + } + return arr; + } + + component SClip_t: QtObject { + property int index + property bool isImage + property string data + } + + function decodeAndCopy(text) { + toDecode = text; + decodeAndCopyProc.running = true; + } + + function copy(text) { + toCopy = text; + copyProc.running = true; + } + + function _update() { + clipProc.running = true; + imgProc.running = true; + } + + Process { + id: decodeAndCopyProc + running: false + command: ["sh", "-c", "cliphist decode" + toDecode + " | wl-copy"] + stdout: StdioCollector { + onStreamFinished: () => { + decoded = data; + } + } + onStarted: { + decoded = ""; + } + onExited: { + toDecode = ""; + } + } + + Process { + id: clipProc + running: true + command: ["cliphist", "-preview-width", 9 ** 9, "-max-items", 9 ** 9, "list"] + property bool finished: false + stdout: SplitParser { + onRead: line => { + if (clipProc.finished) { + _clipHist = []; + clipProc.finished = false; + } + if (line) + _clipHist.push(line); + } + } + onExited: { + finished = true; + } + } + + Process { + id: imgProc + running: true + command: ["sh", Quickshell.shellDir + "/utils/cliphist-img.sh"] + stdout: SplitParser { + onRead: line => { + if (line) + _clipImg.push(line); + } + } + } + + Process { + id: copyProc + running: false + command: ["wl-copy", toCopy] + onExited: { + toCopy = ""; + } + } + + Process { + id: watchProc + running: true + command: ["wl-paste", "-w", "echo"] + stdout: SplitParser { + onRead: line => { + _update(); + } + } + } +} |
