diff --git a/setup/clean-install-grimblast.sh b/setup/clean-install-grimblast.sh new file mode 100755 index 000000000..cd0ce373e --- /dev/null +++ b/setup/clean-install-grimblast.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +# Assume grimblast was installed manually, and uninstall instances +while [ -n "$(which grimblast 2>/dev/null)" ]; do + sudo rm -v "$(which grimblast)" +done + +# Install grimblast from source +GRIMBLAST_BUILD_DIR=$(mktemp -d) +trap 'rm -fr "$GRIMBLAST_BUILD_DIR"' EXIT +git clone --depth=1 https://github.com/hyprwm/contrib.git "$GRIMBLAST_BUILD_DIR" +make -C "$GRIMBLAST_BUILD_DIR/grimblast" +sudo make -C "$GRIMBLAST_BUILD_DIR/grimblast" install diff --git a/setup/post-fedora.sh b/setup/post-fedora.sh index 6a7d9935f..a40417199 100755 --- a/setup/post-fedora.sh +++ b/setup/post-fedora.sh @@ -63,7 +63,7 @@ sudo pip install pywalfox # Grimblast # -------------------------------------------------------------- -sudo cp $repo_path/setup/scripts/grimblast /usr/bin +source $repo_path/setup/clean-install-grimblast.sh # -------------------------------------------------------------- # Cursors diff --git a/setup/post-opensuse.sh b/setup/post-opensuse.sh index 1d87d37b2..6e299edd7 100755 --- a/setup/post-opensuse.sh +++ b/setup/post-opensuse.sh @@ -84,7 +84,7 @@ pipx install pywalfox # Grimblast # -------------------------------------------------------------- -sudo cp $repo_path/setup/scripts/grimblast /usr/bin +source $repo_path/setup/clean-install-grimblast.sh # -------------------------------------------------------------- # Cursors diff --git a/setup/scripts/grimblast b/setup/scripts/grimblast deleted file mode 100755 index c12ace1ef..000000000 --- a/setup/scripts/grimblast +++ /dev/null @@ -1,276 +0,0 @@ -#!/usr/bin/env bash -## Grimblast: a helper for screenshots within hyprland -## Requirements: -## - `grim`: screenshot utility for wayland -## - `slurp`: to select an area -## - `hyprctl`: to read properties of current window (provided by Hyprland) -## - `hyprpicker`: to freeze the screen when selecting area -## - `wl-copy`: clipboard utility (provided by wl-clipboard) -## - `jq`: json utility to parse hyprctl output -## - `notify-send`: to show notifications (provided by libnotify) -## Those are needed to be installed, if unsure, run `grimblast check` -## -## See `man 1 grimblast` or `grimblast usage` for further details. - -## Author: Misterio (https://github.com/misterio77) - -## This tool is based on grimshot, with swaymsg commands replaced by their -## hyprctl equivalents. -## https://github.com/swaywm/sway/blob/master/contrib/grimshot - -# Check whether another instance is running - -grimblastInstanceCheck="${XDG_RUNTIME_DIR:-$XDG_CACHE_DIR:-$HOME/.cache}/grimblast.lock" -if [ -e "$grimblastInstanceCheck" ]; then - exit 2 -else - touch "$grimblastInstanceCheck" -fi -trap "rm -f '$grimblastInstanceCheck'" EXIT - -getTargetDirectory() { - test -f "${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs" && - . "${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs" - - echo "${XDG_SCREENSHOTS_DIR:-${XDG_PICTURES_DIR:-$HOME}}" -} - -tmp_editor_directory() { - echo "/tmp" -} - -#Detect if $GRIMBLAST_EDITOR env exist -env_editor_confirm() { - if [ -n "$GRIMBLAST_EDITOR" ]; then - echo "GRIMBLAST_EDITOR is set. Continuing..." - else - echo "GRIMBLAST_EDITOR is not set. Defaulting to gimp" - GRIMBLAST_EDITOR=gimp - fi -} - -NOTIFY=no -CURSOR= -FREEZE= -WAIT=no -SCALE= -HYPRPICKER_PID=-1 - -while [ $# -gt 0 ]; do - key="$1" - - case $key in - -n | --notify) - NOTIFY=yes - shift # past argument - ;; - -c | --cursor) - CURSOR=yes - shift # past argument - ;; - -f | --freeze) - FREEZE=yes - shift # past argument - ;; - -w | --wait) - shift - WAIT=$1 - if echo "$WAIT" | grep "[^0-9]" -q; then - echo "Invalid value for wait '$WAIT'" >&2 - exit 3 - fi - shift - ;; - -s | --scale) - shift # past argument - if [ $# -gt 0 ]; then - SCALE="$1" # assign the next argument to SCALE - shift # past argument - else - echo "Error: Missing argument for --scale option." - exit 1 - fi - ;; - *) # unknown option - break # done with parsing --flags - ;; - esac -done - -ACTION=${1:-usage} -SUBJECT=${2:-screen} -FILE=${3:-$(getTargetDirectory)/$(date -Ins).png} -FILE_EDITOR=${3:-$(tmp_editor_directory)/$(date -Ins).png} - -if [ "$ACTION" != "save" ] && [ "$ACTION" != "copy" ] && [ "$ACTION" != "edit" ] && [ "$ACTION" != "copysave" ] && [ "$ACTION" != "check" ]; then - echo "Usage:" - echo " grimblast [--notify] [--cursor] [--freeze] [--wait N] [--scale ] (copy|save|copysave|edit) [active|screen|output|area] [FILE|-]" - echo " grimblast check" - echo " grimblast 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 " copysave: Combine the previous 2 options." - echo " edit: Open screenshot in the image editor of your choice (default is gimp). See man page for info." - 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 or window." - exit -fi - -notify() { - notify-send -t 3000 -a grimblast "$@" -} - -notifyOk() { - [ "$NOTIFY" = "no" ] && return - - notify "$@" -} - -notifyError() { - if [ $NOTIFY = "yes" ]; then - TITLE=${2:-"Screenshot"} - MESSAGE=${1:-"Error taking screenshot with grim"} - notify -u critical "$TITLE" "$MESSAGE" - else - echo "$1" - fi -} - -killHyprpicker() { - if [ ! $HYPRPICKER_PID -eq -1 ]; then - kill $HYPRPICKER_PID - fi -} - -die() { - killHyprpicker - 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 [ -n "$OUTPUT" ]; then - grim ${CURSOR:+-c} ${SCALE:+-s "$SCALE"} -o "$OUTPUT" "$FILE" || die "Unable to invoke grim" - elif [ -z "$GEOM" ]; then - grim ${CURSOR:+-c} ${SCALE:+-s "$SCALE"} "$FILE" || die "Unable to invoke grim" - else - grim ${CURSOR:+-c} ${SCALE:+-s "$SCALE"} -g "$GEOM" "$FILE" || die "Unable to invoke grim" - fi -} - -wait() { - if [ "$WAIT" != "no" ]; then - sleep "$WAIT" - 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 hyprctl - check hyprpicker - check wl-copy - check jq - check notify-send - exit -elif [ "$SUBJECT" = "active" ]; then - wait - FOCUSED=$(hyprctl activewindow -j) - GEOM=$(echo "$FOCUSED" | jq -r '"\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"') - APP_ID=$(echo "$FOCUSED" | jq -r '.class') - WHAT="$APP_ID window" -elif [ "$SUBJECT" = "screen" ]; then - wait - GEOM="" - WHAT="Screen" -elif [ "$SUBJECT" = "output" ]; then - wait - GEOM="" - OUTPUT=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true)' | jq -r '.name') - WHAT="$OUTPUT" -elif [ "$SUBJECT" = "area" ]; then - if [ "$FREEZE" = "yes" ] && [ "$(command -v "hyprpicker")" ] >/dev/null 2>&1; then - hyprpicker -r -z & - sleep 0.2 - HYPRPICKER_PID=$! - fi - - # disable animation for layer namespace "selection" (slurp) - # this removes the black border seen around screenshots - hyprctl keyword layerrule "noanim,selection" >/dev/null - - WORKSPACES="$(hyprctl monitors -j | jq -r '[(foreach .[] as $monitor (0; if $monitor.specialWorkspace.name == "" then $monitor.activeWorkspace else $monitor.specialWorkspace end)).id]')" - WINDOWS="$(hyprctl clients -j | jq -r --argjson workspaces "$WORKSPACES" 'map(select([.workspace.id] | inside($workspaces)))')" - # shellcheck disable=2086 # if we don't split, spaces mess up slurp - GEOM=$(echo "$WINDOWS" | jq -r '.[] | "\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"' | slurp $SLURP_ARGS) - - # Check if user exited slurp without selecting the area - if [ -z "$GEOM" ]; then - killHyprpicker - exit 1 - fi - WHAT="Area" - wait -elif [ "$SUBJECT" = "window" ]; then - die "Subject 'window' is now included in 'area'" -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" -elif [ "$ACTION" = "save" ]; then - if takeScreenshot "$FILE" "$GEOM" "$OUTPUT"; then - TITLE="Screenshot of $SUBJECT" - MESSAGE=$(basename "$FILE") - notifyOk "$TITLE" "$MESSAGE" -i "$FILE" - echo "$FILE" - else - notifyError "Error taking screenshot with grim" - fi -elif [ "$ACTION" = "edit" ]; then - env_editor_confirm - if takeScreenshot "$FILE_EDITOR" "$GEOM" "$OUTPUT"; then - TITLE="Screenshot of $SUBJECT" - MESSAGE="Open screenshot in image editor" - notifyOk "$TITLE" "$MESSAGE" -i "$FILE_EDITOR" - $GRIMBLAST_EDITOR "$FILE_EDITOR" - echo "$FILE_EDITOR" - else - notifyError "Error taking screenshot" - fi -else - if [ "$ACTION" = "copysave" ]; then - takeScreenshot - "$GEOM" "$OUTPUT" | tee "$FILE" | wl-copy --type image/png || die "Clipboard error" - notifyOk "$WHAT copied to buffer and saved to $FILE" -i "$FILE" - echo "$FILE" - else - notifyError "Error taking screenshot with grim" - fi -fi - -killHyprpicker