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
|
#!/bin/bash
VERSION="1.0.0"
DEFAULT_MODE="area"
DEFAULT_PREFIX="Screenshot"
DEFAULT_LOCATION="$HOME/Screenshots"
LOGFILE="$HOME/.cache/hyprland-screenshot.log"
mkdir -p "$(dirname "$LOGFILE")"
echo -e "\n=== $(date '+%F %T.%3N') - Starting screenshot ===" >> "$LOGFILE"
# === Get PID ===
SCRIPT_IDENTIFIER="hyprland-screenshot"
current_pid=$$
echo "Current PID: $current_pid" >> "$LOGFILE"
for pid in $(pgrep -f "$SCRIPT_IDENTIFIER"); do
if [ "$pid" != "$current_pid" ]; then
echo "Killing previous instance: $pid" >> "$LOGFILE"
kill "$pid"
fi
done
# === Default config ===
MODE="$DEFAULT_MODE"
LOCATION="$DEFAULT_LOCATION"
PREFIX="$DEFAULT_PREFIX"
FILENAME_OVERRIDE=""
SOUND_ENABLED="true"
QUIET="false"
# === Dependency check ===
REQUIRED_COMMANDS=(grim slurp wl-copy hyprctl jq notify-send canberra-gtk-play)
for cmd in "${REQUIRED_COMMANDS[@]}"; do
if ! command -v "$cmd" &>/dev/null; then
echo "⚠️ Required command '$cmd' not found. Please install it before running this script."
fi
done
# === Help ===
print_help() {
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " -m, --mode MODE Screenshot mode: area, window, monitor, all"
echo " -l, --location PATH Output directory"
echo " -p, --prefix PREFIX Prefix before timestamp (default: Screenshot)"
echo " -n, --name NAME Full custom filename (no timestamp)"
echo " -s, --sound on|off Enable or disable shutter sound (default: on)"
echo " -q, --quiet Suppress notifications"
echo " -v, --version Print version and exit"
echo " -h, --help Show this help message and exit"
exit 0
}
# === Parse CLI args ===
while [[ "$#" -gt 0 ]]; do
case "$1" in
-m|--mode) MODE="$2"; shift ;;
-l|--location) LOCATION="$2"; shift ;;
-p|--prefix) PREFIX="$2"; shift ;;
-n|--name) FILENAME_OVERRIDE="$2"; shift ;;
-s|--sound)
case "$2" in
on|enable) SOUND_ENABLED="true" ;;
off|disable) SOUND_ENABLED="false" ;;
*) echo "❌ Invalid sound option: $2" && print_help ;;
esac
shift ;;
-q|--quiet) QUIET="true" ;;
-v|--version) echo "gs-screenshot v$VERSION"; exit 0 ;;
-h|--help) print_help ;;
*) echo "Unknown option: $1"; print_help ;;
esac
shift
done
echo "Sound enabled: $SOUND_ENABLED" >> "$LOGFILE"
# === Determine filename ===
mkdir -p "$LOCATION"
if [[ -n "$FILENAME_OVERRIDE" ]]; then
FILENAME="$LOCATION/$FILENAME_OVERRIDE"
else
TIMESTAMP=$(date '+%F_%H-%M-%S-%3N')
FILENAME="$LOCATION/${PREFIX}-$TIMESTAMP.png"
fi
echo "Saving to: $FILENAME" >> "$LOGFILE"
# === Take screenshot ===
case "$MODE" in
area)
GEOM=$(slurp)
if [[ -z "$GEOM" ]]; then
[[ "$QUIET" == "false" ]] && notify-send -u critical -a Screenshot "❌ Screenshot cancelled" "No area selected"
exit 1
fi
if ! echo "$GEOM" | grep -Eq '[0-9]+,[0-9]+ [1-9][0-9]*x[1-9][0-9]*'; then
[[ "$QUIET" == "false" ]] && notify-send -u critical -a Screenshot "❌ Invalid region" "$GEOM"
exit 1
fi
grim -g "$GEOM" - | tee "$FILENAME" | wl-copy
;;
window)
GEOM=$(hyprctl activewindow -j | jq -r '"\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"')
grim -g "$GEOM" - | tee "$FILENAME" | wl-copy
;;
monitor)
MONITOR_INDEX=$(hyprctl activewindow -j | jq -r '.monitor')
MONITOR=$(hyprctl monitors -j | jq -r ".[$MONITOR_INDEX].name")
grim -o "$MONITOR" "$FILENAME"
wl-copy < "$FILENAME"
;;
all)
grim "$FILENAME"
wl-copy < "$FILENAME"
;;
*)
[[ "$QUIET" == "false" ]] && notify-send -u critical -a Screenshot "❌ Invalid screenshot mode: $MODE"
exit 1
;;
esac
# === Notification ===
if [[ "$QUIET" == "false" && -f "$FILENAME" ]]; then
notify-send -u normal -a Screenshot -i "$FILENAME" \
--action=open:"Open Image" \
--action=folder:"Show Folder" \
"📸 Screenshot ($MODE) saved!" "$(basename "$FILENAME")" &>/dev/null &
elif [[ "$QUIET" == "false" ]]; then
notify-send -u critical -a Screenshot "❌ Screenshot failed" "No file created"
exit 1
fi
# === Play shutter sound ===
play_sound() {
if command -v canberra-gtk-play &>/dev/null; then
canberra-gtk-play -i camera-shutter -d "screenshot" &
fi
}
if [[ "$SOUND_ENABLED" == "true" ]]; then
play_sound
fi
echo "✅ Done!" >> "$LOGFILE"
|