diff --git a/.config/hypr/scripts/hyprshot b/.config/hypr/scripts/hyprshot index 28b67a3a..c99e6d5b 100755 --- a/.config/hypr/scripts/hyprshot +++ b/.config/hypr/scripts/hyprshot @@ -3,7 +3,7 @@ set -e function Help() { - cat <&2 printf "$@" + 1>&2 printf "$@" } function send_notification() { - if [ $SILENT -eq 1 ]; then - return 0 - fi + if [ $SILENT -eq 1 ]; then + return 0 + fi - local message=$([ $CLIPBOARD -eq 1 ] && - echo "Image copied to the clipboard" || - echo "Image saved in ${1} and copied to the clipboard.") - action=$(notify-send -i "$1" --action "View Image" "Screenshot saved" \ - "${message}" \ - -t "$NOTIF_TIMEOUT" -i "${1}" -a Hyprshot) - if [ -n "$action" ]; then - if command -v satty &>/dev/null; then - satty -f "$1" - else - xdg-open "$1" - fi - fi + local message=$([ $CLIPBOARD -eq 1 ] && + echo "Image copied to the clipboard" || + echo "Image saved in ${1} and copied to the clipboard.") + action=$(notify-send -i "$1" --action "View Image" "Screenshot saved" \ + "${message}" \ + -t "$NOTIF_TIMEOUT" -i "${1}" -a Hyprshot) + + if [ -n "$action" ]; then + if command -v satty &>/dev/null; then + satty -f "$1" + else + xdg-open "$1" + fi + fi } function trim() { - local geometry="${1}" - local xy_str=$(echo "${geometry}" | cut -d' ' -f1) - local wh_str=$(echo "${geometry}" | cut -d' ' -f2) - local x=$(echo "${xy_str}" | cut -d',' -f1) - local y=$(echo "${xy_str}" | cut -d',' -f2) - local width=$(echo "${wh_str}" | cut -dx -f1) - local height=$(echo "${wh_str}" | cut -dx -f2) + Print "Geometry: %s\n" "${1}" + local geometry="${1}" + local xy_str=$(echo "${geometry}" | cut -d' ' -f1) + local wh_str=$(echo "${geometry}" | cut -d' ' -f2) + local x=$(echo "${xy_str}" | cut -d',' -f1) + local y=$(echo "${xy_str}" | cut -d',' -f2) + local width=$(echo "${wh_str}" | cut -dx -f1) + local height=$(echo "${wh_str}" | cut -dx -f2) - local max_width=$(hyprctl monitors -j | jq -r '[.[] | if (.transform % 2 == 0) then (.x + .width) else (.x + .height) end] | max') - local max_height=$(hyprctl monitors -j | jq -r '[.[] | if (.transform % 2 == 0) then (.y + .height) else (.y + .width) end] | max') + local max_width=$(hyprctl monitors -j | jq -r '[.[] | if (.transform % 2 == 0) then (.x + .width) else (.x + .height) end] | max') + local max_height=$(hyprctl monitors -j | jq -r '[.[] | if (.transform % 2 == 0) then (.y + .height) else (.y + .width) end] | max') - local min_x=$(hyprctl monitors -j | jq -r '[.[] | (.x)] | min') - local min_y=$(hyprctl monitors -j | jq -r '[.[] | (.y)] | min') + local min_x=$(hyprctl monitors -j | jq -r '[.[] | (.x)] | min') + local min_y=$(hyprctl monitors -j | jq -r '[.[] | (.y)] | min') - local cropped_x=$x - local cropped_y=$y - local cropped_width=$width - local cropped_height=$height + local cropped_x=$x + local cropped_y=$y + local cropped_width=$width + local cropped_height=$height - if ((x + width > max_width)); then - cropped_width=$((max_width - x)) - fi - if ((y + height > max_height)); then - cropped_height=$((max_height - y)) - fi + if ((x + width > max_width)); then + cropped_width=$((max_width - x)) + fi + if ((y + height > max_height)); then + cropped_height=$((max_height - y)) + fi - if ((x < min_x)); then - cropped_x="$min_x" - cropped_width=$((cropped_width + x - min_x)) - fi - if ((y < min_y)); then - cropped_y="$min_y" - cropped_height=$((cropped_height + y - min_y)) - fi + if ((x < min_x)); then + cropped_x="$min_x" + cropped_width=$((cropped_width + x - min_x)) + fi + if ((y < min_y)); then + cropped_y="$min_y" + cropped_height=$((cropped_height + y - min_y)) + fi - printf "%s,%s %sx%s\n" \ - "${cropped_x}" "${cropped_y}" \ - "${cropped_width}" "${cropped_height}" + local cropped=$(printf "%s,%s %sx%s\n" \ + "${cropped_x}" "${cropped_y}" \ + "${cropped_width}" "${cropped_height}") + Print "Crop: %s\n" "${cropped}" + echo ${cropped} } function save_geometry() { - Print "Geometry: %s\n" "${1}" - local cropped_geometry=$(trim "${1}") - Print "Crop: %s\n" "${cropped_geometry}" - local output="" + local geometry="${1}" + local output="" - if [ $RAW -eq 1 ]; then - grim -g "${cropped_geometry}" - - return 0 - fi + if [ $RAW -eq 1 ]; then + grim -g "${geometry}" - + return 0 + fi - if [ $CLIPBOARD -eq 0 ]; then - mkdir -p "$SAVEDIR" - grim -g "${cropped_geometry}" "$SAVE_FULLPATH" - output="$SAVE_FULLPATH" - wl-copy <"$output" - [ -z "$COMMAND" ] || { - "$COMMAND" "$output" - } - else - wl-copy < <(grim -g "${cropped_geometry}" -) - fi + if [ $CLIPBOARD -eq 0 ]; then + mkdir -p "$SAVEDIR" + grim -g "${geometry}" "$SAVE_FULLPATH" + output="$SAVE_FULLPATH" + wl-copy --type image/png <"$output" + [ -z "$COMMAND" ] || { + "$COMMAND" "$output" + } + else + wl-copy --type image/png < <(grim -g "${geometry}" -) + fi - send_notification $output + send_notification $output +} + +function checkRunning() { + sleep 1 + while [[ 1 == 1 ]]; do + if [[ $(pgrep slurp | wc -m) == 0 ]]; then + pkill hyprpicker + exit + fi + done } function begin_grab() { - local option=$1 - - if [ $FREEZE -eq 1 ]; then - sleep 0.5 - hyprpicker -r -z & - sleep 0.2 - local picker_pid=$! - fi - - case $option in - output) - if [ $CURRENT -eq 1 ]; then - local geometry=$(grab_active_output) - elif [ -z $SELECTED_MONITOR ]; then - local geometry=$(grab_output) - else - local geometry=$(grab_selected_output $SELECTED_MONITOR) - fi - ;; - region) - local geometry=$(grab_region) - ;; - window) - if [ $CURRENT -eq 1 ]; then - local geometry=$(grab_active_window) - else - local geometry=$(grab_window) - fi - ;; - esac - - save_geometry "${geometry}" - - if [ $FREEZE -eq 1 ]; then - kill $picker_pid - fi + if [ $FREEZE -eq 1 ] && [ "$(command -v "hyprpicker")" ] >/dev/null 2>&1; then + hyprpicker -r -z & + sleep 0.2 + HYPRPICKER_PID=$! + fi + local option=$1 + case $option in + output) + if [ $CURRENT -eq 1 ]; then + local geometry=$(grab_active_output) + elif [ -z $SELECTED_MONITOR ]; then + local geometry=$(grab_output) + else + local geometry=$(grab_selected_output $SELECTED_MONITOR) + fi + ;; + region) + local geometry=$(grab_region) + ;; + window) + if [ $CURRENT -eq 1 ]; then + local geometry=$(grab_active_window) + else + local geometry=$(grab_window) + fi + geometry=$(trim "${geometry}") + ;; + esac + if [ ${DELAY} -gt 0 ] 2>/dev/null; then + sleep ${DELAY} + fi + save_geometry "${geometry}" } function grab_output() { - slurp -or + slurp -or } function grab_active_output() { - local active_workspace=$(hyprctl -j activeworkspace) - local monitors=$(hyprctl -j monitors) - Print "Monitors: %s\n" "$monitors" - Print "Active workspace: %s\n" "$active_workspace" - local current_monitor="$(echo $monitors | jq -r 'first(.[] | select(.activeWorkspace.id == '$(echo $active_workspace | jq -r '.id')'))')" - Print "Current output: %s\n" "$current_monitor" - echo $current_monitor | jq -r '"\(.x),\(.y) \(.width/.scale|round)x\(.height/.scale|round)"' + local active_workspace=$(hyprctl -j activeworkspace) + local monitors=$(hyprctl -j monitors) + Print "Monitors: %s\n" "$monitors" + Print "Active workspace: %s\n" "$active_workspace" + local current_monitor="$(echo $monitors | jq -r 'first(.[] | select(.activeWorkspace.id == '$(echo $active_workspace | jq -r '.id')'))')" + Print "Current output: %s\n" "$current_monitor" + echo $current_monitor | jq -r '"\(.x),\(.y) \(.width/.scale|round)x\(.height/.scale|round)"' } function grab_selected_output() { - local monitor=$(hyprctl -j monitors | jq -r '.[] | select(.name == "'$(echo $1)'")') - Print "Capturing: %s\n" "${1}" - echo $monitor | jq -r '"\(.x),\(.y) \(.width/.scale|round)x\(.height/.scale|round)"' + local monitor=$(hyprctl -j monitors | jq -r '.[] | select(.name == "'$(echo $1)'")') + Print "Capturing: %s\n" "${1}" + echo $monitor | jq -r '"\(.x),\(.y) \(.width/.scale|round)x\(.height/.scale|round)"' } function grab_region() { - slurp -d + slurp -d } function grab_window() { - local monitors=$(hyprctl -j monitors) - local clients=$(hyprctl -j clients | jq -r '[.[] | select(.workspace.id | contains('$(echo $monitors | jq -r 'map(.activeWorkspace.id) | join(",")')'))]') - Print "Monitors: %s\n" "$monitors" - Print "Clients: %s\n" "$clients" - # Generate boxes for each visible window and send that to slurp - # through stdin - local boxes="$(echo $clients | jq -r '.[] | "\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1]) \(.title)"')" - Print "Boxes:\n%s\n" "$boxes" - slurp -r <<<"$boxes" + local monitors=$(hyprctl -j monitors) + local clients=$(hyprctl -j clients | jq -r '[.[] | select(.workspace.id | contains('$(echo $monitors | jq -r 'map(.activeWorkspace.id) | join(",")')'))]') + Print "Monitors: %s\n" "$monitors" + Print "Clients: %s\n" "$clients" + # Generate boxes for each visible window and send that to slurp + # through stdin + local boxes="$(echo $clients | jq -r '.[] | "\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1]) \(.title)"' | cut -f1,2 -d' ')" + Print "Boxes:\n%s\n" "$boxes" + slurp -r <<<"$boxes" } function grab_active_window() { - local active_window=$(hyprctl -j activewindow) - local box=$(echo $active_window | jq -r '"\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"') - Print "Box:\n%s\n" "$box" - echo "$box" + local active_window=$(hyprctl -j activewindow) + local box=$(echo $active_window | jq -r '"\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"' | cut -f1,2 -d' ') + Print "Box:\n%s\n" "$box" + echo "$box" } function parse_mode() { - local mode="${1}" + local mode="${1}" - case $mode in - window | region | output) - OPTION=$mode - ;; - active) - CURRENT=1 - ;; - *) - hyprctl monitors -j | jq -re '.[] | select(.name == "'$(echo $mode)'")' &>/dev/null - SELECTED_MONITOR=$mode - ;; - esac + case $mode in + window | region | output) + OPTION=$mode + ;; + active) + CURRENT=1 + ;; + *) + hyprctl monitors -j | jq -re '.[] | select(.name == "'$(echo $mode)'")' &>/dev/null + SELECTED_MONITOR=$mode + ;; + esac } function args() { - local options=$(getopt -o hf:o:m:dsrt:z --long help,filename:,output-folder:,mode:,clipboard-only,debug,silent,raw,notif-timeout:,freeze -- "$@") - eval set -- "$options" + local options=$(getopt -o hf:o:m:D:dszr:t: --long help,filename:,output-folder:,mode:,delay:,clipboard-only,debug,silent,freeze,raw,notif-timeout: -- "$@") + 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 - parse_mode $1 - ;; - --clipboard-only) - CLIPBOARD=1 - ;; - -d | --debug) - DEBUG=1 - ;; - -s | --silent) - SILENT=1 - ;; - -r | --raw) - RAW=1 - ;; - -t | --notif-timeout) - shift - NOTIF_TIMEOUT=$1 - ;; - -z | --freeze) - FREEZE=1 - ;; - --) - shift # Skip -- argument - COMMAND=${@:2} - break - ;; - esac - shift - done + while true; do + case "$1" in + -h | --help) + Help + exit + ;; + -o | --output-folder) + shift + SAVEDIR=$1 + ;; + -f | --filename) + shift + FILENAME=$1 + ;; + -D | --delay) + shift + DELAY=$1 + ;; + -m | --mode) + shift + parse_mode $1 + ;; + --clipboard-only) + CLIPBOARD=1 + ;; + -d | --debug) + DEBUG=1 + ;; + -z | --freeze) + FREEZE=1 + ;; + -s | --silent) + SILENT=1 + ;; + -r | --raw) + RAW=1 + ;; + -t | --notif-timeout) + shift + NOTIF_TIMEOUT=$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 $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 + Help + exit fi CLIPBOARD=0 DEBUG=0 SILENT=0 RAW=0 -FREEZE=0 NOTIF_TIMEOUT=5000 CURRENT=0 +FREEZE=0 [ -z "$XDG_PICTURES_DIR" ] && type xdg-user-dir &>/dev/null && XDG_PICTURES_DIR=$(xdg-user-dir PICTURES) FILENAME="$(date +'%Y-%m-%d-%H%M%S_hyprshot.png')" [ -z "$HYPRSHOT_DIR" ] && SAVEDIR=${XDG_PICTURES_DIR:=~} || SAVEDIR=${HYPRSHOT_DIR} @@ -310,4 +323,5 @@ args $0 "$@" SAVE_FULLPATH="$SAVEDIR/$FILENAME" [ $CLIPBOARD -eq 0 ] && Print "Saving in: %s\n" "$SAVE_FULLPATH" -begin_grab $OPTION +begin_grab $OPTION & +checkRunning