commit 84fd3614ab71eade20d33fbbd474dff651001b97
parent 5379860679cb25259d9b4f49b0dc7ad9e17b4574
Author: Chris Down <chris@chrisdown.name>
Date: Wed, 25 Mar 2020 15:49:22 +0000
clipmenud: Allow disable with USR1 and enable with USR2
This allows avoiding having to delete after the fact for things like
issues #57 and #98.
Why have this over just stopping clipmenud? Well:
1. Stopping clipmenud should usually be an init system action, but we
are init-system agnostic. If we just exit, we don't have a way of
reliably starting again.
2. Even if we *do* do it using the init system, we don't want some
things (like a lingering xsel which owns the selection for
CM_OWN_CLIPBOARD) being killed as well.
3. This is a nicer interface for things like password managers to stop
clipmenu rather than stopping clipmenu entirely.
Diffstat:
4 files changed, 69 insertions(+), 3 deletions(-)
diff --git a/.travis.yml b/.travis.yml
@@ -3,7 +3,7 @@ language: bash
dist: xenial
script:
- - shellcheck -s bash clipmenu clipmenud clipdel clipfsck
+ - shellcheck -s bash clipmenu clipmenud clipdel clipfsck clipctl
- tests/test-clipmenu
matrix:
diff --git a/README.md b/README.md
@@ -68,6 +68,7 @@ The behavior of `clipmenud` can be customized through environment variables. Fea
* Customizing max number of clips (Default: 1000)
* Choosing which selections to manage
+ * Disabling clip collection temporarily with `clipctl disable`, reenabling with `clipctl enable`
* Ignoring certain windows, like password managers
* Enabling debugging
* Customizing the cache dir location
diff --git a/clipctl b/clipctl
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+
+if [[ -z $1 ]] || [[ $1 == --help ]] || [[ $1 == -h ]]; then
+ cat << 'EOF'
+clipctl provides controls for the clipmenud daemon.
+
+You can temporarily disable clip collection without stopping clipmenud entirely
+by running "clipctl disable". You can then reenable with "clipctl enable".
+EOF
+ exit 0
+fi
+
+_CLIPMENUD_PID=$(pgrep -u "$(id -u)" -nf '.*/?clipmenud$')
+
+if [[ -z "$_CLIPMENUD_PID" ]]; then
+ echo "clipmenud is not running"
+ exit 2
+fi
+
+case $1 in
+ enable) kill -USR2 "$_CLIPMENUD_PID" ;;
+ disable) kill -USR1 "$_CLIPMENUD_PID" ;;
+ *)
+ printf 'Unknown command: %s\n' "$1"
+ exit 1
+ ;;
+esac
diff --git a/clipmenud b/clipmenud
@@ -55,9 +55,26 @@ get_first_line() {
debug() { (( CM_DEBUG )) && printf '%s\n' "$@" >&2; }
+sig_disable() {
+ info "Received disable signal, suspending clipboard capture"
+ _CM_DISABLED=1
+ _CM_FIRST_DISABLE=1
+ [[ -v _CM_CLIPNOTIFY_PID ]] && kill "$_CM_CLIPNOTIFY_PID"
+}
+
+sig_enable() {
+ if ! (( _CM_DISABLED )); then
+ info "Received enable signal but we're not disabled, so doing nothing"
+ return
+ fi
+ info "Received enable signal, resuming clipboard capture"
+ _CM_DISABLED=0
+}
+
if [[ $1 == --help ]] || [[ $1 == -h ]]; then
cat << 'EOF'
-clipmenud collects and caches what's on the clipboard.
+clipmenud collects and caches what's on the clipboard. You can manage its
+operation with clipctl.
Environment variables:
@@ -92,8 +109,29 @@ fi
exec {lock_fd}> "$lock_file"
+trap sig_disable USR1
+trap sig_enable USR2
+
+# Kill all background processes on exit
+trap 'trap - TERM; kill -- -$$' INT TERM EXIT
+
while true; do
- (( CM_ONESHOT )) || clipnotify
+ if ! (( CM_ONESHOT )); then
+ # Make sure we're interruptible for the sig_{en,dis}able traps
+ clipnotify &
+ _CM_CLIPNOTIFY_PID="$!"
+ wait "$_CM_CLIPNOTIFY_PID"
+ fi
+
+ if (( _CM_DISABLED )); then
+ # The first one will just be from interrupting `wait`, so don't print
+ if (( _CM_FIRST_DISABLE )); then
+ unset _CM_FIRST_DISABLE
+ else
+ info "Got a clipboard notification, but we are disabled, skipping"
+ fi
+ continue
+ fi
if [[ $CM_IGNORE_WINDOW ]] && (( has_xdotool )); then
windowname="$(xdotool getactivewindow getwindowname)"