#!/bin/sh # Scan for wlroots and x11 clipboard events and synchronize text strings. # Requirements: # clipnotify https://github.com/cdown/clipnotify (xfixes clipboard events) # wl-clipboard https://github.com/bugaevc/wl-clipboard # xclip https://github.com/astrand/xclip # non-text TARGET/mimetype negotiation requires a more complicated protocol # bridge than what xclip and wl-clipboard can be expected to provide. # To see the scope of the problem for a given selection: # xclip -t TARGETS -o # wl-paste -l set -e set -x # debug #PS4='+ $(sleep .1)' # debug differ() { [ x"$new" != x"$old" ]; } wcp() { printf "%s" "$new" | wl-copy -p; } wcc() { printf "%s" "$new" | wl-copy; } xcp() { printf "%s" "$new" | xclip -selection primary; } #xcc() { printf "%s" "$new" | xclip -selection clipboard; } # why is this broken? xcc() { true; } fifo="${XDG_RUNTIME_DIR:-/tmp}/clipsync-$WAYLAND_DISPLAY-$DISPLAY.sock" mkfifo "$fifo" # unified event stream to prevent multi-process feedback loops # ensure we kill our whole subprocess group on shutdown trap "trap - TERM; rm $fifo; kill -- -$$;" INT TERM EXIT # rewrite trap so it doesn't recurse exec 3<> "$fifo" # open as fd 3 #rm "$fifo" # we don't technically use the link anymore, but it *is* useful as lockfile wl-paste --watch echo wc >&3 & wcpid=$!; read -r spam <&3; unset spam wl-paste --primary --watch echo wp >&3 & wppid=$!; read -r spam <&3; unset spam while clipnotify -s primary ; do echo xp; done >&3 & xppid=$! #while clipnotify -s clipboard; do echo xc; done >&3 & xcpid=$! # why is this broken? while read -r event <&3; do case "$event" in (wc) new="$( wl-paste -n )"; differ && ( wcp; xcc; xcp; ) ;; (wp) new="$( wl-paste -n --primary )"; differ && ( wcc; xcc; xcp; ) ;; (xc) new="$( xclip -o -selection clipboard )"; differ && ( wcc; wcp; xcp; ) ;; (xp) new="$( xclip -o -selection primary )"; differ && ( wcc; wcp; xcc; ) ;; esac old="$new" done # if further process management is needed: #kill $wcpid $wppid $xppid $xcpid #disown $wcpid $wppid $xppid $xcpid