#!/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_low() { notify-send --urgency low \ --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+=--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_low "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 "$@"