initial commit

This commit is contained in:
2026-09-14 15:31:20 -05:00
commit 438546d84f
44 changed files with 3292 additions and 0 deletions
+30
View File
@@ -0,0 +1,30 @@
#!/usr/bin/env bash
# Backlight control with a dunst OSD. usage: brightness up|down|set <n>
set -uo pipefail
STEP="${BRIGHTNESS_STEP:-5}"
MIN=1 # never go fully dark — that looks like a crash
ID=2594
command -v brightnessctl >/dev/null || { echo "brightnessctl not found" >&2; exit 1; }
pct() { brightnessctl -m | awk -F, '{gsub(/%/,"",$4); print $4}'; }
case "${1:-}" in
up) brightnessctl -q set "${STEP}%+" ;;
down) brightnessctl -q set "${STEP}%-" ;;
set) brightnessctl -q set "${2:?need a percentage}%" ;;
""|-h|--help) echo "usage: brightness up|down|set <percent>"; exit 0 ;;
*) echo "unknown action: $1" >&2; exit 2 ;;
esac
# Enforce the floor
current="$(pct)"
if (( current < MIN )); then
brightnessctl -q set "${MIN}%"
current="$MIN"
fi
command -v dunstify >/dev/null && \
dunstify -a osd -u low -r "$ID" -h "int:value:$current" \
-i display-brightness "Brightness ${current}%"
+60
View File
@@ -0,0 +1,60 @@
#!/usr/bin/env bash
# ---------------------------------------------------------------------------
# Minimal xrandr multi-monitor switcher.
# display auto | duplicate | extend | internal | external | list
# "internal" is whichever output name looks like a laptop panel.
# ---------------------------------------------------------------------------
set -uo pipefail
command -v xrandr >/dev/null || { echo "xrandr not installed" >&2; exit 1; }
mapfile -t CONNECTED < <(xrandr --query | awk '/ connected/{print $1}')
INTERNAL="$(printf '%s\n' "${CONNECTED[@]}" | grep -m1 -E '^(eDP|LVDS|DSI)' || true)"
[[ -z "$INTERNAL" ]] && INTERNAL="${CONNECTED[0]:-}"
mapfile -t EXTERNALS < <(printf '%s\n' "${CONNECTED[@]}" | grep -v "^${INTERNAL}$" || true)
reload_bar() { "$HOME/.config/polybar/launch.sh" >/dev/null 2>&1 & }
restore_bg() { "$HOME/.local/bin/set-wallpaper" >/dev/null 2>&1 & }
case "${1:-auto}" in
list)
xrandr --query | grep -E ' connected|disconnected' ; exit 0 ;;
internal)
args=(--output "$INTERNAL" --auto --primary)
for e in "${EXTERNALS[@]}"; do args+=(--output "$e" --off); done
xrandr "${args[@]}" ;;
external)
if [[ ${#EXTERNALS[@]} -eq 0 ]]; then echo "no external display connected" >&2; exit 1; fi
args=(--output "${EXTERNALS[0]}" --auto --primary --output "$INTERNAL" --off)
for e in "${EXTERNALS[@]:1}"; do args+=(--output "$e" --off); done
xrandr "${args[@]}" ;;
duplicate)
if [[ ${#EXTERNALS[@]} -eq 0 ]]; then echo "no external display connected" >&2; exit 1; fi
args=(--output "$INTERNAL" --auto --primary)
for e in "${EXTERNALS[@]}"; do args+=(--output "$e" --auto --same-as "$INTERNAL"); done
xrandr "${args[@]}" ;;
extend)
if [[ ${#EXTERNALS[@]} -eq 0 ]]; then echo "no external display connected" >&2; exit 1; fi
args=(--output "$INTERNAL" --auto --primary)
prev="$INTERNAL"
for e in "${EXTERNALS[@]}"; do
args+=(--output "$e" --auto --right-of "$prev")
prev="$e"
done
xrandr "${args[@]}" ;;
auto)
# Extend if something external is plugged in, otherwise laptop panel only.
if [[ ${#EXTERNALS[@]} -gt 0 ]]; then exec "$0" extend; else exec "$0" internal; fi ;;
*)
echo "usage: display auto|duplicate|extend|internal|external|list" >&2; exit 2 ;;
esac
sleep 0.5
restore_bg
reload_bar
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
# Restart a daemon idempotently — safe to call from i3's exec_always.
# usage: restart-daemon <name> [args…]
set -uo pipefail
name="${1:?usage: restart-daemon <name> [args...]}"
shift || true
command -v "$name" >/dev/null 2>&1 || { echo "restart-daemon: $name not installed" >&2; exit 0; }
pkill -x "$name" >/dev/null 2>&1 || true
for _ in {1..20}; do
pgrep -x "$name" >/dev/null || break
sleep 0.1
done
pgrep -x "$name" >/dev/null && pkill -9 -x "$name"
log="${XDG_CACHE_HOME:-$HOME/.cache}/$name.log"
mkdir -p "$(dirname "$log")"
exec "$name" "$@" >>"$log" 2>&1 &
+49
View File
@@ -0,0 +1,49 @@
#!/usr/bin/env bash
# ---------------------------------------------------------------------------
# Screenshots with maim. usage: screenshot full|area|window [--clip-only]
# Images land in ~/Pictures/Screenshots and are copied to the clipboard.
# ---------------------------------------------------------------------------
set -uo pipefail
DIR="${SCREENSHOT_DIR:-$(xdg-user-dir PICTURES 2>/dev/null || echo "$HOME/Pictures")/Screenshots}"
STAMP="$(date +%Y-%m-%d_%H-%M-%S)"
FILE="$DIR/screenshot_$STAMP.png"
MODE="${1:-full}"
CLIP_ONLY=0
[[ "${2:-}" == "--clip-only" ]] && CLIP_ONLY=1
command -v maim >/dev/null || { echo "maim not installed" >&2; exit 1; }
mkdir -p "$DIR"
# Selection colour = Catppuccin mauve (maim wants floats 0-1)
SELECT_COLOR="0.776,0.627,0.965,0.5"
case "$MODE" in
full)
maim --hidecursor --quality 10 "$FILE" ;;
area)
maim --select --hidecursor --quality 10 --color="$SELECT_COLOR" \
--bordersize=2 --nodrag "$FILE" ;;
window)
maim --window "$(xdotool getactivewindow)" --hidecursor --quality 10 "$FILE" ;;
*)
echo "usage: screenshot full|area|window [--clip-only]" >&2; exit 2 ;;
esac
# maim exits non-zero when the user cancels an area selection with Escape.
if [[ ! -s "$FILE" ]]; then
rm -f "$FILE"
exit 0
fi
command -v xclip >/dev/null && xclip -selection clipboard -t image/png -i "$FILE"
if [[ "$CLIP_ONLY" == "1" ]]; then
rm -f "$FILE"
command -v dunstify >/dev/null && \
dunstify -a screenshot -i camera-photo "Screenshot" "Copied to clipboard"
exit 0
fi
command -v dunstify >/dev/null && \
dunstify -a screenshot -i "$FILE" "Screenshot saved" "$(basename "$FILE")\nCopied to clipboard"
+65
View File
@@ -0,0 +1,65 @@
#!/usr/bin/env bash
# ---------------------------------------------------------------------------
# Apply a wallpaper with feh and remember the choice.
#
# set-wallpaper # restore the remembered wallpaper
# set-wallpaper /path/img.png # set a specific image
# set-wallpaper --random # pick a random one from the wallpaper dir
# set-wallpaper --cache # (re)build the betterlockscreen cache
#
# The current selection is stored in $XDG_STATE_HOME/current-wallpaper.
# ---------------------------------------------------------------------------
set -uo pipefail
WALLPAPER_DIR="${WALLPAPER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/wallpapers}"
STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}"
STATE_FILE="$STATE_DIR/current-wallpaper"
MODE="${FEH_MODE:---bg-fill}"
mkdir -p "$STATE_DIR" "$WALLPAPER_DIR"
pick_random() {
find -L "$WALLPAPER_DIR" -type f \
\( -iname '*.png' -o -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.webp' \) \
| shuf -n1
}
first_available() {
find -L "$WALLPAPER_DIR" -type f \
\( -iname '*.png' -o -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.webp' \) \
| sort | head -n1
}
cache_lockscreen=0
target=""
case "${1:-}" in
--random) target="$(pick_random)" ;;
--cache) cache_lockscreen=1 ;;
"") target="$(cat "$STATE_FILE" 2>/dev/null || true)" ;;
-*) echo "unknown option: $1" >&2; exit 2 ;;
*) target="$1"; cache_lockscreen=1 ;;
esac
# Fall back through: remembered -> anything in the dir -> a flat Macchiato base
if [[ -z "$target" || ! -f "$target" ]]; then
target="$(first_available)"
fi
if [[ -z "$target" || ! -f "$target" ]]; then
echo "set-wallpaper: no image found in $WALLPAPER_DIR — using a flat colour" >&2
command -v xsetroot >/dev/null && xsetroot -solid "#24273a"
exit 0
fi
command -v feh >/dev/null || { echo "set-wallpaper: feh is not installed" >&2; exit 1; }
feh --no-fehbg "$MODE" "$target"
printf '%s\n' "$target" > "$STATE_FILE"
# Keep the lock screen in sync with the desktop. Caching is slow (imagemagick
# blurs the image at every resolution), so only do it when the image changed.
if [[ "$cache_lockscreen" == "1" ]] && command -v betterlockscreen >/dev/null; then
( betterlockscreen --update "$target" --blur 0.5 >/dev/null 2>&1 &
disown ) 2>/dev/null || true
fi
+66
View File
@@ -0,0 +1,66 @@
#!/usr/bin/env bash
# Volume / mic control with a dunst OSD. usage: volume up|down|mute|micmute|set <n>
set -uo pipefail
STEP="${VOLUME_STEP:-5}"
MAX="${VOLUME_MAX:-100}"
SINK="@DEFAULT_AUDIO_SINK@"
SOURCE="@DEFAULT_AUDIO_SOURCE@"
ID=2593 # fixed notification id => the OSD replaces itself instead of stacking
have() { command -v "$1" >/dev/null 2>&1; }
have wpctl || { echo "wpctl (wireplumber) not found" >&2; exit 1; }
get_volume() {
wpctl get-volume "$SINK" | awk '{printf "%d", $2 * 100}'
}
is_muted() {
wpctl get-volume "$SINK" | grep -q MUTED
}
osd() {
have dunstify || return 0
local icon="$1" text="$2" value="$3"
dunstify -a osd -u low -r "$ID" -h "int:value:$value" -i "$icon" "$text"
}
case "${1:-}" in
up)
wpctl set-mute "$SINK" 0
wpctl set-volume -l "$(awk "BEGIN{print $MAX/100}")" "$SINK" "${STEP}%+"
;;
down)
wpctl set-mute "$SINK" 0
wpctl set-volume "$SINK" "${STEP}%-"
;;
set)
wpctl set-volume -l "$(awk "BEGIN{print $MAX/100}")" "$SINK" "${2:?need a percentage}%"
;;
mute)
wpctl set-mute "$SINK" toggle
;;
micmute)
wpctl set-mute "$SOURCE" toggle
if wpctl get-volume "$SOURCE" | grep -q MUTED; then
osd microphone-sensitivity-muted "Microphone muted" 0
else
osd microphone-sensitivity-high "Microphone live" 100
fi
exit 0
;;
""|-h|--help)
echo "usage: volume up|down|mute|micmute|set <percent>"; exit 0 ;;
*)
echo "unknown action: $1" >&2; exit 2 ;;
esac
vol="$(get_volume)"
if is_muted; then
osd audio-volume-muted "Muted" 0
elif (( vol >= 66 )); then osd audio-volume-high "Volume ${vol}%" "$vol"
elif (( vol >= 33 )); then osd audio-volume-medium "Volume ${vol}%" "$vol"
else osd audio-volume-low "Volume ${vol}%" "$vol"
fi
# Nudge polybar so the bar updates instantly rather than on its 5s poll
pkill -RTMIN+1 polybar 2>/dev/null || true