Add support to ignore the clipboard in certain windows (#89)

The clipboard does not get recorded when the title of the currently active
window matches the regular expression in CM_IGNORE_WINDOW. This allows copying
passwords from a password manager without the passwords ending up in clipmenu.

The matching is not 100% exact however, as there is a race condition between the
time the clipboard is populated, clipmenu queries the clipboard, and the active
window gets queried. This race condition can be especially problematic when
using polling with large intervals instead of clipnotify.
This commit is contained in:
Sohalt 2018-11-08 17:39:18 +01:00 committed by Chris Down
parent f748a2e5a6
commit 7de9c9e809

View file

@ -16,6 +16,7 @@ cache_file_prefix=$cache_dir/line_cache
lock_file=$cache_dir/lock lock_file=$cache_dir/lock
lock_timeout=2 lock_timeout=2
has_clipnotify=0 has_clipnotify=0
has_xdotool=0
# This comes from the environment, so we rely on word splitting. # This comes from the environment, so we rely on word splitting.
# shellcheck disable=SC2206 # shellcheck disable=SC2206
@ -93,6 +94,7 @@ Environment variables:
- $CM_ONESHOT: run once immediately, do not loop (default: 0) - $CM_ONESHOT: run once immediately, do not loop (default: 0)
- $CM_OWN_CLIPBOARD: take ownership of the clipboard (default: 1) - $CM_OWN_CLIPBOARD: take ownership of the clipboard (default: 1)
- $CM_SELECTIONS: space separated list of the selections to manage (default: "clipboard primary") - $CM_SELECTIONS: space separated list of the selections to manage (default: "clipboard primary")
- $CM_IGNORE_WINDOW: disable recording the clipboard in windows where the windowname matches the given regex (e.g. a password manager), do not ignore any windows if unset or empty (default: unset)
EOF EOF
exit 0 exit 0
fi fi
@ -113,6 +115,12 @@ if ! (( has_clipnotify )); then
echo "WARN: See https://github.com/cdown/clipnotify." >&2 echo "WARN: See https://github.com/cdown/clipnotify." >&2
fi fi
command -v xdotool >/dev/null 2>&1 && has_xdotool=1
if [[ $CM_IGNORE_WINDOW ]] && ! (( has_xdotool )); then
echo "WARN: CM_IGNORE_WINDOW does not work without xdotool, which is not installed" >&2
fi
exec {lock_fd}> "$lock_file" exec {lock_fd}> "$lock_file"
sleep_cmd=(sleep "${CM_SLEEP:-0.5}") sleep_cmd=(sleep "${CM_SLEEP:-0.5}")
@ -128,6 +136,14 @@ while true; do
fi fi
fi fi
if [[ $CM_IGNORE_WINDOW ]] && (( has_xdotool )); then
windowname="$(xdotool getactivewindow getwindowname)"
if [[ "$windowname" =~ $CM_IGNORE_WINDOW ]]; then
debug "ignoring clipboard because windowname \"$windowname\" matches \"${CM_IGNORE_WINDOW}\""
continue
fi
fi
if ! flock -x -w "$lock_timeout" "$lock_fd"; then if ! flock -x -w "$lock_timeout" "$lock_fd"; then
if (( CM_ONESHOT )); then if (( CM_ONESHOT )); then
printf 'ERROR: %s\n' 'Timed out waiting for lock' >&2 printf 'ERROR: %s\n' 'Timed out waiting for lock' >&2