#!/usr/bin/env bash set -eu -o pipefail APP_NAME="ScreenCapt" declare -A COMMAND COMMAND=( [screenshot]="grim" [video]="wl-screenrec" ) declare -A ICONS ICONS=( ["screenshot"]="accessories-screenshot" ["video"]="record-desktop" ) declare -A OUTPUT_DIR OUTPUT_DIR=( ["screenshot"]="${XDG_PICTURES_DIR:-"~/pictures"}/screenshots" ["video"]="${XDG_VIDEOS_DIR:="~/videos"}/screenrecords" ) declare -A OUTPUT_FILE_EXT OUTPUT_FILE_EXT=( ["screenshot"]="png" ["video"]="mp4" ) TO_FILE=0 RECORD_AUDIO=0 ACTION="screenshot" REGION_TYPE="window" notify() { local summary message command filename="${1:-""}" summary="New ${ACTION}!" if [[ $TO_FILE -eq 1 ]]; then message+="Available in ${filename##*/}" else message+="Available in the clipboard" fi command=(notify-send "${summary}" --app-name="$APP_NAME") if [[ -n "$filename" && "$ACTION" == "screenshots" ]]; then command+=(--icon="${filename}") else command+=("--icon=${ICONS[$ACTION]}") fi command+=("$message") "${command[@]}" } process_args() { while :; do case ''${1:-""} in screenshot) ACTION="$1" ;; video) # If a video record is in progress Stop it if pgrep "wl-screenrec"; then kill -s SIGINT $(pgrep "wl-screenrec") exit 0 fi TO_FILE=1 ACTION="$1" ;; -r | --region) if [[ "${2:-""}" =~ ^(r|region|s|screen|w|window)$ ]]; then REGION_TYPE="$2" else exit 1 fi shift ;; -f | --file) TO_FILE=1 ;; -a | --with-audio) RECORD_AUDIO=1 ;; *) break ;; esac shift done } get_app_name() { local appname case "$REGION_TYPE" in r | region) appname="region" ;; s | screen) appname="screen" ;; w | window) appname=$(swaymsg -t get_tree | jq -r '.. | ((.nodes? // empty) + (.floating_nodes? // empty))[] | select(.visible and .pid and .focused) | "\(.app_id)"') ;; esac printf "%s" "${appname:-}" } get_region() { local region switch case "$REGION_TYPE" in r | region) region=$(slurp) switch="-g" ;; s | screen) region=$(swaymsg -t get_outputs | jq -r '.[] | select(.focused) | "\(.name)"') switch="-o" ;; w | window) region=$(swaymsg -t get_tree | jq -r '.. | ((.nodes? // empty) + (.floating_nodes? // empty))[] | select(.visible and .pid and .focused) | .rect | "\(.x),\(.y) \(.width)x\(.height)"') switch="-g" ;; esac printf "%s%s" "${switch:-}" "${region:-}" } get_output_filename() { local date printf -v date '%(%F_%H.%M.%S)T' printf "%s/%s-%s.%s" "${OUTPUT_DIR[$ACTION]}" "$date" "$(get_app_name)" "${OUTPUT_FILE_EXT[$ACTION]}" } ensure_directories_exist() { for dir in "${!OUTPUT_DIR[@]}"; do mkdir -p "${OUTPUT_DIR[$dir]}" done } main() { process_args "$@" ensure_directories_exist local command command=("${COMMAND[$ACTION]}" "$(get_region)") if [[ "$TO_FILE" -eq 1 ]]; then local filename filename=$(get_output_filename) if [[ "$ACTION" = "video" ]]; then if [[ "$RECORD_AUDIO" -eq 1 ]]; then command+=(--audio) fi command+=(-f) fi command+=("$filename") "${command[@]}" else "${command[@]}" - | wl-copy fi notify "${filename:-""}" exit 0 } main "$@"