neodotfiles/config/fuzzel/scripts/rs_scrot
2024-08-21 20:44:58 -04:00

321 lines
9.4 KiB
Bash
Executable file

#!/usr/bin/env bash
# rs_scrot - A simple screenshot menu script for rofi/dmenu/wofi/fuzzel
# Author: Clay Gomera (Drake)
# Dependencies: {rofi || dmenu || wofi || fuzzel}, grim, slurp, jq, wf-recorder, wl-clipboard (wl-copy), libnotify (notify-send)
############################
# Configuration Parameters #
############################
# Directory to save screenshots
SHOTDIR="$XDG_PICTURES_DIR/Screenshots"
VCAPDIR="$XDG_VIDEOS_DIR/Screencasts" # $MEDIA_DIR refers to a global variable in .xinitrc/.bash_profile
[ ! -d "$SHOTDIR" ] && [ ! -d "$VCAPDIR" ] && mkdir -p "$SHOTDIR" "$VCAPDIR" || echo
# Get audio devices and descriptions
audioDevices=$(pactl list sources | grep "Name" | awk '{print $2}')
audioDescriptions=$(pactl list sources | grep "Description" | cut -d' ' -f2-)
# Create an associative array for mapping pretty names to actual names
declare -A audioMap
while IFS= read -r name && IFS= read -r desc <&3; do
audioMap["$desc"]="$name"
done < <(echo "$audioDevices") 3< <(echo "$audioDescriptions")
#####################
# Main Menu Options #
#####################
mainChoice1="󰹑 Take an screenshot"
mainChoice2="󰻃 Record the screen"
mainChoice3=" Exit"
mainChoices="$mainChoice1\n$mainChoice2\n$mainChoice3"
#############################
## Screenshot menu choices ##
#############################
shotChoice1="󱣴 Entire screen"
shotChoice2="󱎫 Entire screen with delay"
shotChoice3="󱕻 Select region"
shotChoice4="󰖯 Active window"
shotChoice5="󱎘 Exit"
shotChoices="$shotChoice1\n$shotChoice2\n$shotChoice3\n$shotChoice4\n$shotChoice5"
#############################
## Screencast menu choices ##
#############################
vidChoice1="󰕧 Record the screen"
vidChoice2="󰕩 Record region"
vidChoice3="󰕧 Record the screen with audio"
vidChoice4="󰕨 Stop recording"
vidChoice5="󱎘 Exit"
vidChoices="$vidChoice1\n$vidChoice2\n$vidChoice3\n$vidChoice4\n$vidChoice5"
###################
# Submenu Options #
###################
subShotChoice1="󰆏 Copy to clipboard"
subShotChoice2="󰠘 Save to $XDG_PICTURES_DIR"
subShotChoice3="󱎘 Exit"
subShotChoices="$subShotChoice1\n$subShotChoice2\n$subShotChoice3"
####################################
# Screenshot Delay Submenu Options #
####################################
delayChoice1="󱑀 3 sec delay"
delayChoice2="󱑂 5 sec delay"
delayChoice3="󱑇 10 sec delay"
delayChoice4="󱎘 Exit"
delayChoices="$delayChoice1\n$delayChoice2\n$delayChoice3\n$delayChoice4"
########################
# Function Definitions #
########################
# Check for missing dependencies
CheckDependencies() {
local run_launcher_found=false
for launcher in rofi dmenu wofi fuzzel; do
if command -v "$launcher" &> /dev/null; then
run_launcher_found=true
break
fi
done
if [ "$run_launcher_found" = false ]; then
echo "Missing dependency: one of rofi, dmenu, wofi or fuzzel is required."
exit 1
fi
local missing_deps=()
for dep in grim slurp jq wl-copy notify-send wf-recorder; do
if ! command -v "$dep" &> /dev/null; then
missing_deps+=("$dep")
fi
done
if [ ${#missing_deps[@]} -ne 0 ]; then
echo "Missing dependencies: ${missing_deps[*]}"
exit 1
fi
}
# Prompt user for screenshot action
ShotActionPrompt() {
shotActionCases=$(echo -e "$subShotChoices" | $RUNNER -l 3 -i -p "[ What do you want to do with this screenshot?]  ")
}
# Prompt user for screenshot delay
DelayPrompt() {
delayActionsCases=$(echo -e "$delayChoices" | $RUNNER -l 4 -i -p "[ Select Delay]  ")
}
# Take a full screen screenshot without delay
ShotScreen() {
ShotActionPrompt
case "$shotActionCases" in
"$subShotChoice1")
sleep 0.5 && grim - | wl-copy && notify-send "Screenshot copied to clipboard"
;;
"$subShotChoice2")
sleep 0.5 && grim "$SHOTDIR/$(date +%s).png" && notify-send "Screenshot saved to $SHOTDIR"
;;
*)
exit 0
;;
esac
}
# Take a full screen screenshot with delay
ShotScreenDelay() {
ShotActionPrompt
if [ "$shotActionCases" = "$subShotChoice1" ]; then
DelayPrompt
case $delayActionsCases in
"$delayChoice1")
sleep 3 && grim - | wl-copy && notify-send "Screenshot saved to clipboard"
;;
"$delayChoice2")
sleep 5 && grim - | wl-copy && notify-send "Screenshot saved to clipboard"
;;
"$delayChoice3")
sleep 10 && grim - | wl-copy && notify-send "Screenshot saved to clipboard"
;;
"$delayChoice4")
exit 0
;;
esac
elif [ "$shotActionCases" = "$subShotChoice2" ]; then
DelayPrompt
case $delayActionsCases in
"$delayChoice1")
sleep 3 && grim "$SHOTDIR/$(date +%s).png" && notify-send "Screenshot saved to $SHOTDIR"
;;
"$delayChoice2")
sleep 5 && grim "$SHOTDIR/$(date +%s).png" && notify-send "Screenshot saved to $SHOTDIR"
;;
"$delayChoice3")
sleep 10 && grim "$SHOTDIR/$(date +%s).png" && notify-send "Screenshot saved to $SHOTDIR"
;;
"$delayChoice4")
exit 0
;;
esac
else
exit 0
fi
}
# Take a screenshot of a selected area
ShotArea() {
ShotActionPrompt
case "$shotActionCases" in
"$subShotChoice1")
sleep 0.5 && grim -g "$(slurp)" - | wl-copy && notify-send "Screenshot saved to clipboard"
;;
"$subShotChoice2")
sleep 0.5 && grim -g "$(slurp)" "$SHOTDIR/$(date +%s).png" && notify-send "Screenshot saved to $SHOTDIR"
;;
*)
exit 0
;;
esac
}
# Take a screenshot of the active window
ShotWindow() {
ShotActionPrompt
local focused=$(hyprctl activewindow -j)
local geom=$(echo "$focused" | jq -r '"\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"')
case "$shotActionCases" in
"$subShotChoice1")
sleep 0.5 && grim -g "$geom" - | wl-copy && notify-send "Screenshot saved to clipboard"
;;
"$subShotChoice2")
sleep 0.5 && grim -g "$geom" "$SHOTDIR/$(date +%s).png" && notify-send "Screenshot saved to $SHOTDIR"
;;
*)
exit 0
;;
esac
}
# Record the entire screen
VidScreen() {
for ((i = 3; i >= 1; i--)); do
notify-send -t 1000 "Starting in $i seconds"
sleep 1
done
wf-recorder -f "$VCAPDIR/$(date +%s).mp4"
notify-send "Screenshot" "Recording saved to $VCAPDIR"
}
# Record a specific area of the screen
VidArea() {
wf-recorder -g "$(slurp)" -f "$VCAPDIR/$(date +%s).mp4"
notify-send "Screenshot" "Recording saved to $VCAPDIR"
}
# Record the entire screen with audio
VidScreenAudio() {
local chosenPrettyDevice=$(echo -e "$audioDescriptions" | $RUNNER -i -p "[󰕾 Select audio input]  ")
local chosenDevice="${audioMap["$chosenPrettyDevice"]}"
if [ -n "$chosenDevice" ]; then
for ((i = 3; i >= 1; i--)); do
notify-send -t 1000 "Starting in $i seconds"
sleep 1
done
wf-recorder --audio="$chosenDevice" -f "$VCAPDIR/$(date +%s).mp4"
else
exit 1
fi
notify-send "Screenshot" "Recording saved to $VCAPDIR"
}
# Stop the video recording
VidStopRecording() {
if pidof wfrecorder; then
killall -s SIGINT wf-recorder
else
notify-send "You are not recording right now"
exit 1
fi
}
###################
# Check arguments #
###################
# Show help information
if [ "$1" == '--help' ] || [ "$1" = '-h' ]; then
echo "rs_scrot"
echo "USAGE: rs_scrot [OPTION]"
echo -e "(no option)\tshow the screenshot menu"
echo -e "-s, --stop\tstop recording"
echo -e "-h, --help\tthis screen"
exit 1
fi
# stop recording with -s or --stop arguments
if [ "$1" = '--stop' ] || [ "$1" = '-s' ]; then
VidStopRecording
exit 1
fi
####################
# Main Script Flow #
####################
# Check for dependencies
CheckDependencies
# Display main menu and execute selected option
mainCase=$(echo -e "$mainChoices" | $RUNNER -l 3 -i -p "[ Screenshot/Screencast Utility]  ")
if [ -z "$mainCase" ]; then
exit 0
fi
case $mainCase in
"$mainChoice1")
shotCases=$(echo -e "$shotChoices" | $RUNNER -l 5 -i -p "[ Screenshot Menu]  ") # screenshot menu prompt
case $shotCases in
"$shotChoice1")
ShotScreen
;;
"$shotChoice2")
ShotScreenDelay
;;
"$shotChoice3")
ShotArea
;;
"$shotChoice4")
ShotWindow
;;
"$shotChoice5")
exit 0
;;
esac
;;
"$mainChoice2")
vidCases=$(echo -e "$vidChoices" | $RUNNER -l 5 -i -p "[󰕧 Screencast Menu]  ")
case $vidCases in
"$vidChoice1")
VidScreen
;;
"$vidChoice2")
VidArea
;;
"$vidChoice3")
VidScreenAudio
;;
"$vidChoice4")
VidStopRecording
;;
"$vidChoice5")
exit 0
esac
;;
"$mainChoice3")
exit 0
;;
esac