171 lines
4.6 KiB
Bash
Executable File
171 lines
4.6 KiB
Bash
Executable File
#!/usr/bin/env zsh
|
|
|
|
set -euo pipefail
|
|
|
|
readonly LOG_FILE="${HOME}/.screenshots.log"
|
|
readonly NOTIFY_TIME_LOW_MS=1500
|
|
readonly NOTIFY_TIME_NORMAL_MS=3000
|
|
readonly NOTIFY_TIME_CRITICAL_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:-}"
|
|
readonly NONOTIFY="${NONOTIFY:-}"
|
|
|
|
|
|
mkdir -p "${SCREENSHOTS_DIR}"
|
|
|
|
|
|
_notify() {
|
|
local -r level="${1}"
|
|
local -r notify_time_ms="${2}"
|
|
local -r msg="${3}"
|
|
|
|
if [ -n "${NONOTIFY}" ]; then
|
|
return 0
|
|
fi
|
|
|
|
notify-send --urgency "${level}" \
|
|
--expire-time "${notify_time_ms}" \
|
|
"${NOTIFY_LABEL}" \
|
|
"${msg}"
|
|
}
|
|
|
|
_notify_low() {
|
|
_notify low "${NOTIFY_TIME_LOW_MS}" "${1}"
|
|
}
|
|
|
|
_notify_normal() {
|
|
_notify normal "${NOTIFY_TIME_NORMAL_MS}" "${1}"
|
|
}
|
|
|
|
|
|
_notify_error() {
|
|
_notify critical "${NOTIFY_TIME_CRITICAL_MS}" "Error: ${1}"
|
|
}
|
|
|
|
_capture_select() {
|
|
local -r pipe="$(mktemp)"
|
|
grim -g "$(slurp)" - 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() {
|
|
grim -
|
|
}
|
|
|
|
_capture_window() {
|
|
grim -g "$(swaymsg -t get_tree | jq -r '.. | select(.type? == "con" and .focused == true) | .rect | "\(.x),\(.y) \(.width)x\(.height)"')" -
|
|
}
|
|
|
|
_copy_to_clipboard() {
|
|
wl-copy -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_normal "${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 "$@"
|