nix/scripts/ctl

167 lines
5.1 KiB
Bash
Executable file

#!/bin/sh
require() {
for cmd in "$@"; do
command -v "$cmd" >/dev/null 2>&1 || {
echo "ctl: missing dependency: $cmd" >&2
exit 1
}
done
}
case "$1" in
screenshot)
dir="$HOME/img/ss"
mkdir -p "$dir"
file="$dir/$(openssl rand -hex 10)-$(date +'%Y-%m-%d_%H-%M-%S').png"
if [ "${XDG_SESSION_TYPE:-}" = "wayland" ]; then
require grim slurp wl-copy
grim -g "$(slurp)" "$file" && wl-copy < "$file"
else
require maim xclip
maim -s "$file" && xclip -selection clipboard -t image/png -i "$file" &
fi
;;
ocr)
require tesseract
dir="$HOME/img/ss"
mkdir -p "$dir"
file="$dir/$(openssl rand -hex 10)-$(date +'%Y-%m-%d_%H-%M-%S').png"
if [ "${XDG_SESSION_TYPE:-}" = "wayland" ]; then
require grim slurp wl-copy
(
region="$(slurp)"
[ -n "$region" ] || exit 0
grim -g "$region" "$file" &&
tesseract -l eng "$file" - 2>/dev/null | wl-copy
) </dev/null >/dev/null 2>&1 &
else
require maim xclip
(
maim -s "$file" &&
tesseract -l eng "$file" - 2>/dev/null | xclip -selection clipboard -in
) </dev/null >/dev/null 2>&1 &
fi
;;
keyboard)
case "$2" in
toggle)
if [ "${XDG_SESSION_TYPE:-}" = "wayland" ]; then
if [ "$XDG_CURRENT_DESKTOP" = "Hyprland" ]; then
hyprctl switchxkblayout current next
elif [ "$XDG_CURRENT_DESKTOP" = "sway" ]; then
if swaymsg -t get_inputs | grep -qi "Colemak"; then
swaymsg input type:keyboard xkb_variant "''"
else
swaymsg input type:keyboard xkb_variant colemak
fi
fi
else
current="$(setxkbmap -query | awk '/variant/{print $2}')"
if [ "$current" = "colemak" ]; then
setxkbmap -layout us
else
setxkbmap -layout us -variant colemak
fi
fi
;;
*)
echo "Usage: ctl keyboard {toggle}" >&2
exit 1
;;
esac
;;
audio)
require wpctl pw-dump jq
case "$2" in
out)
sinks="$(pw-dump | jq -r '.[] | select(.info.props."media.class" == "Audio/Sink") | "\(.id)\t\(.info.props."node.description" // .info.props."node.name" // "unknown")"')"
[ -z "$sinks" ] && exit 0
if [ "$XDG_SESSION_TYPE" = x11 ]; then
choice="$(printf "%s\n" "$sinks" | awk -F'\t' '{print $1": "$2}' | dmenu -i -p "select sink:" | cut -d: -f1)"
else
choice="$(printf "%s\n" "$sinks" | awk -F'\t' '{print $1": "$2}' | fuzzel --dmenu --prompt="sink: " | cut -d: -f1)"
fi
[ "$choice" ] && wpctl set-default "$choice"
;;
in)
sources="$(pw-dump | jq -r '.[] | select(.info.props."media.class" == "Audio/Source") | "\(.id)\t\(.info.props."node.description" // .info.props."node.name" // "unknown")"')"
[ -z "$sources" ] && exit 0
if [ "$XDG_SESSION_TYPE" = x11 ]; then
choice="$(printf "%s\n" "$sources" | awk -F'\t' '{print $1": "$2}' | dmenu -i -p "select source:" | cut -d: -f1)"
else
choice="$(printf "%s\n" "$sources" | awk -F'\t' '{print $1": "$2}' | fuzzel --dmenu --prompt="source: " | cut -d: -f1)"
fi
[ "$choice" ] && wpctl set-default "$choice"
;;
*)
echo "Usage: ctl audio {in|out}" >&2
exit 1
;;
esac
;;
brightness)
require brightnessctl notify-send
BRIGHT_STEP=5
case "$2" in
up) brightnessctl set "$BRIGHT_STEP"%+ ;;
down) brightnessctl set "$BRIGHT_STEP"%- ;;
*) echo "Usage: ctl brightness {up|down}" >&2; exit 1 ;;
esac
pct=$(awk -v cur="$(brightnessctl get)" -v max="$(brightnessctl max)" 'BEGIN { printf "%d", cur * 100 / max }')
filled=$((pct / 5))
empty=$((20 - filled))
bar=""
i=0; while [ "$i" -lt "$filled" ]; do bar="${bar}"; i=$((i + 1)); done
i=0; while [ "$i" -lt "$empty" ]; do bar="${bar}"; i=$((i + 1)); done
notify-send -a ctl -t 2500 -r 5555 "$bar"
;;
volume)
require wpctl notify-send
SINK="@DEFAULT_AUDIO_SINK@"
VOL_STEP=5
get_vol() { wpctl get-volume "$SINK" | awk '{printf "%d", $2 * 100}'; }
case "$2" in
up) wpctl set-volume "$SINK" "${VOL_STEP}%+" --limit 1.0 ;;
down) wpctl set-volume "$SINK" "${VOL_STEP}%-" ;;
toggle) wpctl set-mute "$SINK" toggle ;;
*) echo "Usage: ctl volume {up|down|toggle}" >&2; exit 1 ;;
esac
vol=$(get_vol)
filled=$((vol / 5))
empty=$((20 - filled))
bar=""
i=0; while [ "$i" -lt "$filled" ]; do bar="${bar}"; i=$((i + 1)); done
i=0; while [ "$i" -lt "$empty" ]; do bar="${bar}"; i=$((i + 1)); done
if wpctl get-volume "$SINK" | grep -q MUTED; then
icon="󰖁"
elif [ "$vol" -le 33 ]; then
icon="󰕿"
elif [ "$vol" -le 66 ]; then
icon="󰖀"
else
icon="󰕾"
fi
notify-send -a ctl -t 2500 -r 5556 "$icon $bar"
;;
power)
require fuzzel
lock="󰌾 Lock"
suspend="󰒲 Suspend"
logout="󰍃 Logout"
reboot="󰜉 Reboot"
shutdown="󰐥 Shutdown"
chosen="$(printf '%s\n' "$lock" "$suspend" "$logout" "$reboot" "$shutdown" | fuzzel --dmenu --hide-prompt --lines=5 --width=20 --no-icons)"
case "$chosen" in
"$lock") hyprlock ;;
"$suspend") systemctl suspend ;;
"$logout") hyprctl dispatch exit ;;
"$reboot") systemctl reboot ;;
"$shutdown") systemctl poweroff ;;
esac
;;
*)
echo "Usage: ctl {screenshot|ocr|keyboard|audio|brightness|volume|power}" >&2
exit 1
;;
esac