Skip to content

Instantly share code, notes, and snippets.

@Dregu
Last active February 22, 2026 15:29
Show Gist options
  • Select an option

  • Save Dregu/7959f27766f23b542a206d4b70606295 to your computer and use it in GitHub Desktop.

Select an option

Save Dregu/7959f27766f23b542a206d4b70606295 to your computer and use it in GitHub Desktop.
yallushot
#!/bin/sh
# Yet Another Luxurious but Laughably Unnecessary screenShot tool for Hyprland by Dregu
# Capture specific window, layer, region or output with a single command and pipe to satty.
# Usage: ./yallushot [region|window|output]
# TOLD YA!
# remember to add `layerrule = no_anim on, match:namespace selection` or you will see slurp in your screenshots!
# PARAMS
# (none): shoots selected region OR clicked window/layer without decorations OR output when clicked outside a window/cancelled
# region: shoots selected region OR clicked window/layer with decorations
# window: shoots active window without decorations, ignores noscreenshare temporarily
# output: shoots active output
# REQUIRES
# Hyprland 0.54+ with ext-image-copy-capture support
# slurp for aiming
# grim for shooting
# satty for editing
# OPTIONS
# margin is added to predefined non-fullscreen window regions in region mode to capture window decorations (make it < gaps)
MARGIN=12
DIR="$HOME/pics/screenshots"
SLURP="slurp -d -b cc870d50 -B cc870d50 -w 0"
GRIM="grim -t ppm"
NAME() {
TIME=$(date +"%Y-%m-%d_%H-%M-%S_%N"|cut -b-23)
echo "$DIR/shot_${TIME}_${1}.png"
}
SATTY() {
satty -f - -o "$1" --init-tool brush --copy-command wl-copy --early-exit
}
# MAGIC, you can probably stop reading now
mkdir -p "$DIR"
WS=$(hyprctl monitors -j | jq -r '[.[].specialWorkspace.id, .[].activeWorkspace.id | select(. != null and . != 0)] | flatten | unique')
TOP=$(hyprctl -j layers | jq -r '.[].[]."2".[] | [.x,.y,.w,.h] | "\(.[0]),\(.[1]) \(.[2])x\(.[3])"')
OVERLAY=$(hyprctl -j layers | jq -r '.[].[]."3".[] | [.x,.y,.w,.h] | "\(.[0]),\(.[1]) \(.[2])x\(.[3])"')
if [ "$1" == "region" ]; then
CLIENTS=$(hyprctl clients -j | jq --argjson WS "$WS" --argjson M $MARGIN -r '.[] | select(.workspace.id | IN($WS[])) | [.at[0], .at[1], .size[0], .size[1], (if .fullscreen == 1 then 0 else $M end)] | "\(.[0]-.[4]),\(.[1]-.[4]) \(.[2]+.[4]*2)x\(.[3]+.[4]*2)"')
RECTS=$(printf "$TOP\n$OVERLAY\n$CLIENTS" | sed '/^$/N;/^\n/D')
RECT=$(echo "$RECTS" | $SLURP 2> /dev/null)
if [ ! -z "$RECT" ]; then
FILE="$(NAME $1)"
ADDR=$(hyprctl -j activewindow | jq -r .address)
NSS=$(hyprctl getprop address:$ADDR no_screen_share)
hyprctl -q dispatch setprop address:$ADDR no_screen_share false
$GRIM -g "$RECT" - | (SATTY "$FILE"&)
hyprctl -q dispatch setprop address:$ADDR no_screen_share $NSS
fi
elif [ "$1" == "window" ]; then
ADDR=$(hyprctl activewindow -j | jq -r '.address')
TLID=$(hyprctl activewindow -j | jq -r '.stableId')
if [ ! -z "$ADDR" ]; then
FILE="$(NAME $1)"
NSS=$(hyprctl getprop address:$ADDR no_screen_share)
hyprctl -q dispatch setprop address:$ADDR no_screen_share false
$GRIM -T "$TLID" - | (SATTY "$FILE"&)
hyprctl -q dispatch setprop address:$ADDR no_screen_share $NSS
fi
elif [ "$1" == "output" ]; then
FILE="$(NAME $1)"
$GRIM -o "$(hyprctl monitors -j | jq -r '.[] | select(.focused) | .name')" - | (SATTY "$FILE"&)
else
CLIENTS=$(hyprctl clients -j | jq --argjson WS "$WS" -r '.[] | select(.workspace.id | IN($WS[])) | [.at[0], .at[1], .size[0], .size[1]] | "\(.[0]),\(.[1]) \(.[2])x\(.[3])"')
RECTS=$(printf "$TOP\n$OVERLAY\n$CLIENTS" | sed '/^$/N;/^\n/D')
RECT=$(echo "$RECTS" | $SLURP 2> /dev/null)
WSID=$(hyprctl -j activeworkspace | jq -r .id)
if [ -z "$RECT" ]; then
FILE="$(NAME output)"
$GRIM -o "$(hyprctl monitors -j | jq -r '.[] | select(.focused) | .name')" - | (SATTY "$FILE"&)
exit
fi
read X Y W H <<< $(echo "$RECT" | sed 's/[^0-9\-]/ /g')
ADDR=$(hyprctl -j clients | jq -r "map(select(.at[0] == $X and .at[1] == $Y and .size[0] == $W and .size[1] == $H and .workspace.id == $WSID and .hidden == false)).[].address")
if [ ! -z "$ADDR" ]; then
TLID=$(hyprctl -j clients | jq -r "map(select(.address == \"$ADDR\"))[0].stableId")
FILE="$(NAME window)"
NSS=$(hyprctl getprop address:$ADDR no_screen_share)
hyprctl -q dispatch setprop address:$ADDR no_screen_share false
$GRIM -T "$TLID" - | (SATTY "$FILE"&)
hyprctl -q dispatch setprop address:$ADDR no_screen_share $NSS
else
FILE="$(NAME region)"
ADDR=$(hyprctl -j activewindow | jq -r .address)
NSS=$(hyprctl getprop address:$ADDR no_screen_share)
hyprctl -q dispatch setprop address:$ADDR no_screen_share false
$GRIM -g "$RECT" - | (SATTY "$FILE"&)
hyprctl -q dispatch setprop address:$ADDR no_screen_share $NSS
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment