summaryrefslogtreecommitdiff
path: root/bin/clipsync3.sh
blob: 2298d468983aba5bed996513d0e3bb97afea17c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#!/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