summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorSuleyman Farajli <suleyman@farajli.net>2025-11-25 18:47:27 +0400
committerSuleyman Farajli <suleyman@farajli.net>2025-11-25 18:47:27 +0400
commitd947956270b092df10637bb3531441caca698b86 (patch)
tree8c32170ef044687b11be79398140a36430e2ff0a /scripts
parentc388ade6b6d955138698731af02dfbe5c676439a (diff)
feat: new api for scripts
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/cli/noc15
-rwxr-xr-xscripts/cli/nospac11
-rwxr-xr-xscripts/cli/sdev80
-rwxr-xr-xscripts/cli/slight27
-rwxr-xr-xscripts/cli/svol30
-rwxr-xr-xscripts/daemons/bat-checkd16
-rwxr-xr-xscripts/daemons/mail-syncd6
-rwxr-xr-xscripts/daemons/notifd35
-rwxr-xr-xscripts/gui/br32
-rwxr-xr-xscripts/gui/nsend56
-rwxr-xr-xscripts/gui/sclip69
-rwxr-xr-xscripts/gui/sdev49
-rwxr-xr-xscripts/gui/shot37
-rwxr-xr-xscripts/gui/sslock67
-rwxr-xr-xscripts/gui/swall56
-rw-r--r--[-rwxr-xr-x]scripts/lib/lib_common.sh (renamed from scripts/slib)76
-rw-r--r--scripts/lib/lib_handle.sh140
17 files changed, 452 insertions, 350 deletions
diff --git a/scripts/cli/noc b/scripts/cli/noc
index 575566c..63bee86 100755
--- a/scripts/cli/noc
+++ b/scripts/cli/noc
@@ -1,6 +1,19 @@
#!/bin/sh
-# Remove empty lines and all the comments starting with "#"
+. "lib_common.sh"
+
+help() {
+cat << EOF
+${0}: Remove empty lines and all the comments starting with '#'.
+options:
+ -h Print this message and exit
+EOF
+exit 0
+}
+
+[ "${1}" = "-h" ] && help
+
+[ ${#} -gt 0 ] && invalid_use
for file in "${@}"; do
sed -i "s/\s*#.*//g; /^$/ d" "${file}"
diff --git a/scripts/cli/nospac b/scripts/cli/nospac
index 6ba466a..7ee5b36 100755
--- a/scripts/cli/nospac
+++ b/scripts/cli/nospac
@@ -1,5 +1,7 @@
#!/bin/sh
+. "lib_common.sh"
+
help() {
cat << EOF
${0}: Replace all the spaces in file and directory
@@ -7,13 +9,12 @@ names with "_" in in the current directory.
options:
-h Print this message and exit
EOF
+exit 0
}
-if [ ${#} -gt 0 ]; then
- [ ${#} = 1 ] && [ "${1}" = "-h" ] && help && exit 0
- printf "%s: Invalid usage\nTry '%s -h' for help.\n" "${0}" "${0}"
- exit 1
-fi
+[ "${1}" = "-h" ] && help
+
+[ ${#} -gt 0 ] && invalid_use
for file in ./*; do
newfile=$(echo "${file}" | tr ' ' '_')
diff --git a/scripts/cli/sdev b/scripts/cli/sdev
deleted file mode 100755
index c227771..0000000
--- a/scripts/cli/sdev
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/bin/sh
-
-. slib
-
-help() {
-cat << EOF
-${0}: Disable and Enable devices
-options:
- -e [dev] Enable dev
- -d [dev] Disable dev
- -t [dev] Toggle dev
- -l List devices
- -h Print this message and exit
-
-Note: Nondescriptive inputs may disable/enable unwanted devices.
-EOF
-
-exit 0
-}
-
-get_id() {
- if ! dev=$(xinput list --name-only | grep -i -m1 "${1}" ); then
- err "Couldn't get device"
- fi
- id="${dev#∼ }"
-}
-
-xenable() {
- echo "${id}"
-
- if ! xinput enable "${1}" > /dev/null 2>&1; then
- err "Failed to enable dev."
- else
- exit 0
- fi
-}
-
-xdisable() {
- echo "${id}"
-
- if ! xinput disable "${1}" > /dev/null 2>&1; then
- err "Failed to disable dev."
- else
- exit 0
- fi
-}
-
-check_program "xinput"
-
-while getopts "e:d:t:lh" option; do
- case "${option}" in
- e)
- get_id "${OPTARG}"
- xenable "${id}"
- ;;
- d)
- get_id "${OPTARG}"
- xdisable "${id}"
- ;;
- t)
- get_id "${OPTARG}"
-
- [ "${id}" = "${dev}" ] && xdisable "${id}"
- xenable "${id}"
- ;;
- l)
- if ! xinput list 2>/dev/null; then
- err "Listing Failed"
- else
- exit 0
- fi
- ;;
- h) help ;;
-
- *) invalid_use -h ;;
-
- esac
-done
-
-invalid_use
diff --git a/scripts/cli/slight b/scripts/cli/slight
index 54edbcd..4efbf19 100755
--- a/scripts/cli/slight
+++ b/scripts/cli/slight
@@ -1,6 +1,7 @@
#!/bin/sh
-. slib
+. "lib_common.sh"
+. "lib_handle.sh"
help() {
cat << EOF
@@ -14,34 +15,22 @@ options:
NOTE: Script interprets values as percentages
EOF
-
exit 0
}
-check_program "brightnessctl"
-
+brightness_handle check_program
[ ${#} != 1 ] && [ ${#} != 2 ] && invalid_use
while getopts "i:d:s:ph" option; do
case "${option}" in
- i) run --reload-status "brightnessctl set +${OPTARG}%" ;;
-
- d) run --reload-status "brightnessctl set ${OPTARG}-%" ;;
-
- s) run --reload-status "brightnessctl set ${OPTARG}%" ;;
-
- p)
- if ! echo $(( ($(brightnessctl g) * 100) / $(brightnessctl m) )); then
- err "Failed to get current brightness"
- else
- exit 0
- fi
- ;;
+ i) run --reload-status "brightness_handle up ${OPTARG}" ;;
+ d) run --reload-status "brightness_handle down ${OPTARG}" ;;
+ s) run --reload-status "brightness_handle set ${OPTARG}" ;;
+ t) run --reload-status "brightness_handle toggle" ;;
+ p) brightness_handle get-current ;;
h) help ;;
*) invalid_use -h ;;
-
esac
done
-
invalid_use
diff --git a/scripts/cli/svol b/scripts/cli/svol
index 0488633..5ce6848 100755
--- a/scripts/cli/svol
+++ b/scripts/cli/svol
@@ -1,10 +1,11 @@
#!/bin/sh
-. slib
+. "lib_common.sh"
+. "lib_handle.sh"
help() {
cat << EOF
-${0}: Wrapper script to change volume
+${0}: Change volume
options:
-i [Vol] Increase volume by Vol
-d [Vol] Decrease volume by Vol
@@ -13,37 +14,24 @@ options:
-t Toggle between mute and unmute
-h Print this message and exit
EOF
-
exit 0
}
-check_program "pactl" "pulseaudio must be installed"
+volume_handle check_program
[ $# != 1 ] && [ $# != 2 ] && invalid_use
while getopts "i:d:s:pth" option; do
case "${option}" in
- i) run --reload-status "pactl set-sink-volume @DEFAULT_SINK@ +${OPTARG}%" ;;
-
- d) run --reload-status "pactl set-sink-volume @DEFAULT_SINK@ -${OPTARG}%" ;;
-
- s) run --reload-status "pactl set-sink-volume @DEFAULT_SINK@ ${OPTARG}%" ;;
-
- t) run --reload-status "pactl set-sink-mute @DEFAULT_SINK@ toggle" ;;
-
- p)
- if ! pactl get-sink-volume @DEFAULT_SINK@ \
- | sed -e 's,.* \([0-9][0-9]*\)%.*,\1,' | head -n1 2>/dev/null; then
- err "Failed to get current volume"
- else
- exit 0
- fi
- ;;
+ i) run --reload-status "volume_handle up ${OPTARG}" ;;
+ d) run --reload-status "volume_handle down ${OPTARG}" ;;
+ s) run --reload-status "volume_handle set ${OPTARG}" ;;
+ t) run --reload-status "volume_handle toggle" ;;
+ p) volume_handle get-current ;;
h) help ;;
*) invalid_use -h ;;
esac
done
-
invalid_use
diff --git a/scripts/daemons/bat-checkd b/scripts/daemons/bat-checkd
new file mode 100755
index 0000000..2c272b8
--- /dev/null
+++ b/scripts/daemons/bat-checkd
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+# FIXME: hardcoded battery
+BAT="/sys/class/power_supply/BAT0"
+
+while true; do
+ percent=$(cat "${BAT}/capacity")
+ status=$(cat "${BAT}/status")
+
+ # Only notify if battery is low AND not charging
+ if [ "${status}" = "Discharging" ] && [ "${percent}" -lt 7 ]; then
+ nsend -s "Battery" "Critically low: ${percent}%"
+ fi
+
+ sleep 120
+done
diff --git a/scripts/daemons/mail-syncd b/scripts/daemons/mail-syncd
new file mode 100755
index 0000000..e317ace
--- /dev/null
+++ b/scripts/daemons/mail-syncd
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+while true; do
+ mbsync -a
+ sleep 300
+done
diff --git a/scripts/daemons/notifd b/scripts/daemons/notifd
new file mode 100755
index 0000000..9ad5697
--- /dev/null
+++ b/scripts/daemons/notifd
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+. "lib_handle.sh"
+
+FIFO=/tmp/noti.fifo
+FILE=/tmp/noti.txt
+
+[ -p "${FIFO}" ] || mkfifo "${FIFO}"
+
+exec 3<"${FIFO}"
+exec 4>"${FIFO}"
+
+tpid=""
+
+cancel() {
+ [ -n "${tpid}" ] && kill "${tpid}" 2>/dev/null
+ tpid=""
+}
+
+while read n <&3; do
+ [ "${n}" = "-1" ] && { cancel; continue; }
+
+ case "${n}" in ''|*[!0-9]*) continue ;; esac
+
+ cancel
+
+ [ "${n}" -gt 0 ] || { :>"${FILE}"; notify_handle reload; continue; }
+
+ (
+ sleep "${n}"
+ :>"${FILE}"
+ notify_handle reload
+ ) &
+ tpid=$!
+done
diff --git a/scripts/gui/br b/scripts/gui/br
index 474b1b1..428e24b 100755
--- a/scripts/gui/br
+++ b/scripts/gui/br
@@ -1,6 +1,6 @@
#!/bin/sh
-. slib
+. "lib_common.sh"
help() {
cat << EOF
@@ -9,33 +9,25 @@ options:
[link] Open link
-h Print this message and exit
-NOTE: bookmarks file is located at ~/.config/sites/bookmarks
+NOTE: bookmarks file is located at ~/.config/sites/bookmarks.txt
EOF
-
exit 0
}
-alias dmenucmd="dmenu -bw 1 -c -g 1 -l 25"
-
-[ -z "${BROWSER}" ] && browser="qutebrowser" || browser="${BROWSER}"
+[ -z "${BROWSER}" ] && BROWSER="firefox"
if [ "${#}" -eq 0 ]; then
+ bookmark_path="${XDG_CONFIG_HOME:-$HOME/.config}/sites/bookmarks.txt"
+ [ -e "${bookmark_path}" ] || err "Couldn't find bookmarks file"
- link_file="${XDG_CONFIG_HOME:-$HOME/.config}/sites/bookmarks.txt"
-
- check_program "dmenu"
+ . "lib_handle.sh"
- [ -z "${XDG_HOME_CONFIG}" ] || link_file="${XDG_HOME_CONFIG}"/sites/bookmarks.txt
- [ -e "${link_file}" ] || err "Couldn't find bookmarks file"
+ link=$(< "${bookmark_path}" menu_handle center)
- link=$(< "${link_file}" dmenucmd)
-
- [ -z "${link}" ] || "${browser}" "${link}"
+ [ -z "${link}" ] || "${BROWSER}" "${link}"
+fi
-elif [ "${#}" -eq 1 ]; then
- [ "${1}" = "-h" ] && help
+[ "${#}" -ne 1 ] && invalid_use
+[ "${1}" = "-h" ] && help
- "${browser}" "${1}"
-else
- invalid_use
-fi
+"${BROWSER}" "${1}"
diff --git a/scripts/gui/nsend b/scripts/gui/nsend
index 1bfc1f4..e1cbd78 100755
--- a/scripts/gui/nsend
+++ b/scripts/gui/nsend
@@ -1,34 +1,44 @@
#!/bin/sh
-. slib
+. "lib_common.sh"
+. "lib_handle.sh"
help() {
cat << EOF
-${0}: Wrapper script to send notifications
+${argv0}: Send notifications
options:
- -s [Name] [Msg] Send Msg with Name
- -s [Msg] Send Msg Without Name
+ -s [Msg] Send Msg
+ -t [Time] Disappear after Time (in second)
-h Print this message and exit
-EOF
+Note: time must be between 0 and 300,
+by default time is set to unlimited.
+EOF
exit 0
}
-case "${#}" in
-1)
- [ "${1}" = "-h" ] && help
- invalid_use
-;;
-2)
- [ "${1}" = "-s" ] || invalid_use
- notification_string="${2}"
-;;
-3)
- [ "${1}" = "-s" ] || invalid_use
- notification_string="${2}: ${3}"
-;;
-*) invalid_use ;;
-esac
-
-
-send_notification "${notification_string}"
+[ "${#}" -eq 0 ] && invalid_use
+
+time=-1
+while getopts "s:t:h" option; do
+ case "${option}" in
+ s) msg="${OPTARG}" ;;
+ t)
+ time="${OPTARG}"
+
+ case "${time}" in
+ ''|*[!0-9]*) err "Not a number: ${time}" ;;
+ esac
+
+ [ "${time}" -gt 300 ] && err "Out of range: ${time}"
+ ;;
+ h) help ;;
+
+ *) invalid_use -h ;;
+ esac
+done
+
+shift $((OPTIND - 1))
+[ ${#} != 0 ] && invalid_use
+
+notify_handle send "${time}" "${msg}"
diff --git a/scripts/gui/sclip b/scripts/gui/sclip
index 4854aa1..56ea57f 100755
--- a/scripts/gui/sclip
+++ b/scripts/gui/sclip
@@ -1,71 +1,72 @@
#!/bin/sh
-. slib
+. "lib_common.sh"
+. "lib_handle.sh"
help() {
cat << EOF
-${0}: print the clipboard content
+${progname}: print the clipboard content
options:
- -h Print this message and exit
-s Do not send notifications
-c [text] Copy text to clipboard
-f [file] Copy content of file into clipboard
-i Copy standart input into clipboard
+ -h Print this message and exit
EOF
-
exit 0
}
-check_program "xclip"
+clipboard_handle check_program
+
+if [ "${#}" -eq 0 ]; then
+ clipboard_handle get-clipboard
+ exit $?
+fi
-i_flg=0
+read_stdin=0
silent=0
while getopts "f:c:sih" option; do
case "${option}" in
f) filepath="${OPTARG}" ;;
-
c) input="${OPTARG}" ;;
-
s) silent=1 ;;
-
- i) i_flg=1 ;;
-
+ i) read_stdin=1 ;;
h) help ;;
*) invalid_use -h ;;
esac
done
-
shift $((OPTIND - 1))
[ "${#}" -ne 0 ] && invalid_use
if [ -n "${filepath}" ]; then
- mime_type=$(file --mime-type -b "${filepath}")
-
- if [ "${silent}" -eq 1 ]; then
- run "xclip -selection clipboard -t ${mime_type} -i ${filepath}"
- fi
+ mime_type=$(file_handle get-mime_type "$filepath") || {
+ err "Failed to detect mime type"; exit 1;}
- run --success-notify "${filepath} copied" \
- --failure-notify "${filepath} failed to copy" \
- "xclip -selection clipboard -t ${mime_type} -i ${filepath}"
-fi
+ clipboard_handle file "${mime_type}" "${filepath}"
+ status=$?
-[ "${i_flg}" -eq 1 ] && input=$(cat)
+else
+ [ -z "$input" ] && [ "$read_stdin" -eq 1 ] && input=$(cat)
+ [ -z "$input" ] && err "Empty input"
-if [ -n "${input}" ]; then
- # Don't use `run` since pipes are used
- printf '%s' "${input}" | xclip -selection clipboard
+ printf '%s' "${input}" | clipboard_handle text
+ status=$?
+fi
- if [ $? -eq 0 ]; then
- [ "${silent}" -eq 0 ] && send_notification "${argv0}:" "'${input}' copied"
- exit 0
+if [ "${silent}" -eq 0 ]; then
+ if [ "${status}" -eq 0 ]; then
+ if [ -n "${filepath}" ]; then
+ notify_handle "Copied file: ${filepath}"
+ else
+ notify_handle "Copied text"
+ fi
+ else
+ if [ -n "${filepath}" ]; then
+ notify_handle "Failed to copy file: ${filepath}"
+ else
+ notify_handle "Failed to copy text"
+ fi
fi
-
- [ "${silent}" -eq 0 ] && send_notification "${argv0}:" "'${input}' failed to copy"
-
- exit 1
fi
-
-run "xclip -o -selection clipboard"
diff --git a/scripts/gui/sdev b/scripts/gui/sdev
new file mode 100755
index 0000000..340bdb1
--- /dev/null
+++ b/scripts/gui/sdev
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+. "lib_common.sh"
+. "lib_handle.sh"
+
+help() {
+cat << EOF
+${0}: Disable and Enable devices
+options:
+ -e [dev] Enable dev
+ -d [dev] Disable dev
+ -t [dev] Toggle dev
+ -l List devices
+ -h Print this message and exit
+
+Note: Nondescriptive inputs may disable/enable unwanted devices.
+EOF
+exit 0
+}
+
+input_device_handle check_program
+
+get_id() {
+ id=$(input_device_handle get-id "$1") || exit 1
+ printf '%s\n' "$id"
+}
+
+while getopts "e:d:t:lh" option; do
+ case "${option}" in
+ e) run "input_device_handle enable $(get_id ${OPTARG})" ;;
+ d) run "input_device_handle disable $(get_id ${OPTARG})" ;;
+ t)
+ id=$(get_id ${OPTARG})
+ if input_device_handle is_enabled "${id}"; then
+ input_device_handle disable "${id}"
+ else
+ input_device_handle enable "${id}"
+ fi
+ exit $?
+ ;;
+ l) run "input_device_handle list" ;;
+ h) help ;;
+
+ *) invalid_use -h ;;
+
+ esac
+done
+
+invalid_use
diff --git a/scripts/gui/shot b/scripts/gui/shot
index 712f60b..a133c16 100755
--- a/scripts/gui/shot
+++ b/scripts/gui/shot
@@ -1,6 +1,7 @@
#!/bin/sh
-. slib
+. "lib_common.sh"
+. "lib_handle.sh"
help() {
cat << EOF
@@ -8,29 +9,26 @@ ${0}: Wrapper script to take screenshots
options:
-d [File] Write to File
-s Select the area with the cursor
+ -w Select the area with the cursor
-h Print this message and exit
-NOTE: save directory is ~/pics/screenshot
+NOTE: save directory is ~/media/photo/screenshot
EOF
-
exit 0
}
-check_program "scrot"
-
+screenshot_handle check_program
default_dir="${XDG_SCREENSHOT_DIR:-${HOME}/media/photo/screenshot}"
-s_flg=""
-while getopts "d:sh" option; do
+mode="fullscreen"
+while getopts "d:swh" option; do
case "${option}" in
- d) input="${OPTARG}" ;;
-
- s) s_flg="1" ;;
-
- h) help ;;
-
- *) invalid_use -h ;;
+ d) input="${OPTARG}" ;;
+ s) mode="select" ;;
+ w) mode="focused-window" ;;
+ h) help ;;
+ *) invalid_use -h ;;
esac
done
@@ -48,12 +46,13 @@ outfile="${input}"
[ -d "${input}" ] && outfile="${input}/$(date '+%b%d::%H%M%S').png"
if [ ! -e "$(dirname "${outfile}")" ]; then
- mkdir -p "$(dirname "${outfile}")" > /dev/null 2>&1 \
- || err "Failed to create directory"
+ mkdir -p "$(dirname "${outfile}")" ||
+ err "Failed to create directory ${outfile}"
fi
-if [ "${s_flg}" = "1" ]; then
- run --reload-compositor "scrot -zs ${outfile}" "${outfile}"
+if [ "${mode}" = "select" ]; then
+ run --no-exit --reload-compositor \
+ "screenshot_handle ${mode} ${outfile}" && echo "${outfile}"
else
- run "scrot -z ${outfile}" "${outfile}"
+ screenshot_handle "${mode}" "${outfile}" && echo "${outfile}"
fi
diff --git a/scripts/gui/sslock b/scripts/gui/sslock
index 26ba2cf..8a3284e 100755
--- a/scripts/gui/sslock
+++ b/scripts/gui/sslock
@@ -1,59 +1,44 @@
#!/bin/sh
-. slib
+. "lib_common.sh"
+. "lib_handle.sh"
help() {
cat << EOF
-${0}: Wrapper script to take screenshots
+${0}: Lock screen
options:
- -n Black screen
- -b Blur
- -c Take the current state of the desktop
+ -n Black screen lock
-h Print this message and exit
EOF
-
exit 0
}
-check_program "slock"
-
-blur=0
-set_current_state=0
-current_wallpaper="${XDG_CACHE_HOME:-$HOME/.cache}/wallpaper/current"
-while getopts "bcnh" option; do
- case "${option}" in
- b)
- check_program "mogrify" "imagemagick must be installed"
- blur=1 ;;
-
- c)
- check_program "scrot"
- set_current_state=1
- ;;
- n)
- slock
- exit 0;;
-
- h) help ;;
-
- *) invalid_use -h ;;
+trap 'rm -f "${lock_image}"' EXIT INT TERM HUP
- esac
-done
-
-shift $((OPTIND - 1))
+if [ "${#}" -eq 1 ]; then
+ [ "${1}" = "-h" ] && help
+ [ "${1}" = "-n" ] || invalid_use
+ screenlock_handle
+ exit 0
+fi
-[ "${#}" -eq 0 ] || invalid_use
+[ "${#}" -ne 0 ] && invalid_use
-background="/tmp/$(date '+%b%d::%H%M%S').png"
+mode=$(printf "Blank\nBlur\nWallpaper" | menu_handle default)
+if [ "${mode}" = "Blank" ]; then
+ screenlock_handle
+ exit 0
+fi
-if [ "$set_current_state" -eq 0 ]; then
- # Avoid distorting the wallpaper when calling `mogrify`
- cp "${current_wallpaper}" "${background}"
-else
- scrot -z "${background}"
+lock_image=$(get_random_filename .png)
+if [ "${mode}" = "Blur" ]; then
+ screenshot_handle fullscreen "${lock_image}"
+ image_handle blur "${lock_image}"
fi
-[ "${blur}" -eq 1 ] && mogrify -blur 0x8 "${background}"
+if [ "${mode}" = "Wallpaper" ]; then
+ current_wallpaper="${XDG_CACHE_HOME:-$HOME/.cache}/wallpaper/current"
+ cp "${current_wallpaper}" "${lock_image}"
+fi
-slock -f "${background}"
+screenlock_handle "${lock_image}"
diff --git a/scripts/gui/swall b/scripts/gui/swall
index a225481..5f22ec8 100755
--- a/scripts/gui/swall
+++ b/scripts/gui/swall
@@ -1,6 +1,7 @@
#!/bin/sh
-. slib
+. "lib_common.sh"
+. "lib_handle.sh"
help() {
cat << EOF
@@ -12,58 +13,53 @@ options:
NOTE: default directory is ~/.local/share/wallpapers
A symlink at ~/.cache/wallpapers/current is created pointing to the selected wallpaper.
-
EOF
-
exit 0
}
-check_program "xwallpaper"
-
+wallpaper_handle check_program
SYMLINK="${XDG_CACHE_HOME:-$HOME/.cache}/wallpaper/current"
-if [ "${#}" = 0 ]; then
- input="${XDG_DATA_HOME:-$HOME/.local/share}/wallpapers"
-elif [ "${#}" != 1 ] && [ "${#}" != 2 ]; then
- invalid_use
-fi
+[ "${#}" -eq 0 ] && input="${XDG_DATA_HOME:-$HOME/.local/share}/wallpapers"
+[ "${#}" -gt 2 ] && invalid_use
-while getopts "hcld:" option; do
+while getopts "cd:h" option; do
case "${option}" in
c)
- unlink "${SYMLINK}"
- run --reload-compositor "xwallpaper --clear" ;;
-
+ rm -f "${SYMLINK}"
+ run --reload-compositor "wallpaper_handle clear"
+ ;;
d) input="${OPTARG}" ;;
-
h) help ;;
*) invalid_use -h ;;
-
esac
done
-
shift $((OPTIND - 1))
[ "${#}" != 0 ] && invalid_use
if [ -n "${input}" ]; then
- case $(file -L -b --mime-type "${input}") in
- image/*) image="${input}" ;;
-
- inode/directory) waldir="${input}" ;;
-
- *) err "Couldn't read given file" ;;
- esac
+ if [ -d "${input}" ]; then
+ waldir="${input}"
+ elif [ -f "${input}" ]; then
+ case "${input}" in
+ *.jpg|*.JPG|*.jpeg|*.JPEG|*.png|*.PNG) image="${input}" ;;
+ *) err "Unsupported file type" ;;
+ esac
+ else
+ err "Couldn't read given file"
+ fi
fi
-if [ -n "${waldir}" ]; then
- image=$(find "${waldir}" -iregex '.*.\(jpg\|jpeg\|png\)' 2>/dev/null \
- | shuf -n 1 )
+if [ -d "$waldir" ]; then
+ image=$(
+ find "$waldir" \( -name '*.jpg' -o -name '*.jpeg' -o -name '*.png' \) 2>/dev/null |
+ awk 'BEGIN{srand()} {a[NR]=$0} END{if(NR>0) print a[int(rand()*NR)+1]}'
+ )
fi
[ -z "${image}" ] && err "No image file found"
-mkdir -p "$(dirname "${SYMLINK}")" && \
- ln -sf "${image}" "${SYMLINK}" && \
- run "xwallpaper --zoom ${image}" "${image}"
+mkdir -p "$(dirname "${SYMLINK}")" && ln -sf "${image}" "${SYMLINK}"
+wallpaper_handle set "${image}" && echo "${image}"
diff --git a/scripts/slib b/scripts/lib/lib_common.sh
index 0df4a50..58ee5ba 100755..100644
--- a/scripts/slib
+++ b/scripts/lib/lib_common.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-argv0=$(basename "${0}")
+progname=$(basename "${0}")
# @FUNCTION: err
# @USAGE: [-x] <message> ...
@@ -12,10 +12,10 @@ argv0=$(basename "${0}")
#
# This function is intended for fatal errors; it always exits the script.
# @EXAMPLE:
-# err "Invalid usage" "Try '${argv0} -h' for help."
+# err "Invalid usage" "Try '${progname} -h' for help."
err() {
if [ "${1}" != "-x" ]; then
- printf "%s: " "${argv0}"
+ printf "%s: " "${progname}"
else
shift
fi
@@ -36,8 +36,8 @@ err() {
# "Try 'program -h' for help."
invalid_use() {
- [ "${1}" = "-h" ] && err -x "Try '${argv0} -h' for help."
- err "Invalid usage" "Try '${argv0} -h' for help."
+ [ "${1}" = "-h" ] && err -x "Try '${progname} -h' for help."
+ err "Invalid usage" "Try '${progname} -h' for help."
}
# @FUNCTION: check_program
@@ -59,23 +59,6 @@ check_program() {
err "${1} must be installed"
}
-# @FUNCTION: send_notification
-# @USAGE: send_notification <message> ...
-# @DESCRIPTION:
-# Write a notification message to a temporary file and trigger a dwm notification signal.
-# The message is written to /tmp/noti.txt. If writing fails, a warning is printed to stderr.
-# After writing, a dwm signal is sent using `xsetroot -name "fsignal:1"`.
-#
-# @EXAMPLE:
-# Send a desktop notification with the message "Backup complete".
-#
-# send_notification "Backup complete"
-
-send_notification() {
- echo "$@" > /tmp/noti.txt || echo "Warning: failed to write to notification file" >&2
- xsetroot -name "fsignal:1"
-}
-
# @FUNCTION: get_random_filename
# @USAGE: get_random_filename [parentdir] <extension>
# @DESCRIPTION:
@@ -84,7 +67,7 @@ send_notification() {
# @EXAMPLE:
# Get a filepath in the `/var` directory with the extension `.png`
#
-# get_random_filename /var .png
+# get_random_filename .png /var
get_random_filename() {
[ "${#}" -eq 2 ] && parentdir="${2}" || parentdir="/tmp"
@@ -131,42 +114,21 @@ get_random_filename() {
# "xwallpaper --zoom ${image}" "Wallpaper updated" "Wallpaper failed"
run() {
- relstat=0
- compstat=0
- exitval=0
-
- while [ $# -gt 0 ]; do
- case "$1" in
- --reload-status) relstat=1 ;;
- --reload-compositor) compstat=1 ;;
- --success-notify) success_msg="${2}"; shift ;;
- --failure-notify) failure_msg="${2}"; shift ;;
- *) break;
- esac
- shift
- done
-
- if [ "${compstat}" -eq 1 ]; then
- pgrep -x picom > /dev/null && killall picom
- fi
-
- if ${1}; then
- [ -n "${2}" ] && echo "${2}"
- [ -n "${success_msg}" ] && send_notification "${argv0}:" "${success_msg}"
- else
- [ -n "${3}" ] && err "${3}"
- [ -n "${failure_msg}" ] && send_notification "${argv0}:" "${failure_msg}"
+ no_exit=0
+ reload_status=0
+ reload_compositor=0
- exitval=1
- fi
+ [ "${1}" = "--no-exit" ] && no_exit=1 && shift
+ [ "${1}" = "--reload-status" ] && reload_status=1 && shift
+ [ "${1}" = "--reload-compositor" ] && reload_compositor=1 && shift
- if [ "${relstat}" -eq 1 ]; then
- slreload || echo "Warning: Failed to reload slstatus" >&2
- fi
+ trap '
+ [ "${reload_status}" -eq 1 ] && status_handle reload
+ [ "${reload_compositor}" -eq 1 ] && compositor_handle start
+ ' EXIT
- if [ "${compstat}" -eq 1 ]; then
- picom -b || echo "Warning: Failed to start picom" >&2
- fi
+ [ "${reload_compositor}" -eq 1 ] && compositor_handle stop
- exit "${exitval}"
+ eval "${@}"
+ [ "${no_exit}" -eq 1 ] || exit "${?}"
}
diff --git a/scripts/lib/lib_handle.sh b/scripts/lib/lib_handle.sh
new file mode 100644
index 0000000..d4524d9
--- /dev/null
+++ b/scripts/lib/lib_handle.sh
@@ -0,0 +1,140 @@
+#!/bin/sh
+. "lib_common.sh"
+
+volume_handle() {
+ case "${1}" in
+ "up") pactl set-sink-volume @DEFAULT_SINK@ +"${2}"% ;;
+ "down") pactl set-sink-volume @DEFAULT_SINK@ -"${2}"% ;;
+ "set") pactl set-sink-volume @DEFAULT_SINK@ "${2}"% ;;
+ "toggle") pactl set-sink-mute @DEFAULT_SINK@ toggle;;
+ "get-current")
+ pactl get-sink-volume @DEFAULT_SINK@ |
+ sed -n 's/.* \([0-9][0-9]*%\).*/\1/p'
+ ;;
+ "check_program")
+ check_program "pactl" "pulseaudio must be installed" ;;
+
+ esac
+}
+
+brightness_handle() {
+ case "${1}" in
+ "up") brightnessctl set +"${2}"% ;;
+ "down") brightnessctl set "${2}"-% ;;
+ "set") brightnessctl set "${2}"% ;;
+ "get-current")
+ printf '%s\n' \
+ $(( ($(brightnessctl g) * 100) / $(brightnessctl m) ))
+ ;;
+ "check_program") check_program "brightnessctl"
+ esac
+}
+
+screenshot_handle() {
+ case "${1}" in
+ "fullscreen") flags="-z" ;;
+ "select") flags="-zs" ;;
+ "focused-window") flags="-zu" ;;
+ "check_program")
+ check_program "scrot"
+ return
+ ;;
+ esac
+ shift
+ scrot "${flags}" "${1}"
+}
+
+wallpaper_handle() {
+ case "${1}" in
+ "clear") xwallpaper --clear ;;
+ "set") xwallpaper --zoom "${2}" ;;
+ "check_program") check_program "xwallpaper" ;;
+ esac
+
+}
+
+screenlock_handle() {
+ if [ "${#}" -eq 0 ]; then
+ slock
+ else
+ slock -f "${1}"
+ fi
+}
+
+input_device_handle() {
+ case "$1" in
+ "enable") xinput enable "${2}";;
+ "disable") xinput disable "${2}";;
+ "list") xinput list ;;
+ "get-id")
+ dev=$(xinput list --name-only | grep -i -m1 "${1}" ) || return 1
+ printf "${dev#∼ }"
+ ;;
+ "is_enabled")
+ xinput list-props "${2}" | grep -q "Device Enabled.*1$"
+ return $?
+ ;;
+ "check_program") check_program "xclip" ;;
+ esac
+}
+
+clipboard_handle() {
+ case "${1}" in
+ "text") xclip -selection clipboard ;;
+ "file") xclip -selection clipboard -t "${2}" -i "${3}" ;;
+ "get-clipboard") xclip -o -selection clipboard ;;
+ esac
+}
+
+image_handle() {
+ case "${1}" in
+ "blur") mogrify -blur 0x8 "${2}" ;;
+ "check_program")
+ check_program "mogrify" "imagemagick must be installed"
+ ;;
+ esac
+}
+
+file_handle() {
+ file=$2
+ case $1 in
+ get-mime_type)
+ m=$(file --mime-type -b "$file" 2>/dev/null) && { echo "$m"; return; }
+ m=$(file -I "$file" 2>/dev/null) && { m=${m#*: }; m=${m%%;*}; echo "$m"; return; }
+ m=$(file -i "$file" 2>/dev/null) && { m=${m#*: }; m=${m%%;*}; echo "$m"; return; }
+ return 1
+ ;;
+ esac
+}
+
+notify_handle() {
+ case "${1}" in
+ "reload") xsetroot -name "fsignal:1" ;;
+ "send")
+ echo "${2}" > /tmp/noti.fifo
+ shift 2
+ printf "%s\n" "$*" > /tmp/noti.txt
+ xsetroot -name "fsignal:1"
+ ;;
+ esac
+}
+
+compositor_handle() {
+ case "${1}" in
+ "start") pgrep -x picom >/dev/null || picom -b & ;;
+ "stop") pgrep -x picom >/dev/null && pkill -x picom ;;
+ esac
+}
+
+status_handle() {
+ [ "${1}" = "reload" ] && slreload
+}
+
+menu_handle() {
+ case "${1}" in
+ "default") flags="" ;;
+ "center") flags="-bw 1 -c -g 1 -l 25" ;;
+ esac
+ shift
+ dmenu ${flags}
+}