added timer

main
The_miro 2026-05-08 15:16:01 +02:00
parent 4b8dd4f5d9
commit c61766960b
9 changed files with 478 additions and 166 deletions

View File

@ -88,7 +88,7 @@ bind = $mainMod CTRL, M, exec, ~/.config/scripts/toggle-layout.sh
bind = $mainMod, S, exec, [tag +mixer] pavucontrol bind = $mainMod, S, exec, [tag +mixer] pavucontrol
bind = $mainMod, F1, exec, [tag +centered] kitty ~/.config/scripts/helpmenu.sh bind = $mainMod, F1, exec, [tag +centered] kitty ~/.config/scripts/helpmenu.sh
bind = $mainMod CTRL, T, exec, [tag +centered] kitty --class timer-popup bash ~/.config/scripts/timer.sh bind = $mainMod CTRL, T, exec, [tag +centered] kitty bash ~/.config/scripts/timer-pick
bind = $mainMod, U, exec, [tag +centered-L] kitty btop bind = $mainMod, U, exec, [tag +centered-L] kitty btop
bind = $mainMod SHIFT, F1, exec, [tag +centered-L] kitty nvim ~/.config/binds.conf bind = $mainMod SHIFT, F1, exec, [tag +centered-L] kitty nvim ~/.config/binds.conf
bind = $mainMod CTRL, E, exec, ~/.config/scripts/screenrotationwcw.sh bind = $mainMod CTRL, E, exec, ~/.config/scripts/screenrotationwcw.sh

View File

@ -44,3 +44,4 @@ application/x-extension-xht=firefox.desktop;
application/xml=nvim.desktop; application/xml=nvim.desktop;
text/x-python=nvim.desktop; text/x-python=nvim.desktop;
video/mp4=firefox.desktop;vlc.desktop; video/mp4=firefox.desktop;vlc.desktop;
application/x-shellscript=nvim.desktop;

0
desktopenvs/hyprland/scripts/frequentcommands.list Normal file → Executable file
View File

View File

@ -1,11 +1,22 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Background timer: sleeps, notifies, rings thrice in 30s unless dismissed # Background timer: sleeps, notifies, rings thrice in 30s unless dismissed
# Usage: timer-notify.sh <seconds> <label> # Usage: timer-notify.sh <seconds> <label> [--verbose]
DURATION=${1:?missing duration} DURATION=${1:?missing duration}
LABEL=${2:-"00:00:00"} LABEL=${2:-"00:00:00"}
VERBOSE=0
[[ "${3:-}" == "--verbose" ]] && VERBOSE=1
sleep "$DURATION" if [[ $VERBOSE -eq 1 ]]; then
printf 'Timer started: %s\n\n' "$LABEL"
for (( i=DURATION; i>0; i-- )); do
printf '\r %02d:%02d:%02d remaining...' $((i/3600)) $(( (i%3600)/60 )) $((i%60))
sleep 1
done
printf '\r 00:00:00 — timer fired! \n\n'
else
sleep "$DURATION"
fi
# Find a ring sound (freedesktop stereo sounds) # Find a ring sound (freedesktop stereo sounds)
SOUND="" SOUND=""

View File

@ -0,0 +1,201 @@
#!/usr/bin/env bash
# timer-pick — TUI time picker
# Install: ~/.config/scripts/timer-pick (companion: timer-run in same dir)
SCRIPTS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
set -uo pipefail
ESC=$'\e'; CSI="${ESC}["
cup() { printf "${CSI}%d;%dH" "$1" "$2"; }
cls() { printf "${CSI}2J${CSI}H"; }
hide() { printf "${CSI}?25l"; }
show() { printf "${CSI}?25h"; }
b="${CSI}1m" ; d="${CSI}2m" ; r="${CSI}0m"
cy="${CSI}96m"; gn="${CSI}92m"
yl="${CSI}93m"; wh="${CSI}97m"; gy="${CSI}90m"
rv="${CSI}7m"
FIELDS=(HH MM SS)
MAX=(99 59 59)
VALUES=(0 0 0)
ACTIVE=1
LABEL=""
TW=34; IW=32; CW=10
BR=2; BC=2
hl() { printf '─%.0s' $(seq 1 "$1"); }
redraw() {
local row=$BR col=$BC
cup $row $col; printf "${d}╭$(hl $IW)╮${r}"
(( row++ )); cup $row $col
printf "${d}│${r}${b}${cy} ⏱ Set Timer%-*s${r}${d}│${r}" $(( IW - 14 )) ""
(( row++ )); cup $row $col
printf "${d}├$(hl $CW)┬$(hl $CW)┬$(hl $CW)┤${r}"
# labels
(( row++ )); cup $row $col; printf "${d}│${r}"
for i in 0 1 2; do
local lpad=$(( (CW - 2) / 2 )) rpad=$(( CW - 2 - (CW-2)/2 ))
(( i == ACTIVE )) \
&& printf "%*s${yl}${b}${FIELDS[$i]}${r}%*s" $lpad "" $rpad "" \
|| printf "%*s${gy}${FIELDS[$i]}${r}%*s" $lpad "" $rpad ""
(( i < 2 )) && printf "${d}│${r}"
done; printf "${d}│${r}"
# up arrows
(( row++ )); cup $row $col; printf "${d}│${r}"
for i in 0 1 2; do
local lpad=$(( (CW-1) / 2 )) rpad=$(( CW - 1 - (CW-1)/2 ))
(( i == ACTIVE )) \
&& printf "%*s${yl}${b}▲${r}%*s" $lpad "" $rpad "" \
|| printf "%*s${gy}▲${r}%*s" $lpad "" $rpad ""
(( i < 2 )) && printf "${d}│${r}"
done; printf "${d}│${r}"
# values
(( row++ )); cup $row $col; printf "${d}│${r}"
for i in 0 1 2; do
local vstr; printf -v vstr '%02d' "${VALUES[$i]}"
local lpad=$(( (CW-4) / 2 )) rpad=$(( CW - 4 - (CW-4)/2 ))
(( i == ACTIVE )) \
&& printf "%*s${rv}${wh}${b} %s ${r}%*s" $lpad "" "$vstr" $rpad "" \
|| printf "%*s${d} %s ${r}%*s" $lpad "" "$vstr" $rpad ""
(( i < 2 )) && printf "${d}│${r}"
done; printf "${d}│${r}"
# down arrows
(( row++ )); cup $row $col; printf "${d}│${r}"
for i in 0 1 2; do
local lpad=$(( (CW-1) / 2 )) rpad=$(( CW - 1 - (CW-1)/2 ))
(( i == ACTIVE )) \
&& printf "%*s${yl}${b}▼${r}%*s" $lpad "" $rpad "" \
|| printf "%*s${gy}▼${r}%*s" $lpad "" $rpad ""
(( i < 2 )) && printf "${d}│${r}"
done; printf "${d}│${r}"
(( row++ )); cup $row $col; printf "${d}├$(hl $IW)┤${r}"
(( row++ )); cup $row $col
local ld="${LABEL:-(optional)}"
printf "${d}│${r} ${gy}label:${r} ${cy}%-*s${r}${d}│${r}" $(( IW - 8 )) "$ld"
(( row++ )); cup $row $col; printf "${d}├$(hl $IW)┤${r}"
(( row++ )); cup $row $col
printf "${d}│${r} ${gy}h/l${r} field ${gy}j/k${r} value ${gy}[N]j/k${r} ${d}│${r}"
(( row++ )); cup $row $col
printf "${d}│${r} ${gy}i${r} label ${gy}0/G${r} min/max ${gn}↵${r} start ${d}│${r}"
(( row++ )); cup $row $col; printf "${d}╰$(hl $IW)╯${r}"
cup $(( row + 1 )) 1
}
read_label() {
show
local lrow=$(( BR + 9 )) lcol=$(( BC + 9 ))
cup $lrow $lcol; printf "${CSI}K"
local buf="" ch
while IFS= read -rsn1 ch; do
case "$ch" in
$'\n'|$'\r'|$'\e') break ;;
$'\x7f'|$'\b')
[[ -n $buf ]] && buf="${buf%?}"
cup $lrow $lcol; printf "${CSI}K%s" "$buf" ;;
*) [[ ${#buf} -lt $(( IW - 10 )) ]] && buf+="$ch" && printf "%s" "$ch" ;;
esac
done
LABEL="$buf"; hide
}
cleanup() {
# only reset tty if we actually changed it
[[ "${TTY_SAVED:-0}" == "1" ]] && stty sane 2>/dev/null
show
cls
tput cup 0 0 2>/dev/null
}
main() {
# Wait for kitty to fully attach the pty — critical when launched via Hyprland
# keybind where the window and pty aren't synchronised at script start.
local tries=0
until [[ -t 0 && -t 1 ]]; do
sleep 0.05
(( tries++ ))
(( tries > 40 )) && exit 1 # give up after 2s
done
hide; cls
stty -echo -icanon min 1 time 0
TTY_SAVED=1
trap cleanup EXIT INT TERM
redraw
local ch seq count_buf=""
while true; do
IFS= read -rsn1 ch || continue
if [[ $ch == $'\e' ]]; then
IFS= read -rsn2 -t 0.05 seq || seq=""
ch="${ch}${seq}"
fi
if [[ $ch =~ ^[1-9]$ ]]; then count_buf+="$ch"; redraw; continue; fi
local N=1
[[ -n $count_buf && $count_buf =~ ^[0-9]+$ ]] && N=$count_buf
case "$ch" in
$'\t'|$'\e[C'|l) ACTIVE=$(( (ACTIVE + 1) % 3 )); count_buf="" ;;
$'\e[Z'|$'\e[D'|h) ACTIVE=$(( (ACTIVE + 2) % 3 )); count_buf="" ;;
'^') ACTIVE=0; count_buf="" ;;
'$') ACTIVE=2; count_buf="" ;;
$'\e[A'|k)
local mx=${MAX[$ACTIVE]} v=${VALUES[$ACTIVE]}
local nv=$(( v + N )); (( nv > mx )) && nv=$mx
VALUES[$ACTIVE]=$nv; count_buf="" ;;
$'\e[B'|j)
local v=${VALUES[$ACTIVE]}
local nv=$(( v - N )); (( nv < 0 )) && nv=0
VALUES[$ACTIVE]=$nv; count_buf="" ;;
0)
if [[ -n $count_buf ]]; then count_buf+="0"; redraw; continue; fi
VALUES[$ACTIVE]=0; count_buf="" ;;
G) VALUES[$ACTIVE]=${MAX[$ACTIVE]}; count_buf="" ;;
i) count_buf=""; read_label ;;
''|$'\n')
count_buf=""
local total=$(( VALUES[0]*3600 + VALUES[1]*60 + VALUES[2] ))
if (( total == 0 )); then redraw; continue; fi
TTY_SAVED=0
stty sane 2>/dev/null; show; cls; tput cup 0 0 2>/dev/null
# SIG_IGN for SIGHUP is inherited through exec, eliminating the race
# between fork() and setsid() creating its own session. Without this,
# kitty closing the pty on exit sends SIGHUP to the foreground process
# group (which includes the child in non-interactive bash) before setsid
# has a chance to move it to a new session.
( trap '' SIGHUP; exec setsid bash "$SCRIPTS_DIR/timer-run" "$total" "$LABEL" </dev/null >/dev/null 2>&1 ) &
exit 0 ;;
q|Q) exit 0 ;;
*) count_buf="" ;;
esac
redraw
done
}
main

View File

@ -0,0 +1,110 @@
#!/usr/bin/env bash
# timer-run <total_seconds> [label]
# Runs entirely in background. No terminal needed after launch.
# Sends a dunst notification + audio beep when done.
#
# Install: ~/.config/scripts/timer-run (companion: timer-pick in same dir)
TOTAL="${1:?missing seconds}"
LABEL="${2:-}"
# ── source the user environment if running without a login shell ───────────────
# When launched from Hyprland keybind → kitty → exec, the process inherits
# kitty's env which already has DBUS_SESSION_BUS_ADDRESS, XDG_RUNTIME_DIR etc.
# But after setsid detach those are preserved since we don't re-login.
# We do need to make sure XDG_RUNTIME_DIR is set for pipewire/pulse socket paths.
if [[ -z "${XDG_RUNTIME_DIR:-}" ]]; then
export XDG_RUNTIME_DIR="/run/user/$(id -u)"
fi
# ── detach from terminal immediately ──────────────────────────────────────────
# Preserve the full environment across the setsid re-exec (no login shell).
if [[ -t 0 || -t 1 || -t 2 ]]; then
( trap '' SIGHUP; exec setsid bash "$0" "$TOTAL" "$LABEL" </dev/null >/dev/null 2>&1 ) &
exit 0
fi
# ── sleep until done ──────────────────────────────────────────────────────────
sleep "$TOTAL"
# ── format a human-readable duration ─────────────────────────────────────────
fmt_dur() {
local s=$1 h=0 m=0 out=""
h=$(( s / 3600 )); s=$(( s % 3600 ))
m=$(( s / 60 )); s=$(( s % 60 ))
(( h > 0 )) && out+="${h}h "
(( m > 0 )) && out+="${m}m "
(( s > 0 || (h == 0 && m == 0) )) && out+="${s}s"
echo "${out% }"
}
DURATION_STR=$(fmt_dur "$TOTAL")
NOTIF_SUMMARY="⏰ Timer done${LABEL:+ — $LABEL}"
NOTIF_BODY="Set for ${DURATION_STR}. Finished at $(date '+%H:%M:%S')."
# ── dunst notification ────────────────────────────────────────────────────────
# notify-send needs DBUS_SESSION_BUS_ADDRESS. If not in env, find it via the
# running dunst process (reliable on single-user Wayland/Hyprland setups).
if [[ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ]]; then
local_uid=$(id -u)
# try to grab it from the environment of any process owned by this user
for pid in $(pgrep -u "$local_uid" dunst 2>/dev/null); do
addr=$(cat /proc/$pid/environ 2>/dev/null \
| tr '\0' '\n' \
| grep '^DBUS_SESSION_BUS_ADDRESS=' \
| cut -d= -f2-)
if [[ -n $addr ]]; then
export DBUS_SESSION_BUS_ADDRESS="$addr"
break
fi
done
fi
if command -v notify-send &>/dev/null; then
notify-send \
--urgency=critical \
--expire-time=0 \
--icon=alarm-timer \
"$NOTIF_SUMMARY" \
"$NOTIF_BODY"
fi
# ── audio alert ───────────────────────────────────────────────────────────────
# pw-play / paplay need PIPEWIRE_RUNTIME_DIR or PULSE_RUNTIME_PATH which live
# under XDG_RUNTIME_DIR — already ensured above.
_beep_pcm() {
python3 - <<'PYEOF'
import struct, math, sys
RATE = 44100
FREQ = 880.0
VOL = 0.65
BEEPS = 3
DUR = 0.55
GAP = 0.18
def sine(freq, secs):
n = int(RATE * secs)
return [int(VOL * 32767 * math.sin(2 * math.pi * freq * i / RATE)) for i in range(n)]
def silence(secs):
return [0] * int(RATE * secs)
samples = []
for i in range(BEEPS):
samples += sine(FREQ, DUR)
if i < BEEPS - 1:
samples += silence(GAP)
sys.stdout.buffer.write(struct.pack(f'<{len(samples)}h', *samples))
PYEOF
}
if command -v pw-play &>/dev/null; then
_beep_pcm | pw-play --rate=44100 --channels=1 --format=s16 - 2>/dev/null
elif command -v paplay &>/dev/null; then
_beep_pcm | paplay --raw --rate=44100 --channels=1 --format=s16le - 2>/dev/null
elif command -v aplay &>/dev/null; then
_beep_pcm | aplay -q -r 44100 -c 1 -f S16_LE - 2>/dev/null
fi

View File

@ -1,162 +0,0 @@
#!/usr/bin/env bash
# TUI timer setter — vim keys, big-digit hh:mm:ss
# ── Setup ──────────────────────────────────────────────────────────────────────
cleanup() { tput cnorm; tput rmcup; }
trap cleanup EXIT INT TERM
tput smcup
tput civis
# ── Colors ─────────────────────────────────────────────────────────────────────
R="$(tput sgr0)"
NORMAL="$(tput bold)$(tput setaf 7)"
SELECT="$(tput bold)$(tput setaf 6)" # cyan — active field
TITLE="$(tput bold)$(tput setaf 5)" # magenta
DIM="$(tput dim)$(tput setaf 7)"
ERR="$(tput bold)$(tput setaf 1)" # red
# ── Block digits — DIGITS[digit*5 + row] ───────────────────────────────────────
DIGITS=(
"█████" "█ █" "█ █" "█ █" "█████" # 0
" █ " " █ " " █ " " █ " " █ " # 1
"█████" " █" "█████" "█ " "█████" # 2
"█████" " █" "█████" " █" "█████" # 3
"█ █" "█ █" "█████" " █" " █" # 4
"█████" "█ " "█████" " █" "█████" # 5
"█████" "█ " "█████" "█ █" "█████" # 6
"█████" " █" " █" " █" " █" # 7
"█████" "█ █" "█████" "█ █" "█████" # 8
"█████" "█ █" "█████" " █" "█████" # 9
)
COLON=(" " "█" " " "█" " ")
# ── State ──────────────────────────────────────────────────────────────────────
VALUES=(0 0 0)
LIMITS=(23 59 59)
LABELS=("HOURS" "MINUTES" "SECONDS")
FIELD=0
SHOW_ERR=0
# ── Draw helpers ───────────────────────────────────────────────────────────────
draw_field() { # draw_field row col val active
local y=$1 x=$2 val=$3 active=$4
local tens=$((val / 10)) units=$((val % 10))
local color; [[ $active -eq 1 ]] && color=$SELECT || color=$NORMAL
for row in 0 1 2 3 4; do
tput cup $((y + row)) $x
printf '%s%s %s%s' \
"$color" \
"${DIGITS[$((tens * 5 + row))]}" \
"${DIGITS[$((units * 5 + row))]}" \
"$R"
done
}
draw_colon() { # draw_colon row col
local y=$1 x=$2
for row in 0 1 2 3 4; do
tput cup $((y + row)) $((x + 1))
printf '%s%s%s' "$DIM" "${COLON[$row]}" "$R"
done
}
draw() {
local W H
W=$(tput cols); H=$(tput lines)
printf '\033[2J\033[H' # clear + home (no flicker vs tput clear)
# Title
local title="─── T I M E R ───"
tput cup 2 $(( (W - ${#title}) / 2 ))
printf '%s%s%s' "$TITLE" "$title" "$R"
# Layout: field(11) + colon(3) + field(11) + colon(3) + field(11) = 39 wide
local sx=$(( (W - 39) / 2 ))
local dy=$(( (H - 5) / 2 - 1 ))
(( dy < 4 )) && dy=4
local -a fx=( $sx $((sx + 14)) $((sx + 28)) )
local -a cx=( $((sx + 11)) $((sx + 25)) )
for i in 0 1 2; do
local active=0; [[ $i -eq $FIELD ]] && active=1
draw_field $dy "${fx[$i]}" "${VALUES[$i]}" $active
done
for x in "${cx[@]}"; do
draw_colon $dy $x
done
# Labels
local ly=$((dy + 6))
for i in 0 1 2; do
local label="${LABELS[$i]}"
local lx=$(( fx[$i] + (11 - ${#label}) / 2 ))
tput cup $ly $lx
if [[ $i -eq $FIELD ]]; then
printf '%s%s%s' "$SELECT" "$label" "$R"
else
printf '%s%s%s' "$DIM" "$label" "$R"
fi
done
# Error
if [[ $SHOW_ERR -eq 1 ]]; then
local msg="set a non-zero time first"
tput cup $((ly + 2)) $(( (W - ${#msg}) / 2 ))
printf '%s%s%s' "$ERR" "$msg" "$R"
fi
# Hint
local hint="h/l field j/k adjust Enter start q cancel"
tput cup $((H - 2)) $(( (W - ${#hint}) / 2 ))
printf '%s%s%s' "$DIM" "$hint" "$R"
}
# ── Key reader — handles ESC sequences (arrow keys) ───────────────────────────
read_key() {
local key seq
IFS= read -rsn1 key
if [[ "$key" == $'\033' ]]; then
IFS= read -rsn2 -t 0.05 seq 2>/dev/null || true
key="$key$seq"
fi
printf '%s' "$key"
}
# ── Main loop ──────────────────────────────────────────────────────────────────
while true; do
draw
SHOW_ERR=0
key=$(read_key)
case "$key" in
q|$'\033')
exit 0
;;
h|$'\033[D')
FIELD=$(( (FIELD + 2) % 3 ))
;;
l|$'\033[C')
FIELD=$(( (FIELD + 1) % 3 ))
;;
k|$'\033[A')
VALUES[$FIELD]=$(( (VALUES[$FIELD] + 1) % (LIMITS[$FIELD] + 1) ))
;;
j|$'\033[B')
VALUES[$FIELD]=$(( (VALUES[$FIELD] - 1 + LIMITS[$FIELD] + 1) % (LIMITS[$FIELD] + 1) ))
;;
$'\n'|$'\r')
total=$(( VALUES[0] * 3600 + VALUES[1] * 60 + VALUES[2] ))
if (( total == 0 )); then
SHOW_ERR=1
else
label=$(printf '%02d:%02d:%02d' "${VALUES[0]}" "${VALUES[1]}" "${VALUES[2]}")
setsid bash "$HOME/.config/scripts/timer-notify.sh" "$total" "$label" &>/dev/null &
disown
exit 0
fi
;;
esac
done

View File

@ -0,0 +1,151 @@
#!/usr/bin/env bash
# TUI timer setter — vim keys, unicode frames, labeled fields
# Usage: timer.sh [-v|--verbose]
SCRIPT_DIR="$(cd "$(dirname "$(realpath "$0")")" && pwd)"
VERBOSE=0
for arg in "$@"; do
[[ "$arg" == "-v" || "$arg" == "--verbose" ]] && VERBOSE=1
done
cleanup() { tput cnorm; tput rmcup; }
trap cleanup EXIT INT TERM
tput smcup
tput civis
R="$(tput sgr0)"
NORMAL="$(tput setaf 7)"
SELECT="$(tput bold)$(tput setaf 6)"
TITLE="$(tput bold)$(tput setaf 5)"
DIM="$(tput dim)$(tput setaf 7)"
ERR="$(tput bold)$(tput setaf 1)"
VALUES=(0 0 0)
LIMITS=(23 59 59)
LABELS=("HOURS" "MINUTES" "SECONDS")
FIELD=0
SHOW_ERR=0
KEY=""
# draw_box row col val label active
# Box inner width = 10, total = 12, height = 6
draw_box() {
local y=$1 x=$2 val=$3 label=$4 active=$5
local num; printf -v num '%02d' "$val"
local inner=10
local tl tr bl br bh bv color
if [[ $active -eq 1 ]]; then
tl='╔' tr='╗' bl='╚' br='╝' bh='═' bv='║' color=$SELECT
else
tl='┌' tr='┐' bl='└' br='┘' bh='─' bv='│' color=$NORMAL
fi
local hline; printf -v hline '%*s' $inner ''; hline="${hline// /$bh}"
local lpad=$(( (inner - ${#label}) / 2 ))
local lrpad=$(( inner - lpad - ${#label} ))
local npad=$(( (inner - ${#num}) / 2 ))
local nrpad=$(( inner - npad - ${#num} ))
tput cup $y $x; printf '%s%s%s%s%s' "$color" "$tl" "$hline" "$tr" "$R"
tput cup $((y+1)) $x; printf '%s%s%*s%s%*s%s%s' "$color" "$bv" $lpad '' "$label" $lrpad '' "$bv" "$R"
tput cup $((y+2)) $x; printf '%s%s%*s%s%s' "$color" "$bv" $inner '' "$bv" "$R"
tput cup $((y+3)) $x; printf '%s%s%*s%s%*s%s%s' "$color" "$bv" $npad '' "$num" $nrpad '' "$bv" "$R"
tput cup $((y+4)) $x; printf '%s%s%*s%s%s' "$color" "$bv" $inner '' "$bv" "$R"
tput cup $((y+5)) $x; printf '%s%s%s%s%s' "$color" "$bl" "$hline" "$br" "$R"
}
draw_colon() {
local y=$1 x=$2
tput cup $((y+3)) $x
printf '%s %s' "$DIM" "$R"
}
draw() {
local W H
W=$(tput cols); H=$(tput lines)
printf '\033[2J\033[H'
local title="─── T I M E R ───"
tput cup 2 $(( (W - ${#title}) / 2 ))
printf '%s%s%s' "$TITLE" "$title" "$R"
# 3 boxes × 12 wide + 2 colons × 3 wide = 42 total
local total=42
local sx=$(( (W - total) / 2 ))
local dy=$(( (H - 6) / 2 ))
(( dy < 4 )) && dy=4
local -a bx=( $sx $((sx + 15)) $((sx + 30)) )
for i in 0 1 2; do
local active=0; [[ $i -eq $FIELD ]] && active=1
draw_box $dy "${bx[$i]}" "${VALUES[$i]}" "${LABELS[$i]}" $active
done
draw_colon $dy $((sx + 12))
draw_colon $dy $((sx + 27))
if [[ $SHOW_ERR -eq 1 ]]; then
local msg="set a non-zero time first"
tput cup $((dy + 7)) $(( (W - ${#msg}) / 2 ))
printf '%s%s%s' "$ERR" "$msg" "$R"
fi
local verbose_tag=""; [[ $VERBOSE -eq 1 ]] && verbose_tag=" [verbose]"
local hint="h/l field j/k adjust Enter start q cancel${verbose_tag}"
tput cup $((H - 2)) $(( (W - ${#hint}) / 2 ))
printf '%s%s%s' "$DIM" "$hint" "$R"
}
read_key() {
local seq
IFS= read -rsn1 KEY
if [[ "$KEY" == $'\033' ]]; then
IFS= read -rsn2 -t 0.05 seq 2>/dev/null || true
KEY="$KEY$seq"
fi
}
while true; do
draw
SHOW_ERR=0
read_key
case "$KEY" in
q|$'\033')
exit 0
;;
h|$'\033[D')
FIELD=$(( (FIELD + 2) % 3 ))
;;
l|$'\033[C')
FIELD=$(( (FIELD + 1) % 3 ))
;;
k|$'\033[A')
VALUES[$FIELD]=$(( (VALUES[$FIELD] + 1) % (LIMITS[$FIELD] + 1) ))
;;
j|$'\033[B')
VALUES[$FIELD]=$(( (VALUES[$FIELD] - 1 + LIMITS[$FIELD] + 1) % (LIMITS[$FIELD] + 1) ))
;;
$'\n'|$'\r')
total=$(( VALUES[0] * 3600 + VALUES[1] * 60 + VALUES[2] ))
if (( total == 0 )); then
SHOW_ERR=1
else
label=$(printf '%02d:%02d:%02d' "${VALUES[0]}" "${VALUES[1]}" "${VALUES[2]}")
if [[ $VERBOSE -eq 1 ]]; then
kitty --title "Timer: $label" bash "$SCRIPT_DIR/timer-notify.sh" "$total" "$label" --verbose &
disown
else
setsid bash "$SCRIPT_DIR/timer-notify.sh" "$total" "$label" &>/dev/null &
disown
fi
exit 0
fi
;;
esac
done

View File

@ -7,7 +7,7 @@
<property name="last-separator-position" type="int" value="139"/> <property name="last-separator-position" type="int" value="139"/>
<property name="misc-single-click" type="bool" value="false"/> <property name="misc-single-click" type="bool" value="false"/>
<property name="last-details-view-zoom-level" type="string" value="THUNAR_ZOOM_LEVEL_50_PERCENT"/> <property name="last-details-view-zoom-level" type="string" value="THUNAR_ZOOM_LEVEL_50_PERCENT"/>
<property name="last-details-view-column-widths" type="string" value="50,50,159,50,50,186,87,150,620,50,50,87,159,177"/> <property name="last-details-view-column-widths" type="string" value="50,50,159,50,50,186,87,645,580,50,50,96,159,231"/>
<property name="last-details-view-visible-columns" type="string" value="THUNAR_COLUMN_DATE_MODIFIED,THUNAR_COLUMN_GROUP,THUNAR_COLUMN_MIME_TYPE,THUNAR_COLUMN_NAME,THUNAR_COLUMN_SIZE,THUNAR_COLUMN_SIZE_IN_BYTES,THUNAR_COLUMN_TYPE"/> <property name="last-details-view-visible-columns" type="string" value="THUNAR_COLUMN_DATE_MODIFIED,THUNAR_COLUMN_GROUP,THUNAR_COLUMN_MIME_TYPE,THUNAR_COLUMN_NAME,THUNAR_COLUMN_SIZE,THUNAR_COLUMN_SIZE_IN_BYTES,THUNAR_COLUMN_TYPE"/>
<property name="last-side-pane" type="string" value="THUNAR_SIDEPANE_TYPE_TREE"/> <property name="last-side-pane" type="string" value="THUNAR_SIDEPANE_TYPE_TREE"/>
<property name="last-show-hidden" type="bool" value="true"/> <property name="last-show-hidden" type="bool" value="true"/>