From 2cae0ba5f555a95012d320811f5f1d7b27b0fc84 Mon Sep 17 00:00:00 2001 From: Max Richter Date: Thu, 3 Mar 2022 19:34:03 +0100 Subject: [PATCH] feat(sway): copy screenshots to clipboard --- configs/sway/config | 8 +- configs/sway/grimshot.sh | 154 +++++++++++++++++++++++++++++++++++++ configs/sway/screenshot.sh | 0 3 files changed, 159 insertions(+), 3 deletions(-) create mode 100755 configs/sway/grimshot.sh create mode 100644 configs/sway/screenshot.sh diff --git a/configs/sway/config b/configs/sway/config index 82c4cf3..a98ba22 100644 --- a/configs/sway/config +++ b/configs/sway/config @@ -25,9 +25,11 @@ set $wofi_scripts ~/.config/wofi set $quickmenu wofi --show drun # Screenshot section -set $screenclip slurp | grim -g - ~/Pictures/Screenshots/scrn-$(date +"%Y-%m-%d-%H-%M-%S").png -set $screenshot grim ~/Pictures/screenshots/scrn-$(date +"%Y-%m-%d-%H-%M-%S").png -set $windowshot swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' | $screenclip +set $screenshot_dir ~/Pictures/Screenshots/ +set $grimshot ~/.config/sway/grimshot.sh +set $screenclip wl-copy < "$($grimshot --notify save area $screenshot_dir/scrn-$(date +"%Y-%m-%d-%H-%M-%S").png)" +set $screenshot wl-copy < "$($grimshot --notify save screen $screenshot_dir/scrn-$(date +"%Y-%m-%d-%H-%M-%S").png)" +set $windowshot wl-copy < "$($grimshot --notify save window $screenshot_dir/scrn-$(date +"%Y-%m-%d-%H-%M-%S").png)" # Default Programs set $term alacritty diff --git a/configs/sway/grimshot.sh b/configs/sway/grimshot.sh new file mode 100755 index 0000000..4ce31f2 --- /dev/null +++ b/configs/sway/grimshot.sh @@ -0,0 +1,154 @@ +#!/bin/sh + +## Grimshot: a helper for screenshots within sway +## Requirements: +## - `grim`: screenshot utility for wayland +## - `slurp`: to select an area +## - `swaymsg`: to read properties of current window +## - `wl-copy`: clipboard utility +## - `jq`: json utility to parse swaymsg output +## - `notify-send`: to show notifications +## Those are needed to be installed, if unsure, run `grimshot check` +## +## See `man 1 grimshot` or `grimshot usage` for further details. + +getTargetDirectory() { + test -f ${XDG_CONFIG_HOME:-~/.config}/user-dirs.dirs && \ + . ${XDG_CONFIG_HOME:-~/.config}/user-dirs.dirs + + echo ${XDG_SCREENSHOTS_DIR:-${XDG_PICTURES_DIR:-$HOME}} +} + +if [ "$1" = "--notify" ]; then + NOTIFY=yes + shift 1 +else + NOTIFY=no +fi + +ACTION=${1:-usage} +SUBJECT=${2:-screen} +FILE=${3:-$(getTargetDirectory)/$(date -Ins).png} + +if [ "$ACTION" != "save" ] && [ "$ACTION" != "copy" ] && [ "$ACTION" != "check" ]; then + echo "Usage:" + echo " grimshot [--notify] (copy|save) [active|screen|output|area|window] [FILE|-]" + echo " grimshot check" + echo " grimshot usage" + echo "" + echo "Commands:" + echo " copy: Copy the screenshot data into the clipboard." + echo " save: Save the screenshot to a regular file or '-' to pipe to STDOUT." + echo " check: Verify if required tools are installed and exit." + echo " usage: Show this message and exit." + echo "" + echo "Targets:" + echo " active: Currently active window." + echo " screen: All visible outputs." + echo " output: Currently active output." + echo " area: Manually select a region." + echo " window: Manually select a window." + exit +fi + +notify() { + notify-send -t 3000 -a grimshot "$@" +} +notifyOk() { + [ "$NOTIFY" = "no" ] && return + + TITLE=${2:-"Screenshot"} + MESSAGE=${1:-"OK"} + notify "$TITLE" "$MESSAGE" +} +notifyError() { + if [ $NOTIFY = "yes" ]; then + TITLE=${2:-"Screenshot"} + MESSAGE=${1:-"Error taking screenshot with grim"} + notify -u critical "$TITLE" "$MESSAGE" + else + echo $1 + fi +} + +die() { + MSG=${1:-Bye} + notifyError "Error: $MSG" + exit 2 +} + +check() { + COMMAND=$1 + if command -v "$COMMAND" > /dev/null 2>&1; then + RESULT="OK" + else + RESULT="NOT FOUND" + fi + echo " $COMMAND: $RESULT" +} + +takeScreenshot() { + FILE=$1 + GEOM=$2 + OUTPUT=$3 + if [ ! -z "$OUTPUT" ]; then + grim -o "$OUTPUT" "$FILE" || die "Unable to invoke grim" + elif [ -z "$GEOM" ]; then + grim "$FILE" || die "Unable to invoke grim" + else + grim -g "$GEOM" "$FILE" || die "Unable to invoke grim" + fi +} + +if [ "$ACTION" = "check" ] ; then + echo "Checking if required tools are installed. If something is missing, install it to your system and make it available in PATH..." + check grim + check slurp + check swaymsg + check wl-copy + check jq + check notify-send + exit +elif [ "$SUBJECT" = "area" ] ; then + GEOM=$(slurp -d) + # Check if user exited slurp without selecting the area + if [ -z "$GEOM" ]; then + exit 1 + fi + WHAT="Area" +elif [ "$SUBJECT" = "active" ] ; then + FOCUSED=$(swaymsg -t get_tree | jq -r 'recurse(.nodes[]?, .floating_nodes[]?) | select(.focused)') + GEOM=$(echo "$FOCUSED" | jq -r '.rect | "\(.x),\(.y) \(.width)x\(.height)"') + APP_ID=$(echo "$FOCUSED" | jq -r '.app_id') + WHAT="$APP_ID window" +elif [ "$SUBJECT" = "screen" ] ; then + GEOM="" + WHAT="Screen" +elif [ "$SUBJECT" = "output" ] ; then + GEOM="" + OUTPUT=$(swaymsg -t get_outputs | jq -r '.[] | select(.focused)' | jq -r '.name') + WHAT="$OUTPUT" +elif [ "$SUBJECT" = "window" ] ; then + GEOM=$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' | slurp) + # Check if user exited slurp without selecting the area + if [ -z "$GEOM" ]; then + exit 1 + fi + WHAT="Window" +else + die "Unknown subject to take a screen shot from" "$SUBJECT" +fi + +if [ "$ACTION" = "copy" ] ; then + takeScreenshot - "$GEOM" "$OUTPUT" | wl-copy --type image/png || die "Clipboard error" + notifyOk "$WHAT copied to buffer" +else + if takeScreenshot "$FILE" "$GEOM" "$OUTPUT"; then + TITLE="Screenshot of $SUBJECT" + MESSAGE=$(basename "$FILE") + notifyOk "$MESSAGE" "$TITLE" + echo $FILE + else + notifyError "Error taking screenshot with grim" + fi +fi diff --git a/configs/sway/screenshot.sh b/configs/sway/screenshot.sh new file mode 100644 index 0000000..e69de29