swayshot.bash

#!/usr/bin/env bash
# vim: set noexpandtab syntax=bash :
#
# swayshot.bash - written by the Iris System <iris@iris.ac.nz>,
# released into the public domain (or licensed under CC0, as required)
#
# does screenshots in sway, using grim/slurp. we didn't like the other
# options for doing this all in one script, so we wrote one. lmao.
#
# will pop up a wofi menu asking which type of screenshot to take, if
# a screenshot type is not provided in ARGV.
# 
# available screenshot types:
# - full (all outputs)
# - currentOutput
# - currentWindow
# - selectWindow (uses slurp to let you click a window to capture)
# - selectRegion (uses slurp to let you click+drag to capture a region) 
#
# requirements:
# - sway (obviously)
# - wofi
# - grim
# - slurp
# - jq
#
# it works for us! :P

set -eo pipefail

_outdir="${SWAYSHOT_OUTPUT_DIR:-${XDG_PICTURES_DIR:-${HOME}/Pictures}/Screenshots}"
_outfmt="${SWAYSHOT_OUTPUT_FORMAT:-%Y%m%d%H%M%S_swayshot.png}"

_mode="${1:-ask}"
if test "x${_mode}" == "xask"
then
	_mode="$(printf "full\ncurrentOutput\ncurrentWindow\nselectWindow\nselectRegion" | wofi -dp 'swayshot mode')"
fi

case "${_mode}" in
	full)
		_region=""
		;;

	currentOutput)
		_region="$(swaymsg -rt get_outputs | jq -r '.[] | select(.focused) | .geometry | "\(.x)x\(.y) \(.width)x\(.height)"')"
		;;

	currentWindow)
		_region="$(swaymsg -rt get_tree | jq -r '.. | (.nodes? // empty)[] | select(.focused and .pid) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' | head -n1)"
		;;

	selectWindow)
		_region="$(swaymsg -rt get_tree | jq -r '.. | (.nodes? // empty)[] | select(.visible and .pid) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' | slurp -r)"
		;;

	selectRegion)
		_region="$(slurp)"
		;;

	*)
		echo "[!!] unknown capture mode ${_mode}"
		exit 1
		;;
esac

_temp_outputfn="$(mktemp)"
if test "x${_region}" == "x"
then
	grim -t png "${_temp_outputfn}"
else
	grim -t png -g "${_region}" "${_temp_outputfn}"
fi

if test "$(stat -c '%s' "${_temp_outputfn}")" -eq 0
then
	echo "[!!] failed to take screenshot"
	exit 2
fi

_outputfn="$(date +"${_outfmt}")"
mkdir -p "${_outdir}"
mv "${_temp_outputfn}" "${_outdir}/${_outputfn}"
echo "${_outdir}/${_outputfn}"