Skip to content

Instantly share code, notes, and snippets.

@ret2src
Last active February 11, 2024 14:47
Show Gist options
  • Save ret2src/769360fc6425c2b79ee973b0563d08f8 to your computer and use it in GitHub Desktop.
Save ret2src/769360fc6425c2b79ee973b0563d08f8 to your computer and use it in GitHub Desktop.
Fakesnip: A pseudo-ksnip for Sway
#!/usr/bin/env bash
# Fakesnip: A pseudo-ksnip for Sway, based on `grim` and `slurp` — because we love the screenshot editing power of ksnip, but it does not have real Wayland + Sway support yet.
# Usage:
#
# Place this script in a location of your choosing, such as `~/.config/sway/scripts/`.
# Then, add the following to your Sway config:
#
# bindsym Mod1+Shift+f exec ~/.config/sway/scripts/fakesnip monitor-full
# bindsym Mod1+Shift+c exec ~/.config/sway/scripts/fakesnip monitor-focused
# bindsym Mod1+Shift+u exec ~/.config/sway/scripts/fakesnip window-select
# bindsym Mod1+Shift+a exec ~/.config/sway/scripts/fakesnip window-active
# bindsym Mod1+Shift+r exec ~/.config/sway/scripts/fakesnip rectangular
# Known Issues:
#
# - We use temporary files for screenshots because directly piping the image into `ksnip` via STDIN sometimes causes the error "Unable to show image. No image provided but one was expected."
# - If the 'Start Minimized to Tray' option is disabled, an empty `ksnip` window will pop up when first invoking this script, as it spawns a new `ksnip` server to avoid other problems such as duplicate instances. Therefore, it is recommended to enable the 'Start Minimized to Tray' option.
# - If the 'Show Main Window after capturing screenshot' option is enabled, the `ksnip` window will pop up after every screenshot. Therefore, it is recommended to disable the 'Show Main Window after capturing screenshot' option.
trap 'rm -f "${tmpfile}"' EXIT
tmpfile="$(mktemp /tmp/fakesnip.XXXXXXXXXXXXXX)"
# Start the `ksnip` server if it isn't running yet.
ksnip_pid="$(pidof ksnip)"
if [[ -z "${ksnip_pid}" ]]; then
ksnip &
fi
case "${1}" in
# Take a screenshot of all outputs.
monitor-full)
# grim -t png - | ksnip -e -
grim -t png "${tmpfile}"
ksnip "${tmpfile}"
wl-copy < "${tmpfile}"
edit_screenshot=$(notify-send 'Screenshot: All Monitors' 'Screenshot copied to clipboard.' --icon=image-x-generic --action=EDIT='Edit Screenshot')
;;
# Take a screenshot of the currently focused monitor.
monitor-focused)
# grim -t png -o "$(swaymsg -t get_outputs | jq -r $'.[] | select(.focused) | .name')" - | ksnip -e -
grim -t png -o "$(swaymsg -t get_outputs | jq -r $'.[] | select(.focused) | .name')" "${tmpfile}"
wl-copy < "${tmpfile}"
ksnip "${tmpfile}"
edit_screenshot=$(notify-send 'Screenshot: Focused Monitor' 'Screenshot copied to clipboard.' --icon=image-x-generic --action=EDIT='Edit Screenshot')
;;
# Take a screenshot of the currently active window.
window-active)
# grim -t png -g "$(swaymsg -t get_tree | jq -j $'.. | select(.type?) | select(.focused).rect | "\(.x),\(.y) \(.width)x\(.height)"')" - | ksnip -e -
grim -t png -g "$(swaymsg -t get_tree | jq -j $'.. | select(.type?) | select(.focused).rect | "\(.x),\(.y) \(.width)x\(.height)"')" "${tmpfile}"
wl-copy < "${tmpfile}"
ksnip "${tmpfile}"
edit_screenshot=$(notify-send 'Screenshot: Active Window' 'Screenshot copied to clipboard.' --icon=image-x-generic --action=EDIT='Edit Screenshot')
;;
# Take a screenshot of the interactively selected window.
window-select)
# grim -t png -g "$(swaymsg -t get_tree | jq -r $'.. | select(.pid? and .visible?) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' | slurp)" - | ksnip -e -
grim -t png -g "$(swaymsg -t get_tree | jq -r $'.. | select(.pid? and .visible?) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' | slurp)" "${tmpfile}"
wl-copy < "${tmpfile}"
ksnip "${tmpfile}"
edit_screenshot=$(notify-send 'Screenshot: Selected Window' 'Screenshot copied to clipboard.' --icon=image-x-generic --action=EDIT='Edit Screenshot')
;;
# Take a screenshot of a rectangular region on the screen.
rectangular)
# grim -t png -g "$(slurp)" - | ksnip -e -
grim -t png -g "$(slurp)" "${tmpfile}"
wl-copy < "${tmpfile}"
ksnip "${tmpfile}"
edit_screenshot=$(notify-send 'Screenshot: Rectangular Region' 'Screenshot copied to clipboard.' --icon=image-x-generic --action=EDIT='Edit Screenshot')
;;
esac
if [[ "${edit_screenshot}" == "EDIT" ]]; then
ksnip
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment