diff --git a/shell/plugins/clipboard/Clipboard.qml b/shell/plugins/clipboard/Clipboard.qml index 1db30c01..e3c9e3f2 100644 --- a/shell/plugins/clipboard/Clipboard.qml +++ b/shell/plugins/clipboard/Clipboard.qml @@ -19,7 +19,7 @@ Item { property string historyPath: Quickshell.env("HOME") + "/.local/state/omarchy/clipboard-history.json" property string captureScript: root.omarchyPath + "/shell/plugins/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 &\nwait" + property string watchCommand: "script=$1\ntrap 'kill $(jobs -p) 2>/dev/null' EXIT\nOMARCHY_CLIPBOARD_WATCH_MIME=text wl-paste --type text --watch \"$script\" 2>/dev/null &\nOMARCHY_CLIPBOARD_WATCH_MIME=image/png wl-paste --type image/png --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. @@ -232,7 +232,7 @@ Item { Process { id: initProc - 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 \"* || $cmdline == *\"/shell/plugins/clipboard/capture.sh\"* ]]; then\n kill \"$pid\" 2>/dev/null || true\n fi\ndone", "clipboard-init", root.captureScript] + 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 --type text --watch $script \"* || $cmdline == *\"wl-paste --type \"*\" --watch $script \"* || $cmdline == *\"/shell/plugins/clipboard/capture.sh\"* ]]; then\n kill \"$pid\" 2>/dev/null || true\n fi\ndone", "clipboard-init", root.captureScript] onExited: { currentProc.command = [root.captureScript] currentProc.running = true diff --git a/shell/plugins/clipboard/capture.sh b/shell/plugins/clipboard/capture.sh index ced86fa1..105d616f 100755 --- a/shell/plugins/clipboard/capture.sh +++ b/shell/plugins/clipboard/capture.sh @@ -63,7 +63,12 @@ emit_image_stream() { '{type:"image", mime:$mime, path:$path, capturedAt:$captured_at}' } +emit_text_stream() { + jq -cRs 'select(length > 0) | {type:"text", text:.}' +} + case "${OMARCHY_CLIPBOARD_WATCH_MIME:-}" in +text) emit_text_stream; exit 0 ;; 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 ;; diff --git a/test/shell.d/clipboard-test.sh b/test/shell.d/clipboard-test.sh index 68c63481..763a9630 100644 --- a/test/shell.d/clipboard-test.sh +++ b/test/shell.d/clipboard-test.sh @@ -171,6 +171,14 @@ capture_output=$(XDG_RUNTIME_DIR="$TMPDIR" PATH="$TMPDIR/bin:$PATH" "$ROOT/shell [[ $capture_output == '{"type":"text","text":"terminal copy"}' ]] || fail "clipboard capture records normal text events" pass "clipboard capture records normal text events" +capture_output=$(printf 'closing app copy' | OMARCHY_CLIPBOARD_WATCH_MIME=text WL_PASTE_TEXT="stale read" XDG_RUNTIME_DIR="$TMPDIR" PATH="$TMPDIR/bin:$PATH" "$ROOT/shell/plugins/clipboard/capture.sh") +[[ $capture_output == '{"type":"text","text":"closing app copy"}' ]] || fail "clipboard capture records watched text from stdin" +pass "clipboard capture records watched text from stdin" + +capture_output=$(printf 'secret' | CLIPBOARD_STATE=sensitive OMARCHY_CLIPBOARD_WATCH_MIME=text XDG_RUNTIME_DIR="$TMPDIR" PATH="$TMPDIR/bin:$PATH" "$ROOT/shell/plugins/clipboard/capture.sh") +[[ -z $capture_output ]] || fail "clipboard capture ignores sensitive watched text" +pass "clipboard capture ignores sensitive watched text" + capture_output=$(CLIPBOARD_STATE=sensitive XDG_RUNTIME_DIR="$TMPDIR" PATH="$TMPDIR/bin:$PATH" "$ROOT/shell/plugins/clipboard/capture.sh") [[ -z $capture_output ]] || fail "clipboard capture ignores sensitive clipboard events" pass "clipboard capture ignores sensitive clipboard events"