diff --git a/shell/plugins/clipboard/Clipboard.qml b/shell/plugins/clipboard/Clipboard.qml index 7918f167..848e4847 100644 --- a/shell/plugins/clipboard/Clipboard.qml +++ b/shell/plugins/clipboard/Clipboard.qml @@ -16,6 +16,7 @@ Item { property string historyPath: Quickshell.env("HOME") + "/.local/state/omarchy/clipboard-history.json" property string captureScript: root.omarchyPath + "/shell/scripts/clipboard-capture.sh" + property string watchCommand: "script=$1\ntrap 'kill $(jobs -p) 2>/dev/null' EXIT\nwl-paste --watch \"$script\" &\nOMARCHY_CLIPBOARD_WATCH_MIME=image/png wl-paste --type image/png --watch \"$script\" 2>/dev/null &\nOMARCHY_CLIPBOARD_WATCH_MIME=image/jpeg wl-paste --type image/jpeg --watch \"$script\" 2>/dev/null &\nOMARCHY_CLIPBOARD_WATCH_MIME=image/webp wl-paste --type image/webp --watch \"$script\" 2>/dev/null &\nOMARCHY_CLIPBOARD_WATCH_MIME=image/gif wl-paste --type image/gif --watch \"$script\" 2>/dev/null &\nOMARCHY_CLIPBOARD_WATCH_MIME=image/bmp wl-paste --type image/bmp --watch \"$script\" 2>/dev/null &\nOMARCHY_CLIPBOARD_WATCH_MIME=image/tiff wl-paste --type image/tiff --watch \"$script\" 2>/dev/null &\nwait" // Shares the [menu] surface tokens — themes that style the menu also // style the clipboard. Selected-row colors composed in the // singleton so consumers drop them straight into Rectangle bindings. @@ -212,11 +213,11 @@ Item { Process { id: initProc - command: ["bash", "-lc", "mkdir -p ~/.local/state/omarchy"] + command: ["bash", "-c", "mkdir -p ~/.local/state/omarchy\nscript=$1\nfor pid in $(pgrep -x wl-paste || true); do\n cmdline=$(tr '\\0' ' ' <\"/proc/$pid/cmdline\" 2>/dev/null || true)\n if [[ $cmdline == *\"wl-paste --watch $script \"* || $cmdline == *\"wl-paste --type \"*\" --watch $script \"* ]]; then\n kill \"$pid\" 2>/dev/null || true\n fi\ndone", "clipboard-init", root.captureScript] onExited: { currentProc.command = [root.captureScript] currentProc.running = true - watchProc.command = ["wl-paste", "--watch", root.captureScript] + watchProc.command = ["bash", "-c", root.watchCommand, "clipboard-watch", root.captureScript] watchProc.running = true } } diff --git a/shell/scripts/clipboard-capture.sh b/shell/scripts/clipboard-capture.sh index f9c3909a..08aab31d 100755 --- a/shell/scripts/clipboard-capture.sh +++ b/shell/scripts/clipboard-capture.sh @@ -16,7 +16,7 @@ emit_image() { local file="" tmp=$(mktemp --tmpdir="$IMAGE_DIR" clipboard.XXXXXX) || return 0 - if ! wl-paste --type "$mime" > "$tmp" 2>/dev/null || [[ ! -s $tmp ]]; then + if ! timeout 2s wl-paste --type "$mime" > "$tmp" 2>/dev/null || [[ ! -s $tmp ]]; then rm -f "$tmp" return 0 fi @@ -32,6 +32,40 @@ emit_image() { jq -cn --arg mime "$mime" --arg path "$file" '{type:"image", mime:$mime, path:$path}' } +emit_image_stream() { + local mime="$1" + local ext="$2" + local tmp="" + local hash="" + local file="" + + tmp=$(mktemp --tmpdir="$IMAGE_DIR" clipboard.XXXXXX) || return 0 + cat >"$tmp" + if [[ ! -s $tmp ]]; then + rm -f "$tmp" + return 0 + fi + + hash=$(sha256sum "$tmp" | awk '{print $1}') + file="$IMAGE_DIR/$hash.$ext" + if [[ -e $file ]]; then + rm -f "$tmp" + else + mv "$tmp" "$file" + fi + + jq -cn --arg mime "$mime" --arg path "$file" '{type:"image", mime:$mime, path:$path}' +} + +case "${OMARCHY_CLIPBOARD_WATCH_MIME:-}" in +image/png) emit_image_stream 'image/png' 'png'; exit 0 ;; +image/jpeg) emit_image_stream 'image/jpeg' 'jpg'; exit 0 ;; +image/webp) emit_image_stream 'image/webp' 'webp'; exit 0 ;; +image/gif) emit_image_stream 'image/gif' 'gif'; exit 0 ;; +image/bmp) emit_image_stream 'image/bmp' 'bmp'; exit 0 ;; +image/tiff) emit_image_stream 'image/tiff' 'tiff'; exit 0 ;; +esac + if grep -qx 'image/png' <<<"$types"; then emit_image 'image/png' 'png' elif grep -qx 'image/jpeg' <<<"$types"; then @@ -45,5 +79,5 @@ elif grep -qx 'image/bmp' <<<"$types"; then elif grep -qx 'image/tiff' <<<"$types"; then emit_image 'image/tiff' 'tiff' elif grep -q '^text/' <<<"$types" || grep -qx 'UTF8_STRING' <<<"$types" || grep -qx 'STRING' <<<"$types"; then - wl-paste --type text --no-newline 2>/dev/null | jq -Rs 'select(length > 0) | {type:"text", text:.}' + wl-paste --type text --no-newline 2>/dev/null | jq -cRs 'select(length > 0) | {type:"text", text:.}' fi