dotfiles/home/user/.local/bin/screenshot

164 lines
4.4 KiB
Bash
Executable File

#!/usr/bin/env zsh
set -euo pipefail
readonly LOG_FILE="${HOME}/.screenshots.log"
readonly NOTIFY_TIME_MS=3000
readonly NOTIFY_TIME_ERROR_MS=5000
readonly CODE_CANCELED=22
readonly NOTIFY_LABEL="Screenshot"
readonly SCREENSHOTS_DIR="${SCREENSHOTS_DIR:-${HOME}/Pictures/screenshots}"
readonly TIMESTAMP_FORMAT="%H-%M-%S_%Y-%m-%d"
readonly NOOPENGL="${NOOPENGL:-false}"
mkdir -p "${SCREENSHOTS_DIR}"
_notify() {
notify-send --urgency normal \
--expire-time "${NOTIFY_TIME_MS}" \
"${NOTIFY_LABEL}" \
"${1}"
}
_notify_error() {
notify-send --urgency critical \
--expire-time "${NOTIFY_TIME_ERROR_MS}" \
"${NOTIFY_LABEL}" \
"Error: ${1}"
}
_maim() {
local maim_args=(--quality 10)
if ${NOOPENGL}; then
maim_args=(${maim_args} --noopengl)
fi
maim ${maim_args} "${@}"
}
_capture_select() {
local -r pipe="$(mktemp)"
_maim --select 2>"${pipe}"
local -r code="$?"
if grep -F "Selection was cancelled by keystroke or right-click." <"${pipe}"; then
rm "${pipe}"
return "${CODE_CANCELED}"
fi
cat "${pipe}" 1>&2
rm "${pipe}"
return "${code}"
}
_capture_entire() {
_maim
}
_capture_window() {
_maim --window "$(xdotool getactivewindow)"
}
_copy_to_clipboard() {
xclip -selection clipboard -t image/png
}
_save_to_file() {
cat > "${1}"
}
_process_screenshot() {
local -r capture_func="${1}"
local -r output_func="${2}"
local -r success_msg="${3}"
local -r error_msg="${4}"
local -r output_arg="${5:-}"
if ! ${capture_func} | ${output_func} "${output_arg}"; then
if (( ${pipestatus[1]} == "${CODE_CANCELED}" )); then
_notify "Selection was cancelled by keystroke or right-click."
return 0
fi
_notify_error "${error_msg}"
return 1
fi
_notify "${success_msg}"
return 0
}
_select_save() {
local -r filename="${SCREENSHOTS_DIR}/selection_$(date +"${TIMESTAMP_FORMAT}").png"
_process_screenshot _capture_select \
_save_to_file \
"Selection saved to ${filename}" \
"Failed to save selection screenshot" \
"${filename}"
}
_select_copy() {
_process_screenshot _capture_select \
_copy_to_clipboard \
"Selection copied to clipboard" \
"Failed to copy selection to clipboard"
}
_window_save() {
local -r filename="${SCREENSHOTS_DIR}/window_$(date +"${TIMESTAMP_FORMAT}").png"
_process_screenshot _capture_window \
_save_to_file \
"Current window saved to ${filename}" \
"Failed to save Current window screenshot" \
"${filename}"
}
_window_copy() {
_process_screenshot _capture_window \
_copy_to_clipboard \
"Current window copied to clipboard" \
"Failed to copy current window to clipboard"
}
_entire_save() {
local -r filename="${SCREENSHOTS_DIR}/screen_$(date +"${TIMESTAMP_FORMAT}").png"
_process_screenshot _capture_entire \
_save_to_file \
"Entire screen saved to ${filename}" \
"Failed to save entire screen" \
"${filename}"
}
_entire_copy() {
_process_screenshot _capture_entire \
_copy_to_clipboard \
"Entire screen copied to clipboard" \
"Failed to copy entire screen to clipboard"
}
main() {
if [ $# -ne 2 ]; then
echo "Usage: ${0} {select|window|entire} {save|copy}"
exit 1
fi
local -r target="${1}"
local -r action="${2}"
case "${target}-${action}" in
select-save) _select_save &>> "${LOG_FILE}" ;;
select-copy) _select_copy &>> "${LOG_FILE}" ;;
window-save) _window_save &>> "${LOG_FILE}" ;;
window-copy) _window_copy &>> "${LOG_FILE}" ;;
entire-save) _entire_save &>> "${LOG_FILE}" ;;
entire-copy) _entire_copy &>> "${LOG_FILE}" ;;
*)
echo "Invalid options: target=${target}, action=${action}"
echo "Available targets: select, window, entire"
echo "Available actions: save, copy"
exit 1
;;
esac
}
main "$@"