chore: updated rofi clipd
e97f71df
1 file(s) · +29 −3
| 20 | 20 | # threshold where a copy-then-immediately-quit would be missed in practice. |
|
| 21 | 21 | LIMIT=${ROFI_CLIP_LIMIT:-200} |
|
| 22 | 22 | INTERVAL=${ROFI_CLIP_INTERVAL:-1} |
|
| 23 | + | # How long to give an unresponsive selection owner before giving up on a read. |
|
| 24 | + | READ_TIMEOUT=${ROFI_CLIP_READ_TIMEOUT:-2} |
|
| 23 | 25 | ||
| 24 | 26 | mkdir -p "$STORE" |
|
| 25 | 27 | ||
| 68 | 70 | ||
| 69 | 71 | # UTF8_STRING keeps this to text: asking for whatever target an image or a |
|
| 70 | 72 | # file-manager copy offers would store a blob nothing can paste back. |
|
| 71 | - | current() { xclip -o -selection clipboard -t UTF8_STRING 2>/dev/null; } |
|
| 73 | + | # |
|
| 74 | + | # The timeout is not optional. An X selection is served by the process that |
|
| 75 | + | # owns it, so reading one is a round trip to another program — and if that |
|
| 76 | + | # program stops answering (it died mid-transfer, or it is wedged), xclip waits |
|
| 77 | + | # on the reply forever. With no timeout that hangs this loop too, and history |
|
| 78 | + | # quietly stops recording until the daemon is restarted by hand. |
|
| 79 | + | current() { timeout "$READ_TIMEOUT" xclip -o -selection clipboard -t UTF8_STRING 2>/dev/null; } |
|
| 72 | 80 | ||
| 73 | 81 | case "${1:-}" in |
|
| 74 | 82 | --once) |
|
| 86 | 94 | esac |
|
| 87 | 95 | ||
| 88 | 96 | # A second daemon would double every entry, so check for a live one first. |
|
| 89 | - | if [ -f "$PIDFILE" ] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then |
|
| 97 | + | # The trap below clears the pidfile on a clean exit, but a kill -9 or a reboot |
|
| 98 | + | # leaves it behind — and that stale pid is eventually handed to some unrelated |
|
| 99 | + | # process, which would make this refuse to start at every login from then on. |
|
| 100 | + | # So the pid has to still be this script, not merely alive. |
|
| 101 | + | running() { |
|
| 102 | + | [ -f "$PIDFILE" ] || return 1 |
|
| 103 | + | pid=$(cat "$PIDFILE" 2>/dev/null) || return 1 |
|
| 104 | + | [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null || return 1 |
|
| 105 | + | tr '\0' ' ' < "/proc/$pid/cmdline" 2>/dev/null | grep -q "${0##*/}" |
|
| 106 | + | } |
|
| 107 | + | ||
| 108 | + | if running; then |
|
| 90 | 109 | echo "rofi-clipd: already running (pid $(cat "$PIDFILE"))" >&2 |
|
| 91 | 110 | exit 1 |
|
| 92 | 111 | fi |
|
| 93 | 112 | echo $$ > "$PIDFILE" |
|
| 94 | - | trap 'rm -f "$PIDFILE"' EXIT INT TERM |
|
| 113 | + | # EXIT clears the pidfile on every way out. INT and TERM need handlers that |
|
| 114 | + | # actually exit: a handler that just cleans up returns into the loop, leaving a |
|
| 115 | + | # daemon that ignores kill *and* has already deleted the pidfile guarding |
|
| 116 | + | # against a second one — so the next login starts a duplicate that records |
|
| 117 | + | # every copy twice. |
|
| 118 | + | trap 'rm -f "$PIDFILE"' EXIT |
|
| 119 | + | trap 'exit 130' INT |
|
| 120 | + | trap 'exit 143' TERM |
|
| 95 | 121 | ||
| 96 | 122 | last="" |
|
| 97 | 123 | while :; do |
|