summary refs log tree commit diff
path: root/bin/grimshot
blob: af7bcd1f90da2ef93e691240ce795d4e17bd37cb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!/bin/sh

## Grimshot: a helper for screenshots within sway
## Requirements:
##  - `grim`: screenshot utility for wayland
##  - `slurp`: to select an area
##  - `wf-recorder`: screen-recording utility
##  - `swaymsg`: to read properties of current window
##  - `wl-copy`: clipboard utility
##  - `jq`: json uliity to parse swaymsg output
##  - `notify-send`: to show notifications
##  - `mktemp`: to create a temporary file
## Those are needed to be installed, if unsure, run `grimshot check`
##
## Examples:
## `grimshot copy win` - to copy current window
## `grimshot save area` - to select area and save it to default file (Pictures/Grimshot-$datetime.png)
## `grimshot save screen ~/screenshot.png` - to save screenshot under ~/screenshot.png
## `grimshot | grimshot -h` - usage
## `grimshot check` - verify if tools are installed

_slurp() {
	slurp -d -c '#4E437188' -w 3
}
_silence_notifications() {
	once -k mako
	trap '{ once mako; }' EXIT
}

ACTION=${1:-usage}
SUBJECT=${2:-screen}
FILE=${3:-$(xdg-user-dir PICTURES)/screenshots/$(now).png}
case "$ACTION" in
	usage | help | -h | --help)
		echo "Usage:"
		echo "  grimshot copy|save|rec win|screen|area|output [FILE]"
		echo "Troubleshoot:"
		echo "  grimshot check"
		exit
		;;
esac

notify() {
	notify-send -i "${TMP:-${FILE}}" -t 3000 -a grimshot "$@"
	# notify-send -i "${TMP:-${FILE}}" -t 3000 "$@"
}
notifyOk() {
	TITLE=${2:-"Screenshot"}
	MESSAGE=${1:-"OK"}
	notify "$TITLE" "$MESSAGE"
}
notifyError() {
	TITLE=${2:-"Screenshot"}
	MESSAGE=${1:-"Error taking screenshot with grim"}
	TMP=/usr/share/icons/Adwaita/scalable/apps/applets-screenshooter-symbolic.svg
	notify -u critical "$TITLE" "$MESSAGE"
}

die() {
	MSG=${1:-Bye}
	notifyError "Error: $MSG"
	exit 2
}

check() {
	COMMAND=$1
	command -v "$COMMAND" >/dev/null 2>&1
	if [ $? ]; then
		RESULT="OK"
	else
		RESULT="NOT FOUND"
	fi
	echo "   $COMMAND: $RESULT"
}

takeScreenshot() {
	FILE=$1
	GEOM=$2
	OUTPUT=$3
	if [ -n "$GEOM" ]; then
		grim -g "$GEOM" "$FILE" || die "Unable to invoke grim"
	elif [ -n "$OUTPUT" ]; then
		grim -o "$OUTPUT" "$FILE" || die "Unable to invoke grim"
	else
		grim "$FILE" || die "Unable to invoke grim"
	fi
}

recordScreen() {
	_silence_notifications

	FILE=$1
	GEOM=$2
	OUTPUT=$3
	REC_OPTS="-d /dev/dri/renderD128"
	if [ -n "$GEOM" ]; then
		wf-recorder ${REC_OPTS} -g "${GEOM}" -f "$FILE" || die "Unable to invoke wf-recorder"
	elif [ -n "$OUTPUT" ]; then
		wf-recorder ${REC_OPTS} -o "${OUTPUT}" -f "$FILE" || die "Unable to invoke wf-recorder"
	else
		wf-recorder ${REC_OPTS} -f "$FILE" || die "Unable to invoke wf-recorder"
	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 wf-recorder
	check swaymsg
	check swq
	check wl-copy
	check jq
	check notify-send
	check mktemp
	exit
elif [ "$SUBJECT" = "area" ]; then
	GEOM=$(_slurp)
	[ -z "$GEOM" ] && die "Selection cancelled"
	WHAT="Area"
elif [ "$SUBJECT" = "win" ]; then
	FOCUSED=$(swaymsg -t get_tree | jq -r 'recurse(.nodes[]?, .floating_nodes[]?) | select(.focused)')
	GEOM=$(echo "$FOCUSED" | jq -r '.rect | "\(.x),\(.y) \(.width)x\(.height)"')
	APP_ID=$(echo "$FOCUSED" | jq -r '.app_id')
	WHAT="$APP_ID window"
elif [ "$SUBJECT" = "screen" ]; then
	GEOM=""
	WHAT="Screen"
elif [ "$SUBJECT" = "output" ]; then
	GEOM=""
	OUTPUT="$(swq current output)"
	WHAT="output $OUTPUT"
else
	die "Unknown subject to take a screen shot from" "$SUBJECT"
fi

if [ "$ACTION" = "copy" ]; then
	TMP=$(mktemp) || die "Unable to create temp file: is mktemp installed?"
	takeScreenshot "$TMP" "$GEOM" "$OUTPUT"
	wl-copy --type image/png <"$TMP" || die "Clipboard error"
	notifyOk "$WHAT copied to clipboard"
	rm "$TMP"
elif [ "$ACTION" = "save" ]; then
	takeScreenshot "$FILE" "$GEOM" "$OUTPUT"
	if [ $? ]; then
		TITLE="Screenshot of $SUBJECT"
		MESSAGE=$(basename "$FILE")
		wl-copy --type image/png <"$FILE" || die "Clipboard error"
		notifyOk "$MESSAGE" "$TITLE"
	else
		notifyError "Error taking screenshot with grim"
	fi
elif [ "$ACTION" = "rec" ]; then
	echo "$FILE" | awk '/png$/{exit 0}' \
		&& FILE=$(xdg-user-dir VIDEOS)/grimshot/$(now).mp4
	# create dir if not exists
	[ -d "$(dirname "$FILE")" ] || mkdir -p "$(dirname "$FILE")"
	recordScreen "$FILE" "$GEOM" "$OUTPUT"
	wl-copy "$FILE" || die "Clipboard error"
	if [ $? ]; then
		TITLE="Screen recording of $SUBJECT"
		MESSAGE=$(basename "$FILE")
		notifyOk "$MESSAGE" "$TITLE"
	else
		notifyError "Error recording screen with wf-recorder"
	fi
else
	die "Unknown action" "$ACTION"
fi