config/scripts/sway-screenshot

163 lines
4.3 KiB
Bash
Executable file

#!/usr/bin/env bash
set -e
AVAILABLE_MODES=(output window region)
function Help() {
cat <<EOF
Usage: sway-screenshot [options ..] -m [mode] -- [command]
sway-screenshot is an utility to easily take screenshot in swaywm using your mouse.
It allows taking screenshots of windows, regions and monitors which are saved to a folder of your choosing and copied to your clipboard.
Options:
-h, --help show help message
-m, --mode one of: output, window, region
-o, --output-folder directory in which to save screenshot
-f, --filename the file name of the resulting screenshot
-d, --debug print debug information
-s, --silent don't send notification when screenshot is saved
--clipboard-only copy screenshot to clipboard and don't save image in disk
-- [command] open screenshot with a command of your choosing. e.g. sway-screenshot -m window -- mirage
Modes:
output take screenshot of an entire monitor
window take screenshot of an open window
region take screenshot of selected region
EOF
}
function Print() {
if [ $DEBUG -eq 0 ]; then
return 0
fi
1>&2 printf "$@"
}
function send_notification() {
if [ $SILENT -eq 1 ]; then
return 0
fi
notify-send "Screenshot saved" \
"Image saved in <i>${1}</i> and copied to the clipboard." \
-i "${1}"
}
function save_geometry() {
Print "Geometry: %s\n" "${1}"
if [ $CLIPBOARD -eq 0 ]; then
mkdir -p "$SAVEDIR"
grim -g "${1}" "$SAVE_FULLPATH"
local output="$SAVE_FULLPATH"
# Trim transparent pixels, in case the window was floating and partially
# outside the monitor
convert $output -trim +repage $output
wl-copy < "$output"
send_notification $output
[ -z "$COMMAND" ] || {
"$COMMAND" "$output"
}
else
wl-copy < <(grim -g "${1}" - | convert - -trim +repage -)
fi
}
function begin_grab() {
local option=$1
case $option in
output)
local geometry=`grab_output`
;;
region)
local geometry=`grab_region`
;;
window)
local geometry=`grab_window`
;;
esac
save_geometry "${geometry}"
}
function grab_output() {
slurp -or
}
function grab_region() {
slurp -d
}
function grab_window() {
local clients=`swaymsg -t get_tree | jq -r '[.. | ((.nodes? // empty) + (.floating_nodes? // empty))[] | select(.visible and .pid)]'`
Print "Clients: %s\n" "$clients"
# Generate boxes for each visible window and send that to slurp
# through stdin
local boxes="$(echo $clients | jq -r '.[] | "\(.rect.x),\(.rect.y) \(.rect.width)x\(.rect.height) \(.name)"')"
Print "Boxes:\n%s\n" "$boxes"
slurp -r <<< "$boxes"
}
function args() {
local options=$(getopt -o hf:o:m:ds --long help,filename:,output-folder:,mode:,clipboard-only,debug,silent -- "$@")
eval set -- "$options"
while true; do
case "$1" in
-h | --help)
Help
exit
;;
-o | --output-folder)
shift;
SAVEDIR=$1
;;
-f | --filename)
shift;
FILENAME=$1
;;
-m | --mode)
shift;
echo "${AVAILABLE_MODES[@]}" | grep -wq $1
OPTION=$1;;
--clipboard-only)
CLIPBOARD=1
;;
-d | --debug)
DEBUG=1
;;
-s | --silent)
SILENT=1
;;
--)
shift # Skip -- argument
COMMAND=${@:2}
break;;
esac
shift
done
if [ -z $OPTION ]; then
Print "A mode is required\n\nAvailable modes are:\n\toutput\n\tregion\n\twindow\n"
exit 2
fi
}
if [ -z $1 ]; then
Help
exit
fi
CLIPBOARD=0
DEBUG=0
SILENT=0
FILENAME="$(date +'%Y-%m-%d-%H%M%S_sway-screenshot.png')"
[ -z "$SWAY_SCREENSHOT_DIR" ] && SAVEDIR=${XDG_PICTURES_DIR:=~} || SAVEDIR=${SWAY_SCREENSHOT_DIR}
args $0 "$@"
SAVE_FULLPATH="$SAVEDIR/$FILENAME"
[ $CLIPBOARD -eq 0 ] && Print "Saving in: %s\n" "$SAVE_FULLPATH"
begin_grab $OPTION